crewly 1.6.1 → 1.6.3

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 (367) hide show
  1. package/config/roles/orchestrator/prompt.md +16 -0
  2. package/config/skills/agent/core/get-my-active-work/SKILL.md +101 -0
  3. package/config/skills/agent/core/get-my-active-work/execute.sh +122 -0
  4. package/config/skills/agent/core/record-learning/SKILL.md +29 -0
  5. package/config/skills/agent/core/reply-channel/SKILL.md +41 -0
  6. package/config/skills/agent/core/reply-channel/execute.sh +165 -0
  7. package/config/skills/agent/core/reply-channel/execute.test.sh +148 -0
  8. package/config/skills/agent/remote-browser/execute.sh +296 -14
  9. package/config/skills/agent/remote-browser/execute.test.sh +482 -0
  10. package/config/skills/orchestrator/send-message/SKILL.md +30 -7
  11. package/config/skills/orchestrator/team-health-scan/SKILL.md +98 -0
  12. package/config/skills/orchestrator/team-health-scan/execute.sh +44 -0
  13. package/config/skills/registry.json +62 -1
  14. package/config/slack-app-manifest.json +2 -1
  15. package/config/sops/developer/git-workflow.md +38 -3
  16. package/dist/backend/backend/src/constants.d.ts +69 -1
  17. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  18. package/dist/backend/backend/src/constants.js +69 -2
  19. package/dist/backend/backend/src/constants.js.map +1 -1
  20. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts +53 -0
  21. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -0
  22. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +92 -0
  23. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -0
  24. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
  25. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +18 -1
  26. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
  27. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +68 -0
  28. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  29. package/dist/backend/backend/src/controllers/browser/browser.controller.js +233 -5
  30. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  31. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  32. package/dist/backend/backend/src/controllers/browser/browser.routes.js +10 -1
  33. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  34. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  35. package/dist/backend/backend/src/controllers/chat/chat.controller.js +8 -3
  36. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  37. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +132 -0
  38. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -0
  39. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +401 -0
  40. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -0
  41. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +29 -0
  42. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -0
  43. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +39 -0
  44. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -0
  45. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts +8 -0
  46. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts.map +1 -0
  47. package/dist/backend/backend/src/controllers/chat-v2/index.js +8 -0
  48. package/dist/backend/backend/src/controllers/chat-v2/index.js.map +1 -0
  49. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +13 -13
  50. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
  51. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +74 -234
  52. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
  53. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
  54. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +76 -15
  55. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js.map +1 -1
  56. package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
  57. package/dist/backend/backend/src/controllers/request/request.controller.js +4 -6
  58. package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
  59. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts +43 -0
  60. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
  61. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +200 -72
  62. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
  63. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  64. package/dist/backend/backend/src/controllers/team/team.controller.js +49 -0
  65. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  66. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts +59 -0
  67. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts.map +1 -0
  68. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js +127 -0
  69. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js.map +1 -0
  70. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts +13 -0
  71. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts.map +1 -0
  72. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js +20 -0
  73. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js.map +1 -0
  74. package/dist/backend/backend/src/index.d.ts +9 -0
  75. package/dist/backend/backend/src/index.d.ts.map +1 -1
  76. package/dist/backend/backend/src/index.js +233 -0
  77. package/dist/backend/backend/src/index.js.map +1 -1
  78. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  79. package/dist/backend/backend/src/routes/api.routes.js +40 -6
  80. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  81. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +498 -0
  82. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  83. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +759 -0
  84. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  85. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +25 -0
  86. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/agent/agent-registration.service.js +221 -58
  88. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +9 -2
  90. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +35 -2
  92. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  93. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +8 -2
  94. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +1 -0
  96. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  97. package/dist/backend/backend/src/services/agent/tmux-command.service.d.ts.map +1 -1
  98. package/dist/backend/backend/src/services/agent/tmux-command.service.js +2 -1
  99. package/dist/backend/backend/src/services/agent/tmux-command.service.js.map +1 -1
  100. package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
  102. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +148 -3
  104. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +241 -2
  106. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  107. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -1
  108. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +13 -0
  109. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -1
  110. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
  111. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +26 -1
  112. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
  113. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  114. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  115. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  116. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  117. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +161 -0
  118. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +382 -2
  120. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  121. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +105 -0
  122. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  123. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +232 -13
  124. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  125. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +178 -0
  126. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
  127. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +254 -0
  128. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
  129. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
  130. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
  131. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
  132. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
  133. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts +25 -0
  134. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts.map +1 -0
  135. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js +23 -0
  136. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js.map +1 -0
  137. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +254 -0
  138. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +467 -0
  140. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  141. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  142. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  143. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  144. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  145. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts +43 -0
  146. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts.map +1 -0
  147. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js +54 -0
  148. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js.map +1 -0
  149. package/dist/backend/backend/src/services/chat-v2/config.d.ts +100 -0
  150. package/dist/backend/backend/src/services/chat-v2/config.d.ts.map +1 -0
  151. package/dist/backend/backend/src/services/chat-v2/config.js +174 -0
  152. package/dist/backend/backend/src/services/chat-v2/config.js.map +1 -0
  153. package/dist/backend/backend/src/services/chat-v2/index.d.ts +11 -0
  154. package/dist/backend/backend/src/services/chat-v2/index.d.ts.map +1 -0
  155. package/dist/backend/backend/src/services/chat-v2/index.js +12 -0
  156. package/dist/backend/backend/src/services/chat-v2/index.js.map +1 -0
  157. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +114 -0
  158. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  159. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +194 -0
  160. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  161. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +100 -0
  162. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  163. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +351 -0
  164. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  165. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +132 -0
  166. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  167. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +281 -0
  168. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  169. package/dist/backend/backend/src/services/chat-v2/types.d.ts +295 -0
  170. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -0
  171. package/dist/backend/backend/src/services/chat-v2/types.js +61 -0
  172. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -0
  173. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +113 -0
  174. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +1 -0
  175. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +179 -0
  176. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +1 -0
  177. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +131 -0
  178. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +1 -0
  179. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +227 -0
  180. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +1 -0
  181. package/dist/backend/backend/src/services/core/config.service.js +3 -3
  182. package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
  183. package/dist/backend/backend/src/services/core/storage.service.d.ts +22 -0
  184. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  185. package/dist/backend/backend/src/services/core/storage.service.js +57 -0
  186. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  187. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +69 -1
  188. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  189. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +118 -0
  190. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  191. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +275 -0
  192. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -0
  193. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +736 -0
  194. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -0
  195. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  196. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -2
  197. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  198. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  199. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  200. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  201. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  202. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
  203. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
  204. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js +304 -0
  205. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
  206. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  207. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +24 -4
  208. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  209. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +174 -0
  210. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -0
  211. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +375 -0
  212. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -0
  213. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +97 -0
  214. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +1 -0
  215. package/dist/backend/backend/src/services/memory/learning-format.validator.js +209 -0
  216. package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +1 -0
  217. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
  218. package/dist/backend/backend/src/services/memory/vector-store.service.js +19 -4
  219. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
  220. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts +16 -5
  221. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts.map +1 -1
  222. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js +32 -5
  223. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js.map +1 -1
  224. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +157 -0
  225. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -0
  226. package/dist/backend/backend/src/services/onboarding/onboarding.service.js +229 -0
  227. package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -0
  228. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +141 -0
  229. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -0
  230. package/dist/backend/backend/src/services/onboarding/onboarding.types.js +18 -0
  231. package/dist/backend/backend/src/services/onboarding/onboarding.types.js.map +1 -0
  232. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -1
  233. package/dist/backend/backend/src/services/pr-review/pr-review.service.js +1 -1
  234. package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -1
  235. package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +17 -1
  237. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
  238. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +39 -1
  239. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +158 -26
  241. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  242. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +248 -6
  243. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  244. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +531 -51
  245. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  246. package/dist/backend/backend/src/services/team-health/index.d.ts +16 -0
  247. package/dist/backend/backend/src/services/team-health/index.d.ts.map +1 -0
  248. package/dist/backend/backend/src/services/team-health/index.js +16 -0
  249. package/dist/backend/backend/src/services/team-health/index.js.map +1 -0
  250. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts +52 -0
  251. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -0
  252. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +161 -0
  253. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -0
  254. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts +53 -0
  255. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts.map +1 -0
  256. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js +88 -0
  257. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js.map +1 -0
  258. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts +44 -0
  259. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts.map +1 -0
  260. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js +83 -0
  261. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js.map +1 -0
  262. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts +92 -0
  263. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts.map +1 -0
  264. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js +328 -0
  265. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js.map +1 -0
  266. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts +41 -0
  267. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts.map +1 -0
  268. package/dist/backend/backend/src/services/team-health/team-health-config.js +213 -0
  269. package/dist/backend/backend/src/services/team-health/team-health-config.js.map +1 -0
  270. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts +46 -0
  271. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts.map +1 -0
  272. package/dist/backend/backend/src/services/team-health/team-health-detector.js +347 -0
  273. package/dist/backend/backend/src/services/team-health/team-health-detector.js.map +1 -0
  274. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts +154 -0
  275. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts.map +1 -0
  276. package/dist/backend/backend/src/services/team-health/team-health-types.js +94 -0
  277. package/dist/backend/backend/src/services/team-health/team-health-types.js.map +1 -0
  278. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts +111 -0
  279. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts.map +1 -0
  280. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js +226 -0
  281. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js.map +1 -0
  282. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +148 -0
  283. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -0
  284. package/dist/backend/backend/src/services/v3/mission-reminder.service.js +545 -0
  285. package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -0
  286. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +499 -0
  287. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  288. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +1105 -0
  289. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  290. package/dist/backend/backend/src/services/v3/request.service.d.ts +22 -0
  291. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  292. package/dist/backend/backend/src/services/v3/request.service.js +71 -0
  293. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  294. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +1 -0
  295. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  296. package/dist/backend/backend/src/services/v3/v3-data.service.js +22 -6
  297. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  298. package/dist/backend/backend/src/types/event-bus.types.d.ts +19 -1
  299. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  300. package/dist/backend/backend/src/types/event-bus.types.js +43 -0
  301. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  302. package/dist/backend/backend/src/types/index.d.ts +22 -1
  303. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  304. package/dist/backend/backend/src/types/index.js.map +1 -1
  305. package/dist/backend/backend/src/types/review-reason.types.d.ts +63 -0
  306. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -0
  307. package/dist/backend/backend/src/types/review-reason.types.js +50 -0
  308. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -0
  309. package/dist/backend/backend/src/types/slack.types.d.ts +4 -1
  310. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  311. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  312. package/dist/backend/backend/src/types/v2/mission.types.d.ts +18 -0
  313. package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
  314. package/dist/backend/backend/src/types/v2/mission.types.js +1 -0
  315. package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
  316. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  317. package/dist/backend/backend/src/types/v2/work-item.types.js +25 -1
  318. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  319. package/dist/backend/backend/src/utils/team.utils.d.ts +38 -0
  320. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -0
  321. package/dist/backend/backend/src/utils/team.utils.js +45 -0
  322. package/dist/backend/backend/src/utils/team.utils.js.map +1 -0
  323. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +195 -0
  324. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -0
  325. package/dist/backend/backend/src/websocket/chat-v2.gateway.js +401 -0
  326. package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -0
  327. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +37 -2
  328. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  329. package/dist/backend/backend/src/websocket/terminal.gateway.js +106 -5
  330. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  331. package/dist/cli/backend/src/constants.d.ts +69 -1
  332. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  333. package/dist/cli/backend/src/constants.js +69 -2
  334. package/dist/cli/backend/src/constants.js.map +1 -1
  335. package/dist/cli/backend/src/services/core/config.service.js +3 -3
  336. package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
  337. package/dist/cli/backend/src/services/core/storage.service.d.ts +22 -0
  338. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  339. package/dist/cli/backend/src/services/core/storage.service.js +57 -0
  340. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  341. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  342. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -2
  343. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  344. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  345. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  346. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  347. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  348. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  349. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +24 -4
  350. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  351. package/dist/cli/backend/src/types/index.d.ts +22 -1
  352. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  353. package/dist/cli/backend/src/types/index.js.map +1 -1
  354. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  355. package/dist/cli/backend/src/types/v2/work-item.types.js +25 -1
  356. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  357. package/frontend/dist/assets/{index-70356616.js → index-7a4e7df5.js} +328 -326
  358. package/frontend/dist/assets/index-b7e59b2b.css +33 -0
  359. package/frontend/dist/index.html +2 -2
  360. package/package.json +2 -1
  361. package/config/skills/orchestrator/recall/SKILL.md +0 -47
  362. package/config/skills/orchestrator/recall/execute.sh +0 -13
  363. package/config/skills/orchestrator/record-learning/SKILL.md +0 -47
  364. package/config/skills/orchestrator/record-learning/execute.sh +0 -13
  365. package/config/skills/orchestrator/remember/SKILL.md +0 -55
  366. package/config/skills/orchestrator/remember/execute.sh +0 -15
  367. package/frontend/dist/assets/index-6aaa0630.css +0 -33
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) Controller
3
+ *
4
+ * HTTP handlers for THW status, on-demand scan, and silence commands.
5
+ * Backs the orchestrator-facing `team-health-scan` skill (§6.5).
6
+ *
7
+ * Per Sam's etiquette nudge: this controller resolves the watchdog via
8
+ * the `getTeamHealthWatchdogSingleton()` accessor — NOT a module-load
9
+ * import — so /api/health can fail-soft when the singleton isn't ready.
10
+ *
11
+ * @module controllers/team-health/team-health.controller
12
+ */
13
+ import type { Request, Response, NextFunction } from 'express';
14
+ import { type TeamHealthWatchdogService } from '../../services/team-health/index.js';
15
+ /**
16
+ * Override the singleton accessor for tests. Pass `null` to clear.
17
+ * Production code should use `setTeamHealthWatchdogSingleton()` from
18
+ * `services/team-health` instead.
19
+ *
20
+ * @param service - The instance to use, or null to fall back to singleton
21
+ */
22
+ export declare function setTeamHealthWatchdogService(service: TeamHealthWatchdogService | null): void;
23
+ /**
24
+ * Read the current watchdog service. Used internally by handlers; also
25
+ * exported for /api/health augmentation in index.ts.
26
+ */
27
+ export declare function getTeamHealthWatchdogService(): TeamHealthWatchdogService | null;
28
+ /**
29
+ * GET /api/team-health/scan
30
+ *
31
+ * Returns current verdicts (last sweep). Optional ?teamId=... filter.
32
+ *
33
+ * @param req - Express request with optional `teamId` query param
34
+ * @param res - Express response with verdicts payload
35
+ * @param next - Express next function for error forwarding
36
+ */
37
+ export declare function getTeamHealthScan(req: Request, res: Response, next: NextFunction): Promise<void>;
38
+ /**
39
+ * POST /api/team-health/run
40
+ *
41
+ * Manually trigger one sweep on demand. Returns the result.
42
+ *
43
+ * @param _req - Express request (unused)
44
+ * @param res - Express response with TeamHealthSweepResult
45
+ * @param next - Express next function for error forwarding
46
+ */
47
+ export declare function runTeamHealthSweep(_req: Request, res: Response, next: NextFunction): Promise<void>;
48
+ /**
49
+ * POST /api/team-health/silence
50
+ *
51
+ * Apply a manual silence to a team. Body: { teamId, durationMs }.
52
+ * Used by the Slack 🔇 react handler.
53
+ *
54
+ * @param req - Express request with body { teamId, durationMs }
55
+ * @param res - Express response with success flag
56
+ * @param next - Express next function for error forwarding
57
+ */
58
+ export declare function silenceTeamHealthAlerts(req: Request, res: Response, next: NextFunction): Promise<void>;
59
+ //# sourceMappingURL=team-health.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,qCAAqC,CAAC;AAK7C;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAE5F;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,yBAAyB,GAAG,IAAI,CAE/E;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) Controller
3
+ *
4
+ * HTTP handlers for THW status, on-demand scan, and silence commands.
5
+ * Backs the orchestrator-facing `team-health-scan` skill (§6.5).
6
+ *
7
+ * Per Sam's etiquette nudge: this controller resolves the watchdog via
8
+ * the `getTeamHealthWatchdogSingleton()` accessor — NOT a module-load
9
+ * import — so /api/health can fail-soft when the singleton isn't ready.
10
+ *
11
+ * @module controllers/team-health/team-health.controller
12
+ */
13
+ import { getTeamHealthWatchdogSingleton, } from '../../services/team-health/index.js';
14
+ // Local override for tests — bypasses the singleton accessor when set.
15
+ let testOverride = null;
16
+ /**
17
+ * Override the singleton accessor for tests. Pass `null` to clear.
18
+ * Production code should use `setTeamHealthWatchdogSingleton()` from
19
+ * `services/team-health` instead.
20
+ *
21
+ * @param service - The instance to use, or null to fall back to singleton
22
+ */
23
+ export function setTeamHealthWatchdogService(service) {
24
+ testOverride = service;
25
+ }
26
+ /**
27
+ * Read the current watchdog service. Used internally by handlers; also
28
+ * exported for /api/health augmentation in index.ts.
29
+ */
30
+ export function getTeamHealthWatchdogService() {
31
+ return testOverride ?? getTeamHealthWatchdogSingleton();
32
+ }
33
+ /**
34
+ * GET /api/team-health/scan
35
+ *
36
+ * Returns current verdicts (last sweep). Optional ?teamId=... filter.
37
+ *
38
+ * @param req - Express request with optional `teamId` query param
39
+ * @param res - Express response with verdicts payload
40
+ * @param next - Express next function for error forwarding
41
+ */
42
+ export async function getTeamHealthScan(req, res, next) {
43
+ try {
44
+ const watchdog = getTeamHealthWatchdogService();
45
+ if (!watchdog) {
46
+ res.status(503).json({ success: false, error: 'TeamHealthWatchdog not initialized' });
47
+ return;
48
+ }
49
+ const rawTeamId = req.query.teamId;
50
+ const teamId = typeof rawTeamId === 'string' && rawTeamId.length > 0 ? rawTeamId : undefined;
51
+ const verdicts = watchdog.getCurrentVerdicts(teamId);
52
+ const lastSweep = watchdog.getLastSweep();
53
+ res.json({
54
+ success: true,
55
+ data: {
56
+ verdicts,
57
+ lastSweep: lastSweep ? {
58
+ sweptAt: lastSweep.sweptAt,
59
+ durationMs: lastSweep.durationMs,
60
+ shadowMode: lastSweep.shadowMode,
61
+ } : null,
62
+ lastSweepAgeMs: watchdog.getLastSweepAgeMs(),
63
+ degraded: watchdog.isDegraded(),
64
+ },
65
+ });
66
+ }
67
+ catch (error) {
68
+ next(error);
69
+ }
70
+ }
71
+ /**
72
+ * POST /api/team-health/run
73
+ *
74
+ * Manually trigger one sweep on demand. Returns the result.
75
+ *
76
+ * @param _req - Express request (unused)
77
+ * @param res - Express response with TeamHealthSweepResult
78
+ * @param next - Express next function for error forwarding
79
+ */
80
+ export async function runTeamHealthSweep(_req, res, next) {
81
+ try {
82
+ const watchdog = getTeamHealthWatchdogService();
83
+ if (!watchdog) {
84
+ res.status(503).json({ success: false, error: 'TeamHealthWatchdog not initialized' });
85
+ return;
86
+ }
87
+ const result = await watchdog.runOnce();
88
+ res.json({ success: true, data: result });
89
+ }
90
+ catch (error) {
91
+ next(error);
92
+ }
93
+ }
94
+ /**
95
+ * POST /api/team-health/silence
96
+ *
97
+ * Apply a manual silence to a team. Body: { teamId, durationMs }.
98
+ * Used by the Slack 🔇 react handler.
99
+ *
100
+ * @param req - Express request with body { teamId, durationMs }
101
+ * @param res - Express response with success flag
102
+ * @param next - Express next function for error forwarding
103
+ */
104
+ export async function silenceTeamHealthAlerts(req, res, next) {
105
+ try {
106
+ const watchdog = getTeamHealthWatchdogService();
107
+ if (!watchdog) {
108
+ res.status(503).json({ success: false, error: 'TeamHealthWatchdog not initialized' });
109
+ return;
110
+ }
111
+ const { teamId, durationMs } = req.body ?? {};
112
+ if (typeof teamId !== 'string' || teamId.length === 0) {
113
+ res.status(400).json({ success: false, error: 'teamId is required' });
114
+ return;
115
+ }
116
+ if (typeof durationMs !== 'number' || durationMs <= 0) {
117
+ res.status(400).json({ success: false, error: 'durationMs must be a positive number' });
118
+ return;
119
+ }
120
+ watchdog.silenceTeam(teamId, durationMs);
121
+ res.json({ success: true });
122
+ }
123
+ catch (error) {
124
+ next(error);
125
+ }
126
+ }
127
+ //# sourceMappingURL=team-health.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) Routes
3
+ *
4
+ * @module controllers/team-health/team-health.routes
5
+ */
6
+ import { Router } from 'express';
7
+ /**
8
+ * Create the team-health router.
9
+ *
10
+ * @returns Express router for /api/team-health
11
+ */
12
+ export declare function createTeamHealthRouter(): Router;
13
+ //# sourceMappingURL=team-health.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health.routes.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAOjC;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAM/C"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) Routes
3
+ *
4
+ * @module controllers/team-health/team-health.routes
5
+ */
6
+ import { Router } from 'express';
7
+ import { getTeamHealthScan, runTeamHealthSweep, silenceTeamHealthAlerts, } from './team-health.controller.js';
8
+ /**
9
+ * Create the team-health router.
10
+ *
11
+ * @returns Express router for /api/team-health
12
+ */
13
+ export function createTeamHealthRouter() {
14
+ const router = Router();
15
+ router.get('/scan', getTeamHealthScan);
16
+ router.post('/run', runTeamHealthSweep);
17
+ router.post('/silence', silenceTeamHealthAlerts);
18
+ return router;
19
+ }
20
+ //# sourceMappingURL=team-health.routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health.routes.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACxC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -20,9 +20,18 @@ export declare class CrewlyServer {
20
20
  private queueProcessorService;
