crewly 1.6.5 → 1.8.0

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 (338) hide show
  1. package/config/constants.ts +2 -0
  2. package/config/roles/auditor/prompt.md +24 -0
  3. package/config/roles/developer/prompt.md +2 -1
  4. package/config/roles/orchestrator/prompt.md +118 -2
  5. package/config/roles/team-leader/prompt.md +6 -0
  6. package/config/skills/agent/core/create-request/SKILL.md +1 -1
  7. package/config/skills/agent/core/create-request/execute.sh +29 -2
  8. package/config/skills/agent/core/create-request/execute.test.sh +168 -0
  9. package/config/skills/agent/core/report-status/SKILL.md +8 -1
  10. package/config/skills/agent/core/report-status/execute.sh +23 -1
  11. package/config/skills/orchestrator/heartbeat/execute.sh +48 -6
  12. package/config/sops/common/mid-flight-milestone-surface.md +128 -0
  13. package/config/sops/common/owner-facing-communication.md +46 -2
  14. package/config/sops/developer/git-workflow.md +33 -0
  15. package/dist/backend/backend/src/constants.d.ts +13 -0
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +12 -0
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/browser/browser.controller.js +2 -2
  20. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  21. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  22. package/dist/backend/backend/src/controllers/chat/chat.controller.js +6 -0
  23. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  24. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +73 -0
  25. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  26. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +128 -0
  27. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  28. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +3 -0
  29. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -1
  30. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +8 -0
  31. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -1
  32. package/dist/backend/backend/src/controllers/session/session.controller.d.ts.map +1 -1
  33. package/dist/backend/backend/src/controllers/session/session.controller.js +50 -8
  34. package/dist/backend/backend/src/controllers/session/session.controller.js.map +1 -1
  35. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  36. package/dist/backend/backend/src/controllers/slack/slack.controller.js +215 -94
  37. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  38. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  39. package/dist/backend/backend/src/controllers/team/team.controller.js +27 -0
  40. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  41. package/dist/backend/backend/src/index.d.ts +1 -0
  42. package/dist/backend/backend/src/index.d.ts.map +1 -1
  43. package/dist/backend/backend/src/index.js +201 -37
  44. package/dist/backend/backend/src/index.js.map +1 -1
  45. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  46. package/dist/backend/backend/src/routes/api.routes.js +11 -1
  47. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  48. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +45 -3
  49. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  50. package/dist/backend/backend/src/services/agent/agent-registration.service.js +219 -7
  51. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  52. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +61 -1
  53. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -1
  54. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +117 -9
  55. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -1
  56. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +44 -0
  57. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +179 -10
  59. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts +6 -6
  61. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts.map +1 -1
  62. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js +3 -3
  63. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js.map +1 -1
  64. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +7 -1
  65. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  66. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  67. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +33 -0
  68. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/agent/idle-detection.service.js +108 -4
  70. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  71. package/dist/backend/backend/src/services/agent/runtime-service.factory.js +4 -4
  72. package/dist/backend/backend/src/services/agent/runtime-service.factory.js.map +1 -1
  73. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +1 -1
  74. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +40 -2
  76. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  77. package/dist/backend/backend/src/services/chat/chat.service.d.ts +48 -331
  78. package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
  79. package/dist/backend/backend/src/services/chat/chat.service.js +261 -712
  80. package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
  81. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +82 -1
  82. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +120 -2
  84. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  85. package/dist/backend/backend/src/services/chat-v2/chat-v2.providers.d.ts +114 -0
  86. package/dist/backend/backend/src/services/chat-v2/chat-v2.providers.d.ts.map +1 -0
  87. package/dist/backend/backend/src/services/chat-v2/chat-v2.providers.js +182 -0
  88. package/dist/backend/backend/src/services/chat-v2/chat-v2.providers.js.map +1 -0
  89. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.d.ts +188 -0
  90. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.d.ts.map +1 -0
  91. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.js +434 -0
  92. package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.js.map +1 -0
  93. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +401 -5
  94. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +619 -3
  96. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  97. package/dist/backend/backend/src/services/chat-v2/legacy-dto.utils.d.ts +93 -0
  98. package/dist/backend/backend/src/services/chat-v2/legacy-dto.utils.d.ts.map +1 -0
  99. package/dist/backend/backend/src/services/chat-v2/legacy-dto.utils.js +138 -0
  100. package/dist/backend/backend/src/services/chat-v2/legacy-dto.utils.js.map +1 -0
  101. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +46 -0
  102. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -1
  103. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +75 -0
  104. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -1
  105. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +10 -2
  106. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +178 -10
  108. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -1
  109. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +37 -0
  110. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  111. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +71 -0
  112. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  113. package/dist/backend/backend/src/services/chat-v2/types.d.ts +33 -1
  114. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -1
  115. package/dist/backend/backend/src/services/chat-v2/types.js +1 -1
  116. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -1
  117. package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts +22 -0
  118. package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/cloud/cloud-sync.service.js +71 -1
  120. package/dist/backend/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
  121. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +102 -1
  122. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  123. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +61 -0
  124. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  125. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.d.ts +21 -3
  126. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.d.ts.map +1 -1
  127. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.js +47 -13
  128. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.js.map +1 -1
  129. package/dist/backend/backend/src/services/core/system-health.util.d.ts +25 -4
  130. package/dist/backend/backend/src/services/core/system-health.util.d.ts.map +1 -1
  131. package/dist/backend/backend/src/services/core/system-health.util.js +30 -5
  132. package/dist/backend/backend/src/services/core/system-health.util.js.map +1 -1
  133. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  134. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +22 -11
  135. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  136. package/dist/backend/backend/src/services/mcp-server.d.ts.map +1 -1
  137. package/dist/backend/backend/src/services/mcp-server.js +5 -0
  138. package/dist/backend/backend/src/services/mcp-server.js.map +1 -1
  139. package/dist/backend/backend/src/services/mcp-tool-definitions.d.ts +4 -0
  140. package/dist/backend/backend/src/services/mcp-tool-definitions.d.ts.map +1 -1
  141. package/dist/backend/backend/src/services/mcp-tool-definitions.js +12 -1
  142. package/dist/backend/backend/src/services/mcp-tool-definitions.js.map +1 -1
  143. package/dist/backend/backend/src/services/memory/capability-inference.d.ts +73 -0
  144. package/dist/backend/backend/src/services/memory/capability-inference.d.ts.map +1 -0
  145. package/dist/backend/backend/src/services/memory/capability-inference.js +115 -0
  146. package/dist/backend/backend/src/services/memory/capability-inference.js.map +1 -0
  147. package/dist/backend/backend/src/services/memory/memory.service.d.ts +22 -1
  148. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  149. package/dist/backend/backend/src/services/memory/memory.service.js +81 -3
  150. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  151. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts +25 -1
  152. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  153. package/dist/backend/backend/src/services/memory/project-memory.service.js +43 -0
  154. package/dist/backend/backend/src/services/memory/project-memory.service.js.map +1 -1
  155. package/dist/backend/backend/src/services/memory/task-history-seeder.d.ts +47 -0
  156. package/dist/backend/backend/src/services/memory/task-history-seeder.d.ts.map +1 -0
  157. package/dist/backend/backend/src/services/memory/task-history-seeder.js +89 -0
  158. package/dist/backend/backend/src/services/memory/task-history-seeder.js.map +1 -0
  159. package/dist/backend/backend/src/services/memory/task-history.subscriber.d.ts +76 -0
  160. package/dist/backend/backend/src/services/memory/task-history.subscriber.d.ts.map +1 -0
  161. package/dist/backend/backend/src/services/memory/task-history.subscriber.js +199 -0
  162. package/dist/backend/backend/src/services/memory/task-history.subscriber.js.map +1 -0
  163. package/dist/backend/backend/src/services/messaging/message-replay.service.d.ts +2 -4
  164. package/dist/backend/backend/src/services/messaging/message-replay.service.d.ts.map +1 -1
  165. package/dist/backend/backend/src/services/messaging/message-replay.service.js +22 -12
  166. package/dist/backend/backend/src/services/messaging/message-replay.service.js.map +1 -1
  167. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  168. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +25 -5
  169. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  170. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.d.ts.map +1 -1
  171. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.js +13 -3
  172. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.js.map +1 -1
  173. package/dist/backend/backend/src/services/notification/milestone-notification.subscriber.d.ts +99 -0
  174. package/dist/backend/backend/src/services/notification/milestone-notification.subscriber.d.ts.map +1 -0
  175. package/dist/backend/backend/src/services/notification/milestone-notification.subscriber.js +225 -0
  176. package/dist/backend/backend/src/services/notification/milestone-notification.subscriber.js.map +1 -0
  177. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +39 -18
  178. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  179. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +60 -32
  180. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  181. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +134 -0
  182. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  183. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +416 -13
  184. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  185. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  186. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +73 -7
  187. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  188. package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
  189. package/dist/backend/backend/src/services/session/session-handoff.service.js +30 -4
  190. package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -1
  191. package/dist/backend/backend/src/services/skill/skill-executor.service.d.ts.map +1 -1
  192. package/dist/backend/backend/src/services/skill/skill-executor.service.js +13 -1
  193. package/dist/backend/backend/src/services/skill/skill-executor.service.js.map +1 -1
  194. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.d.ts.map +1 -1
  195. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.js +9 -6
  196. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.js.map +1 -1
  197. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +21 -2
  198. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  199. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +120 -46
  200. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  201. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  202. package/dist/backend/backend/src/services/slack/slack.service.js +49 -0
  203. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  204. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +33 -2
  205. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  206. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +160 -8
  207. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  208. package/dist/backend/backend/src/services/v3/cascade-request-status.d.ts.map +1 -1
  209. package/dist/backend/backend/src/services/v3/cascade-request-status.js +55 -2
  210. package/dist/backend/backend/src/services/v3/cascade-request-status.js.map +1 -1
  211. package/dist/backend/backend/src/services/v3/mission-executor.service.d.ts.map +1 -1
  212. package/dist/backend/backend/src/services/v3/mission-executor.service.js +9 -1
  213. package/dist/backend/backend/src/services/v3/mission-executor.service.js.map +1 -1
  214. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.d.ts.map +1 -1
  215. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js +28 -3
  216. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js.map +1 -1
  217. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -1
  218. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +5 -2
  219. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -1
  220. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.d.ts.map +1 -1
  221. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.js +57 -15
  222. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.js.map +1 -1
  223. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts +39 -0
  224. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts.map +1 -1
  225. package/dist/backend/backend/src/services/v3/trigger-engine.service.js +81 -0
  226. package/dist/backend/backend/src/services/v3/trigger-engine.service.js.map +1 -1
  227. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +17 -1
  228. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  229. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +22 -3
  230. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  231. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts +1 -1
  232. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -1
  233. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +26 -10
  234. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -1
  235. package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/workflow/cron-task.service.js +68 -5
  237. package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
  238. package/dist/backend/backend/src/services/workflow/team-identifier-resolver.d.ts +44 -0
  239. package/dist/backend/backend/src/services/workflow/team-identifier-resolver.d.ts.map +1 -0
  240. package/dist/backend/backend/src/services/workflow/team-identifier-resolver.js +57 -0
  241. package/dist/backend/backend/src/services/workflow/team-identifier-resolver.js.map +1 -0
  242. package/dist/backend/backend/src/types/credential.types.d.ts +17 -1
  243. package/dist/backend/backend/src/types/credential.types.d.ts.map +1 -1
  244. package/dist/backend/backend/src/types/credential.types.js +15 -5
  245. package/dist/backend/backend/src/types/credential.types.js.map +1 -1
  246. package/dist/backend/backend/src/types/cron-task.types.d.ts +17 -0
  247. package/dist/backend/backend/src/types/cron-task.types.d.ts.map +1 -1
  248. package/dist/backend/backend/src/types/event-bus.types.d.ts +1 -1
  249. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  250. package/dist/backend/backend/src/types/event-bus.types.js +12 -0
  251. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  252. package/dist/backend/backend/src/types/intent-task.types.d.ts +10 -13
  253. package/dist/backend/backend/src/types/intent-task.types.d.ts.map +1 -1
  254. package/dist/backend/backend/src/types/intent-task.types.js +4 -1
  255. package/dist/backend/backend/src/types/intent-task.types.js.map +1 -1
  256. package/dist/backend/backend/src/types/memory.types.d.ts +94 -1
  257. package/dist/backend/backend/src/types/memory.types.d.ts.map +1 -1
  258. package/dist/backend/backend/src/types/memory.types.js.map +1 -1
  259. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +23 -0
  260. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  261. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  262. package/dist/backend/backend/src/utils/team.utils.d.ts +3 -1
  263. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -1
  264. package/dist/backend/backend/src/utils/team.utils.js +26 -5
  265. package/dist/backend/backend/src/utils/team.utils.js.map +1 -1
  266. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +23 -0
  267. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -1
  268. package/dist/backend/backend/src/websocket/chat-v2.gateway.js +56 -7
  269. package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -1
  270. package/dist/backend/backend/src/websocket/chat.gateway.d.ts +19 -4
  271. package/dist/backend/backend/src/websocket/chat.gateway.d.ts.map +1 -1
  272. package/dist/backend/backend/src/websocket/chat.gateway.js +78 -63
  273. package/dist/backend/backend/src/websocket/chat.gateway.js.map +1 -1
  274. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  275. package/dist/backend/backend/src/websocket/terminal.gateway.js +10 -2
  276. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  277. package/dist/backend/config/constants.d.ts +2 -0
  278. package/dist/backend/config/constants.d.ts.map +1 -1
  279. package/dist/backend/config/constants.js +2 -0
  280. package/dist/backend/config/constants.js.map +1 -1
  281. package/dist/backend/config/index.d.ts +1 -0
  282. package/dist/backend/config/index.d.ts.map +1 -1
  283. package/dist/cli/backend/src/constants.d.ts +13 -0
  284. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  285. package/dist/cli/backend/src/constants.js +12 -0
  286. package/dist/cli/backend/src/constants.js.map +1 -1
  287. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  288. package/dist/cli/backend/src/services/event-bus/event-bus.service.js +22 -11
  289. package/dist/cli/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  290. package/dist/cli/backend/src/services/mcp-server.d.ts.map +1 -1
  291. package/dist/cli/backend/src/services/mcp-server.js +5 -0
  292. package/dist/cli/backend/src/services/mcp-server.js.map +1 -1
  293. package/dist/cli/backend/src/services/mcp-tool-definitions.d.ts +4 -0
  294. package/dist/cli/backend/src/services/mcp-tool-definitions.d.ts.map +1 -1
  295. package/dist/cli/backend/src/services/mcp-tool-definitions.js +12 -1
  296. package/dist/cli/backend/src/services/mcp-tool-definitions.js.map +1 -1
  297. package/dist/cli/backend/src/services/memory/memory.service.d.ts +22 -1
  298. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  299. package/dist/cli/backend/src/services/memory/memory.service.js +81 -3
  300. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  301. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +25 -1
  302. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  303. package/dist/cli/backend/src/services/memory/project-memory.service.js +43 -0
  304. package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -1
  305. package/dist/cli/backend/src/services/skill/skill-executor.service.d.ts.map +1 -1
  306. package/dist/cli/backend/src/services/skill/skill-executor.service.js +13 -1
  307. package/dist/cli/backend/src/services/skill/skill-executor.service.js.map +1 -1
  308. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +33 -2
  309. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  310. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +160 -8
  311. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  312. package/dist/cli/backend/src/types/credential.types.d.ts +17 -1
  313. package/dist/cli/backend/src/types/credential.types.d.ts.map +1 -1
  314. package/dist/cli/backend/src/types/credential.types.js +15 -5
  315. package/dist/cli/backend/src/types/credential.types.js.map +1 -1
  316. package/dist/cli/backend/src/types/event-bus.types.d.ts +1 -1
  317. package/dist/cli/backend/src/types/event-bus.types.d.ts.map +1 -1
  318. package/dist/cli/backend/src/types/event-bus.types.js +12 -0
  319. package/dist/cli/backend/src/types/event-bus.types.js.map +1 -1
  320. package/dist/cli/backend/src/types/memory.types.d.ts +94 -1
  321. package/dist/cli/backend/src/types/memory.types.d.ts.map +1 -1
  322. package/dist/cli/backend/src/types/memory.types.js.map +1 -1
  323. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +23 -0
  324. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  325. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  326. package/dist/cli/cli/src/commands/start.js +73 -12
  327. package/dist/cli/cli/src/commands/start.js.map +1 -1
  328. package/dist/cli/config/constants.d.ts +2 -0
  329. package/dist/cli/config/constants.d.ts.map +1 -1
  330. package/dist/cli/config/constants.js +2 -0
  331. package/dist/cli/config/constants.js.map +1 -1
  332. package/dist/cli/config/index.d.ts +1 -0
  333. package/dist/cli/config/index.d.ts.map +1 -1
  334. package/frontend/dist/assets/index-b279da34.js +4926 -0
  335. package/frontend/dist/assets/{index-b7e59b2b.css → index-c07e04c0.css} +2 -2
  336. package/frontend/dist/index.html +2 -2
  337. package/package.json +1 -1
  338. package/frontend/dist/assets/index-698305f3.js +0 -5228
