@rubytech/create-maxy-code 0.1.600 → 0.1.602

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 (274) hide show
  1. package/dist/__tests__/email-sampler-unit.test.js +31 -0
  2. package/dist/index.js +18 -2
  3. package/dist/port-resolution.js +24 -0
  4. package/package.json +1 -1
  5. package/payload/platform/plugins/admin/hooks/video-frames-inject.sh +141 -0
  6. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -1
  7. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +10 -0
  8. package/payload/platform/plugins/docs/references/admin-ui.md +2 -0
  9. package/payload/platform/plugins/docs/references/telegram-guide.md +2 -0
  10. package/payload/platform/plugins/email/PLUGIN.md +7 -1
  11. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts +27 -0
  12. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
  13. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +78 -0
  14. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
  15. package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.d.ts +2 -0
  16. package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.d.ts.map +1 -0
  17. package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.js +96 -0
  18. package/payload/platform/plugins/email/mcp/dist/sampler/__tests__/sample-mailbox.test.js.map +1 -0
  19. package/payload/platform/plugins/email/mcp/dist/sampler/main.d.ts +2 -0
  20. package/payload/platform/plugins/email/mcp/dist/sampler/main.d.ts.map +1 -0
  21. package/payload/platform/plugins/email/mcp/dist/sampler/main.js +75 -0
  22. package/payload/platform/plugins/email/mcp/dist/sampler/main.js.map +1 -0
  23. package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.d.ts +48 -0
  24. package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.d.ts.map +1 -0
  25. package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.js +77 -0
  26. package/payload/platform/plugins/email/mcp/dist/sampler/sample-mailbox.js.map +1 -0
  27. package/payload/platform/plugins/scheduling/PLUGIN.md +2 -0
  28. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +67 -1
  29. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
  30. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +89 -1
  31. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
  32. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.d.ts +2 -0
  33. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.d.ts.map +1 -0
  34. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.js +160 -0
  35. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.js.map +1 -0
  36. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js +16 -0
  37. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js.map +1 -1
  38. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +31 -1
  39. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
  40. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +42 -4
  41. package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
  42. package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.d.ts +101 -0
  43. package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.d.ts.map +1 -0
  44. package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.js +130 -0
  45. package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.js.map +1 -0
  46. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +10 -1
  47. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
  48. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
  49. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +24 -0
  50. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
  51. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +89 -0
  52. package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
  53. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +67 -1
  54. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  55. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +31 -0
  56. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
  57. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +10 -1
  58. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +46 -1
  60. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  61. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +72 -4
  62. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  63. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +81 -4
  64. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
  65. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +50 -0
  66. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
  67. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +48 -7
  68. package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
  69. package/payload/platform/plugins/telegram/PLUGIN.md +4 -0
  70. package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin-registry.test.js +33 -1
  71. package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin-registry.test.js.map +1 -1
  72. package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js +166 -1
  73. package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js.map +1 -1
  74. package/payload/platform/plugins/telegram/mcp/dist/index.js +39 -14
  75. package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
  76. package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.d.ts +95 -0
  77. package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.d.ts.map +1 -1
  78. package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js +125 -0
  79. package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js.map +1 -1
  80. package/payload/platform/scripts/logs-read.sh +18 -3
  81. package/payload/platform/services/telegram-channel/dist/notification.d.ts +6 -0
  82. package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
  83. package/payload/platform/services/telegram-channel/dist/notification.js +12 -5
  84. package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
  85. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +5 -0
  86. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  87. package/payload/platform/services/whatsapp-channel/dist/notification.js +9 -3
  88. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  89. package/payload/platform/templates/account-settings.json +6 -0
  90. package/payload/server/chunk-CYU75QAV.js +377 -0
  91. package/payload/server/{chunk-34FPJYHN.js → chunk-GI5AVCRG.js} +87 -146
  92. package/payload/server/chunk-KUVNCAE4.js +77 -0
  93. package/payload/server/{manager-7BXVB76I.js → manager-VDHT3YYI.js} +2 -1
  94. package/payload/server/maxy-edge.js +33 -1
  95. package/payload/server/public/activity.html +6 -6
  96. package/payload/server/public/agents.html +5 -5
  97. package/payload/server/public/assets/{AdminLoginScreens-B3W6J6Bl.js → AdminLoginScreens-CaQqLuxZ.js} +1 -1
  98. package/payload/server/public/assets/AdminLoginScreens-CaQqLuxZ.js.br +0 -0
  99. package/payload/server/public/assets/AdminLoginScreens-CaQqLuxZ.js.gz +0 -0
  100. package/payload/server/public/assets/{AdminShell-C3R-vMZ5.js → AdminShell-D8WTrqem.js} +1 -1
  101. package/payload/server/public/assets/AdminShell-D8WTrqem.js.br +0 -0
  102. package/payload/server/public/assets/AdminShell-D8WTrqem.js.gz +0 -0
  103. package/payload/server/public/assets/{activity-tzv68iBs.js → activity-B3fiJrC2.js} +1 -1
  104. package/payload/server/public/assets/activity-B3fiJrC2.js.br +0 -0
  105. package/payload/server/public/assets/activity-B3fiJrC2.js.gz +0 -0
  106. package/payload/server/public/assets/admin-ouF-DflP.js +1 -0
  107. package/payload/server/public/assets/admin-ouF-DflP.js.br +0 -0
  108. package/payload/server/public/assets/admin-ouF-DflP.js.gz +0 -0
  109. package/payload/server/public/assets/{agents-DUZfeY3X.js → agents-C8RSXHdh.js} +1 -1
  110. package/payload/server/public/assets/agents-C8RSXHdh.js.br +0 -0
  111. package/payload/server/public/assets/agents-C8RSXHdh.js.gz +0 -0
  112. package/payload/server/public/assets/{browser-DwLaXqjO.js → browser-Dbv6-Rag.js} +1 -1
  113. package/payload/server/public/assets/browser-Dbv6-Rag.js.br +0 -0
  114. package/payload/server/public/assets/browser-Dbv6-Rag.js.gz +0 -0
  115. package/payload/server/public/assets/{calendar-Cli8Qjl9.js → calendar-vJjtsH9n.js} +1 -1
  116. package/payload/server/public/assets/calendar-vJjtsH9n.js.br +0 -0
  117. package/payload/server/public/assets/calendar-vJjtsH9n.js.gz +0 -0
  118. package/payload/server/public/assets/chat-cqL4qPUy.js +1 -0
  119. package/payload/server/public/assets/chat-cqL4qPUy.js.br +1 -0
  120. package/payload/server/public/assets/chat-cqL4qPUy.js.gz +0 -0
  121. package/payload/server/public/assets/chevron-left-DB98DSG3.js +1 -0
  122. package/payload/server/public/assets/chevron-left-DB98DSG3.js.br +0 -0
  123. package/payload/server/public/assets/clock-4YwsYe4L.js +1 -0
  124. package/payload/server/public/assets/clock-4YwsYe4L.js.br +0 -0
  125. package/payload/server/public/assets/clock-4YwsYe4L.js.gz +0 -0
  126. package/payload/server/public/assets/{copy-yhhwfEbQ.js → copy-DyG7sC5o.js} +1 -1
  127. package/payload/server/public/assets/copy-DyG7sC5o.js.br +0 -0
  128. package/payload/server/public/assets/copy-DyG7sC5o.js.gz +0 -0
  129. package/payload/server/public/assets/data-BAzLtx9C.js +1 -0
  130. package/payload/server/public/assets/data-BAzLtx9C.js.br +0 -0
  131. package/payload/server/public/assets/data-BAzLtx9C.js.gz +0 -0
  132. package/payload/server/public/assets/{field-jg0YQNDy.js → field-Bx6pM-vq.js} +1 -1
  133. package/payload/server/public/assets/field-Bx6pM-vq.js.br +0 -0
  134. package/payload/server/public/assets/field-Bx6pM-vq.js.gz +0 -0
  135. package/payload/server/public/assets/{file-text-D0EdW7h4.js → file-text-CpHWsMGe.js} +1 -1
  136. package/payload/server/public/assets/file-text-CpHWsMGe.js.br +0 -0
  137. package/payload/server/public/assets/file-text-CpHWsMGe.js.gz +0 -0
  138. package/payload/server/public/assets/{graph--AUr4uBc.js → graph-DjOywuv_.js} +1 -1
  139. package/payload/server/public/assets/graph-DjOywuv_.js.br +0 -0
  140. package/payload/server/public/assets/graph-DjOywuv_.js.gz +0 -0
  141. package/payload/server/public/assets/{graph-labels-DM0CiAX1.js → graph-labels-CGWtqa-m.js} +1 -1
  142. package/payload/server/public/assets/graph-labels-CGWtqa-m.js.br +0 -0
  143. package/payload/server/public/assets/graph-labels-CGWtqa-m.js.gz +0 -0
  144. package/payload/server/public/assets/{jsx-runtime-lfcjzaWi.css → jsx-runtime-D75_aR1J.css} +1 -1
  145. package/payload/server/public/assets/jsx-runtime-D75_aR1J.css.br +0 -0
  146. package/payload/server/public/assets/{jsx-runtime-lfcjzaWi.css.gz → jsx-runtime-D75_aR1J.css.gz} +0 -0
  147. package/payload/server/public/assets/{operator-CNYKStFX.js → operator-_DN0RF1R.js} +1 -1
  148. package/payload/server/public/assets/operator-_DN0RF1R.js.br +0 -0
  149. package/payload/server/public/assets/operator-_DN0RF1R.js.gz +0 -0
  150. package/payload/server/public/assets/page-DI4qQIK0.js +1 -0
  151. package/payload/server/public/assets/page-DI4qQIK0.js.br +0 -0
  152. package/payload/server/public/assets/page-DI4qQIK0.js.gz +0 -0
  153. package/payload/server/public/assets/page-zCwgrs8m.js +32 -0
  154. package/payload/server/public/assets/page-zCwgrs8m.js.br +0 -0
  155. package/payload/server/public/assets/page-zCwgrs8m.js.gz +0 -0
  156. package/payload/server/public/assets/play-CHQ5a9yh.js +1 -0
  157. package/payload/server/public/assets/play-CHQ5a9yh.js.br +0 -0
  158. package/payload/server/public/assets/play-CHQ5a9yh.js.gz +0 -0
  159. package/payload/server/public/assets/{public-7gXDqCog.js → public-DDVWBNSH.js} +1 -1
  160. package/payload/server/public/assets/public-DDVWBNSH.js.br +0 -0
  161. package/payload/server/public/assets/public-DDVWBNSH.js.gz +0 -0
  162. package/payload/server/public/assets/{rotate-ccw-DhqNTPpo.js → rotate-ccw-xTwkf-m7.js} +1 -1
  163. package/payload/server/public/assets/rotate-ccw-xTwkf-m7.js.br +0 -0
  164. package/payload/server/public/assets/rotate-ccw-xTwkf-m7.js.gz +0 -0
  165. package/payload/server/public/assets/{routines-DN_yDtEj.js → routines-Bu5MdNmG.js} +1 -1
  166. package/payload/server/public/assets/routines-Bu5MdNmG.js.br +0 -0
  167. package/payload/server/public/assets/routines-Bu5MdNmG.js.gz +0 -0
  168. package/payload/server/public/assets/{skills-pb_3BdOl.js → skills-DRunh5vy.js} +1 -1
  169. package/payload/server/public/assets/skills-DRunh5vy.js.br +0 -0
  170. package/payload/server/public/assets/skills-DRunh5vy.js.gz +0 -0
  171. package/payload/server/public/assets/{tasks-BQm4boat.js → tasks-DI2fznvd.js} +1 -1
  172. package/payload/server/public/assets/tasks-DI2fznvd.js.br +0 -0
  173. package/payload/server/public/assets/tasks-DI2fznvd.js.gz +0 -0
  174. package/payload/server/public/assets/{triangle-alert-d7yjaIqv.js → triangle-alert-B6CHZeUf.js} +1 -1
  175. package/payload/server/public/assets/triangle-alert-B6CHZeUf.js.br +0 -0
  176. package/payload/server/public/assets/triangle-alert-B6CHZeUf.js.gz +0 -0
  177. package/payload/server/public/assets/{useCopyFeedback-CZ6Qhfkj.js → useCopyFeedback-6rU2IEPk.js} +1 -1
  178. package/payload/server/public/assets/useCopyFeedback-6rU2IEPk.js.br +2 -0
  179. package/payload/server/public/assets/useCopyFeedback-6rU2IEPk.js.gz +0 -0
  180. package/payload/server/public/assets/{useMediaQuery-R1smYLx4.js → useMediaQuery-D7A5Bzs3.js} +1 -1
  181. package/payload/server/public/assets/useMediaQuery-D7A5Bzs3.js.br +0 -0
  182. package/payload/server/public/assets/useMediaQuery-D7A5Bzs3.js.gz +0 -0
  183. package/payload/server/public/assets/useVoiceRecorder-CptrerVA.js +2 -0
  184. package/payload/server/public/assets/useVoiceRecorder-CptrerVA.js.br +0 -0
  185. package/payload/server/public/assets/useVoiceRecorder-CptrerVA.js.gz +0 -0
  186. package/payload/server/public/assets/{wrench-DL1pbaCs.js → wrench-DyX4C8aY.js} +1 -1
  187. package/payload/server/public/assets/wrench-DyX4C8aY.js.br +0 -0
  188. package/payload/server/public/assets/wrench-DyX4C8aY.js.gz +0 -0
  189. package/payload/server/public/browser.html +5 -5
  190. package/payload/server/public/calendar.html +8 -8
  191. package/payload/server/public/chat.html +14 -14
  192. package/payload/server/public/data.html +12 -12
  193. package/payload/server/public/field.html +3 -3
  194. package/payload/server/public/graph.html +10 -10
  195. package/payload/server/public/index.html +14 -14
  196. package/payload/server/public/operator.html +15 -15
  197. package/payload/server/public/public.html +14 -14
  198. package/payload/server/public/routines.html +8 -8
  199. package/payload/server/public/skills.html +6 -6
  200. package/payload/server/public/tasks.html +7 -7
  201. package/payload/server/server.js +634 -461
  202. package/payload/server/video-extract.js +36 -0
  203. package/payload/server/public/assets/AdminLoginScreens-B3W6J6Bl.js.br +0 -0
  204. package/payload/server/public/assets/AdminLoginScreens-B3W6J6Bl.js.gz +0 -0
  205. package/payload/server/public/assets/AdminShell-C3R-vMZ5.js.br +0 -0
  206. package/payload/server/public/assets/AdminShell-C3R-vMZ5.js.gz +0 -0
  207. package/payload/server/public/assets/activity-tzv68iBs.js.br +0 -0
  208. package/payload/server/public/assets/activity-tzv68iBs.js.gz +0 -0
  209. package/payload/server/public/assets/admin-CzW_9jm3.js +0 -1
  210. package/payload/server/public/assets/admin-CzW_9jm3.js.br +0 -0
  211. package/payload/server/public/assets/admin-CzW_9jm3.js.gz +0 -0
  212. package/payload/server/public/assets/agents-DUZfeY3X.js.br +0 -0
  213. package/payload/server/public/assets/agents-DUZfeY3X.js.gz +0 -0
  214. package/payload/server/public/assets/browser-DwLaXqjO.js.br +0 -0
  215. package/payload/server/public/assets/browser-DwLaXqjO.js.gz +0 -0
  216. package/payload/server/public/assets/calendar-Cli8Qjl9.js.br +0 -0
  217. package/payload/server/public/assets/calendar-Cli8Qjl9.js.gz +0 -0
  218. package/payload/server/public/assets/chat-ByAgBgm1.js +0 -1
  219. package/payload/server/public/assets/chat-ByAgBgm1.js.br +0 -1
  220. package/payload/server/public/assets/chat-ByAgBgm1.js.gz +0 -0
  221. package/payload/server/public/assets/chevron-left-BIYVnwvk.js +0 -1
  222. package/payload/server/public/assets/chevron-left-BIYVnwvk.js.br +0 -0
  223. package/payload/server/public/assets/clock-Dzy79hq3.js +0 -1
  224. package/payload/server/public/assets/clock-Dzy79hq3.js.br +0 -0
  225. package/payload/server/public/assets/clock-Dzy79hq3.js.gz +0 -0
  226. package/payload/server/public/assets/copy-yhhwfEbQ.js.br +0 -0
  227. package/payload/server/public/assets/copy-yhhwfEbQ.js.gz +0 -0
  228. package/payload/server/public/assets/data-CsMMki2A.js +0 -1
  229. package/payload/server/public/assets/data-CsMMki2A.js.br +0 -0
  230. package/payload/server/public/assets/data-CsMMki2A.js.gz +0 -0
  231. package/payload/server/public/assets/field-jg0YQNDy.js.br +0 -0
  232. package/payload/server/public/assets/field-jg0YQNDy.js.gz +0 -0
  233. package/payload/server/public/assets/file-text-D0EdW7h4.js.br +0 -0
  234. package/payload/server/public/assets/file-text-D0EdW7h4.js.gz +0 -0
  235. package/payload/server/public/assets/graph--AUr4uBc.js.br +0 -0
  236. package/payload/server/public/assets/graph--AUr4uBc.js.gz +0 -0
  237. package/payload/server/public/assets/graph-labels-DM0CiAX1.js.br +0 -0
  238. package/payload/server/public/assets/graph-labels-DM0CiAX1.js.gz +0 -0
  239. package/payload/server/public/assets/jsx-runtime-lfcjzaWi.css.br +0 -0
  240. package/payload/server/public/assets/operator-CNYKStFX.js.br +0 -0
  241. package/payload/server/public/assets/operator-CNYKStFX.js.gz +0 -0
  242. package/payload/server/public/assets/page-DSsEpl8J.js +0 -32
  243. package/payload/server/public/assets/page-DSsEpl8J.js.br +0 -0
  244. package/payload/server/public/assets/page-DSsEpl8J.js.gz +0 -0
  245. package/payload/server/public/assets/page-DjhmwxnY.js +0 -1
  246. package/payload/server/public/assets/page-DjhmwxnY.js.br +0 -0
  247. package/payload/server/public/assets/page-DjhmwxnY.js.gz +0 -0
  248. package/payload/server/public/assets/play-DhZlml5b.js +0 -1
  249. package/payload/server/public/assets/play-DhZlml5b.js.br +0 -0
  250. package/payload/server/public/assets/play-DhZlml5b.js.gz +0 -0
  251. package/payload/server/public/assets/public-7gXDqCog.js.br +0 -0
  252. package/payload/server/public/assets/public-7gXDqCog.js.gz +0 -0
  253. package/payload/server/public/assets/rotate-ccw-DhqNTPpo.js.br +0 -0
  254. package/payload/server/public/assets/rotate-ccw-DhqNTPpo.js.gz +0 -0
  255. package/payload/server/public/assets/routines-DN_yDtEj.js.br +0 -0
  256. package/payload/server/public/assets/routines-DN_yDtEj.js.gz +0 -0
  257. package/payload/server/public/assets/skills-pb_3BdOl.js.br +0 -0
  258. package/payload/server/public/assets/skills-pb_3BdOl.js.gz +0 -0
  259. package/payload/server/public/assets/tasks-BQm4boat.js.br +0 -0
  260. package/payload/server/public/assets/tasks-BQm4boat.js.gz +0 -0
  261. package/payload/server/public/assets/triangle-alert-d7yjaIqv.js.br +0 -0
  262. package/payload/server/public/assets/triangle-alert-d7yjaIqv.js.gz +0 -0
  263. package/payload/server/public/assets/useCopyFeedback-CZ6Qhfkj.js.br +0 -0
  264. package/payload/server/public/assets/useCopyFeedback-CZ6Qhfkj.js.gz +0 -0
  265. package/payload/server/public/assets/useMediaQuery-R1smYLx4.js.br +0 -0
  266. package/payload/server/public/assets/useMediaQuery-R1smYLx4.js.gz +0 -0
  267. package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js +0 -2
  268. package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js.br +0 -0
  269. package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js.gz +0 -0
  270. package/payload/server/public/assets/wrench-DL1pbaCs.js.br +0 -0
  271. package/payload/server/public/assets/wrench-DL1pbaCs.js.gz +0 -0
  272. /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js → jsx-runtime-B2Q1UOSJ.js} +0 -0
  273. /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js.br → jsx-runtime-B2Q1UOSJ.js.br} +0 -0
  274. /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js.gz → jsx-runtime-B2Q1UOSJ.js.gz} +0 -0