21
21
  private threadStatusQueueService;
22
22
  private eventBusService;
23
+ /** BRIDGE-1: subscribes to autonomy events and creates WorkItems. */
24
+ private eventToWorkItemBridge;
25
+ /** LEARN-1: subscribes to terminal task / mission:replanned events and auto-records learnings. */
26
+ private autoLearningSubscriber;
27
+ /** INBOUND-1: subscribes to request:created and tracks 5/10 min SLA on respond_to_user WIs. */
28
+ private requestSlaSubscriber;
23
29
  private notifyReconciliationService;
24
30
  private systemResourceAlertService;
25
31
  private reconcilerService;
32
+ private teamHealthWatchdog;
33
+ private chatV2Gateway;
34
+ private chatV2Dispatcher;
26
35
  private isShuttingDown;
27
36
  private healthMonitoringInterval;
28
37
  constructor(config?: Partial<StartupConfig>);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":";AAyCA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA0GjD,qBAAa,YAAY;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAqE;IAEnF,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,uBAAuB,CAA2B;IAC1D,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,4BAA4B,CAAgC;IACpE,OAAO,CAAC,uBAAuB,CAA2B;IAC1D,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,qBAAqB,CAAyB;IACtD,OAAO,CAAC,wBAAwB,CAA4B;IAC5D,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,2BAA2B,CAA+B;IAClE,OAAO,CAAC,0BAA0B,CAA8B;IAChE,OAAO,CAAC,iBAAiB,CAAkC;IAG3D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,wBAAwB,CAA+B;gBAEnD,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC;IA2D3C,OAAO,CAAC,kBAAkB;IAuQ1B,OAAO,CAAC,mBAAmB;IAmD3B,OAAO,CAAC,eAAe;IA+GvB,OAAO,CAAC,kBAAkB;IAwBpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAy7B5B;;;OAGG;YACW,2BAA2B;IA8BzC;;;OAGG;YACW,8BAA8B;IAsB5C;;;OAGG;YACW,gCAAgC;IAsB9C;;;OAGG;YACW,8BAA8B;IAsB5C;;;;OAIG;YACW,8BAA8B;IA2F5C;;;;;OAKG;YACW,iCAAiC;IA4G/C;;;;OAIG;YACW,2BAA2B;YA0B3B,qBAAqB;YAsBrB,eAAe;YAiCf,kBAAkB;IAgBhC,OAAO,CAAC,WAAW,CAAK;IAExB,OAAO,CAAC,sBAAsB;IAqD9B,OAAO,CAAC,qBAAqB;IAmB7B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0D1B;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAsH7B,OAAO,CAAC,cAAc;IAchB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAoQ/B,SAAS,IAAI,aAAa;CAG1B;AAeD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":";AAyCA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA4HjD,qBAAa,YAAY;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAqE;IAEnF,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,uBAAuB,CAA2B;IAC1D,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,4BAA4B,CAAgC;IACpE,OAAO,CAAC,uBAAuB,CAA2B;IAC1D,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,qBAAqB,CAAyB;IACtD,OAAO,CAAC,wBAAwB,CAA4B;IAC5D,OAAO,CAAC,eAAe,CAAmB;IAC1C,qEAAqE;IACrE,OAAO,CAAC,qBAAqB,CAAsC;IACnE,kGAAkG;IAClG,OAAO,CAAC,sBAAsB,CAAuC;IACrE,+FAA+F;IAC/F,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,2BAA2B,CAA+B;IAClE,OAAO,CAAC,0BAA0B,CAA8B;IAChE,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,kBAAkB,CAA0C;IAKpE,OAAO,CAAC,aAAa,CAAuE;IAC5F,OAAO,CAAC,gBAAgB,CAET;IAGf,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,wBAAwB,CAA+B;gBAEnD,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC;IA2D3C,OAAO,CAAC,kBAAkB;IAqX1B,OAAO,CAAC,mBAAmB;IAmD3B,OAAO,CAAC,eAAe;IA6HvB,OAAO,CAAC,kBAAkB;IAwBpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAs/B5B;;;OAGG;YACW,2BAA2B;IA8BzC;;;OAGG;YACW,8BAA8B;IAsB5C;;;OAGG;YACW,gCAAgC;IAsB9C;;;OAGG;YACW,8BAA8B;IAsB5C;;;;OAIG;YACW,8BAA8B;IA2F5C;;;;;OAKG;YACW,iCAAiC;IA4G/C;;;;OAIG;YACW,2BAA2B;YA0B3B,qBAAqB;YAsBrB,eAAe;YAiCf,kBAAkB;IAgBhC,OAAO,CAAC,WAAW,CAAK;IAExB,OAAO,CAAC,sBAAsB;IAqD9B,OAAO,CAAC,qBAAqB;IAsC7B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0D1B;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAsH7B,OAAO,CAAC,cAAc;IAchB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkS/B,SAAS,IAAI,aAAa;CAG1B;AAeD,eAAe,YAAY,CAAC"}