@@ -25,6 +25,7 @@ import { getSettingsService } from './services/settings/index.js';
25
25
  import { MemoryService } from './services/memory/memory.service.js';
26
26
  import { getImprovementStartupService } from './services/orchestrator/improvement-startup.service.js';
27
27
  import { initializeSlackIfConfigured, shutdownSlack } from './services/slack/index.js';
28
+ import { resolveTeamByIdOrSlug, slugifyTeamName } from './services/workflow/team-identifier-resolver.js';
28
29
  import { initializeWhatsAppIfConfigured, shutdownWhatsApp } from './services/whatsapp/index.js';
29
30
  import { initializeGoogleChatIfConfigured } from './services/messaging/google-chat-initializer.js';
30
31
  import { initializeTelegramIfConfigured, shutdownTelegram } from './services/telegram/index.js';
@@ -34,6 +35,7 @@ import { ThreadStatusQueueService } from './services/messaging/thread-status-que
34
35
  import { EventBusService } from './services/event-bus/index.js';
35
36
  import { EventToWorkItemBridge } from './services/event-bus/event-to-workitem-bridge.service.js';
36
37
  import { AutoLearningSubscriber } from './services/memory/auto-learning.subscriber.js';
38
+ import { MilestoneNotificationSubscriber } from './services/notification/milestone-notification.subscriber.js';
37
39
  import { RequestSlaSubscriber, setRequestSlaSubscriber, } from './services/v3/request-sla.subscriber.js';
