@rubytech/create-sitedesk-code 0.1.521 → 0.1.522

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 (255) hide show
  1. package/dist/index.js +17 -3
  2. package/package.json +1 -1
  3. package/payload/platform/lib/account-schema-regions/package-lock.json +12 -0
  4. package/payload/platform/lib/active-rules/package-lock.json +12 -0
  5. package/payload/platform/lib/mcp-lifeline/package-lock.json +12 -0
  6. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +43 -6
  7. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
  8. package/payload/platform/plugins/docs/references/admin-ui.md +10 -0
  9. package/payload/platform/plugins/docs/references/internals.md +4 -0
  10. package/payload/platform/plugins/docs/references/outlook-guide.md +27 -4
  11. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  12. package/payload/platform/plugins/outlook/PLUGIN.md +9 -1
  13. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.d.ts +2 -0
  14. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.d.ts.map +1 -0
  15. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.js +151 -0
  16. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.js.map +1 -0
  17. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.d.ts +2 -0
  18. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.d.ts.map +1 -0
  19. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.js +151 -0
  20. package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.js.map +1 -0
  21. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js +38 -4
  22. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js.map +1 -1
  23. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.d.ts +2 -0
  24. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.d.ts.map +1 -0
  25. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.js +146 -0
  26. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.js.map +1 -0
  27. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.d.ts +2 -0
  28. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.d.ts.map +1 -0
  29. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.js +120 -0
  30. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.js.map +1 -0
  31. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js +8 -8
  32. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js.map +1 -1
  33. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.d.ts +2 -0
  34. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.d.ts.map +1 -0
  35. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.js +27 -0
  36. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.js.map +1 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.d.ts +2 -0
  38. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.d.ts.map +1 -0
  39. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.js +70 -0
  40. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.js.map +1 -0
  41. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.d.ts +2 -0
  42. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.d.ts.map +1 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.js +152 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.js.map +1 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.d.ts +57 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.d.ts.map +1 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.js +163 -0
  48. package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.js.map +1 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts +12 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts.map +1 -1
  51. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js +21 -1
  52. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js.map +1 -1
  53. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts +35 -4
  54. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts.map +1 -1
  55. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js +92 -10
  56. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js.map +1 -1
  57. package/payload/platform/plugins/outlook/mcp/dist/index.js +106 -3
  58. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  59. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +49 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
  61. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +126 -8
  62. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  63. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.d.ts +13 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.d.ts.map +1 -1
  65. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.js +9 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.js.map +1 -1
  67. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts +42 -8
  68. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts.map +1 -1
  69. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js +59 -19
  70. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js.map +1 -1
  71. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.d.ts +47 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.d.ts.map +1 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.js +67 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.js.map +1 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.d.ts +12 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.d.ts.map +1 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.js +18 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.js.map +1 -0
  79. package/payload/platform/plugins/outlook/references/auth.md +15 -2
  80. package/payload/platform/plugins/outlook/references/graph-surfaces.md +8 -0
  81. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +21 -1
  82. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  83. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
  84. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  85. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  86. package/payload/server/{chunk-AZLT4LVO.js → chunk-K7CJGZPU.js} +419 -189
  87. package/payload/server/{manager-CQBSUJXR.js → manager-RKL7JZ4Y.js} +3 -1
  88. package/payload/server/public/activity.html +5 -5
  89. package/payload/server/public/agents.html +4 -4
  90. package/payload/server/public/assets/{AdminLoginScreens-Dar_MMJm.js → AdminLoginScreens-zc2_qqh-.js} +1 -1
  91. package/payload/server/public/assets/AdminLoginScreens-zc2_qqh-.js.br +0 -0
  92. package/payload/server/public/assets/AdminLoginScreens-zc2_qqh-.js.gz +0 -0
  93. package/payload/server/public/assets/{AdminShell-CpaI2F_p.js → AdminShell-IGUdTx5q.js} +1 -1
  94. package/payload/server/public/assets/AdminShell-IGUdTx5q.js.br +0 -0
  95. package/payload/server/public/assets/{AdminShell-CpaI2F_p.js.gz → AdminShell-IGUdTx5q.js.gz} +0 -0
  96. package/payload/server/public/assets/{activity-B1rt4GIy.js → activity-DVgO8YuM.js} +1 -1
  97. package/payload/server/public/assets/activity-DVgO8YuM.js.br +0 -0
  98. package/payload/server/public/assets/activity-DVgO8YuM.js.gz +0 -0
  99. package/payload/server/public/assets/admin-xtpM7fgl.js +1 -0
  100. package/payload/server/public/assets/admin-xtpM7fgl.js.br +0 -0
  101. package/payload/server/public/assets/admin-xtpM7fgl.js.gz +0 -0
  102. package/payload/server/public/assets/{agents-BXq8woVf.js → agents-P0nTIxo-.js} +1 -1
  103. package/payload/server/public/assets/agents-P0nTIxo-.js.br +0 -0
  104. package/payload/server/public/assets/agents-P0nTIxo-.js.gz +0 -0
  105. package/payload/server/public/assets/{browser-1QSCPl3X.js → browser-Mw7DY3ft.js} +1 -1
  106. package/payload/server/public/assets/browser-Mw7DY3ft.js.br +0 -0
  107. package/payload/server/public/assets/browser-Mw7DY3ft.js.gz +0 -0
  108. package/payload/server/public/assets/{calendar-D009qWVV.js → calendar-B9gvL_1_.js} +1 -1
  109. package/payload/server/public/assets/calendar-B9gvL_1_.js.br +0 -0
  110. package/payload/server/public/assets/calendar-B9gvL_1_.js.gz +0 -0
  111. package/payload/server/public/assets/chat-DBGqh4wg.js +1 -0
  112. package/payload/server/public/assets/chat-DBGqh4wg.js.br +2 -0
  113. package/payload/server/public/assets/chat-DBGqh4wg.js.gz +0 -0
  114. package/payload/server/public/assets/chevron-left-Bl4vpOM0.js +1 -0
  115. package/payload/server/public/assets/chevron-left-Bl4vpOM0.js.br +0 -0
  116. package/payload/server/public/assets/chevron-right-BExigCnp.js +1 -0
  117. package/payload/server/public/assets/chevron-right-BExigCnp.js.br +0 -0
  118. package/payload/server/public/assets/clock-D8TJvgJC.js +1 -0
  119. package/payload/server/public/assets/clock-D8TJvgJC.js.br +0 -0
  120. package/payload/server/public/assets/data-HfFSxaC2.js +1 -0
  121. package/payload/server/public/assets/data-HfFSxaC2.js.br +0 -0
  122. package/payload/server/public/assets/data-HfFSxaC2.js.gz +0 -0
  123. package/payload/server/public/assets/{file-text-DwGAfCsd.js → file-text-dYBnXNEX.js} +1 -1
  124. package/payload/server/public/assets/file-text-dYBnXNEX.js.br +0 -0
  125. package/payload/server/public/assets/file-text-dYBnXNEX.js.gz +0 -0
  126. package/payload/server/public/assets/{graph-D-DGlfhW.js → graph-CDyzd1Et.js} +1 -1
  127. package/payload/server/public/assets/graph-CDyzd1Et.js.br +0 -0
  128. package/payload/server/public/assets/graph-CDyzd1Et.js.gz +0 -0
  129. package/payload/server/public/assets/{graph-labels-BbX3fXzl.js → graph-labels-D1LkKiJr.js} +1 -1
  130. package/payload/server/public/assets/graph-labels-D1LkKiJr.js.br +0 -0
  131. package/payload/server/public/assets/graph-labels-D1LkKiJr.js.gz +0 -0
  132. package/payload/server/public/assets/{maximize-2-C_-KapxH.js → maximize-2-M-iSaznd.js} +1 -1
  133. package/payload/server/public/assets/maximize-2-M-iSaznd.js.br +0 -0
  134. package/payload/server/public/assets/maximize-2-M-iSaznd.js.gz +0 -0
  135. package/payload/server/public/assets/{operator-CFrZVcv6.js → operator-9jfCv1Fg.js} +1 -1
  136. package/payload/server/public/assets/operator-9jfCv1Fg.js.br +0 -0
  137. package/payload/server/public/assets/operator-9jfCv1Fg.js.gz +0 -0
  138. package/payload/server/public/assets/{page-E74MYB18.js → page-CZ-73FAk.js} +1 -1
  139. package/payload/server/public/assets/page-CZ-73FAk.js.br +0 -0
  140. package/payload/server/public/assets/page-CZ-73FAk.js.gz +0 -0
  141. package/payload/server/public/assets/{page-CHt62f1_.js → page-CjwSt7kx.js} +1 -1
  142. package/payload/server/public/assets/page-CjwSt7kx.js.br +0 -0
  143. package/payload/server/public/assets/page-CjwSt7kx.js.gz +0 -0
  144. package/payload/server/public/assets/{public-CI6K1sNW.js → public-CN-ltC8x.js} +1 -1
  145. package/payload/server/public/assets/public-CN-ltC8x.js.br +0 -0
  146. package/payload/server/public/assets/public-CN-ltC8x.js.gz +0 -0
  147. package/payload/server/public/assets/{rotate-ccw-PWu_QGrD.js → rotate-ccw-Buopsc22.js} +1 -1
  148. package/payload/server/public/assets/rotate-ccw-Buopsc22.js.br +0 -0
  149. package/payload/server/public/assets/rotate-ccw-Buopsc22.js.gz +0 -0
  150. package/payload/server/public/assets/{routines-Cp3_XS7S.js → routines-C-yr8ddT.js} +1 -1
  151. package/payload/server/public/assets/routines-C-yr8ddT.js.br +0 -0
  152. package/payload/server/public/assets/routines-C-yr8ddT.js.gz +0 -0
  153. package/payload/server/public/assets/{skills-g8HvunPA.js → skills-DiiuVzDK.js} +1 -1
  154. package/payload/server/public/assets/skills-DiiuVzDK.js.br +0 -0
  155. package/payload/server/public/assets/skills-DiiuVzDK.js.gz +0 -0
  156. package/payload/server/public/assets/tasks-CnHIfn2_.js +1 -0
  157. package/payload/server/public/assets/tasks-CnHIfn2_.js.br +0 -0
  158. package/payload/server/public/assets/tasks-CnHIfn2_.js.gz +0 -0
  159. package/payload/server/public/assets/{time-entry-format-BXWuQ6Sw.js → time-entry-format-BBokCF-D.js} +1 -1
  160. package/payload/server/public/assets/time-entry-format-BBokCF-D.js.br +0 -0
  161. package/payload/server/public/assets/time-entry-format-BBokCF-D.js.gz +0 -0
  162. package/payload/server/public/assets/{triangle-alert-BNshRC13.js → triangle-alert-C_AcpTW5.js} +1 -1
  163. package/payload/server/public/assets/triangle-alert-C_AcpTW5.js.br +0 -0
  164. package/payload/server/public/assets/triangle-alert-C_AcpTW5.js.gz +0 -0
  165. package/payload/server/public/assets/{useCopyFeedback-CwTZ9DqH.js → useCopyFeedback-TdimmPVR.js} +1 -1
  166. package/payload/server/public/assets/useCopyFeedback-TdimmPVR.js.br +0 -0
  167. package/payload/server/public/assets/useCopyFeedback-TdimmPVR.js.gz +0 -0
  168. package/payload/server/public/assets/{useSubAccountSwitcher-BuUYMDWl.js → useSubAccountSwitcher-BwHqV55p.js} +1 -1
  169. package/payload/server/public/assets/useSubAccountSwitcher-BwHqV55p.js.br +0 -0
  170. package/payload/server/public/assets/{useSubAccountSwitcher-BuUYMDWl.js.gz → useSubAccountSwitcher-BwHqV55p.js.gz} +0 -0
  171. package/payload/server/public/assets/{useSubAccountSwitcher-dzDnmWq9.css → useSubAccountSwitcher-CsrPYqtm.css} +1 -1
  172. package/payload/server/public/assets/useSubAccountSwitcher-CsrPYqtm.css.br +0 -0
  173. package/payload/server/public/assets/{useSubAccountSwitcher-dzDnmWq9.css.gz → useSubAccountSwitcher-CsrPYqtm.css.gz} +0 -0
  174. package/payload/server/public/assets/{useVoiceRecorder-BGqV5R6u.js → useVoiceRecorder-BT2738ZS.js} +1 -1
  175. package/payload/server/public/assets/useVoiceRecorder-BT2738ZS.js.br +0 -0
  176. package/payload/server/public/assets/useVoiceRecorder-BT2738ZS.js.gz +0 -0
  177. package/payload/server/public/assets/{wrench-DQ045Pyk.js → wrench-B51s5kGA.js} +1 -1
  178. package/payload/server/public/assets/wrench-B51s5kGA.js.br +0 -0
  179. package/payload/server/public/assets/wrench-B51s5kGA.js.gz +0 -0
  180. package/payload/server/public/browser.html +4 -4
  181. package/payload/server/public/calendar.html +7 -7
  182. package/payload/server/public/chat.html +13 -13
  183. package/payload/server/public/data.html +11 -11
  184. package/payload/server/public/graph.html +9 -9
  185. package/payload/server/public/index.html +14 -14
  186. package/payload/server/public/operator.html +14 -14
  187. package/payload/server/public/public.html +13 -13
  188. package/payload/server/public/routines.html +6 -6
  189. package/payload/server/public/skills.html +5 -5
  190. package/payload/server/public/tasks.html +6 -6
  191. package/payload/server/server.js +1006 -606
  192. package/payload/server/public/assets/AdminLoginScreens-Dar_MMJm.js.br +0 -0
  193. package/payload/server/public/assets/AdminLoginScreens-Dar_MMJm.js.gz +0 -0
  194. package/payload/server/public/assets/AdminShell-CpaI2F_p.js.br +0 -0
  195. package/payload/server/public/assets/activity-B1rt4GIy.js.br +0 -0
  196. package/payload/server/public/assets/activity-B1rt4GIy.js.gz +0 -0
  197. package/payload/server/public/assets/admin-DE3lLNje.js +0 -1
  198. package/payload/server/public/assets/admin-DE3lLNje.js.br +0 -0
  199. package/payload/server/public/assets/admin-DE3lLNje.js.gz +0 -0
  200. package/payload/server/public/assets/agents-BXq8woVf.js.br +0 -0
  201. package/payload/server/public/assets/agents-BXq8woVf.js.gz +0 -0
  202. package/payload/server/public/assets/browser-1QSCPl3X.js.br +0 -0
  203. package/payload/server/public/assets/browser-1QSCPl3X.js.gz +0 -0
  204. package/payload/server/public/assets/calendar-D009qWVV.js.br +0 -0
  205. package/payload/server/public/assets/calendar-D009qWVV.js.gz +0 -0
  206. package/payload/server/public/assets/chat-CUg1fTqJ.js +0 -1
  207. package/payload/server/public/assets/chat-CUg1fTqJ.js.br +0 -1
  208. package/payload/server/public/assets/chat-CUg1fTqJ.js.gz +0 -0
  209. package/payload/server/public/assets/chevron-left-C2JEy7uU.js +0 -1
  210. package/payload/server/public/assets/chevron-left-C2JEy7uU.js.br +0 -0
  211. package/payload/server/public/assets/chevron-right-DWa047Ys.js +0 -1
  212. package/payload/server/public/assets/chevron-right-DWa047Ys.js.br +0 -0
  213. package/payload/server/public/assets/clock-C3OqfCnn.js +0 -1
  214. package/payload/server/public/assets/clock-C3OqfCnn.js.br +0 -0
  215. package/payload/server/public/assets/clock-C3OqfCnn.js.gz +0 -0
  216. package/payload/server/public/assets/data-Bu_yCScC.js +0 -1
  217. package/payload/server/public/assets/data-Bu_yCScC.js.br +0 -0
  218. package/payload/server/public/assets/data-Bu_yCScC.js.gz +0 -0
  219. package/payload/server/public/assets/file-text-DwGAfCsd.js.br +0 -0
  220. package/payload/server/public/assets/file-text-DwGAfCsd.js.gz +0 -0
  221. package/payload/server/public/assets/graph-D-DGlfhW.js.br +0 -0
  222. package/payload/server/public/assets/graph-D-DGlfhW.js.gz +0 -0
  223. package/payload/server/public/assets/graph-labels-BbX3fXzl.js.br +0 -0
  224. package/payload/server/public/assets/graph-labels-BbX3fXzl.js.gz +0 -0
  225. package/payload/server/public/assets/maximize-2-C_-KapxH.js.br +0 -0
  226. package/payload/server/public/assets/maximize-2-C_-KapxH.js.gz +0 -0
  227. package/payload/server/public/assets/operator-CFrZVcv6.js.br +0 -0
  228. package/payload/server/public/assets/operator-CFrZVcv6.js.gz +0 -0
  229. package/payload/server/public/assets/page-CHt62f1_.js.br +0 -0
  230. package/payload/server/public/assets/page-CHt62f1_.js.gz +0 -0
  231. package/payload/server/public/assets/page-E74MYB18.js.br +0 -0
  232. package/payload/server/public/assets/page-E74MYB18.js.gz +0 -0
  233. package/payload/server/public/assets/public-CI6K1sNW.js.br +0 -0
  234. package/payload/server/public/assets/public-CI6K1sNW.js.gz +0 -0
  235. package/payload/server/public/assets/rotate-ccw-PWu_QGrD.js.br +0 -0
  236. package/payload/server/public/assets/rotate-ccw-PWu_QGrD.js.gz +0 -0
  237. package/payload/server/public/assets/routines-Cp3_XS7S.js.br +0 -0
  238. package/payload/server/public/assets/routines-Cp3_XS7S.js.gz +0 -0
  239. package/payload/server/public/assets/skills-g8HvunPA.js.br +0 -0
  240. package/payload/server/public/assets/skills-g8HvunPA.js.gz +0 -0
  241. package/payload/server/public/assets/tasks-CMC_jDVm.js +0 -1
  242. package/payload/server/public/assets/tasks-CMC_jDVm.js.br +0 -0
  243. package/payload/server/public/assets/tasks-CMC_jDVm.js.gz +0 -0
  244. package/payload/server/public/assets/time-entry-format-BXWuQ6Sw.js.br +0 -2
  245. package/payload/server/public/assets/time-entry-format-BXWuQ6Sw.js.gz +0 -0
  246. package/payload/server/public/assets/triangle-alert-BNshRC13.js.br +0 -0
  247. package/payload/server/public/assets/triangle-alert-BNshRC13.js.gz +0 -0
  248. package/payload/server/public/assets/useCopyFeedback-CwTZ9DqH.js.br +0 -0
  249. package/payload/server/public/assets/useCopyFeedback-CwTZ9DqH.js.gz +0 -0
  250. package/payload/server/public/assets/useSubAccountSwitcher-BuUYMDWl.js.br +0 -0
  251. package/payload/server/public/assets/useSubAccountSwitcher-dzDnmWq9.css.br +0 -0
  252. package/payload/server/public/assets/useVoiceRecorder-BGqV5R6u.js.br +0 -0
  253. package/payload/server/public/assets/useVoiceRecorder-BGqV5R6u.js.gz +0 -0
  254. package/payload/server/public/assets/wrench-DQ045Pyk.js.br +0 -0
  255. package/payload/server/public/assets/wrench-DQ045Pyk.js.gz +0 -0