@@ -32,6 +32,11 @@ import { initializeCloudIfConfigured } from './services/cloud/cloud-initializer.
32
32
  import { MessageQueueService, QueueProcessorService, ResponseRouterService } from './services/messaging/index.js';
33
33
  import { ThreadStatusQueueService } from './services/messaging/thread-status-queue.service.js';
34
34
  import { EventBusService } from './services/event-bus/index.js';
35
+ import { EventToWorkItemBridge } from './services/event-bus/event-to-workitem-bridge.service.js';
36
+ import { AutoLearningSubscriber } from './services/memory/auto-learning.subscriber.js';
37
+ import { RequestSlaSubscriber, setRequestSlaSubscriber, } from './services/v3/request-sla.subscriber.js';
38
+ import { setRequestServiceEventBus, RequestService } from './services/v3/request.service.js';
39
+ import { getSlackService } from './services/slack/slack.service.js';
35
40
  import { SlackThreadStoreService, setSlackThreadStore, getSlackThreadStore } from './services/slack/slack-thread-store.service.js';
36
41
  import { GoogleChatThreadStoreService, setGchatThreadStore } from './services/messaging/gchat-thread-store.service.js';
37
42
  import { SlackImageService, setSlackImageService } from './services/slack/slack-image.service.js';
@@ -67,6 +72,7 @@ import { setReconcilerService } from './controllers/reconciler/reconciler.contro
67
72
  import { FissionGuardService } from './services/fission/fission-guard.service.js';
