crewly 1.6.1 → 1.6.2

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 (363) 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/sops/developer/git-workflow.md +38 -3
  15. package/dist/backend/backend/src/constants.d.ts +69 -1
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +69 -2
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts +53 -0
  20. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -0
  21. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +92 -0
  22. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -0
  23. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
  24. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +18 -1
  25. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +68 -0
  27. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  28. package/dist/backend/backend/src/controllers/browser/browser.controller.js +233 -5
  29. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  30. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  31. package/dist/backend/backend/src/controllers/browser/browser.routes.js +10 -1
  32. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  33. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  34. package/dist/backend/backend/src/controllers/chat/chat.controller.js +8 -3
  35. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  36. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +132 -0
  37. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -0
  38. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +401 -0
  39. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -0
  40. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +29 -0
  41. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -0
  42. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +39 -0
  43. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -0
  44. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts +8 -0
  45. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts.map +1 -0
  46. package/dist/backend/backend/src/controllers/chat-v2/index.js +8 -0
  47. package/dist/backend/backend/src/controllers/chat-v2/index.js.map +1 -0
  48. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +13 -13
  49. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
  50. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +74 -234
  51. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
  52. package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
  53. package/dist/backend/backend/src/controllers/request/request.controller.js +4 -6
  54. package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
  55. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts +43 -0
  56. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
  57. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +200 -72
  58. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
  59. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  60. package/dist/backend/backend/src/controllers/team/team.controller.js +46 -0
  61. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  62. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts +59 -0
  63. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts.map +1 -0
  64. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js +127 -0
  65. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js.map +1 -0
  66. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts +13 -0
  67. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts.map +1 -0
  68. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js +20 -0
  69. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js.map +1 -0
  70. package/dist/backend/backend/src/index.d.ts +9 -0
  71. package/dist/backend/backend/src/index.d.ts.map +1 -1
  72. package/dist/backend/backend/src/index.js +233 -0
  73. package/dist/backend/backend/src/index.js.map +1 -1
  74. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  75. package/dist/backend/backend/src/routes/api.routes.js +40 -6
  76. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  77. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +498 -0
  78. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  79. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +759 -0
  80. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  81. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +25 -0
  82. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/agent/agent-registration.service.js +193 -57
  84. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  85. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +9 -2
  86. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +35 -2
  88. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  89. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +8 -2
  90. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +1 -0
  92. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  93. package/dist/backend/backend/src/services/agent/tmux-command.service.d.ts.map +1 -1
  94. package/dist/backend/backend/src/services/agent/tmux-command.service.js +2 -1
  95. package/dist/backend/backend/src/services/agent/tmux-command.service.js.map +1 -1
  96. package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
  98. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  99. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +148 -3
  100. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +241 -2
  102. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -1
  104. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +13 -0
  105. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -1
  106. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +26 -1
  108. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
  109. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  110. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  111. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  112. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  113. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +161 -0
  114. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  115. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +382 -2
  116. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  117. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +105 -0
  118. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +232 -13
  120. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  121. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +178 -0
  122. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
  123. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +254 -0
  124. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
  125. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
  126. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
  127. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
  128. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
  129. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts +25 -0
  130. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts.map +1 -0
  131. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js +23 -0
  132. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js.map +1 -0
  133. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +254 -0
  134. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  135. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +467 -0
  136. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  137. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  138. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  140. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  141. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts +43 -0
  142. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts.map +1 -0
  143. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js +54 -0
  144. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js.map +1 -0
  145. package/dist/backend/backend/src/services/chat-v2/config.d.ts +100 -0
  146. package/dist/backend/backend/src/services/chat-v2/config.d.ts.map +1 -0
  147. package/dist/backend/backend/src/services/chat-v2/config.js +174 -0
  148. package/dist/backend/backend/src/services/chat-v2/config.js.map +1 -0
  149. package/dist/backend/backend/src/services/chat-v2/index.d.ts +11 -0
  150. package/dist/backend/backend/src/services/chat-v2/index.d.ts.map +1 -0
  151. package/dist/backend/backend/src/services/chat-v2/index.js +12 -0
  152. package/dist/backend/backend/src/services/chat-v2/index.js.map +1 -0
  153. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +114 -0
  154. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  155. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +194 -0
  156. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  157. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +100 -0
  158. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  159. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +351 -0
  160. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  161. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +132 -0
  162. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  163. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +281 -0
  164. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  165. package/dist/backend/backend/src/services/chat-v2/types.d.ts +295 -0
  166. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -0
  167. package/dist/backend/backend/src/services/chat-v2/types.js +61 -0
  168. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -0
  169. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +113 -0
  170. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +1 -0
  171. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +179 -0
  172. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +1 -0
  173. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +131 -0
  174. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +1 -0
  175. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +227 -0
  176. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +1 -0
  177. package/dist/backend/backend/src/services/core/config.service.js +3 -3
  178. package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
  179. package/dist/backend/backend/src/services/core/storage.service.d.ts +7 -0
  180. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  181. package/dist/backend/backend/src/services/core/storage.service.js +15 -0
  182. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  183. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +69 -1
  184. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  185. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +118 -0
  186. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  187. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +275 -0
  188. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -0
  189. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +736 -0
  190. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -0
  191. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  192. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -2
  193. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  194. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  195. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  196. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  197. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  198. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
  199. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
  200. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js +304 -0
  201. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
  202. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  203. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +24 -4
  204. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  205. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +174 -0
  206. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -0
  207. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +375 -0
  208. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -0
  209. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +97 -0
  210. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +1 -0
  211. package/dist/backend/backend/src/services/memory/learning-format.validator.js +209 -0
  212. package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +1 -0
  213. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
  214. package/dist/backend/backend/src/services/memory/vector-store.service.js +19 -4
  215. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
  216. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts +16 -5
  217. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts.map +1 -1
  218. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js +32 -5
  219. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js.map +1 -1
  220. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +157 -0
  221. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -0
  222. package/dist/backend/backend/src/services/onboarding/onboarding.service.js +229 -0
  223. package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -0
  224. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +141 -0
  225. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -0
  226. package/dist/backend/backend/src/services/onboarding/onboarding.types.js +18 -0
  227. package/dist/backend/backend/src/services/onboarding/onboarding.types.js.map +1 -0
  228. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -1
  229. package/dist/backend/backend/src/services/pr-review/pr-review.service.js +1 -1
  230. package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -1
  231. package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
  232. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +17 -1
  233. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
  234. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +39 -1
  235. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +158 -26
  237. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  238. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +248 -6
  239. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +531 -51
  241. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  242. package/dist/backend/backend/src/services/team-health/index.d.ts +16 -0
  243. package/dist/backend/backend/src/services/team-health/index.d.ts.map +1 -0
  244. package/dist/backend/backend/src/services/team-health/index.js +16 -0
  245. package/dist/backend/backend/src/services/team-health/index.js.map +1 -0
  246. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts +52 -0
  247. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -0
  248. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +161 -0
  249. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -0
  250. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts +53 -0
  251. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts.map +1 -0
  252. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js +88 -0
  253. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js.map +1 -0
  254. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts +44 -0
  255. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts.map +1 -0
  256. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js +83 -0
  257. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js.map +1 -0
  258. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts +92 -0
  259. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts.map +1 -0
  260. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js +328 -0
  261. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js.map +1 -0
  262. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts +41 -0
  263. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts.map +1 -0
  264. package/dist/backend/backend/src/services/team-health/team-health-config.js +213 -0
  265. package/dist/backend/backend/src/services/team-health/team-health-config.js.map +1 -0
  266. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts +46 -0
  267. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts.map +1 -0
  268. package/dist/backend/backend/src/services/team-health/team-health-detector.js +347 -0
  269. package/dist/backend/backend/src/services/team-health/team-health-detector.js.map +1 -0
  270. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts +154 -0
  271. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts.map +1 -0
  272. package/dist/backend/backend/src/services/team-health/team-health-types.js +94 -0
  273. package/dist/backend/backend/src/services/team-health/team-health-types.js.map +1 -0
  274. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts +111 -0
  275. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts.map +1 -0
  276. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js +226 -0
  277. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js.map +1 -0
  278. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +148 -0
  279. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -0
  280. package/dist/backend/backend/src/services/v3/mission-reminder.service.js +545 -0
  281. package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -0
  282. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +499 -0
  283. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  284. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +1105 -0
  285. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  286. package/dist/backend/backend/src/services/v3/request.service.d.ts +22 -0
  287. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  288. package/dist/backend/backend/src/services/v3/request.service.js +71 -0
  289. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  290. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +1 -0
  291. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  292. package/dist/backend/backend/src/services/v3/v3-data.service.js +22 -6
  293. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  294. package/dist/backend/backend/src/types/event-bus.types.d.ts +19 -1
  295. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  296. package/dist/backend/backend/src/types/event-bus.types.js +43 -0
  297. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  298. package/dist/backend/backend/src/types/index.d.ts +22 -1
  299. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  300. package/dist/backend/backend/src/types/index.js.map +1 -1
  301. package/dist/backend/backend/src/types/review-reason.types.d.ts +63 -0
  302. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -0
  303. package/dist/backend/backend/src/types/review-reason.types.js +50 -0
  304. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -0
  305. package/dist/backend/backend/src/types/slack.types.d.ts +4 -1
  306. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  307. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  308. package/dist/backend/backend/src/types/v2/mission.types.d.ts +18 -0
  309. package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
  310. package/dist/backend/backend/src/types/v2/mission.types.js +1 -0
  311. package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
  312. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  313. package/dist/backend/backend/src/types/v2/work-item.types.js +25 -1
  314. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  315. package/dist/backend/backend/src/utils/team.utils.d.ts +38 -0
  316. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -0
  317. package/dist/backend/backend/src/utils/team.utils.js +45 -0
  318. package/dist/backend/backend/src/utils/team.utils.js.map +1 -0
  319. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +195 -0
  320. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -0
  321. package/dist/backend/backend/src/websocket/chat-v2.gateway.js +401 -0
  322. package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -0
  323. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +37 -2
  324. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  325. package/dist/backend/backend/src/websocket/terminal.gateway.js +106 -5
  326. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  327. package/dist/cli/backend/src/constants.d.ts +69 -1
  328. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  329. package/dist/cli/backend/src/constants.js +69 -2
  330. package/dist/cli/backend/src/constants.js.map +1 -1
  331. package/dist/cli/backend/src/services/core/config.service.js +3 -3
  332. package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
  333. package/dist/cli/backend/src/services/core/storage.service.d.ts +7 -0
  334. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  335. package/dist/cli/backend/src/services/core/storage.service.js +15 -0
  336. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  337. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  338. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -2
  339. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  340. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  341. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  342. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  343. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  344. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  345. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +24 -4
  346. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  347. package/dist/cli/backend/src/types/index.d.ts +22 -1
  348. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  349. package/dist/cli/backend/src/types/index.js.map +1 -1
  350. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  351. package/dist/cli/backend/src/types/v2/work-item.types.js +25 -1
  352. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  353. package/frontend/dist/assets/{index-70356616.js → index-7a4e7df5.js} +328 -326
  354. package/frontend/dist/assets/index-b7e59b2b.css +33 -0
  355. package/frontend/dist/index.html +2 -2
  356. package/package.json +2 -1
  357. package/config/skills/orchestrator/recall/SKILL.md +0 -47
  358. package/config/skills/orchestrator/recall/execute.sh +0 -13
  359. package/config/skills/orchestrator/record-learning/SKILL.md +0 -47
  360. package/config/skills/orchestrator/record-learning/execute.sh +0 -13
  361. package/config/skills/orchestrator/remember/SKILL.md +0 -55
  362. package/config/skills/orchestrator/remember/execute.sh +0 -15
  363. package/frontend/dist/assets/index-6aaa0630.css +0 -33
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) — Shared Types (Layer 4 Liveness Aggregator)
3
+ *
4
+ * Per the SEALED design at `.crewly/knowledge/team-health-watchdog-design-2026-04-25.md`,
5
+ * these types are the contract surface between the pure detector, alert
6
+ * router, watchdog service, and the orchestrator skill.
7
+ *
8
+ * Verdict tier names (§17 Q1, SEALED 2026-04-25T15:25Z):
9
+ * code: 'healthy' | 'stalling' | 'stuck' | 'cascade' | 'stale'
10
+ * display: 🟢 | 🟡 | 🔴 | 🚨 | 🟪
11
+ *
12
+ * Layer-4 invariant (§A.1, SEALED): THW READS, NEVER WRITES lower-layer
13
+ * state.
14
+ *
15
+ * @module services/team-health/team-health-types
16
+ */
17
+ import type { WorkItem, Request, Trigger } from '../../types/v2/index.js';
18
+ import type { AgentHealth } from '../reconciler/reconcile-rules.js';
19
+ export type VerdictCode = 'healthy' | 'stalling' | 'stuck' | 'cascade' | 'stale';
20
+ export declare const VERDICT_CODES: readonly VerdictCode[];
21
+ /**
22
+ * Single source of truth for code → emoji rendering.
23
+ */
24
+ export declare const VERDICT_DISPLAY: Record<VerdictCode, string>;
25
+ /**
26
+ * Severity ordering for verdict tiers — used to merge multiple gates'
27
+ * verdicts into one. Higher number = more severe.
28
+ */
29
+ export declare const VERDICT_SEVERITY: Record<VerdictCode, number>;
30
+ export interface TeamHealthGates {
31
+ team_idle: boolean;
32
+ team_pending: boolean;
33
+ team_silent: boolean;
34
+ cascade_with_siblings: boolean;
35
+ }
36
+ export interface TeamHealthDetection {
37
+ teamId: string;
38
+ verdict: VerdictCode;
39
+ gates: TeamHealthGates;
40
+ cascadeWith?: string[];
41
+ staleWorkItemIds?: string[];
42
+ /** WorkItem IDs flagged by the lost-dispatch detector (post-SEALED amendment) */
43
+ lostDispatchWorkItemIds?: string[];
44
+ orphanRequestIds?: string[];
45
+ pendingWorkItemIds: string[];
46
+ idleAgentSessions: string[];
47
+ detectedAt: string;
48
+ rationale: string;
49
+ }
50
+ export interface TeamSummary {
51
+ id: string;
52
+ name?: string;
53
+ slackThreadId?: string;
54
+ memberSessions: string[];
55
+ tlSession?: string;
56
+ parentTeamId?: string;
57
+ }
58
+ export interface TeamHealthSnapshot {
59
+ now: Date;
60
+ teams: TeamSummary[];
61
+ agentHealth: Map<string, AgentHealth & {
62
+ workingStatus?: AgentWorkingStatus;
63
+ }>;
64
+ workItems: WorkItem[];
65
+ requests: Request[];
66
+ triggers: Trigger[];
67
+ priorDoneCounts?: Map<string, number>;
68
+ /** WorkItem ID → list of artifact probes parsed from description */
69
+ artifactProbes?: Map<string, ArtifactProbeResult[]>;
70
+ thinkingOverrides?: Map<string, Date>;
71
+ bootedAt: Date;
72
+ }
73
+ export type AgentWorkingStatus = 'idle' | 'in_progress' | 'working' | 'inactive' | 'suspended' | 'thinking';
74
+ export interface ArtifactProbeResult {
75
+ kind: 'package_version' | 'prior_done_count' | 'route' | 'migration' | 'file_state';
76
+ isStale: boolean;
77
+ evidence: string;
78
+ }
79
+ export interface TeamHealthThresholds {
80
+ TEAM_IDLE_T1_MS: number;
81
+ PENDING_T1_MS: number;
82
+ TRIGGER_SILENCE_T1_MS: number;
83
+ STUCK_T2_MS: number;
84
+ ORPHAN_REQUEST_T1_MS: number;
85
+ }
86
+ /** SEALED default thresholds (§17 Q2). */
87
+ export declare const DEFAULT_THRESHOLDS: TeamHealthThresholds;
88
+ export interface OffHoursConfig {
89
+ enabled: boolean;
90
+ ownerTimezone: string;
91
+ workingHours: string;
92
+ }
93
+ export interface TeamHealthAlertingConfig {
94
+ yellowCooldownMs: number;
95
+ redCooldownMs: number;
96
+ cascadeCooldownMs: number;
97
+ alertBudgetWindowMs: number;
98
+ alertBudgetMaxAlertsPerTeam: number;
99
+ }
100
+ export declare const DEFAULT_ALERTING: TeamHealthAlertingConfig;
101
+ /**
102
+ * Stale-trigger detector config (§B.4).
103
+ */
104
+ export interface StaleTriggerConfig {
105
+ enabled: boolean;
106
+ minPriorDoneCountForRedundancy: number;
107
+ }
108
+ export declare const DEFAULT_STALE_TRIGGER: StaleTriggerConfig;
109
+ /**
110
+ * Lost-dispatch detector config — POST-SEALED amendment 2026-04-25
111
+ * approved by Sam (TL) for Cases #5/#6/#7 (PM/UX/TL restart drops).
112
+ */
113
+ export interface LostDispatchConfig {
114
+ enabled: boolean;
115
+ T1Ms: number;
116
+ postRestartGraceMs: number;
117
+ }
118
+ export declare const DEFAULT_LOST_DISPATCH: LostDispatchConfig;
119
+ export type PerTeamThresholdOverride = Partial<TeamHealthThresholds>;
120
+ export interface TeamHealthConfig {
121
+ enabled: boolean;
122
+ shadowMode: boolean;
123
+ sweepIntervalMs: number;
124
+ bootGraceMs: number;
125
+ thresholds: TeamHealthThresholds;
126
+ byTeam: Record<string, PerTeamThresholdOverride>;
127
+ alerting: TeamHealthAlertingConfig;
128
+ offHoursSuppression: OffHoursConfig;
129
+ staleTriggerDetection: StaleTriggerConfig;
130
+ /** Post-SEALED amendment — lost-dispatch detection, default ON */
131
+ lostDispatchDetection: LostDispatchConfig;
132
+ }
133
+ export declare const DEFAULT_CONFIG: TeamHealthConfig;
134
+ export type AlertChannel = 'team-thread' | 'tl-dm' | 'ops-channel' | 'suppressed';
135
+ export type SuppressionReason = 'shadow_mode' | 'cooldown' | 'alert_budget_exceeded' | 'boot_grace' | 'off_hours_downgrade' | 'stable_healthy' | 'silenced_by_react';
136
+ export interface AlertDecision {
137
+ detection: TeamHealthDetection;
138
+ channel: AlertChannel;
139
+ effectiveVerdict: VerdictCode;
140
+ message: string;
141
+ suppressionReason?: SuppressionReason;
142
+ dedupKey: string;
143
+ }
144
+ export interface TeamHealthSweepResult {
145
+ sweptAt: string;
146
+ durationMs: number;
147
+ detections: TeamHealthDetection[];
148
+ alerts: AlertDecision[];
149
+ bootGraceSuppressed: boolean;
150
+ shadowMode: boolean;
151
+ }
152
+ export declare function isValidVerdictCode(value: string): value is VerdictCode;
153
+ export declare function maxVerdict(a: VerdictCode, b: VerdictCode): VerdictCode;
154
+ //# sourceMappingURL=team-health-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health-types.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-health/team-health-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) — Shared Types (Layer 4 Liveness Aggregator)
3
+ *
4
+ * Per the SEALED design at `.crewly/knowledge/team-health-watchdog-design-2026-04-25.md`,
5
+ * these types are the contract surface between the pure detector, alert
6
+ * router, watchdog service, and the orchestrator skill.
7
+ *
8
+ * Verdict tier names (§17 Q1, SEALED 2026-04-25T15:25Z):
9
+ * code: 'healthy' | 'stalling' | 'stuck' | 'cascade' | 'stale'
10
+ * display: 🟢 | 🟡 | 🔴 | 🚨 | 🟪
11
+ *
12
+ * Layer-4 invariant (§A.1, SEALED): THW READS, NEVER WRITES lower-layer
13
+ * state.
14
+ *
15
+ * @module services/team-health/team-health-types
16
+ */
17
+ export const VERDICT_CODES = [
18
+ 'healthy',
19
+ 'stalling',
20
+ 'stuck',
21
+ 'cascade',
22
+ 'stale',
23
+ ];
24
+ /**
25
+ * Single source of truth for code → emoji rendering.
26
+ */
27
+ export const VERDICT_DISPLAY = {
28
+ healthy: '🟢',
29
+ stalling: '🟡',
30
+ stuck: '🔴',
31
+ cascade: '🚨',
32
+ stale: '🟪',
33
+ };
34
+ /**
35
+ * Severity ordering for verdict tiers — used to merge multiple gates'
36
+ * verdicts into one. Higher number = more severe.
37
+ */
38
+ export const VERDICT_SEVERITY = {
39
+ healthy: 0,
40
+ stalling: 1,
41
+ stale: 2,
42
+ stuck: 3,
43
+ cascade: 4,
44
+ };
45
+ /** SEALED default thresholds (§17 Q2). */
46
+ export const DEFAULT_THRESHOLDS = {
47
+ TEAM_IDLE_T1_MS: 30 * 60 * 1000,
48
+ PENDING_T1_MS: 30 * 60 * 1000,
49
+ TRIGGER_SILENCE_T1_MS: 60 * 60 * 1000,
50
+ STUCK_T2_MS: 60 * 60 * 1000,
51
+ ORPHAN_REQUEST_T1_MS: 15 * 60 * 1000,
52
+ };
53
+ export const DEFAULT_ALERTING = {
54
+ yellowCooldownMs: 60 * 60 * 1000,
55
+ redCooldownMs: 30 * 60 * 1000,
56
+ cascadeCooldownMs: 15 * 60 * 1000,
57
+ alertBudgetWindowMs: 6 * 60 * 60 * 1000,
58
+ alertBudgetMaxAlertsPerTeam: 3,
59
+ };
60
+ export const DEFAULT_STALE_TRIGGER = {
61
+ enabled: true,
62
+ minPriorDoneCountForRedundancy: 3,
63
+ };
64
+ export const DEFAULT_LOST_DISPATCH = {
65
+ enabled: true,
66
+ T1Ms: 10 * 60 * 1000,
67
+ postRestartGraceMs: 60_000,
68
+ };
69
+ export const DEFAULT_CONFIG = {
70
+ enabled: true,
71
+ shadowMode: true,
72
+ sweepIntervalMs: 60_000,
73
+ bootGraceMs: 5 * 60 * 1000,
74
+ thresholds: { ...DEFAULT_THRESHOLDS },
75
+ byTeam: {},
76
+ alerting: { ...DEFAULT_ALERTING },
77
+ offHoursSuppression: {
78
+ enabled: true,
79
+ ownerTimezone: 'America/New_York',
80
+ workingHours: '09:00-21:00',
81
+ },
82
+ staleTriggerDetection: { ...DEFAULT_STALE_TRIGGER },
83
+ lostDispatchDetection: { ...DEFAULT_LOST_DISPATCH },
84
+ };
85
+ // ---------------------------------------------------------------------------
86
+ // Type Guards / Helpers
87
+ // ---------------------------------------------------------------------------
88
+ export function isValidVerdictCode(value) {
89
+ return VERDICT_CODES.includes(value);
90
+ }
91
+ export function maxVerdict(a, b) {
92
+ return VERDICT_SEVERITY[b] > VERDICT_SEVERITY[a] ? b : a;
93
+ }
94
+ //# sourceMappingURL=team-health-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health-types.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-health/team-health-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAoBH,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,SAAS;IACT,UAAU;IACV,OAAO;IACP,SAAS;IACT,OAAO;CACC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAgC;IAC1D,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAgC;IAC3D,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;CACX,CAAC;AAiFF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,kBAAkB,GAAyB;IACtD,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IAC/B,aAAa,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IAC7B,qBAAqB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACrC,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IAC3B,oBAAoB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;CACrC,CAAC;AAgBF,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IAChC,aAAa,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IAC7B,iBAAiB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACjC,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;IACvC,2BAA2B,EAAE,CAAC;CAC/B,CAAC;AAUF,MAAM,CAAC,MAAM,qBAAqB,GAAuB;IACvD,OAAO,EAAE,IAAI;IACb,8BAA8B,EAAE,CAAC;CAClC,CAAC;AAYF,MAAM,CAAC,MAAM,qBAAqB,GAAuB;IACvD,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACpB,kBAAkB,EAAE,MAAM;CAC3B,CAAC;AAkBF,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;IAC1B,UAAU,EAAE,EAAE,GAAG,kBAAkB,EAAE;IACrC,MAAM,EAAE,EAAE;IACV,QAAQ,EAAE,EAAE,GAAG,gBAAgB,EAAE;IACjC,mBAAmB,EAAE;QACnB,OAAO,EAAE,IAAI;QACb,aAAa,EAAE,kBAAkB;QACjC,YAAY,EAAE,aAAa;KAC5B;IACD,qBAAqB,EAAE,EAAE,GAAG,qBAAqB,EAAE;IACnD,qBAAqB,EAAE,EAAE,GAAG,qBAAqB,EAAE;CACpD,CAAC;AAuCF,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAQ,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAc,EAAE,CAAc;IACvD,OAAO,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) — Service Shell (Layer 4)
3
+ *
4
+ * Wires the pure detector + alert router to live data sources, runs the
5
+ * 60s sweep loop, exposes API for the orchestrator skill / health endpoint.
6
+ *
7
+ * Architecture (§A.5): keep sweep+dedup+rate-limit+heartbeat strictly
8
+ * separable from the detector. v0.5 will extract these protected members
9
+ * into a `WatchdogBase`.
10
+ *
11
+ * Layer-4 invariant (§A.1): READS lower-layer state, EMITS alerts.
12
+ * NEVER mutates `agent.status`, claims, or work items.
13
+ *
14
+ * @module services/team-health/team-health-watchdog.service
15
+ */
16
+ import type { AlertDecision, TeamHealthConfig, TeamHealthDetection, TeamHealthSnapshot, TeamHealthSweepResult } from './team-health-types.js';
17
+ import { TeamHealthAlertRouter } from './team-health-alert-router.js';
18
+ /**
19
+ * THW data provider — connects the detector to live state. Tests pass
20
+ * a fixture-driven provider; production wiring lives outside this module.
21
+ */
22
+ export interface TeamHealthDataProvider {
23
+ collectSnapshot(now: Date): Promise<TeamHealthSnapshot>;
24
+ }
25
+ /**
26
+ * Delivers an alert decision out to humans. Resolves successfully even
27
+ * on transport error; the watchdog logs but does not retry — next sweep
28
+ * re-emits if the verdict still holds (idempotent dedup).
29
+ */
30
+ export interface AlertSink {
31
+ deliver(decision: AlertDecision): Promise<void>;
32
+ }
33
+ export interface WatchdogLogger {
34
+ info(msg: string, meta?: Record<string, unknown>): void;
35
+ warn(msg: string, meta?: Record<string, unknown>): void;
36
+ error(msg: string, meta?: Record<string, unknown>): void;
37
+ }
38
+ export interface TeamHealthWatchdogOptions {
39
+ config: TeamHealthConfig;
40
+ dataProvider: TeamHealthDataProvider;
41
+ alertSink: AlertSink;
42
+ bootedAt?: Date;
43
+ logger?: WatchdogLogger;
44
+ clock?: () => Date;
45
+ }
46
+ /**
47
+ * The watchdog service. Owns the sweep loop and exposes the public API.
48
+ */
49
+ export declare class TeamHealthWatchdogService {
50
+ protected sweepIntervalMs: number;
51
+ protected bootedAt: Date;
52
+ protected router: TeamHealthAlertRouter;
53
+ private config;
54
+ private dataProvider;
55
+ private alertSink;
56
+ private logger;
57
+ private clock;
58
+ private timer;
59
+ private lastSweep;
60
+ private isRunning;
61
+ constructor(opts: TeamHealthWatchdogOptions);
62
+ /**
63
+ * Start the periodic sweep loop. Idempotent. Per §11.3 self-instrumentation,
64
+ * we run `runOnce` immediately on start so /api/health has data from boot.
65
+ */
66
+ start(): void;
67
+ /**
68
+ * Stop the periodic sweep loop. After stop(), `last_sweep_age_ms` grows;
69
+ * /api/health surfaces this so a stuck watchdog itself shows as 'degraded'
70
+ * (§E.8 watchdog-watchdog).
71
+ */
72
+ stop(): void;
73
+ /**
74
+ * Run one sweep on demand. Catches own errors and returns a degraded
75
+ * sweep result rather than throwing.
76
+ */
77
+ runOnce(): Promise<TeamHealthSweepResult>;
78
+ /**
79
+ * Get the most recent sweep result; null until `start()`/`runOnce()` runs.
80
+ */
81
+ getLastSweep(): TeamHealthSweepResult | null;
82
+ /**
83
+ * Milliseconds since the last sweep. -1 if no sweep has ever completed.
84
+ */
85
+ getLastSweepAgeMs(): number;
86
+ /**
87
+ * Self-health probe — the watchdog-watchdog (§E.8). True when the
88
+ * sweep loop appears stuck (age > 3× sweep interval).
89
+ */
90
+ isDegraded(): boolean;
91
+ /**
92
+ * Per-team verdicts from the most recent sweep. Backs the
93
+ * orchestrator `team-health-scan` skill (§6.5).
94
+ */
95
+ getCurrentVerdicts(teamId?: string): TeamHealthDetection[];
96
+ /**
97
+ * Apply an updated config at runtime (e.g., post-edit reload).
98
+ */
99
+ reconfigure(config: TeamHealthConfig): void;
100
+ /**
101
+ * Apply a manual silence to a team (Slack 🔇 react handler).
102
+ */
103
+ silenceTeam(teamId: string, durationMs: number): void;
104
+ /**
105
+ * Read the running flag — used by /api/health.
106
+ */
107
+ isActive(): boolean;
108
+ }
109
+ export declare function setTeamHealthWatchdogSingleton(svc: TeamHealthWatchdogService): void;
110
+ export declare function getTeamHealthWatchdogSingleton(): TeamHealthWatchdogService | null;
111
+ //# sourceMappingURL=team-health-watchdog.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health-watchdog.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-health/team-health-watchdog.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1D;AAMD,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,sBAAsB,CAAC;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,yBAAyB;IAEpC,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;IACzB,SAAS,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAGxC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,yBAAyB;IAe3C;;;OAGG;IACH,KAAK,IAAI,IAAI;IA0Bb;;;;OAIG;IACH,IAAI,IAAI,IAAI;IASZ;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAuD/C;;OAEG;IACH,YAAY,IAAI,qBAAqB,GAAG,IAAI;IAI5C;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAK3B;;;OAGG;IACH,UAAU,IAAI,OAAO;IAMrB;;;OAGG;IACH,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAM1D;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAiB3C;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAIrD;;OAEG;IACH,QAAQ,IAAI,OAAO;CAGpB;AAWD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,yBAAyB,GAAG,IAAI,CAEnF;AAED,wBAAgB,8BAA8B,IAAI,yBAAyB,GAAG,IAAI,CAEjF"}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Team-Health-Watchdog (THW) — Service Shell (Layer 4)
3
+ *
4
+ * Wires the pure detector + alert router to live data sources, runs the
5
+ * 60s sweep loop, exposes API for the orchestrator skill / health endpoint.
6
+ *
7
+ * Architecture (§A.5): keep sweep+dedup+rate-limit+heartbeat strictly
8
+ * separable from the detector. v0.5 will extract these protected members
9
+ * into a `WatchdogBase`.
10
+ *
11
+ * Layer-4 invariant (§A.1): READS lower-layer state, EMITS alerts.
12
+ * NEVER mutates `agent.status`, claims, or work items.
13
+ *
14
+ * @module services/team-health/team-health-watchdog.service
15
+ */
16
+ import { detectTeamHealth, detectOrphanRequests } from './team-health-detector.js';
17
+ import { TeamHealthAlertRouter } from './team-health-alert-router.js';
18
+ const noopLogger = {
19
+ info: () => { }, warn: () => { }, error: () => { },
20
+ };
21
+ /**
22
+ * The watchdog service. Owns the sweep loop and exposes the public API.
23
+ */
24
+ export class TeamHealthWatchdogService {
25
+ // Hoist candidates for `WatchdogBase` extraction in v0.5 (§A.5).
26
+ sweepIntervalMs;
27
+ bootedAt;
28
+ router;
29
+ // v0-specific state.
30
+ config;
31
+ dataProvider;
32
+ alertSink;
33
+ logger;
34
+ clock;
35
+ timer = null;
36
+ lastSweep = null;
37
+ isRunning = false;
38
+ constructor(opts) {
39
+ this.config = opts.config;
40
+ this.dataProvider = opts.dataProvider;
41
+ this.alertSink = opts.alertSink;
42
+ this.logger = opts.logger ?? noopLogger;
43
+ this.clock = opts.clock ?? (() => new Date());
44
+ this.bootedAt = opts.bootedAt ?? this.clock();
45
+ this.sweepIntervalMs = opts.config.sweepIntervalMs;
46
+ this.router = new TeamHealthAlertRouter(opts.config.alerting, opts.config.offHoursSuppression, opts.config.shadowMode);
47
+ }
48
+ /**
49
+ * Start the periodic sweep loop. Idempotent. Per §11.3 self-instrumentation,
50
+ * we run `runOnce` immediately on start so /api/health has data from boot.
51
+ */
52
+ start() {
53
+ if (!this.config.enabled) {
54
+ this.logger.info('TeamHealthWatchdog disabled by config; not starting.');
55
+ return;
56
+ }
57
+ if (this.isRunning)
58
+ return;
59
+ this.isRunning = true;
60
+ this.logger.info('TeamHealthWatchdog starting', {
61
+ sweepIntervalMs: this.sweepIntervalMs,
62
+ shadowMode: this.config.shadowMode,
63
+ bootedAt: this.bootedAt.toISOString(),
64
+ });
65
+ this.runOnce().catch((err) => {
66
+ this.logger.error('Initial THW sweep failed', {
67
+ error: err instanceof Error ? err.message : String(err),
68
+ });
69
+ });
70
+ this.timer = setInterval(() => {
71
+ void this.runOnce().catch((err) => {
72
+ this.logger.error('THW sweep failed', {
73
+ error: err instanceof Error ? err.message : String(err),
74
+ });
75
+ });
76
+ }, this.sweepIntervalMs);
77
+ }
78
+ /**
79
+ * Stop the periodic sweep loop. After stop(), `last_sweep_age_ms` grows;
80
+ * /api/health surfaces this so a stuck watchdog itself shows as 'degraded'
81
+ * (§E.8 watchdog-watchdog).
82
+ */
83
+ stop() {
84
+ if (this.timer) {
85
+ clearInterval(this.timer);
86
+ this.timer = null;
87
+ }
88
+ this.isRunning = false;
89
+ this.logger.info('TeamHealthWatchdog stopped');
90
+ }
91
+ /**
92
+ * Run one sweep on demand. Catches own errors and returns a degraded
93
+ * sweep result rather than throwing.
94
+ */
95
+ async runOnce() {
96
+ const now = this.clock();
97
+ const startedMs = Date.now();
98
+ let detections = [];
99
+ const alerts = [];
100
+ let bootGraceSuppressed = false;
101
+ try {
102
+ const snapshot = await this.dataProvider.collectSnapshot(now);
103
+ const bootGraceUntil = snapshot.bootedAt.getTime() + this.config.bootGraceMs;
104
+ bootGraceSuppressed = now.getTime() < bootGraceUntil;
105
+ detections = detectTeamHealth(snapshot, this.config);
106
+ const orphans = detectOrphanRequests(snapshot.requests, snapshot.workItems, now, this.config.thresholds.ORPHAN_REQUEST_T1_MS);
107
+ const teamSummaryById = new Map(snapshot.teams.map((t) => [t.id, t]));
108
+ for (const detection of detections) {
109
+ const team = teamSummaryById.get(detection.teamId);
110
+ if (!team)
111
+ continue;
112
+ const decision = this.router.route(detection, team, now, orphans.systemTotal);
113
+ alerts.push(decision);
114
+ }
115
+ for (const decision of alerts) {
116
+ if (decision.channel === 'suppressed')
117
+ continue;
118
+ try {
119
+ await this.alertSink.deliver(decision);
120
+ this.router.commitDecision(decision, now);
121
+ }
122
+ catch (err) {
123
+ this.logger.warn('Alert delivery failed; will retry on next sweep', {
124
+ teamId: decision.detection.teamId,
125
+ verdict: decision.effectiveVerdict,
126
+ error: err instanceof Error ? err.message : String(err),
127
+ });
128
+ }
129
+ }
130
+ }
131
+ catch (err) {
132
+ this.logger.error('THW snapshot collection or detection failed', {
133
+ error: err instanceof Error ? err.message : String(err),
134
+ });
135
+ }
136
+ const result = {
137
+ sweptAt: now.toISOString(),
138
+ durationMs: Date.now() - startedMs,
139
+ detections, alerts, bootGraceSuppressed,
140
+ shadowMode: this.config.shadowMode,
141
+ };
142
+ this.lastSweep = result;
143
+ return result;
144
+ }
145
+ /**
146
+ * Get the most recent sweep result; null until `start()`/`runOnce()` runs.
147
+ */
148
+ getLastSweep() {
149
+ return this.lastSweep;
150
+ }
151
+ /**
152
+ * Milliseconds since the last sweep. -1 if no sweep has ever completed.
153
+ */
154
+ getLastSweepAgeMs() {
155
+ if (!this.lastSweep)
156
+ return -1;
157
+ return Math.max(0, this.clock().getTime() - new Date(this.lastSweep.sweptAt).getTime());
158
+ }
159
+ /**
160
+ * Self-health probe — the watchdog-watchdog (§E.8). True when the
161
+ * sweep loop appears stuck (age > 3× sweep interval).
162
+ */
163
+ isDegraded() {
164
+ const age = this.getLastSweepAgeMs();
165
+ if (age < 0)
166
+ return false;
167
+ return age > 3 * this.sweepIntervalMs;
168
+ }
169
+ /**
170
+ * Per-team verdicts from the most recent sweep. Backs the
171
+ * orchestrator `team-health-scan` skill (§6.5).
172
+ */
173
+ getCurrentVerdicts(teamId) {
174
+ if (!this.lastSweep)
175
+ return [];
176
+ if (!teamId)
177
+ return this.lastSweep.detections;
178
+ return this.lastSweep.detections.filter((d) => d.teamId === teamId);
179
+ }
180
+ /**
181
+ * Apply an updated config at runtime (e.g., post-edit reload).
182
+ */
183
+ reconfigure(config) {
184
+ this.config = config;
185
+ this.sweepIntervalMs = config.sweepIntervalMs;
186
+ this.router.setShadowMode(config.shadowMode);
187
+ this.router.reconfigure(config.alerting, config.offHoursSuppression);
188
+ if (this.timer) {
189
+ clearInterval(this.timer);
190
+ this.timer = setInterval(() => {
191
+ void this.runOnce().catch((err) => {
192
+ this.logger.error('THW sweep failed (post-reconfigure)', {
193
+ error: err instanceof Error ? err.message : String(err),
194
+ });
195
+ });
196
+ }, this.sweepIntervalMs);
197
+ }
198
+ }
199
+ /**
200
+ * Apply a manual silence to a team (Slack 🔇 react handler).
201
+ */
202
+ silenceTeam(teamId, durationMs) {
203
+ this.router.silenceTeam(teamId, this.clock(), durationMs);
204
+ }
205
+ /**
206
+ * Read the running flag — used by /api/health.
207
+ */
208
+ isActive() {
209
+ return this.isRunning;
210
+ }
211
+ }
212
+ /**
213
+ * Module-level singleton for lazy init (per Sam's etiquette nudge:
214
+ * `getInstance()` + first-call init, not module-load side effect).
215
+ *
216
+ * Production wiring calls `setTeamHealthWatchdogSingleton(svc)` once during
217
+ * boot; the controller and /api/health helpers consume `getTeamHealthWatchdogSingleton()`.
218
+ */
219
+ let singletonInstance = null;
220
+ export function setTeamHealthWatchdogSingleton(svc) {
221
+ singletonInstance = svc;
222
+ }
223
+ export function getTeamHealthWatchdogSingleton() {
224
+ return singletonInstance;
225
+ }
226
+ //# sourceMappingURL=team-health-watchdog.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-health-watchdog.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-health/team-health-watchdog.service.ts"],"names":[],"mappings":"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"}