@@ -0,0 +1,96 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { sampleMailbox } from "../sample-mailbox.js";
3
+ const config = { email: "box@x.com", agentAddress: "box@x.com" };
4
+ const account = { accountId: "acc-1", config, password: "pw" };
5
+ const email = (uid) => ({
6
+ uid,
7
+ messageId: `<m${uid}@x>`,
8
+ inReplyTo: null,
9
+ toAddresses: ["box@x.com"],
10
+ ccAddresses: [],
11
+ fromAddress: "s@y.com",
12
+ fromName: "S",
13
+ subject: `s${uid}`,
14
+ date: "2026-08-13T00:00:00Z",
15
+ bodyPreview: "b",
16
+ attachments: [],
17
+ });
18
+ function deps(over = {}) {
19
+ return {
20
+ fetchSince: vi.fn(async () => ({ uidValidity: 100, emails: [], maxUid: 0 })),
21
+ write: vi.fn(async () => ({
22
+ threadsDispatched: 1,
23
+ threadsSkipped: 0,
24
+ unresolvedAddresses: [],
25
+ attachmentsAttached: 0,
26
+ attachmentsFailed: 0,
27
+ })),
28
+ readCursor: vi.fn(async () => null),
29
+ advanceCursor: vi.fn(async () => { }),
30
+ recipients: () => ["box@x.com"],
31
+ log: vi.fn(),
32
+ ...over,
33
+ };
34
+ }
35
+ describe("sampleMailbox", () => {
36
+ it("writes above-cursor messages once and advances the cursor to maxUid", async () => {
37
+ const d = deps({
38
+ readCursor: vi.fn(async () => ({ cursorUid: 10, uidValidity: 100 })),
39
+ fetchSince: vi.fn(async () => ({ uidValidity: 100, emails: [email(11), email(12)], maxUid: 12 })),
40
+ });
41
+ const r = await sampleMailbox(d, account);
42
+ expect(d.write).toHaveBeenCalledTimes(1);
43
+ expect(d.write.mock.calls[0][0]).toHaveLength(2);
44
+ expect(d.advanceCursor).toHaveBeenCalledWith("acc-1", "box@x.com", 12, 100);
45
+ expect(r).toMatchObject({ fetched: 2, cursor: 12 });
46
+ });
47
+ it("leaves the cursor unadvanced when the write fails", async () => {
48
+ const d = deps({
49
+ readCursor: vi.fn(async () => ({ cursorUid: 10, uidValidity: 100 })),
50
+ fetchSince: vi.fn(async () => ({ uidValidity: 100, emails: [email(11)], maxUid: 11 })),
51
+ write: vi.fn(async () => {
52
+ throw new Error("neo4j down");
53
+ }),
54
+ });
55
+ const r = await sampleMailbox(d, account);
56
+ expect(d.advanceCursor).not.toHaveBeenCalled();
57
+ expect(r.error).toContain("neo4j down");
58
+ expect(d.log.mock.calls.some((c) => String(c[0]).includes("op=sample-error"))).toBe(true);
59
+ });
60
+ it("is a no-op when nothing is above the cursor", async () => {
61
+ const d = deps({
62
+ readCursor: vi.fn(async () => ({ cursorUid: 10, uidValidity: 100 })),
63
+ fetchSince: vi.fn(async () => ({ uidValidity: 100, emails: [], maxUid: 0 })),
64
+ });
65
+ const r = await sampleMailbox(d, account);
66
+ expect(d.write).not.toHaveBeenCalled();
67
+ expect(d.advanceCursor).not.toHaveBeenCalled();
68
+ expect(r).toMatchObject({ fetched: 0, cursor: 10 });
69
+ });
70
+ it("a second cycle over a persistent store does not re-ingest", async () => {
71
+ let stored = null;
72
+ const d = deps({
73
+ readCursor: vi.fn(async () => stored),
74
+ advanceCursor: vi.fn(async (_a, _e, uid, v) => {
75
+ stored = { cursorUid: uid, uidValidity: v };
76
+ }),
77
+ fetchSince: vi.fn(async (_c, _p, sinceUid) => sinceUid < 12
78
+ ? { uidValidity: 100, emails: [email(11), email(12)], maxUid: 12 }
79
+ : { uidValidity: 100, emails: [], maxUid: 0 }),
80
+ });
81
+ await sampleMailbox(d, account);
82
+ await sampleMailbox(d, account);
83
+ expect(d.write).toHaveBeenCalledTimes(1);
84
+ });
85
+ it("resets the cursor to a backfill when uidValidity changed", async () => {
86
+ const d = deps({
87
+ readCursor: vi.fn(async () => ({ cursorUid: 5000, uidValidity: 100 })),
88
+ fetchSince: vi.fn(async () => ({ uidValidity: 200, emails: [email(1)], maxUid: 1 })),
89
+ });
90
+ const r = await sampleMailbox(d, account);
91
+ expect(d.write).not.toHaveBeenCalled();
92
+ expect(d.advanceCursor).toHaveBeenCalledWith("acc-1", "box@x.com", 0, 200);
93
+ expect(r).toMatchObject({ fetched: 0, cursor: 0 });
94
+ });
95
+ });
96
+ //# sourceMappingURL=sample-mailbox.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-mailbox.test.js","sourceRoot":"","sources":["../../../src/sampler/__tests__/sample-mailbox.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,aAAa,EAAyC,MAAM,sBAAsB,CAAC;AAE5F,MAAM,MAAM,GAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACtE,MAAM,OAAO,GAAmB,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC/E,MAAM,KAAK,GAAG,CAAC,GAAW,EAAO,EAAE,CAAC,CAAC;IACnC,GAAG;IACH,SAAS,EAAE,KAAK,GAAG,KAAK;IACxB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,CAAC,WAAW,CAAC;IAC1B,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,SAAS;IACtB,QAAQ,EAAE,GAAG;IACb,OAAO,EAAE,IAAI,GAAG,EAAE;IAClB,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,GAAG;IAChB,WAAW,EAAE,EAAE;CAChB,CAAC,CAAC;AAEH,SAAS,IAAI,CAAC,OAA6B,EAAE;IAC3C,OAAO;QACL,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5E,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACxB,iBAAiB,EAAE,CAAC;YACpB,cAAc,EAAE,CAAC;YACjB,mBAAmB,EAAE,EAAE;YACvB,mBAAmB,EAAE,CAAC;YACtB,iBAAiB,EAAE,CAAC;SACrB,CAAC,CAAC;QACH,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;QACnC,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;QACpC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC;QAC/B,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;QACZ,GAAG,IAAI;KACR,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,CAAC,GAAG,IAAI,CAAC;YACb,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACpE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;SAClG,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,KAAY,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAE,CAAC,CAAC,KAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,CAAC,CAAC,aAAoB,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QACnF,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,CAAC,GAAG,IAAI,CAAC;YACb,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACpE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YACtF,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE;gBACtB,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAChC,CAAC,CAAC;SACH,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,aAAoB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACtD,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAE,CAAC,CAAC,GAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,CAAC,GAAG,IAAI,CAAC;YACb,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACpE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;SAC7E,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,KAAY,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC9C,MAAM,CAAC,CAAC,CAAC,aAAoB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACtD,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,IAAI,MAAM,GAA6D,IAAI,CAAC;QAC5E,MAAM,CAAC,GAAG,IAAI,CAAC;YACb,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC;YACrC,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;gBAC5C,MAAM,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;YAC9C,CAAC,CAAC;YACF,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAC3C,QAAQ,GAAG,EAAE;gBACX,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;gBAClE,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAChD;SACF,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,KAAY,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,CAAC,GAAG,IAAI,CAAC;YACb,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACtE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;SACrF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,KAAY,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC9C,MAAM,CAAC,CAAC,CAAC,aAAoB,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAClF,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/sampler/main.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import { appendFileSync, statSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { fetchSinceUid, resolveDefaultRecipients } from "../lib/imap.js";
4
+ import { dispatchEmailMessagesToConversationArchive } from "../lib/conversation-archive-dispatch.js";
5
+ import { listAllImapAccounts, readSamplerCursor, advanceSamplerCursor } from "../lib/credentials.js";
6
+ import { sampleMailbox } from "./sample-mailbox.js";
7
+ // The standing email-sampler (Task 2682): a per-brand systemd user unit that
8
+ // each cycle enumerates every IMAP mailbox on the install and writes new
9
+ // inbound messages to the graph via the plugin's own dispatch, independent of
10
+ // any agent turn. The cursor is the only state; it advances only on a
11
+ // successful write, so the loop is restart-safe by construction.
12
+ const LOG_PATH = process.env.EMAIL_SAMPLER_LOG_PATH ?? "/tmp/email-sampler.log";
13
+ const INTERVAL_MS = (Number(process.env.EMAIL_SAMPLER_INTERVAL_SEC ?? "60") || 60) * 1000;
14
+ const LOG_MAX = Number(process.env.EMAIL_SAMPLER_LOG_MAX_BYTES ?? "10485760") || 10485760;
15
+ /** Append one structured line, capping the file at LOG_MAX by keeping the tail
16
+ * (mirrors rss-sampler's self-cap). Logging must never kill the loop. */
17
+ function logLine(line) {
18
+ const stamped = `${new Date().toISOString()} [email-sampler] ${line}\n`;
19
+ try {
20
+ mkdirSync(dirname(LOG_PATH), { recursive: true });
21
+ appendFileSync(LOG_PATH, stamped);
22
+ if (statSync(LOG_PATH).size > LOG_MAX) {
23
+ const buf = readFileSync(LOG_PATH);
24
+ // Keep roughly the last half, but start at the next line boundary so the
25
+ // first retained line is whole, not a mid-line fragment a tail reader
26
+ // would show as garbage.
27
+ const approx = buf.length - Math.floor(LOG_MAX / 2);
28
+ const nl = buf.indexOf(0x0a, approx);
29
+ const start = nl === -1 ? approx : nl + 1;
30
+ writeFileSync(LOG_PATH, buf.subarray(start));
31
+ }
32
+ }
33
+ catch {
34
+ /* a logging failure is never fatal to ingest */
35
+ }
36
+ }
37
+ const deps = {
38
+ fetchSince: fetchSinceUid,
39
+ write: (m) => dispatchEmailMessagesToConversationArchive(m),
40
+ readCursor: readSamplerCursor,
41
+ advanceCursor: advanceSamplerCursor,
42
+ recipients: (c) => resolveDefaultRecipients(c),
43
+ log: logLine,
44
+ };
45
+ async function cycle() {
46
+ let accounts;
47
+ try {
48
+ accounts = await listAllImapAccounts();
49
+ }
50
+ catch (e) {
51
+ logLine(`op=sample-error mailbox=<enumeration> detail=${e instanceof Error ? e.message : String(e)}`);
52
+ return;
53
+ }
54
+ for (const account of accounts) {
55
+ try {
56
+ await sampleMailbox(deps, account);
57
+ }
58
+ catch (e) {
59
+ logLine(`op=sample-error mailbox=${account.config.email} detail=${e instanceof Error ? e.message : String(e)}`);
60
+ }
61
+ }
62
+ }
63
+ async function main() {
64
+ logLine(`boot interval_sec=${INTERVAL_MS / 1000} log=${LOG_PATH}`);
65
+ // eslint-disable-next-line no-constant-condition
66
+ while (true) {
67
+ await cycle();
68
+ await new Promise((r) => setTimeout(r, INTERVAL_MS));
69
+ }
70
+ }
71
+ main().catch((e) => {
72
+ logLine(`op=sample-error mailbox=<fatal> detail=${e instanceof Error ? e.message : String(e)}`);
73
+ process.exit(1);
74
+ });
75
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/sampler/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { EmailConfig, SamplerCursor } from "../lib/credentials.js";
2
+ import type { FetchedEmail } from "../lib/imap.js";
3
+ import type { EmailData } from "../lib/graph.js";
4
+ import type { DispatchResult } from "../lib/conversation-archive-dispatch.js";
5
+ /**
6
+ * The email-sampler's single ingest step, isolated as a pure function with
7
+ * injected fetch / writer / cursor so the loop and the systemd unit stay thin
8
+ * and every branch is testable without IMAP, Neo4j, or a clock (Task 2682).
9
+ */
10
+ export interface SamplerDeps {
11
+ fetchSince: (config: EmailConfig, password: string, sinceUid: number, recipients: string[] | undefined) => Promise<{
12
+ uidValidity: number;
13
+ emails: FetchedEmail[];
14
+ maxUid: number;
15
+ }>;
16
+ write: (messages: EmailData[]) => Promise<DispatchResult>;
17
+ readCursor: (accountId: string, email: string) => Promise<SamplerCursor | null>;
18
+ advanceCursor: (accountId: string, email: string, cursorUid: number, uidValidity: number) => Promise<void>;
19
+ recipients: (config: EmailConfig) => string[] | undefined;
20
+ log: (line: string) => void;
21
+ }
22
+ export interface SamplerAccount {
23
+ accountId: string;
24
+ config: EmailConfig;
25
+ password: string;
26
+ }
27
+ export interface SampleResult {
28
+ mailbox: string;
29
+ fetched: number;
30
+ cursor: number;
31
+ error?: string;
32
+ }
33
+ /**
34
+ * Sample one mailbox: fetch inbound UIDs above the sampler's own cursor, write
35
+ * them to the graph, and advance the cursor — but only after a successful write.
36
+ *
37
+ * Cases, in order:
38
+ * - fetch throws → log op=sample-error, cursor unchanged, retried next cycle.
39
+ * - the mailbox's live uidValidity differs from the stored one → the stored UID
40
+ * is void (the server renumbered), so reset the cursor to 0 for the new
41
+ * uidValidity and let the next cycle backfill cleanly. This cycle writes
42
+ * nothing, because `UID > oldCursor` against a new sequence is unreliable.
43
+ * - no messages above the cursor → no-op, cursor unchanged.
44
+ * - write throws → log op=sample-error, cursor unchanged, retried next cycle.
45
+ * - otherwise → advance the cursor to the fetched maxUid.
46
+ */
47
+ export declare function sampleMailbox(deps: SamplerDeps, account: SamplerAccount): Promise<SampleResult>;
48
+ //# sourceMappingURL=sample-mailbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-mailbox.d.ts","sourceRoot":"","sources":["../../src/sampler/sample-mailbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAE9E;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,CACV,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAAE,GAAG,SAAS,KAC7B,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1D,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAChF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3G,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;IAC1D,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgCD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAoCrG"}
@@ -0,0 +1,77 @@
1
+ function msg(e) {
2
+ return e instanceof Error ? e.message : String(e);
3
+ }
4
+ /** Map a fetched IMAP message to the archive-writer's record shape. The mapping
5
+ * matches what email-ingest builds, EXCEPT the screening label: email-ingest
6
+ * stamps "clean" because an operator approved the message, whereas the sampler
7
+ * runs no screen and has no operator, so it stamps "unscreened" — the honest
8
+ * value a later gate needs to tell auto-sampled mail from operator-vetted mail. */
9
+ function toEmailData(e, accountId, config, uidValidity) {
10
+ return {
11
+ messageId: e.messageId,
12
+ inReplyTo: e.inReplyTo,
13
+ toAddresses: e.toAddresses,
14
+ ccAddresses: e.ccAddresses,
15
+ uid: e.uid,
16
+ uidValidity,
17
+ mailbox: "INBOX",
18
+ recipientAddress: config.email,
19
+ fromAddress: e.fromAddress,
20
+ fromName: e.fromName,
21
+ subject: e.subject,
22
+ bodyPreview: e.bodyPreview,
23
+ receivedAt: e.date,
24
+ accountId,
25
+ screening: "unscreened",
26
+ screeningReason: "sampler-ingest",
27
+ };
28
+ }
29
+ /**
30
+ * Sample one mailbox: fetch inbound UIDs above the sampler's own cursor, write
31
+ * them to the graph, and advance the cursor — but only after a successful write.
32
+ *
33
+ * Cases, in order:
34
+ * - fetch throws → log op=sample-error, cursor unchanged, retried next cycle.
35
+ * - the mailbox's live uidValidity differs from the stored one → the stored UID
36
+ * is void (the server renumbered), so reset the cursor to 0 for the new
37
+ * uidValidity and let the next cycle backfill cleanly. This cycle writes
38
+ * nothing, because `UID > oldCursor` against a new sequence is unreliable.
39
+ * - no messages above the cursor → no-op, cursor unchanged.
40
+ * - write throws → log op=sample-error, cursor unchanged, retried next cycle.
41
+ * - otherwise → advance the cursor to the fetched maxUid.
42
+ */
43
+ export async function sampleMailbox(deps, account) {
44
+ const { accountId, config, password } = account;
45
+ const box = config.email;
46
+ const stored = await deps.readCursor(accountId, box);
47
+ const sinceUid = stored?.cursorUid ?? 0;
48
+ let result;
49
+ try {
50
+ result = await deps.fetchSince(config, password, sinceUid, deps.recipients(config));
51
+ }
52
+ catch (e) {
53
+ deps.log(`op=sample-error mailbox=${box} detail=${msg(e)}`);
54
+ return { mailbox: box, fetched: 0, cursor: sinceUid, error: msg(e) };
55
+ }
56
+ if (stored?.uidValidity != null && stored.uidValidity !== result.uidValidity) {
57
+ await deps.advanceCursor(accountId, box, 0, result.uidValidity);
58
+ deps.log(`op=sample mailbox=${box} fetched=0 cursor=0 note=uidvalidity-reset`);
59
+ return { mailbox: box, fetched: 0, cursor: 0 };
60
+ }
61
+ if (result.emails.length === 0) {
62
+ deps.log(`op=sample mailbox=${box} fetched=0 cursor=${sinceUid}`);
63
+ return { mailbox: box, fetched: 0, cursor: sinceUid };
64
+ }
65
+ const messages = result.emails.map((e) => toEmailData(e, accountId, config, result.uidValidity));
66
+ try {
67
+ await deps.write(messages);
68
+ }
69
+ catch (e) {
70
+ deps.log(`op=sample-error mailbox=${box} detail=${msg(e)}`);
71
+ return { mailbox: box, fetched: messages.length, cursor: sinceUid, error: msg(e) };
72
+ }
73
+ await deps.advanceCursor(accountId, box, result.maxUid, result.uidValidity);
74
+ deps.log(`op=sample mailbox=${box} fetched=${messages.length} cursor=${result.maxUid}`);
75
+ return { mailbox: box, fetched: messages.length, cursor: result.maxUid };
76
+ }
77
+ //# sourceMappingURL=sample-mailbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-mailbox.js","sourceRoot":"","sources":["../../src/sampler/sample-mailbox.ts"],"names":[],"mappings":"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"}
@@ -348,6 +348,8 @@ The position written is the one the GATE read, carried back in the result rather
348
348
 