68
73
  import { setFissionGuardService } from './controllers/fission/fission.controller.js';
69
74
  import { TaskPoolService } from './services/task-pool/task-pool.service.js';
75
+ import { TeamHealthWatchdogService, LiveTeamHealthDataProvider, loadTeamHealthConfig, setTeamHealthWatchdogSingleton, getTeamHealthWatchdogSingleton, } from './services/team-health/index.js';
70
76
  // ESM __dirname equivalent using import.meta.url
71
77
  const __filename = fileURLToPath(import.meta.url);
72
78
  const __dirname = path.dirname(__filename);
@@ -125,9 +131,21 @@ export class CrewlyServer {
125
131
  queueProcessorService;
126
132
  threadStatusQueueService;
127
133
  eventBusService;
134
+ /** BRIDGE-1: subscribes to autonomy events and creates WorkItems. */
135
+ eventToWorkItemBridge = null;
136
+ /** LEARN-1: subscribes to terminal task / mission:replanned events and auto-records learnings. */
137
+ autoLearningSubscriber = null;
138
+ /** INBOUND-1: subscribes to request:created and tracks 5/10 min SLA on respond_to_user WIs. */
139
+ requestSlaSubscriber = null;
128
140
  notifyReconciliationService;
129
141
  systemResourceAlertService;
130
142
  reconcilerService = null;
143
+ teamHealthWatchdog = null;
144
+ // Chat MVP Phase 1 — initialized lazily in `start()` after the HTTP
145
+ // server is created. Kept as fields so the shutdown path can close
146
+ // them cleanly and tests can reach in with a reference.
147
+ chatV2Gateway = null;
148
+ chatV2Dispatcher = null;
131
149
  // Shutdown state
132
150
  isShuttingDown = false;
133
151
  healthMonitoringInterval = null;
@@ -231,6 +249,11 @@ export class CrewlyServer {
231
249
  this.threadStatusQueueService = new ThreadStatusQueueService(this.config.crewlyHome);
232
250
  responseRouter.setThreadStatusQueue(this.threadStatusQueueService);
233
251
  this.queueProcessorService.setThreadStatusQueue(this.threadStatusQueueService);
252
+ // INBOUND-1.f1: Wire EventBus into the TaskPool singleton so addToPool
253
+ // can publish `workitem:queued` events. Must run before any code path
254
+ // triggers addToPool — the slack listener / TaskPool router below both
255
+ // depend on this for the auto-close path b chain. Idempotent.
256
+ TaskPoolService.getInstance().setEventBusService(this.eventBusService);
234
257
  // Wire Task Pool router so [TASK]-prefixed messages route through the pool
235
258
  this.queueProcessorService.setTaskPoolRouter(async (messageContent, targetSession) => {
236
259
  const { createWorkItem } = await import('./types/v2/work-item.types.js');
@@ -277,6 +300,39 @@ export class CrewlyServer {
277
300
  taskId: payload.taskId,
278
301
  });
279
302
  });
303
+ // BRIDGE-1: subscribe to autonomy events (task:done_by_worker,
304
+ // task:rejected, task:blocked, team:all_tasks_done, mission:*) and
305
+ // create the appropriate WorkItem(s) — verification WI for TL on
306
+ // done_by_worker, retry WI / escalation WI on rejected, review WI on
307
+ // blocked / mission events. See `event-to-workitem-bridge.service.ts`
308
+ // for idempotency contract + retry cap + cron-recursion guard.
309
+ this.eventToWorkItemBridge = EventToWorkItemBridge.boot(this.eventBusService);
310
+ this.eventToWorkItemBridge.start();
311
+ // LEARN-1: subscribe to terminal task / mission:replanned events and
312
+ // auto-record a learning entry via MemoryService.recordLearning. Closes
313
+ // the prompt-driven "agents-forget-to-record" gap. See
314
+ // `auto-learning.subscriber.ts` for category mapping + idempotency
315
+ // contract (V1) and the V7/V9 self-checks in the co-located test.
316
+ this.autoLearningSubscriber = AutoLearningSubscriber.boot(this.eventBusService);
317
+ this.autoLearningSubscriber.start();
318
+ // INBOUND-1: wire RequestService → bus, then subscribe SLA tracker.
319
+ // Order matters: setRequestServiceEventBus must run BEFORE any code
320
+ // path can call RequestService.create() — the slack listener at
321
+ // line ~370 is the first hot caller, but the slack service hasn't
322
+ // been initialised yet at this point in boot, so we're safe.
323
+ setRequestServiceEventBus(this.eventBusService);
324
+ this.requestSlaSubscriber = RequestSlaSubscriber.boot(this.eventBusService, RequestService.getInstance(), TaskPoolService.getInstance(), async ({ channelId, threadTs, messageText }) => {
325
+ // Production wiring of the 10-min escalation hook: nudge the user
326
+ // in the same Slack thread so they're never blind to the miss.
327
+ const slack = getSlackService();
328
+ await slack.sendMessage({
329
+ channelId,
330
+ threadTs,
331
+ text: messageText,
332
+ });
333
+ });
334
+ this.requestSlaSubscriber.start();
335
+ setRequestSlaSubscriber(this.requestSlaSubscriber);
280
336
  // Initialize Slack thread store for persistent thread conversations
281
337
  const slackThreadStore = new SlackThreadStoreService(this.config.crewlyHome);
282
338
  setSlackThreadStore(slackThreadStore);
@@ -348,6 +404,68 @@ export class CrewlyServer {
348
404
  }
349
405
  reconcilerLogger.info('ReconcilerService initialized and wired to EventBus');
350
406
  }