@@ -99,10 +99,22 @@ export declare class TokenRefreshError extends Error {
99
99
  get oauthError(): string | null;
100
100
  get statusCode(): number;
101
101
  }
102
+ /**
103
+ * Mint a new access token from a stored refresh token.
104
+ *
105
+ * `grantedScopes` is what THIS mailbox actually consented to, read from its
106
+ * stored blob — never the `SCOPES` constant. A refresh must ask for what was
107
+ * granted: widening `SCOPES` (Task 2122 added the two `.Shared` scopes) would
108
+ * otherwise make every already-connected mailbox request consent it never gave,
109
+ * and an `invalid_grant` answer to that is treated as a revoked grant, which
110
+ * clears the mailbox's credentials. An empty list omits `scope` entirely, which
111
+ * is how the token endpoint is told to return the original grant unchanged.
112
+ */
102
113
  export declare function refreshAccessToken(args: {
103
114
  clientId: string;
104
115
  tenantId: string;
105
116
  refreshToken: string;
117
+ grantedScopes: string[];
106
118
  }): Promise<TokenResponse>;
107
119
  export declare const _internals: {
108
120
  SCOPES: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwBH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAWD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6B3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;iFAC6E;IAC7E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACnE,eAAe,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CA6CtF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC9C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CA+BtB;AAMD;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,KAAK,EAAE,eAAe;gBAD/B,OAAO,EAAE,MAAM,EACN,KAAK,EAAE,eAAe;IAMjC;6CACyC;IACzC,IAAI,UAAU,IAAI,MAAM,GAAG,IAAI,CAE9B;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;CACF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,aAAa,CAAC,CAsBzB;AAED,eAAO,MAAM,UAAU;;CAAa,CAAC"}
1
+ {"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA+BH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAWD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6B3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;iFAC6E;IAC7E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACnE,eAAe,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CA6CtF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC9C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CA+BtB;AAMD;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,KAAK,EAAE,eAAe;gBAD/B,OAAO,EAAE,MAAM,EACN,KAAK,EAAE,eAAe;IAMjC;6CACyC;IACzC,IAAI,UAAU,IAAI,MAAM,GAAG,IAAI,CAE9B;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,OAAO,CAAC,aAAa,CAAC,CAwBzB;AAED,eAAO,MAAM,UAAU;;CAAa,CAAC"}
@@ -10,11 +10,18 @@
10
10
  * `refreshAccessToken` (used by the read path in graph-client.ts) and the SCOPES
11
11
  * set are unchanged from the prior Auth-Code implementation.
12
12
  */
13
+ // The two `.Shared` scopes are what make a shared or delegated mailbox
14
+ // reachable at /users/<address>; without them Graph returns 403 even when the
15
+ // signed-in user holds Full Access. They widen only what THIS registration
16
+ // consents to — a mailbox already connected keeps the grant it was given and
17
+ // must be re-registered before it can reach a shared mailbox (Task 2122).
13
18
  const SCOPES = [
14
19
  "offline_access",
15
20
  "User.Read",
16
21
  "Mail.ReadWrite",
17
22
  "Mail.Send",
23
+ "Mail.ReadWrite.Shared",
24
+ "Mail.Send.Shared",
18
25
  "Calendars.ReadWrite",
19
26
  "Contacts.Read",
20
27
  ];
@@ -172,14 +179,27 @@ export class TokenRefreshError extends Error {
172
179
  return this.azure.httpStatus;
173
180
  }
174
181
  }