349
349
  Three lines record it. `[schedule-gate] op=mark-advanced eventId=… advanced=… positions=…` per accepted wake, `op=mark-not-advanced eventId=… reason=no-observation|watermark-unreadable|write-failed` when nothing moved, and the standing `[schedule-audit] op=gate-mark-stalled acct=… count=… eventIds=[…]`, which names any gated event with three or more accepted wakes since its mark last moved. That last one is the check for the failure that emits nothing at all: a promote that runs, writes nothing, and leaves every surface reading normally. `op=gate-watermark-age` measures the same mark against the clock and so reads a weekly routine as stale; this one measures it against the routine's own wakes. A watermark file that exists and is not a watermark object is named by `[scheduling-gate] op=watermark-unreadable eventId=… reason=…` on every read of it, and is never overwritten, so its positions survive for an operator to look at; a missing file stays silent, because that is a first fire. `reason=` names the shape found: a body holding a JSON array reads `an array, not a watermark object`, because an array is an object to `typeof` and so passed the guard, was promoted into, and was then written back by `JSON.stringify` with every promoted position dropped.
350
350
 
351
+ **An unreachable source is reported once per outage, not once per fire.** A check that cannot reach its source still counts as work and still fires — that is what fail-open means — but the REPEAT is deduplicated. The result carries `genuineWork`, set only by a check that answered, and a `source` on every `errored[]` entry (the mailbox, the connector, the database, the bot, or the channel). When nothing answered with work and one or more checks errored, the sorted set of those sources is compared with the set last reported, held as `outageReported {sources, at}` inside the event's own watermark file. An unchanged set skips the fire: no turn, no message, no watermark advance, and a run recorded `gated` with `dispatchResult = 'outage-suppressed'`. A new or changed set dispatches, and the set is stored only once the inject route accepts the wake, because a refused dispatch told nobody anything. A fire with genuine work dispatches regardless and records whatever is unreachable at that fire: real work on one check is no evidence about another check's source, so a delivery on a healthy mailbox leaves a sick mailbox's marker exactly where it was, and clearing there would re-report the same outage on the next quiet fire. The marker clears when a dispatching fire has nothing unreachable, and when the gate answers quiet, so the next outage reports afresh; recovery rides the routine's next real wake rather than a message of its own. Re-recording a set already held rewrites nothing, so its age stays measurable. Four lines record it: the per-fire `[schedule-gate] op=evaluated … genuineWork=… errored=[…] class=has-work|outage-report|outage-suppressed|no-work`, then `op=outage-reported eventId=… sources=[…]`, `op=outage-suppressed eventId=… sources=[…] promoted=0`, and `op=outage-cleared eventId=… priorSources=[…] reason=…`. A marker that stops clearing would mute that routine's outage reporting permanently with no other symptom, so the standing `[schedule-audit] op=outage-marker-census acct=… held=… stale=… ok=…` prints per account on every reconcile tick and `op=stale-outage-marker eventId=… sources=[…] agedCycles=… agedHours=…` names any marker older than a day. A gate server built before this contract returns neither field, reads as genuine work, and is never suppressed.
352
+
351
353
  **Recurring only.** A one-time agent event is never gated — its row is already `due` by the time the dispatcher sees it, so a skip there would drop the routine for good — and it is therefore outside the refusal. `schedule-update` takes no waiver either: an existing routine keeps what it has until it is edited.