407
+ // Initialize Team-Health-Watchdog (THW) — Layer 4 liveness aggregator
408
+ // Lazy singleton wiring per Sam's etiquette nudge: no module-load
409
+ // side effects; controller and /api/health resolve via accessor.
410
+ {
411
+ const thwLogger = LoggerService.getInstance().createComponentLogger('TeamHealthInit');
412
+ try {
413
+ const config = loadTeamHealthConfig({
414
+ warn: (msg, meta) => thwLogger.warn(msg, meta ?? {}),
415
+ info: (msg, meta) => thwLogger.info(msg, meta ?? {}),
416
+ });
417
+ if (!config.enabled) {
418
+ thwLogger.info('TeamHealthWatchdog disabled by config; skipping init.');
419
+ }
420
+ else if (!this.reconcilerService) {
421
+ thwLogger.warn('Reconciler not available; skipping TeamHealthWatchdog init.');
422
+ }
423
+ else {
424
+ const reconcilerProvider = new LiveReconcilerDataProvider();
425
+ const dataProvider = new LiveTeamHealthDataProvider({
426
+ reconcilerProvider,
427
+ getTeams: async () => StorageService.getInstance().getTeams(),
428
+ bootedAt: new Date(),
429
+ });
430
+ // Phase 0 alert sink: log-only. Slack delivery wires up
431
+ // in Phase 1 (per §G phasing). Shadow-mode is the
432
+ // default config.json setting, so this sink is mostly
433
+ // invoked for the recovery announcement path.
434
+ const alertSink = {
435
+ deliver: async (decision) => {
436
+ thwLogger.info('THW alert (Phase 0 log-only sink)', {
437
+ teamId: decision.detection.teamId,
438
+ verdict: decision.effectiveVerdict,
439
+ channel: decision.channel,
440
+ message: decision.message,
441
+ });
442
+ },
443
+ };
444
+ this.teamHealthWatchdog = new TeamHealthWatchdogService({
445
+ config,
446
+ dataProvider,
447
+ alertSink,
448
+ bootedAt: new Date(),
449
+ logger: {
450
+ info: (msg, meta) => thwLogger.info(msg, meta ?? {}),
451
+ warn: (msg, meta) => thwLogger.warn(msg, meta ?? {}),
452
+ error: (msg, meta) => thwLogger.error(msg, meta ?? {}),
453
+ },
454
+ });
455
+ setTeamHealthWatchdogSingleton(this.teamHealthWatchdog);
456
+ this.teamHealthWatchdog.start();
457
+ thwLogger.info('TeamHealthWatchdog initialized', {
458
+ shadowMode: config.shadowMode,
459
+ sweepIntervalMs: config.sweepIntervalMs,
460
+ });
461
+ }
462
+ }
463
+ catch (err) {
464
+ thwLogger.error('Failed to initialize TeamHealthWatchdog (continuing without it)', {
465
+ error: err instanceof Error ? err.message : String(err),
466
+ });
467
+ }
468
+ }
351
469
  // Initialize Fission Guard Service