182
+ /**
183
+ * Mint a new access token from a stored refresh token.
184
+ *
185
+ * `grantedScopes` is what THIS mailbox actually consented to, read from its
186
+ * stored blob — never the `SCOPES` constant. A refresh must ask for what was
187
+ * granted: widening `SCOPES` (Task 2122 added the two `.Shared` scopes) would
188
+ * otherwise make every already-connected mailbox request consent it never gave,
189
+ * and an `invalid_grant` answer to that is treated as a revoked grant, which
190
+ * clears the mailbox's credentials. An empty list omits `scope` entirely, which
191
+ * is how the token endpoint is told to return the original grant unchanged.
192
+ */
175
193
  export async function refreshAccessToken(args) {
176
194
  const { tokenUrl } = buildUrls(args.tenantId);
177
195
  const params = new URLSearchParams({
178
196
  client_id: args.clientId,
179
- scope: SCOPES.join(" "),
180
197
  refresh_token: args.refreshToken,
181
198
  grant_type: "refresh_token",
182
199
  });
200
+ if (args.grantedScopes.length > 0) {
201
+ params.set("scope", args.grantedScopes.join(" "));
202
+ }
183
203
  const response = await fetch(tokenUrl, {
184
204
  method: "POST",
185
205
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
@@ -1 +1 @@
1
- {"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,12 @@ export type ResolveResult = {
53
53
  kind: "ok";
54
54
  store: TokenStore;
55
55
  descriptor: MailboxDescriptor;
56
+ /** "/me" for a signed-in mailbox, "/users/<encoded address>" for a delegated one. */
57
+ pathPrefix: string;
58
+ /** The delegator's identity when this is a delegated mailbox, else null. */
59
+ via: string | null;
60
+ /** The delegated address when this is a delegated mailbox, else null. */
61
+ delegatedAddress: string | null;
56
62
  } | {
57
63
  kind: "none";
58
64
  } | {
@@ -62,12 +68,27 @@ export type ResolveResult = {
62
68
  kind: "notfound";
63
69
  selector: string;
64
70
  identities: string[];
71
+ }
72
+ /** A shared mailbox is attached, but the mailbox that delegates for it is no
73
+ * longer connected. Distinct from `notfound` because the record exists and
74
+ * the remedy is different: re-register the delegator, or drop the record. */
75
+ | {
76
+ kind: "delegator-missing";
77
+ selector: string;
78
+ via: string;
65
79
  };
66
80
  export interface CredResolveEvent {
67
81
  event: "cred-resolve";
68
82
  account: string;
69
83
  mailbox: string;
70
84
  source: "arg" | "sole" | "none" | "refused";
85
+ /** Whether the call runs against the operator's own mailbox or through a
86
+ * delegation. Without it, a delegated call is indistinguishable in the log
87
+ * from a signed-in one, which is exactly the difference that matters when a
88
+ * shared mailbox stops answering. */
89
+ kind: "signed-in" | "delegated";
90
+ /** The delegator's identity on a delegated resolution, else "". */
91
+ via: string;
71
92
  }
72
93
  /**
73
94
  * The observability line for a resolution: names the *resolved* mailbox and how
@@ -82,6 +103,7 @@ export declare class MailboxRegistry {
82
103
  private readonly secretsDir;
83
104
  private readonly mailboxesDir;
84
105
  private readonly legacyTokensPath;
106
+ private readonly delegatedStore;
85
107
  constructor(accountId: string, accountsDir: string);
86
108
  /**
87
109
  * Move a pre-migration `secrets/outlook/tokens.enc` into
@@ -94,12 +116,21 @@ export declare class MailboxRegistry {
94
116
  list(): MailboxDescriptor[];
95
117
  private describe;
96
118
  /**
97
- * Resolve a mailbox selector to a TokenStore. Order: explicit selector
98
- * (matched against graphUserId or mail, case-insensitive) the sole readable
99
- * mailbox ambiguous (≥2 readable, none named) → none (zero readable).
100
- * Unreadable mailboxes are never addressable.
119
+ * Resolve a mailbox selector to a TokenStore and the Graph path prefix that
120
+ * addresses it. Order: an explicit selector against the signed-in mailboxes
121
+ * (graphUserId or mail, case-insensitive) → the same selector against the
122
+ * delegated records the sole readable signed-in mailbox → ambiguous (≥2
123
+ * attached, none named) → none. Unreadable mailboxes are never addressable.
124
+ *
125
+ * Delegated records deliberately take part in NEITHER the sole-mailbox
126
+ * default nor the ambiguity count. Attaching a shared mailbox must not change
127
+ * what a bare call means, or every existing tool call on a single-mailbox
128
+ * account would start refusing the moment a shared mailbox was added.
101
129
  */
102
130
  resolve(selector?: string): ResolveResult;
131
+ /** Every selectable identity on this account, signed-in and delegated, so a
132
+ * refusal is honest about what IS attached rather than listing half of it. */
133
+ private identities;
103
134
  /** A TokenStore for a specific mailbox key (a graphUserId at register time, or
104
135
  * a descriptor's mailboxKey). Overwrites that mailbox in place on store(). */
105
136
  storeFor(mailboxKey: string): TokenStore;
@@ -1 +1 @@
1
- {"version":3,"file":"mailbox-registry.d.ts","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAC;AAElE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,aAAa,GAAG,iBAAiB,GAAG,IAAI,CAAC;AAEpF,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,aAAa,CAKhB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAUjE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,CAalB;AAED,qBAAa,eAAe;aAMR,SAAS,EAAE,MAAM;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAGxB,SAAS,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM;IAOtC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IA4BrB,8EAA8E;IAC9E,IAAI,IAAI,iBAAiB,EAAE;IAa3B,OAAO,CAAC,QAAQ;IAuBhB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa;IA8BzC;kFAC8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;CAGzC"}
1
+ {"version":3,"file":"mailbox-registry.d.ts","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@
14
14
  import { existsSync, mkdirSync, readdirSync, renameSync, unlinkSync } from "node:fs";
15
15
  import { join } from "node:path";
16
16
  import { TokenStore, sanitizeMailboxKey } from "./token-store.js";
17
+ import { DelegatedStore, normalizeAddress } from "./delegated-store.js";
18
+ import { OWN_MAILBOX_PREFIX, sharedMailboxPrefix } from "../lib/graph-client.js";
17
19
  /**
18
20
  * Classify a mailbox's usability from its readable/mail/refresh facts. Pure and
19
21
  * total, evaluated in precedence order so the most blocking condition wins:
@@ -48,14 +50,43 @@ export function credResolveEvent(resolved, account, selector) {
48
50
  return {
49
51
  event: "cred-resolve",
50
52
  account,
51
- mailbox: identityOf(resolved.descriptor),
53
+ mailbox: resolved.delegatedAddress ?? identityOf(resolved.descriptor),
52
54
  source: selector ? "arg" : "sole",
55
+ kind: resolved.delegatedAddress ? "delegated" : "signed-in",
56
+ via: resolved.via ?? "",
53
57
  };
54
58
  }
55
59
  if (resolved.kind === "none") {
56
- return { event: "cred-resolve", account, mailbox: "", source: "none" };
60
+ return {
61
+ event: "cred-resolve",
62
+ account,
63
+ mailbox: "",
64
+ source: "none",
65
+ kind: "signed-in",
66
+ via: "",
67
+ };
57
68
  }
58
- return { event: "cred-resolve", account, mailbox: selector ?? "", source: "refused" };
69
+ if (resolved.kind === "delegator-missing") {
70
+ // The one refusal these two fields exist to diagnose. Labelling it
71
+ // signed-in with no delegator would hide exactly the fact the operator
72
+ // needs: which mailbox was supposed to reach this shared one.
73
+ return {
74
+ event: "cred-resolve",
75
+ account,
76
+ mailbox: resolved.selector,
77
+ source: "refused",
78
+ kind: "delegated",
79
+ via: resolved.via,
80
+ };
81
+ }
82
+ return {
83
+ event: "cred-resolve",
84
+ account,
85
+ mailbox: selector ?? "",
86
+ source: "refused",
87
+ kind: "signed-in",
88
+ via: "",
89
+ };
59
90
  }
60
91
  export class MailboxRegistry {
61
92
  accountId;
@@ -63,12 +94,14 @@ export class MailboxRegistry {
63
94
  secretsDir;
64
95
  mailboxesDir;
65
96
  legacyTokensPath;
97
+ delegatedStore;
66
98
  constructor(accountId, accountsDir) {
67
99
  this.accountId = accountId;
68
100
  this.accountsDir = accountsDir;
69
101
  this.secretsDir = join(accountsDir, accountId, "secrets", "outlook");
70
102
  this.mailboxesDir = join(this.secretsDir, "mailboxes");
71
103
  this.legacyTokensPath = join(this.secretsDir, "tokens.enc");
104
+ this.delegatedStore = new DelegatedStore(accountId, accountsDir);
72
105
  }
73
106
  /**
74
107
  * Move a pre-migration `secrets/outlook/tokens.enc` into
@@ -149,22 +182,56 @@ export class MailboxRegistry {
149
182
  }
150
183
  }
151
184
  /**
152
- * Resolve a mailbox selector to a TokenStore. Order: explicit selector
153
- * (matched against graphUserId or mail, case-insensitive) the sole readable
154
- * mailbox ambiguous (≥2 readable, none named) → none (zero readable).
155
- * Unreadable mailboxes are never addressable.
185
+ * Resolve a mailbox selector to a TokenStore and the Graph path prefix that
186
+ * addresses it. Order: an explicit selector against the signed-in mailboxes
187
+ * (graphUserId or mail, case-insensitive) → the same selector against the
188
+ * delegated records the sole readable signed-in mailbox → ambiguous (≥2
189
+ * attached, none named) → none. Unreadable mailboxes are never addressable.
190
+ *
191
+ * Delegated records deliberately take part in NEITHER the sole-mailbox
192
+ * default nor the ambiguity count. Attaching a shared mailbox must not change
193
+ * what a bare call means, or every existing tool call on a single-mailbox
194
+ * account would start refusing the moment a shared mailbox was added.
156
195
  */
157
196
  resolve(selector) {
158
197
  const all = this.list();
159
198
  const addressable = all.filter((d) => d.readable);
199
+ const delegated = this.delegatedStore.read();
160
200
  if (selector) {
161
201
  const needle = selector.toLowerCase();
162
202
  const match = addressable.find((d) => d.graphUserId?.toLowerCase() === needle ||
163
203
  d.mail?.toLowerCase() === needle);
164
204
  if (match) {
165
- return { kind: "ok", store: this.storeFor(match.mailboxKey), descriptor: match };
205
+ return {
206
+ kind: "ok",
207
+ store: this.storeFor(match.mailboxKey),
208
+ descriptor: match,
209
+ pathPrefix: OWN_MAILBOX_PREFIX,
210
+ via: null,
211
+ delegatedAddress: null,
212
+ };
166
213
  }
167
- return { kind: "notfound", selector, identities: all.map(identityOf) };
214
+ const address = normalizeAddress(selector);
215
+ // Own-property check, not a bare index: a plain object answers
216
+ // "constructor" or "toString" with an inherited function, which would
217
+ // read as an attached delegated record and refuse with a confabulated
218
+ // "attached through a mailbox that is no longer connected".
219
+ const entry = Object.hasOwn(delegated, address) ? delegated[address] : undefined;
220
+ if (entry) {
221
+ const delegator = addressable.find((d) => d.mailboxKey === entry.viaMailboxKey);
222
+ if (!delegator) {
223
+ return { kind: "delegator-missing", selector: address, via: entry.viaMailboxKey };
224
+ }
225
+ return {
226
+ kind: "ok",
227
+ store: this.storeFor(delegator.mailboxKey),
228
+ descriptor: delegator,
229
+ pathPrefix: sharedMailboxPrefix(address),
230
+ via: identityOf(delegator),
231
+ delegatedAddress: address,
232
+ };
233
+ }
234
+ return { kind: "notfound", selector, identities: this.identities(all, delegated) };
168
235
  }
169
236
  // Ambiguity is decided by the number of mailboxes *attached* (readable or
170
237
  // not), never the readable subset. If a second mailbox is transiently
@@ -174,11 +241,26 @@ export class MailboxRegistry {
174
241
  return { kind: "none" };
175
242
  if (all.length === 1) {
176
243
  return addressable.length === 1
177
- ? { kind: "ok", store: this.storeFor(addressable[0].mailboxKey), descriptor: addressable[0] }
244
+ ? {
245
+ kind: "ok",
246
+ store: this.storeFor(addressable[0].mailboxKey),
247
+ descriptor: addressable[0],
248
+ pathPrefix: OWN_MAILBOX_PREFIX,
249
+ via: null,
250
+ delegatedAddress: null,
251
+ }
178
252
  : { kind: "none" };
179
253
  }
180
254
  return { kind: "ambiguous", identities: all.map(identityOf) };
181
255
  }
256
+ /** Every selectable identity on this account, signed-in and delegated, so a
257
+ * refusal is honest about what IS attached rather than listing half of it. */
258
+ identities(all, delegated) {
259
+ return [
260
+ ...all.map(identityOf),
261
+ ...Object.keys(delegated).map((address) => `${address} (delegated)`),
262
+ ];
263
+ }
182
264
  /** A TokenStore for a specific mailbox key (a graphUserId at register time, or
183
265
  * a descriptor's mailboxKey). Overwrites that mailbox in place on store(). */
184
266
  storeFor(mailboxKey) {
@@ -1 +1 @@
1
- {"version":3,"file":"mailbox-registry.js","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AA8BlE;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,CAI7B;IACC,IAAI,CAAC,CAAC,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC;IACrC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,aAAa,CAAC;IAC1D,IAAI,CAAC,CAAC,cAAc;QAAE,OAAO,iBAAiB,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC;AAQD;;wEAEwE;AACxE,SAAS,UAAU,CAAC,CAAoB;IACtC,IAAI,CAAC,CAAC,CAAC,QAAQ;QAAE,OAAO,GAAG,CAAC,CAAC,UAAU,eAAe,CAAC;IACvD,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,UAAU,CAAC;AACjD,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAuB,EACvB,OAAe,EACf,QAAiB;IAEjB,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,OAAO;YACP,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC;YACxC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;SAClC,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACxF,CAAC;AAED,MAAM,OAAO,eAAe;IAMR;IACC;IANF,UAAU,CAAS;IACnB,YAAY,CAAS;IACrB,gBAAgB,CAAS;IAE1C,YACkB,SAAiB,EAChB,WAAmB;QADpB,cAAS,GAAT,SAAS,CAAQ;QAChB,gBAAW,GAAX,WAAW,CAAQ;QAEpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACrE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACvD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;OAKG;IACK,aAAa;QACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC;YAAE,OAAO;QAC/C,IAAI,GAAG,GAAG,SAAS,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;YACrE,IAAI,IAAI,EAAE,WAAW;gBAAE,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,4EAA4E;YAC5E,GAAG,GAAG,mBAAmB,CAAC;QAC5B,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC7C,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,yEAAyE;gBACzE,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,sEAAsE;YACtE,4EAA4E;YAC5E,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAwB,EAAE,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC5E,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YACnC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;YAC9B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;gBAAE,SAAS;YAC7E,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,QAAQ,CAAC,UAAkB;QACjC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAC3E,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;YACpJ,CAAC;YACD,MAAM,cAAc,GAAG,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACnD,OAAO;gBACL,UAAU;gBACV,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBACtD,cAAc;gBACd,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC;aAC3E,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QACpJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAAiB;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAElD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAC5B,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,MAAM;gBACvC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,MAAM,CACnC,CAAC;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;YACnF,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACzE,CAAC;QAED,0EAA0E;QAC1E,sEAAsE;QACtE,2EAA2E;QAC3E,yEAAyE;QACzE,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC9C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,WAAW,CAAC,MAAM,KAAK,CAAC;gBAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE;gBAC7F,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;IAChE,CAAC;IAED;kFAC8E;IAC9E,QAAQ,CAAC,UAAkB;QACzB,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACtE,CAAC;CACF"}
1
+ {"version":3,"file":"mailbox-registry.js","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,9 @@ import { z } from "zod";
21
21
  import { TokenStore } from "./auth/token-store.js";
22
22
  import { PendingStore } from "./auth/pending-store.js";
23
23
  import { MailboxRegistry, credResolveEvent } from "./auth/mailbox-registry.js";
24
+ import { callGraph, OWN_MAILBOX_PREFIX } from "./lib/graph-client.js";
25
+ import { graphInboxProbe, runSharedMailboxAdd } from "./tools/shared-mailbox-add.js";
26
+ import { runSharedMailboxRemove } from "./tools/shared-mailbox-remove.js";
24
27
  import { runAccountRegisterStart, runAccountRegisterPoll } from "./tools/account-register.js";
25
28
  import { runMailList } from "./tools/mail-list.js";
26
29
  import { runMailSearch } from "./tools/mail-search.js";
@@ -99,6 +102,46 @@ function getClientCreds() {
99
102
  }
100
103
  return { clientId: OUTLOOK_CLIENT_ID, tenantId: OUTLOOK_TENANT_ID };
101
104
  }
105
+ /**
106
+ * Resolve the SIGNED-IN mailbox that will delegate for a shared one.
107
+ *
108
+ * Distinct from getConfig because a delegation cannot itself be delegated: the
109
+ * caller must name a mailbox that actually signed in, and resolving to a
110
+ * delegated record here would silently build a pointer to a pointer.
111
+ */
112
+ function getDelegator(via) {
113
+ if (!ACCOUNT_ID) {
114
+ throw new Error("getDelegator() called without ACCOUNT_ID — handler guard missing");
115
+ }
116
+ const { clientId, tenantId } = getClientCreds();
117
+ const resolved = getRegistry().resolve(via);
118
+ log({ ...credResolveEvent(resolved, ACCOUNT_ID, via) });
119
+ if (resolved.kind === "ambiguous") {
120
+ throw new Error(`This account has ${resolved.identities.length} Outlook mailboxes (${resolved.identities.join(", ")}). Pass via=<email or id> to say which one has Full Access to the shared mailbox.`);
121
+ }
122
+ // Each refusal names what is actually true. Collapsing these into "nothing is
123
+ // connected" asserts the opposite of the resolver's own result whenever the
124
+ // caller merely mistyped `via`, and sends the operator to re-register a
125
+ // mailbox that is working.
126
+ if (resolved.kind === "notfound") {
127
+ throw new Error(`No connected Outlook mailbox matches via="${resolved.selector}". Connected: ${resolved.identities.join(", ") || "none"}. Pass via=<one of those> — it must be a mailbox that signed in, not the shared mailbox you are attaching.`);
128
+ }
129
+ if (resolved.kind === "delegator-missing") {
130
+ throw new Error(`via="${resolved.selector}" is itself a shared mailbox, and the mailbox that reaches it (${resolved.via}) is no longer connected. Pass via=<a signed-in mailbox>.`);
131
+ }
132
+ if (resolved.kind !== "ok") {
133
+ throw new Error("No Outlook mailbox is connected for this account, so there is nothing to delegate through. Run outlook-account-register first.");
134
+ }
135
+ if (resolved.delegatedAddress) {
136
+ throw new Error(`${resolved.delegatedAddress} is itself a shared mailbox reached through ${resolved.via}. Pass via=<the signed-in mailbox> instead.`);
137
+ }
138
+ return {
139
+ config: { clientId, tenantId, accountId: ACCOUNT_ID, tokenStore: resolved.store },
140
+ mailboxKey: resolved.descriptor.mailboxKey,
141
+ identity: resolved.descriptor.mail ?? resolved.descriptor.graphUserId ?? resolved.descriptor.mailboxKey,
142
+ scopes: resolved.descriptor.scopes,
143
+ };
144
+ }
102
145
  /**
103
146
  * Build a GraphClientConfig for the mailbox the caller named, or the sole
104
147
  * configured mailbox when none is named. Resolution order: explicit `mailbox`
@@ -116,8 +159,10 @@ function getConfig(mailbox) {
116
159
  const resolved = getRegistry().resolve(mailbox);
117
160
  log({ ...credResolveEvent(resolved, ACCOUNT_ID, mailbox) });
118
161
  let tokenStore;
162
+ let mailboxPathPrefix = OWN_MAILBOX_PREFIX;
119
163
  if (resolved.kind === "ok") {
120
164
  tokenStore = resolved.store;
165
+ mailboxPathPrefix = resolved.pathPrefix;
121
166
  }
122
167
  else if (resolved.kind === "none") {
123
168
  tokenStore = new TokenStore(ACCOUNT_ID, ACCOUNTS_DIR, UNCONFIGURED_MAILBOX);
@@ -125,10 +170,13 @@ function getConfig(mailbox) {
125
170
  else if (resolved.kind === "ambiguous") {
126
171
  throw new Error(`This account has ${resolved.identities.length} Outlook mailboxes (${resolved.identities.join(", ")}). Pass mailbox=<email or id> to choose one.`);
127
172
  }
173
+ else if (resolved.kind === "delegator-missing") {
174
+ throw new Error(`The shared mailbox "${resolved.selector}" is attached through a mailbox that is no longer connected (${resolved.via}). Re-run outlook-account-register for that mailbox, or drop the shared mailbox with outlook-shared-mailbox-remove.`);
175
+ }
128
176
  else {
129
177
  throw new Error(`No Outlook mailbox "${resolved.selector}" is connected for this account. Connected: ${resolved.identities.join(", ") || "none"}.`);
130
178
  }
131
- return { clientId, tenantId, accountId: ACCOUNT_ID, tokenStore };
179
+ return { clientId, tenantId, accountId: ACCOUNT_ID, tokenStore, mailboxPathPrefix };
132
180
  }
133
181
  function ok(payload) {
134
182
  return {
@@ -478,17 +526,72 @@ lifelineTool(server, "outlook-mailbox-info", "Health probe — reports auth stat
478
526
  return fail(`outlook-mailbox-info failed: ${err.message}`);
479
527
  }
480
528
  });
481
- lifelineTool(server, "outlook-mailbox-list", "List every Outlook mailbox attached to this account, with each mailbox's email, graphUserId, granted scopes, token expiry, and a `status`. `count` is how many records are attached; `addressable` is how many are usable by their email right now (`status:ok`). Do NOT read a bare `count` of 1 as 'connected' — a record can be attached but not addressable: `status:blank-email` (readable but no stored email, so it cannot be resolved by address), `status:refresh-expired` (needs re-auth), or `status:unreadable` (stored credentials will not decrypt). Local only — reads the stored credentials, never the network. Call this before addressing a specific mailbox; pass the email or graphUserId of an `ok` mailbox as the `mailbox` argument on the other tools.", {}, async () => {
529
+ lifelineTool(server, "outlook-mailbox-list", "List every Outlook mailbox attached to this account, with each mailbox's email, graphUserId, granted scopes, token expiry, and a `status`. `count` is how many records are attached; `addressable` is how many SIGNED-IN mailboxes are usable by their email right now (`status:ok`); `delegated` is how many are shared mailboxes reached through another. Each entry carries `kind` (`signed-in` or `delegated`) and, when delegated, `via` (the mailbox whose Full Access reaches it). Do NOT read a bare `count` of 1 as 'connected' — a record can be attached but not addressable: `status:blank-email` (readable but no stored email, so it cannot be resolved by address), `status:refresh-expired` (needs re-auth), `status:unreadable` (stored credentials will not decrypt), or `status:delegator-missing` (a shared mailbox whose delegating mailbox is no longer connected). Local only by default — reads the stored credentials, never the network. Pass verify:true to probe each attached shared mailbox and report `reachable`. `reachable:false` means the probe did not succeed just now — a revoked Full Access grant is the usual cause, but so is a network or Graph outage, so read the `graph-error` log line for the reason rather than treating false as proof the delegation is gone. Call this before addressing a specific mailbox; pass the email of an `ok` or `delegated` mailbox as the `mailbox` argument on the other tools.", {
530
+ verify: z
531
+ .boolean()
532
+ .optional()
533
+ .describe("Probe each attached shared mailbox against Graph and report `reachable`. Off by default; the listing is otherwise local-only and works when Graph is unreachable. A false answer means the probe failed now, not specifically that Full Access was revoked."),
534
+ }, async ({ verify }) => {
482
535
  if (!ACCOUNT_ID)
483
536
  return refuseNoAccount("outlook-mailbox-list");
484
537
  try {
485
- const result = runMailboxList(ACCOUNT_ID, ACCOUNTS_DIR);
538
+ const result = await runMailboxList(ACCOUNT_ID, ACCOUNTS_DIR, {
539
+ verify,
540
+ probe: async (address) => {
541
+ try {
542
+ await callGraph(getConfig(address), async (client) => client.api("/me/mailFolders/Inbox").select("id").get(), { tool: "mailbox-list", target: address });
543
+ return true;
544
+ }
545
+ catch {
546
+ // Any failure means "cannot reach it right now". The reason is
547
+ // already on the graph-error line; this flag answers only whether
548
+ // the mailbox still answers.
549
+ return false;
550
+ }
551
+ },
552
+ });
486
553
  return ok(result);
487
554
  }
488
555
  catch (err) {
489
556
  return fail(`outlook-mailbox-list failed: ${err.message}`);
490
557
  }
491
558
  });
559
+ lifelineTool(server, "outlook-shared-mailbox-add", "Attach a Microsoft 365 SHARED mailbox (one with no sign-in of its own, e.g. team@company.com) so the mail tools can read, draft, reply and send from it. This is the correct answer whenever an operator asks for a shared, team or delegated mailbox — it does NOT need a licence and must never be given a sign-in. It works through the signed-in mailbox's Full Access delegation: pass address=<the shared mailbox>, plus via=<the signed-in mailbox> when this account has more than one connected. Access is proved before anything is stored, so a refusal here is the real answer: 'does not have Full Access' means the delegation is missing and is granted in the Microsoft 365 admin centre, and 'no mailbox with this address' means the address is wrong or is a distribution list. Once attached, pass the shared address as the `mailbox` argument to any mail tool, and see it in outlook-mailbox-list. Calendar and contacts tools are refused on a shared mailbox. Requires the delegating mailbox to hold the Mail.ReadWrite.Shared scope; a mailbox connected before that scope existed must be re-registered with outlook-account-register first.", {
560
+ address: z.string().min(3),
561
+ via: z
562
+ .string()
563
+ .optional()
564
+ .describe("The signed-in mailbox that has Full Access to the shared one. Required only when two or more mailboxes are connected."),
565
+ }, async ({ address, via }) => {
566
+ if (!ACCOUNT_ID)
567
+ return refuseNoAccount("outlook-shared-mailbox-add");
568
+ try {
569
+ const delegator = getDelegator(via);
570
+ const result = await runSharedMailboxAdd({
571
+ config: delegator.config,
572
+ accountsDir: ACCOUNTS_DIR,
573
+ viaMailboxKey: delegator.mailboxKey,
574
+ viaIdentity: delegator.identity,
575
+ viaScopes: delegator.scopes,
576
+ nowMs: Date.now(),
577
+ probe: graphInboxProbe,
578
+ }, { address });
579
+ return ok(result);
580
+ }
581
+ catch (err) {
582
+ return fail(`outlook-shared-mailbox-add failed: ${err.message}`);
583
+ }
584
+ });
585
+ lifelineTool(server, "outlook-shared-mailbox-remove", "Detach a shared mailbox attached by outlook-shared-mailbox-add. Drops the pointer only — no credential is touched, and the mailbox that delegates for it keeps working. `removed:false` means the address was not attached in the first place.", { address: z.string().min(3) }, async ({ address }) => {
586
+ if (!ACCOUNT_ID)
587
+ return refuseNoAccount("outlook-shared-mailbox-remove");
588
+ try {
589
+ return ok(runSharedMailboxRemove(ACCOUNT_ID, ACCOUNTS_DIR, address));
590
+ }
591
+ catch (err) {
592
+ return fail(`outlook-shared-mailbox-remove failed: ${err.message}`);
593
+ }
594
+ });
492
595
  lifelineTool(server, "outlook-mail-send", "Send a message via Microsoft Graph. Recipients are string arrays (to required, cc/bcc optional). The body is HTML when isHtml=true, otherwise plain text. attachments is an array of file paths inside the account directory (up to 25 MB per file) — with no attachments the message goes via POST /me/sendMail; with attachments it is composed as a draft, the files are attached, and the draft is sent, because /me/sendMail cannot carry a large file. Saves a copy to Sent Items. Success is asserted on Graph's 202; the message is not returned with an id on either route. Requires the Mail.Send scope (plus Mail.ReadWrite when attaching) — a mailbox registered under the old read-only consent returns an actionable 're-register to grant send' error.", {
493
596
  to: z.array(z.string().min(3)).min(1),
494
597
  cc: z.array(z.string()).optional(),