352
354
 
353
355
  An event carries **either** an `action` **or** an `agentDispatch`, never both — setting one clears the other. Agent dispatch is stored as `agentChannel`, `agentDestination`, `agentPrompt`; the gate as `gatePlugin`, `gateTool`, `gateArgs`; the waiver as `gateWaived`. Use `schedule-update` with `agentDispatch` to modify or `agentDispatch: null` to clear. On WhatsApp, a destination bound as an account-manager scopes the spawned session to its sub-account — unless that same phone is also on the house `adminPhones` list, in which case it scopes to the channel account, because the dispatch rides the house socket and so arrives from the house number. On Telegram the session runs on the house account.
@@ -9,7 +9,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
9
9
  import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
10
10
  import { tmpdir } from "node:os";
11
11
  import { join } from "node:path";
12
- import { auditGateAlwaysSkipping, auditGateNeverGates, auditGateWatermarkAge, auditGateMarkStalled, } from "../schedule-audit.js";
12
+ import { auditGateAlwaysSkipping, auditGateNeverGates, auditGateWatermarkAge, auditGateMarkStalled, auditStaleOutageMarker, } from "../schedule-audit.js";
13
13
  import { watermarkPath } from "../../tools/scheduling-gate.js";
14
14
  const ACCT = "20028fb5-0000-4000-8000-000000000000";