352
470
  {
353
471
  const fissionLogger = LoggerService.getInstance().createComponentLogger('FissionInit');
@@ -467,6 +585,18 @@ export class CrewlyServer {
467
585
  version = process.env.npm_package_version || 'unknown';
468
586
  }
469
587
  }
588
+ // THW self-instrumentation (§F.3): surface last-sweep age + degraded
589
+ // flag so the watchdog-watchdog (§E.8) bubbles up here. Fail-soft
590
+ // per Sam's etiquette nudge — when the singleton isn't ready, return
591
+ // status:"warming" rather than 5xx.
592
+ const watchdog = getTeamHealthWatchdogSingleton();
593
+ const teamHealthBlock = watchdog
594
+ ? {
595
+ status: watchdog.isDegraded() ? 'degraded' : (watchdog.isActive() ? 'ok' : 'inactive'),
596
+ last_sweep_age_ms: watchdog.getLastSweepAgeMs(),
597
+ shadowMode: watchdog.getLastSweep()?.shadowMode ?? null,
598
+ }
599
+ : { status: 'warming', last_sweep_age_ms: -1, shadowMode: null };
470
600
  res.json({
471
601
  status: 'healthy',
472
602
  timestamp: new Date().toISOString(),
@@ -479,6 +609,7 @@ export class CrewlyServer {
479
609
  active: agentCount,
480
610
  total: agentCount,
481
611
  },
612
+ team_health: teamHealthBlock,
482
613
  });