38
40
  import { RequestDecomposeSubscriber, setRequestDecomposeSubscriber, } from './services/v3/request-decompose.subscriber.js';
39
41
  import { RequestStatusUpdateSubscriber } from './services/v3/request-status-update.subscriber.js';
@@ -76,6 +78,8 @@ import { setReconcilerService } from './controllers/reconciler/reconciler.contro
76
78
  import { FissionGuardService } from './services/fission/fission-guard.service.js';
77
79
  import { setFissionGuardService } from './controllers/fission/fission.controller.js';
78
80
  import { TaskPoolService } from './services/task-pool/task-pool.service.js';
81
+ import { ProjectMemoryService } from './services/memory/project-memory.service.js';
82
+ import { TaskHistorySubscriber } from './services/memory/task-history.subscriber.js';
79
83
  import { TeamHealthWatchdogService, LiveTeamHealthDataProvider, loadTeamHealthConfig, setTeamHealthWatchdogSingleton, getTeamHealthWatchdogSingleton, } from './services/team-health/index.js';
80
84
  // ESM __dirname equivalent using import.meta.url
81
85
  const __filename = fileURLToPath(import.meta.url);
@@ -138,6 +142,9 @@ export class CrewlyServer {
138
142
  eventToWorkItemBridge = null;
139
143
  /** LEARN-1: subscribes to terminal task / mission:replanned events and auto-records learnings. */
140
144
  autoLearningSubscriber = null;
145
+ // DF-1 #438 — symmetric to AutoLearningSubscriber; surfaces milestones
146
+ // to orc's chat queue.
147
+ milestoneNotificationSubscriber = null;
141
148
  /** INBOUND-1: subscribes to request:created and tracks 5/10 min SLA on respond_to_user WIs. */
142
149
  requestSlaSubscriber = null;
143
150
  /** Pipeline-#4 follow-up: subscribes to request:created and auto-decomposes actionable L2 Requests via plan() → addToPool. */
@@ -262,6 +269,19 @@ export class CrewlyServer {
262
269
  // triggers addToPool — the slack listener / TaskPool router below both
263
270
  // depend on this for the auto-close path b chain. Idempotent.
264
271
  TaskPoolService.getInstance().setEventBusService(this.eventBusService);
272
+ // Memory: TaskHistorySubscriber listens on the bus for
273
+ // task:done_by_worker / task:rejected / task:cancelled and writes
274
+ // the resulting TaskHistoryEntry into ProjectMemory. This is the
275
+ // load-bearing write path behind "who in my team has done X?" —
276
+ // the orchestrator queries via recall(capability:...). Must run
277
+ // AFTER TaskPoolService is wired to the bus (above) so the events
278
+ // it publishes have a subscriber to consume them.
279
+ const taskHistorySubscriber = new TaskHistorySubscriber({
280
+ eventBus: this.eventBusService,
281
+ projectMemoryService: ProjectMemoryService.getInstance(),
282
+ taskPoolService: TaskPoolService.getInstance(),
283
+ });
284
+ taskHistorySubscriber.start();
265
285
  // P1 Bug B (Pool umbrella WI 72ca743a): Wire RequestService into the
266
286
  // TaskPool singleton so addToPool intrinsically links new WIs into
267
287
  // their parent Request.workItemIds[] — independent of the
@@ -330,6 +350,19 @@ export class CrewlyServer {
330
350
  // contract (V1) and the V7/V9 self-checks in the co-located test.
331
351
  this.autoLearningSubscriber = AutoLearningSubscriber.boot(this.eventBusService);
332
352
  this.autoLearningSubscriber.start();
353
+ // DF-1 #438: symmetric notification subscriber. Same architectural
354
+ // pattern as AutoLearningSubscriber — listens to terminal lifecycle
355
+ // events (`task:verified`, `mission:replanned`) and enqueues a
356
+ // `[MILESTONE]` envelope into orc's chat queue. The QW-3 row in
357
+ // `config/roles/orchestrator/prompt.md` (#436) handles the
358
+ // always-forward-to-owner rule on the orc side; this subscriber
359
+ // closes the gap where an agent ships work but forgets to call
360
+ // `report-status --status milestone` (the agent-side QW-1 path).
361
+ this.milestoneNotificationSubscriber = new MilestoneNotificationSubscriber({
362
+ eventBus: this.eventBusService,
363
+ messageQueueService: this.messageQueueService,
364
+ });
365
+ this.milestoneNotificationSubscriber.start();
333
366
  // INBOUND-1 + Pipeline-#4 follow-up: wire RequestService → bus, then
334
367
  // boot both v3 subscribers (SLA tracker + auto-decompose). Order
335
368
  // matters within the block: setRequestServiceEventBus must run
@@ -473,28 +506,45 @@ export class CrewlyServer {
473
506
  }
474
507
  }
475
508
  });