15
15
  const NOW = Date.parse("2026-08-02T20:00:00.000Z");
@@ -256,4 +256,70 @@ describe("auditGateMarkStalled", () => {
256
256
  expect(lines.join("\n")).toContain("op=gate-mark-stalled-error");
257
257
  });
258
258
  });
259
+ // Task 2699 — the outage marker that stopped clearing. While one is held every
260
+ // errors-only fire is suppressed, and a marker that outlives its outage mutes
261
+ // the routine's outage reporting for good with no other symptom.
262
+ describe("auditStaleOutageMarker", () => {
263
+ const rowDriver = (rows) => ({
264
+ session: () => ({
265
+ run: async () => ({ records: rows.map((r) => ({ get: (k) => r[k] })) }),
266
+ close: async () => { },
267
+ }),
268
+ });
269
+ const gatedRow = (eventId, suppressedAt = []) => ({
270
+ eventId,
271
+ accountId: ACCT,
272
+ suppressedAt,
273
+ });
274
+ it("prints a census line per account even when no marker is held", async () => {
275
+ await auditStaleOutageMarker(rowDriver([gatedRow("e-1")]), [ACCT], platformRoot, NOW);
276
+ expect(lines).toEqual([
277
+ "[schedule-audit] op=outage-marker-census acct=20028fb5 held=0 stale=0 ok=true",
278
+ ]);
279
+ });
280
+ it("counts a fresh marker as held and not stale", async () => {
281
+ seedMarks("e-1", {
282
+ outageReported: { sources: ["a@x"], at: "2026-08-02T18:00:00.000Z" },
283
+ });
284
+ await auditStaleOutageMarker(rowDriver([gatedRow("e-1")]), [ACCT], platformRoot, NOW);
285
+ expect(lines).toEqual([
286
+ "[schedule-audit] op=outage-marker-census acct=20028fb5 held=1 stale=0 ok=true",
287
+ ]);
288
+ });
289
+ it("names a marker older than a day, with the fires it has suppressed", async () => {
290
+ seedMarks("e-1", {
291
+ outageReported: { sources: ["a@x", "b@x"], at: "2026-08-01T18:00:00.000Z" },
292
+ });
293
+ await auditStaleOutageMarker(rowDriver([
294
+ gatedRow("e-1", [
295
+ // Before the marker: a different episode, not this marker's cost.
296
+ "2026-08-01T17:00:00.000Z",
297
+ "2026-08-01T19:00:00.000Z",
298
+ "2026-08-02T19:00:00.000Z",
299
+ ]),
300
+ ]), [ACCT], platformRoot, NOW);
301
+ expect(lines[0]).toBe("[schedule-audit] op=stale-outage-marker eventId=e-1 sources=[a@x,b@x] agedCycles=2 agedHours=26");
302
+ expect(lines[1]).toBe("[schedule-audit] op=outage-marker-census acct=20028fb5 held=1 stale=1 ok=false");
303
+ });
304
+ it("treats an unparsable stamp as stale — nothing could ever measure it", async () => {
305
+ seedMarks("e-1", { outageReported: { sources: ["a@x"], at: "not a date" } });
306
+ await auditStaleOutageMarker(rowDriver([gatedRow("e-1")]), [ACCT], platformRoot, NOW);
307
+ expect(lines[0]).toContain("op=stale-outage-marker eventId=e-1 sources=[a@x]");
308
+ expect(lines[0]).toContain("agedHours=-1");
309
+ });
310
+ it("names its own failure rather than going quiet when neo4j is down", async () => {
311
+ const throwing = {
312
+ session: () => ({
313
+ run: async () => {
314
+ throw new Error("neo4j down");
315
+ },
316
+ close: async () => { },
317
+ }),
318
+ };
319
+ await auditStaleOutageMarker(throwing, [ACCT], platformRoot, NOW);
320
+ expect(lines).toEqual([
321
+ "[schedule-audit] op=outage-marker-census-error detail=neo4j down",
322
+ ]);
323
+ });
324
+ });
259
325
  //# sourceMappingURL=gate-audits.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gate-audits.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/gate-audits.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gate-audits.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/gate-audits.test.ts"],"names":[],"mappings":"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"}