483
614
  });
484
615
  // H5 quick entry static page (served regardless of headless mode)
@@ -788,6 +919,62 @@ export class CrewlyServer {
788
919
  error: error instanceof Error ? error.message : String(error),
789
920
  });
790
921
  }
922
+ // Start chat-v2 WebSocket gateway + dispatcher (Phase 1 Chat MVP).
923
+ // The gateway fans `message`/`presence` frames to subscribers of
924
+ // `/ws/chat?channelId=...`. The dispatcher pushes user-origin
925
+ // messages into the bound agent session so it can reply via the
926
+ // `reply-channel` skill. See chat-v2.gateway.ts for the contract.
927
+ try {
928
+ const [{ ChatV2Gateway, devAnonymousTokenVerifier }, { ChatV2DispatcherService }, { ChatV2MentionResolver }, { getChatV2Service }, { setChatV2RealtimeDeps }, { verifyHs256Token },] = await Promise.all([
929
+ import('./websocket/chat-v2.gateway.js'),
930
+ import('./services/chat-v2/chat-v2.dispatcher.service.js'),
931
+ import('./services/chat-v2/chat-v2.mention-resolver.js'),
932
+ import('./services/chat-v2/chat-v2.singleton.js'),
933
+ import('./services/chat-v2/chat-v2.realtime-holder.js'),
934
+ import('./middleware/require-auth.middleware.js'),
935
+ ]);
936
+ const chatService = getChatV2Service();
937
+ const jwtSecret = process.env['CREWLY_JWT_SECRET'];
938
+ const verifyToken = jwtSecret
939
+ ? async (token) => {
940
+ if (!token)
941
+ return null;
942
+ const payload = verifyHs256Token(token, jwtSecret);
943
+ if (!payload?.sub)
944
+ return null;
945
+ return { userId: payload.sub };
946
+ }
947
+ : devAnonymousTokenVerifier;
948
+ const chatGateway = new ChatV2Gateway({ service: chatService, verifyToken });
949
+ chatGateway.attach(this.httpServer);
950
+ // Phase C BE.3 — inject the mention resolver so type='channel'
951
+ // messages fan out to @-mentioned recipients instead of
952
+ // short-circuiting with strategy='skip' at the dispatcher.
953
+ // Pattern matches LiveTeamHealthDataProvider wiring (~line 487):
954
+ // `getTeams: async () => StorageService.getInstance().getTeams()`.
955
+ const chatMentionResolver = new ChatV2MentionResolver({
956
+ loadTeams: async () => StorageService.getInstance().getTeams(),
957
+ });
958
+ const chatDispatcher = new ChatV2DispatcherService({
959
+ agentSink: this.apiController.agentRegistrationService,
960
+ mentionResolver: chatMentionResolver,
961
+ });
962
+ this.chatV2Gateway = chatGateway;
963
+ this.chatV2Dispatcher = chatDispatcher;
964
+ // The chat-v2 router mounted earlier reads realtime deps from
965
+ // this holder at request time, so it picks up broadcast +
966
+ // dispatch without a re-mount.
967
+ setChatV2RealtimeDeps({ gateway: chatGateway, dispatcher: chatDispatcher });
968
+ this.logger.info('chat-v2 WebSocket gateway + dispatcher started', {
969
+ path: '/ws/chat',
970
+ authMode: jwtSecret ? 'jwt' : 'dev-anonymous',
971
+ });
972
+ }
973
+ catch (error) {
974
+ this.logger.warn('Failed to start chat-v2 WS gateway (non-critical)', {
975
+ error: error instanceof Error ? error.message : String(error),
976
+ });
977
+ }
791
978
  // Connect BrowserProxyService to Cloud Relay (lazy — does not block startup)