509
+ // Shared LiveReconcilerDataProvider instance used by both the
510
+ // Reconciler service and the TeamHealthWatchdog data provider.
511
+ // Sharing is required so the memory-pressure broadcast state
512
+ // (`consecutivePressureSkips` / `lastPressureNotifiedAt`) is
513
+ // counted ONCE per sustained pressure episode. Two separate
514
+ // instances would each cross the 5-skip threshold around the same
515
+ // time and publish two `system:memory_pressure` events with
516
+ // distinct `event.id` values (no debounce match), so orc would
517
+ // receive duplicates. See follow-up #5 from PR #543 review.
518
+ const liveDataProvider = new LiveReconcilerDataProvider();
519
+ liveDataProvider.setEventBus(this.eventBusService);
520
+ // Wire AgentRegistrationService so the memory-pressure eviction
521
+ // path can terminate idle agents to free wake slots (issue surfaced
522
+ // 2026-05-16: queued WIs for inactive Atlas could not get woken
523
+ // because the floor was held by idle product/marketing agents).
524
+ liveDataProvider.setAgentRegistrationService(this.apiController.agentRegistrationService);
476
525
  // Initialize Reconciler Service (V2 — system truth recomputation)
477
526
  {
478
527
  const reconcilerLogger = LoggerService.getInstance().createComponentLogger('ReconcilerInit');
479
528
  // Live data provider — connects Reconciler to Task Pool, Claim Service,
480
529
  // Storage Service, and Agent Suspend for real reconciliation including
481
530
  // Hybrid Wake (auto-rehydrating suspended agents when tasks go unclaimed).
482
- const liveDataProvider = new LiveReconcilerDataProvider();
483
531
  this.reconcilerService = new ReconcilerService(liveDataProvider);
484
532
  setReconcilerService(this.reconcilerService);
485
533
  // Subscribe EventBus events for targeted reconciliation
486
534
  if (this.reconcilerService) {
487
535
  const reconciler = this.reconcilerService;
488
- const eventTypes = ['agent:idle', 'task:completed', 'task:failed', 'agent:inactive'];
489
- for (const eventType of eventTypes) {
490
- this.eventBusService.subscribe({
491
- eventType,
492
- filter: {},
493
- subscriberSession: '__reconciler__',
494
- oneShot: false,
495
- ttlMinutes: 525_600, // 1 yearpermanent subscription
496
- });
497
- }
536
+ // 2026-05-15 Steve dogfood: the prior `subscribe({ subscriberSession:
537
+ // '__reconciler__' })` loop here was redundant AND wrong. The
538
+ // subscribe path routes critical events through
539
+ // `MessageQueueService.enqueue` keyed by `targetSession`, which
540
+ // then fails noisily because `__reconciler__` is not a PTY
541
+ // session ("Session '__reconciler__' does not exist", every
542
+ // reconciler tick). The in-process `event_published` listener
543
+ // below already drives the reconciler no second wiring needed.
544
+ // Removed the subscribe-block; if a future change needs persistent
545
+ // metadata for the reconciler subscription, attach it as a real
546
+ // in-process subscriber via `onInProcess` rather than the
547
+ // session-targeted `subscribe` API.
498
548
  // Listen for all published events and trigger targeted reconciliation
499
549
  this.eventBusService.on('event_published', (payload) => {
500
550
  const targetedEventTypes = ['task:completed', 'task:failed', 'agent:idle', 'agent:inactive'];
@@ -527,9 +577,11 @@ export class CrewlyServer {
527
577
  thwLogger.warn('Reconciler not available; skipping TeamHealthWatchdog init.');
528
578
  }
529
579
  else {
530
- const reconcilerProvider = new LiveReconcilerDataProvider();
580
+ // Reuse the shared LiveReconcilerDataProvider declared
581
+ // above (follow-up #5 from PR #543 review) — instantiating
582
+ // a second copy would double-broadcast memory-pressure.
531
583
  const dataProvider = new LiveTeamHealthDataProvider({
532
- reconcilerProvider,
584
+ reconcilerProvider: liveDataProvider,
533
585
  getTeams: async () => StorageService.getInstance().getTeams(),
534
586
  bootedAt: new Date(),
535
587
  });
@@ -1078,6 +1130,11 @@ export class CrewlyServer {
1078
1130
  const chatDispatcher = new ChatV2DispatcherService({
1079
1131
  agentSink: this.apiController.agentRegistrationService,
1080
1132
  mentionResolver: chatMentionResolver,
1133
+ // Phase B-2 — huddle roster lookup. ChatV2Service owns
1134
+ // the chat_channel_members table; the dispatcher just
1135
+ // needs the list of session names for a given channel
1136
+ // to fan-out a user message to every huddle member.
1137
+ huddleMembersFor: (channelId) => chatService.queryHuddleMembersForDispatch(channelId),
1081
1138
  });
1082
1139
  this.chatV2Gateway = chatGateway;
1083
1140
  this.chatV2Dispatcher = chatDispatcher;
@@ -1089,9 +1146,42 @@ export class CrewlyServer {
1089
1146
  path: '/ws/chat',
1090
1147
  authMode: jwtSecret ? 'jwt' : 'dev-anonymous',
1091
1148
  });
1149
+ // Cloud Portal relay bridge — gives the Crewly Portal at
1150
+ // crewlyai.com the same /agents experience by tunnelling chat-v2
1151
+ // RPC calls through the Cloud relay queue + forwarding gateway
1152
+ // broadcasts as `chat_event` messages. Only wired when Cloud Sync
1153
+ // is running (BrowserRelayAdapter pattern).
1154
+ try {
1155
+ const { ChatV2RelayAdapter } = await import('./services/chat-v2/chat-v2.relay-adapter.service.js');
1156
+ const { CloudSyncService } = await import('./services/cloud/cloud-sync.service.js');
1157
+ const { createOssAgentDirectoryProvider, createOssAgentPresenceProvider, } = await import('./services/chat-v2/chat-v2.providers.js');
1158
+ const sync = CloudSyncService.getInstance();
1159
+ if (sync) {
1160
+ const chatRelayAdapter = new ChatV2RelayAdapter({
1161
+ service: chatService,
1162
+ gateway: chatGateway,
1163
+ cloudSync: sync,
1164
+ // Wire the dispatcher so Portal-sent user messages also fire the
1165
+ // agent-side prompt (parity with the HTTP controller path).
1166
+ // Without this, Portal user-messages persist but the bound agent
1167
+ // never receives the `[CHAT:<id>]` prompt — orc/etc. stay silent.
1168
+ dispatcher: chatDispatcher,
1169
+ directory: createOssAgentDirectoryProvider(this.storageService),
1170
+ presence: createOssAgentPresenceProvider(this.storageService),
1171
+ });
1172
+ chatRelayAdapter.start();
1173
+ this.logger.info('ChatV2RelayAdapter started — Cloud Portal can now drive chat-v2 via relay');
1174
+ }
1175
+ }
1176
+ catch (err) {
1177
+ // Adapter wiring failure is non-fatal — local OSS UI still works.
1178
+ this.logger.warn('ChatV2RelayAdapter wiring skipped', {
1179
+ error: err instanceof Error ? err.message : String(err),
1180
+ });
1181
+ }
1092
1182
  // Onboarding v3 (B1) — wire the cold-start detector with the
1093
1183
  // chat-v2 service we just stood up. The orc bootstrap path
1094
- // (CrewlyAgentRuntimeService.detectOnboardingMode) probes this
1184
+ // (CrewlyAgentExternalRuntimeService.detectOnboardingMode) probes this
1095
1185
  // singleton; null means "skip the cold-start probe", so this
1096
1186
  // wiring is what flips onboarding mode on for the demo path.
1097
1187
  try {
@@ -1209,6 +1299,7 @@ export class CrewlyServer {
1209
1299
  // resume notification won't re-send already-answered conversations.
1210
1300
  try {
1211
1301
  const { RequestService } = await import('./services/v3/request.service.js');
1302
+ const { extractSlackChannelId, extractSlackThreadTs } = await import('./services/v3/request-sla.subscriber.js');
1212
1303
  const reqSvc = RequestService.getInstance();
1213
1304
  const allReqs = await reqSvc.listAll();
1214
1305
  let backfilled = 0;
@@ -1216,13 +1307,17 @@ export class CrewlyServer {
1216
1307
  if (req.status !== 'done')
1217
1308
  continue;
1218
1309
  const scid = req.sourceConversationItemId || '';
1219
- if (!scid.startsWith('slack-'))
1220
- continue;
1221
- const m = scid.match(/^slack-(.+)-(\d+)[.-](\d+)$/);
1222
- if (!m)
1310
+ // `extractSlack*` strips the optional `-msg-{ts}` thread-reply
1311
+ // suffix before parsing, so both top-level and in-thread
1312
+ // Requests resolve to the canonical `{channelId}:{threadRoot}`.
1313
+ // Previously a local regex was used here and its greedy `.+`
1314
+ // swallowed the suffix, producing a malformed threadKey that
1315
+ // missed the dedup check and bloated the persistence file.
1316
+ const channelId = extractSlackChannelId(scid);
1317
+ const threadTs = extractSlackThreadTs(scid);
1318
+ if (!channelId || !threadTs)
1223
1319
  continue;
1224
- const [, channelId, t1, t2] = m;
1225
- const threadKey = `${channelId}:${t1}.${t2}`;
1320
+ const threadKey = `${channelId}:${threadTs}`;
1226
1321
  if (this.threadStatusQueueService.get(threadKey))
1227
1322
  continue;
1228
1323
  this.threadStatusQueueService.trackInbound({
@@ -1248,9 +1343,7 @@ export class CrewlyServer {
1248
1343
  // but before the queue processor starts (so replayed messages are ready for delivery).
1249
1344
  try {
1250
1345
  const { MessageReplayService } = await import('./services/messaging/message-replay.service.js');
1251
- const { getChatService } = await import('./services/chat/chat.service.js');
1252
- const chatService = getChatService();
1253
- const replayService = new MessageReplayService(this.messageQueueService, chatService, this.config.crewlyHome);
1346
+ const replayService = new MessageReplayService(this.messageQueueService, this.config.crewlyHome);
1254
1347
  const replayResult = await replayService.replayPendingMessages();
1255
1348
  if (replayResult.replayedCount > 0) {
1256
1349
  this.logger.info('Replayed pending messages from offline period (#247)', {
@@ -1306,6 +1399,16 @@ export class CrewlyServer {
1306
1399
  this.logger.info('Executing cron task', { id: task.id, target: task.targetAgent });
1307
1400
  await registrationRef.sendMessageToAgent(task.targetAgent, `[CRON_TASK:${task.id}] ${task.taskDescription}`);
1308
1401
  });
1402
+ // Issue #307: cron tasks created with `targetTeamId` set to a
1403
+ // name slug (e.g. "stock-ops-team") instead of the UUID would
1404
+ // silently 404 on every fire — `teams.find(t => t.id === teamId)`
1405
+ // returned undefined and both callbacks returned `false` with
1406
+ // no log surface. `resolveTeamByIdOrSlug` (imported statically
1407
+ // at the top of the file) tries UUID first, then falls back
1408
+ // to a slug match against `name`. Misses now surface a distinct
1409
+ // warn-log with the available slugs so the cause is visible
1410
+ // instead of hiding behind the generic "agent offline" warn
1411
+ // from cron-task.service.
1309
1412
  cronTaskService.setAgentStatusCallback(async (sessionName, teamId) => {
1310
1413
  // Handle orchestrator separately — it's not in regular teams
1311
1414
  if (sessionName === CREWLY_CONSTANTS.SESSIONS.ORCHESTRATOR_NAME || teamId === 'orchestrator') {
@@ -1313,9 +1416,16 @@ export class CrewlyServer {
1313
1416
  return orchStatus?.agentStatus === 'active' || orchStatus?.agentStatus === 'started';
1314
1417
  }
1315
1418
  const teams = await storageRef.getTeams();
1316
- const team = teams.find((t) => t.id === teamId);
1317
- if (!team)
1419
+ const team = resolveTeamByIdOrSlug(teams, teamId);
1420
+ if (!team) {
1421
+ this.logger.warn('CronTask: targetTeamId resolves to no team', {
1422
+ sessionName,
1423
+ targetTeamId: teamId,
1424
+ availableSlugs: teams.slice(0, 10).map((t) => slugifyTeamName(t.name)),
1425
+ hint: 'Set targetTeamId to either the team UUID or one of availableSlugs (lowercase, spaces→-)',
1426
+ });
1318
1427
  return false;
1428
+ }
1319
1429
  const member = team.members.find((m) => m.sessionName === sessionName);
1320
1430
  if (!member)
1321
1431
  return false;
@@ -1325,16 +1435,25 @@ export class CrewlyServer {
1325
1435
  cronTaskService.setAgentStartCallback(async (sessionName, teamId) => {
1326
1436
  try {
1327
1437
  const teams = await storageRef.getTeams();
1328
- const team = teams.find((t) => t.id === teamId);
1329
- if (!team)
1438
+ const team = resolveTeamByIdOrSlug(teams, teamId);
1439
+ if (!team) {
1440
+ this.logger.warn('CronTask auto-start: targetTeamId resolves to no team', {
1441
+ sessionName,
1442
+ targetTeamId: teamId,
1443
+ availableSlugs: teams.slice(0, 10).map((t) => slugifyTeamName(t.name)),
1444
+ hint: 'Set targetTeamId to either the team UUID or one of availableSlugs (lowercase, spaces→-)',
1445
+ });
1330
1446
  return false;
1447
+ }
1331
1448
  const member = team.members.find((m) => m.sessionName === sessionName);
1332
1449
  if (!member)
1333
1450
  return false;
1334
1451
  await registrationRef.createAgentSession({
1335
1452
  sessionName: member.sessionName,
1336
1453
  role: member.role,
1337
- teamId,
1454
+ // Use the resolved team's UUID — not the user-supplied identifier
1455
+ // — so downstream agent-registration always sees the canonical id.
1456
+ teamId: team.id,
1338
1457
  memberId: member.id,
1339
1458
  });
1340
1459
  return true;
@@ -2046,15 +2165,56 @@ export class CrewlyServer {
2046
2165
  // and auditor sessions when auditor is disabled
2047
2166
  const isAuditorEnabled = process.env[AUDITOR_CONSTANTS.ENV_VAR]?.toLowerCase() === 'true'
2048
2167
  || (process.env[AUDITOR_CONSTANTS.ENV_VAR] === undefined && AUDITOR_CONSTANTS.ENABLED_BY_DEFAULT);
2049
- const agentSessions = state.sessions.filter((s) => {
2168
+ const baselineSessions = state.sessions.filter((s) => {
2050
2169
  if (s.role === ORCHESTRATOR_ROLE)
2051
2170
  return false;
2052
2171
  if (!isAuditorEnabled && s.name === AUDITOR_SCHEDULER_CONSTANTS.AUDITOR_SESSION_NAME)
2053
2172
  return false;
2054
2173
  return true;
2055
2174
  });
2175
+ // 2026-05-17 — gate by task-pool work. Pre-fix the boot path
2176
+ // blindly resurrected every persisted session even when none had
2177
+ // pending work, defeating the wake-gate philosophy (PR #574/#585)
2178
+ // and bloating RAM until IdleDetection eventually drained them
2179
+ // back. Now: only restore a session if the pool has at least one
2180
+ // non-terminal WorkItem with `target === sessionName`. Idle
2181
+ // agents stay dead until orc dispatches new work, at which point
2182
+ // the dispatcher / wake path raises them on demand.
2183
+ //
2184
+ // Safety valve: if the pool lookup throws (e.g. SQLite not yet
2185
+ // open during early boot), preserve the legacy behaviour rather
2186
+ // than block all restores — better to over-restore than to
2187
+ // silently strand work.
2188
+ let agentSessions = baselineSessions;
2189
+ try {
2190
+ const pool = TaskPoolService.getInstance();
2191
+ const allItems = await pool.getAllItems();
2192
+ const targetedSessions = new Set();
2193
+ for (const wi of allItems) {
2194
+ if (wi.status === 'done' || wi.status === 'cancelled')
2195
+ continue;
2196
+ const t = wi.target;
2197
+ if (typeof t === 'string' && t.length > 0)
2198
+ targetedSessions.add(t);
2199
+ }
2200
+ const filtered = baselineSessions.filter((s) => targetedSessions.has(s.name));
2201
+ const skipped = baselineSessions
2202
+ .filter((s) => !targetedSessions.has(s.name))
2203
+ .map((s) => s.name);
2204
+ if (skipped.length > 0) {
2205
+ this.logger.info('Skipping auto-restore for sessions with no pending WorkItem (idle agents stay dead until dispatched work arrives)', {
2206
+ skippedCount: skipped.length,
2207
+ skipped: skipped.slice(0, 20),
2208
+ truncated: skipped.length > 20,
2209
+ });
2210
+ }
2211
+ agentSessions = filtered;
2212
+ }
2213
+ catch (poolErr) {
2214
+ this.logger.warn('Auto-restore could not query task pool; falling back to restoring every persisted session', { error: poolErr instanceof Error ? poolErr.message : String(poolErr) });
2215
+ }
2056
2216
  if (agentSessions.length === 0) {
2057
- this.logger.debug('No non-orchestrator sessions to restore');
2217
+ this.logger.info('No persisted agent sessions to restore (all idle, no pending WorkItems)');
2058
2218
  return;
2059
2219
  }
2060
2220
  this.logger.info('Auto-restoring agent sessions from persisted state', {
@@ -2480,14 +2640,13 @@ export class CrewlyServer {
2480
2640
  if (req.sourceConversationItemId.startsWith('slack-')) {
2481
2641
  try {
2482
2642
  const { ThreadStatusQueueService } = await import('./services/messaging/thread-status-queue.service.js');
2643
+ const { extractSlackChannelId, extractSlackThreadTs } = await import('./services/v3/request-sla.subscriber.js');
2483
2644
  const tsq = ThreadStatusQueueService.getInstance();
2484
- // sourceConversationItemId format: "slack-{channelId}-{messageTs}"
2485
- // messageTs format in the ID uses hyphens: "1775935980-197679"
2486
- // Slack threadTs uses dots: "1775935980.197679"
2487
- const match = req.sourceConversationItemId.match(/^slack-(.+)-(\d+)[.-](\d+)$/);
2488
- if (match) {
2489
- const channelId = match[1];
2490
- const threadTs = `${match[2]}.${match[3]}`;
2645
+ // Use the canonical parser (handles both `slack-{ch}-{ts}` and
2646
+ // the thread-reply `slack-{ch}-{root}-msg-{msgTs}` shapes).
2647
+ const channelId = extractSlackChannelId(req.sourceConversationItemId);
2648
+ const threadTs = extractSlackThreadTs(req.sourceConversationItemId);
2649
+ if (channelId && threadTs) {
2491
2650
  const threadKey = `${channelId}:${threadTs}`;
2492
2651
  // Create entry if not tracked, then mark terminal
2493
2652
  if (!tsq.get(threadKey)) {
@@ -2684,6 +2843,11 @@ export class CrewlyServer {
2684
2843
  this.autoLearningSubscriber.stop();
2685
2844
  this.autoLearningSubscriber = null;
2686
2845
  }
2846
+ // DF-1 #438: same shutdown window as auto-learning above.
2847
+ if (this.milestoneNotificationSubscriber) {
2848
+ this.milestoneNotificationSubscriber.stop();
2849
+ this.milestoneNotificationSubscriber = null;
2850
+ }
2687
2851
  // INBOUND-1: stop the SLA subscriber and unset the module-level
2688
2852
  // references so a follow-up start() doesn't see stale singletons.
2689
2853
  if (this.requestSlaSubscriber) {