@@ -49,7 +49,14 @@ describe("chooseGate", () => {
49
49
  describe("evaluateGate", () => {
50
50
  it("hasWork true dispatches and logs op=evaluated", async () => {
51
51
  const call = async () => ok({ hasWork: true, reasons: ["d1"] });
52
- expect(await evaluateGate(GATE, EVENT, ACCOUNT, call)).toEqual({ kind: "has-work", observed: {} });
52
+ expect(await evaluateGate(GATE, EVENT, ACCOUNT, call)).toEqual({
53
+ kind: "has-work",
54
+ observed: {},
55
+ // Task 2699 — a gate server predating `genuineWork` reads as genuine work
56
+ // with no named source, so an install mid-upgrade is never suppressed and
57
+ // records no outage.
58
+ outage: [],
59
+ });
53
60
  expect(lines.join("\n")).toContain("[schedule-gate] op=evaluated");
54
61
  expect(lines.join("\n")).toContain("hasWork=true");
55
62
  });
@@ -211,6 +218,7 @@ describe("evaluateGate", () => {
211
218
  expect(await evaluateGate(GATE, EVENT, ACCOUNT, async () => ok({ hasWork: true }))).toEqual({
212
219
  kind: "has-work",
213
220
  observed: {},
221
+ outage: [],
214
222
  });
215
223
  expect(lines).toHaveLength(1);
216
224
  expect(lines[0]).toContain("op=evaluated");
@@ -224,4 +232,84 @@ describe("evaluateGate", () => {
224
232
  expect(lines).toHaveLength(1);
225
233
  });
226
234
  });
235
+ // Task 2699 — the classification an errors-only wake gets, against the set last
236
+ // reported. Each case is separate because the two directions fail differently:
237
+ // suppressing a fire that had real work mutes the routine, and failing to
238
+ // suppress a repeat re-notifies the operator every fire for the whole outage.
239
+ describe("evaluateGate — outage dedup (Task 2699)", () => {
240
+ const errored = (...sources) => sources.map((source) => ({ kind: "mail", detail: "ETIMEDOUT", source }));
241
+ /** A gate result in the post-2699 shape. */
242
+ const gateResult = (over) => ok({ hasWork: true, reasons: ["mail"], genuineWork: false, errored: [], ...over });
243
+ const evaluate = (structured, stored) => evaluateGate(GATE, EVENT, ACCOUNT, async () => ok(structured), () => stored);
244
+ it("errors-only with no marker held dispatches and carries the set to report", async () => {
245
+ expect(await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, null)).toEqual({ kind: "has-work", observed: {}, outage: ["a@x"] });
246
+ });
247
+ it("errors-only whose set is already reported is suppressed", async () => {
248
+ expect(await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x", "b@x") }, [
249
+ "a@x",
250
+ "b@x",
251
+ ])).toEqual({ kind: "outage-suppressed", sources: ["a@x", "b@x"] });
252
+ });
253
+ it("errors-only whose set changed dispatches again with the new set", async () => {
254
+ expect(await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x", "b@x") }, ["a@x"])).toEqual({ kind: "has-work", observed: {}, outage: ["a@x", "b@x"] });
255
+ });
256
+ it("genuine work beside a still-down source dispatches and clears the marker", async () => {
257
+ expect(await evaluate({ hasWork: true, genuineWork: true, errored: errored("a@x") }, ["a@x"])).toEqual({ kind: "has-work", observed: {}, outage: ["a@x"] });
258
+ });
259
+ it("genuine work with nothing down carries an empty set, which clears the marker", async () => {
260
+ expect(await evaluate({ hasWork: true, genuineWork: true, errored: [] }, ["a@x"])).toEqual({
261
+ kind: "has-work",
262
+ observed: {},
263
+ outage: [],
264
+ });
265
+ });
266
+ it("a quiet gate is no-work, whatever marker is held", async () => {
267
+ expect(await evaluate({ hasWork: false, genuineWork: false, errored: [] }, ["a@x"])).toEqual({
268
+ kind: "no-work",
269
+ });
270
+ });
271
+ it("an unreadable gate still fails open, and reads no marker at all", async () => {
272
+ const reads = [];
273
+ const verdict = await evaluateGate(GATE, EVENT, ACCOUNT, async () => {
274
+ throw new PluginToolError("boom", "error", "");
275
+ }, (id) => {
276
+ reads.push(id);
277
+ return ["a@x"];
278
+ });
279
+ expect(verdict).toMatchObject({ kind: "fail-open" });
280
+ expect(reads).toEqual([]);
281
+ });
282
+ it("a gate server predating genuineWork is never suppressed", async () => {
283
+ // The upgrade window: `errored[]` without `source`, and no `genuineWork`.
284
+ expect(await evaluate({ hasWork: true, errored: [{ kind: "mail", detail: "ETIMEDOUT" }] }, ["a@x"])).toEqual({ kind: "has-work", observed: {}, outage: [] });
285
+ });
286
+ it("names the report class on the fire that starts an outage episode", async () => {
287
+ await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, null);
288
+ expect(lines.join("\n")).toContain("errored=[a@x] class=outage-report");
289
+ });
290
+ it("names the class on every readable fire", async () => {
291
+ await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, ["a@x"]);
292
+ expect(lines.join("\n")).toContain("op=evaluated eventId=65ef758c plugin=scheduling tool=scheduling-gate " +
293
+ "hasWork=true genuineWork=false errored=[a@x] class=outage-suppressed");
294
+ });
295
+ it("never reports a suppressed class beside genuine work", async () => {
296
+ // Signature (a) of the task's observability section: the fail-loud
297
+ // regression. `class=outage-suppressed genuineWork=true` must not exist.
298
+ await evaluate({ hasWork: true, genuineWork: true, errored: errored("a@x") }, ["a@x"]);
299
+ await evaluate({ hasWork: true, genuineWork: false, errored: errored("a@x") }, ["a@x"]);
300
+ await evaluate({ hasWork: false, genuineWork: false, errored: [] }, null);
301
+ const classes = lines.filter((l) => l.includes("op=evaluated"));
302
+ expect(classes).toHaveLength(3);
303
+ expect(classes.some((l) => l.includes("class=outage-suppressed") && l.includes("genuineWork=true"))).toBe(false);
304
+ });
305
+ it("gateResult keeps the tool's own shape honest", () => {
306
+ // Guards the fixture above: if the real result stops carrying these fields,
307
+ // every case here would pass against a shape the gate no longer returns.
308
+ expect(gateResult({}).result.structuredContent).toMatchObject({
309
+ hasWork: true,
310
+ genuineWork: false,
311
+ errored: [],
312
+ });
313
+ });
314
+ });
227
315
  //# sourceMappingURL=gate.test.js.map