792
979
  try {
793
980
  const { BrowserProxyService } = await import('./services/browser/browser-proxy.service.js');
@@ -1893,10 +2080,30 @@ export class CrewlyServer {
1893
2080
  // Catches direct orchestrator responses that finish within a single poll cycle
1894
2081
  // and never trigger the EventBus agent:idle event
1895
2082
  setInterval(() => this.autoCloseOpenRequests(), 2 * 60 * 1000);
2083
+ // V3: Mission OKR Reminders (every hour)
2084
+ // Scans active missions and sends Slack alerts for off-track KRs
2085
+ setInterval(async () => {
2086
+ try {
2087
+ const { MissionReminderService } = await import('./services/v3/mission-reminder.service.js');
2088
+ await MissionReminderService.getInstance().runSweep();
2089
+ }
2090
+ catch (err) {
2091
+ this.logger.warn('Mission OKR reminder sweep failed', { error: String(err) });
2092
+ }
2093
+ }, 60 * 60 * 1000);
1896
2094
  // Purge done Requests and WorkItems older than 24h (every hour)
1897
2095
  setInterval(() => this.purgeCompletedData(), 60 * 60 * 1000);
1898
2096
  // Run once at startup after a short delay
1899
2097
  setTimeout(() => this.purgeCompletedData(), 30 * 1000);
2098
+ setTimeout(async () => {
2099
+ try {
2100
+ const { MissionReminderService } = await import('./services/v3/mission-reminder.service.js');
2101
+ await MissionReminderService.getInstance().runSweep();
2102
+ }
2103
+ catch (err) {
2104
+ // Non-critical
2105
+ }
2106
+ }, 60 * 1000);
1900
2107
  }
1901
2108
  /**
1902
2109
  * Removes done/cancelled Requests older than 24h from disk,
@@ -2217,12 +2424,38 @@ export class CrewlyServer {
2217
2424
  this.reconcilerService.stop();
2218
2425
  this.logger.info('Reconciler stopped');
2219
2426
  }
2427
+ // Stop Team-Health-Watchdog sweep loop (Layer 4)
2428
+ if (this.teamHealthWatchdog) {
2429
+ this.teamHealthWatchdog.stop();
2430
+ this.logger.info('TeamHealthWatchdog stopped');
2431
+ }
2220
2432
  // Stop NOTIFY reconciliation service
2221
2433
  if (this.notifyReconciliationService) {
2222
2434
  this.notifyReconciliationService.stop();
2223
2435
  }
2224
2436
  // Stop message queue processor
2225
2437
  this.queueProcessorService.stop();
2438
+ // Stop the EventToWorkItemBridge BEFORE cleaning the event bus so
2439
+ // in-flight handler dispatches drain against a still-live bus.
2440
+ if (this.eventToWorkItemBridge) {
2441
+ this.eventToWorkItemBridge.stop();
2442
+ this.eventToWorkItemBridge = null;
2443
+ }
2444
+ // LEARN-1: stop the AutoLearningSubscriber on the same window as the
2445
+ // bridge so its in-flight recordLearning calls drain before the bus
2446
+ // is cleaned.
2447
+ if (this.autoLearningSubscriber) {
2448
+ this.autoLearningSubscriber.stop();
2449
+ this.autoLearningSubscriber = null;
2450
+ }
2451
+ // INBOUND-1: stop the SLA subscriber and unset the module-level
2452
+ // references so a follow-up start() doesn't see stale singletons.
2453
+ if (this.requestSlaSubscriber) {
2454
+ this.requestSlaSubscriber.stop();
2455
+ this.requestSlaSubscriber = null;
2456
+ }
2457
+ setRequestSlaSubscriber(null);
2458
+ setRequestServiceEventBus(null);
2226
2459
  // Clean up event bus service
2227
2460
  this.eventBusService.cleanup();
2228
2461
  // Clean up schedulers