crewly 1.20.202 → 1.20.204

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 (230) hide show
  1. package/config/skills/agent/core/reply/SKILL.md +1 -0
  2. package/config/skills/agent/core/reply/execute.sh +7 -1
  3. package/config/skills/agent/core/reply-channel/SKILL.md +4 -0
  4. package/config/skills/agent/core/reply-channel/execute.sh +12 -1
  5. package/dist/backend/backend/src/constants.d.ts +158 -0
  6. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  7. package/dist/backend/backend/src/constants.js +158 -0
  8. package/dist/backend/backend/src/constants.js.map +1 -1
  9. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -1
  10. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +1 -0
  11. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -1
  12. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  13. package/dist/backend/backend/src/controllers/chat/chat.controller.js +11 -1
  14. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  15. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  16. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +50 -0
  17. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  18. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +6 -0
  19. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  20. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +30 -2
  21. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  22. package/dist/backend/backend/src/controllers/session/session.controller.d.ts.map +1 -1
  23. package/dist/backend/backend/src/controllers/session/session.controller.js +7 -0
  24. package/dist/backend/backend/src/controllers/session/session.controller.js.map +1 -1
  25. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  26. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +4 -1
  27. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  28. package/dist/backend/backend/src/index.d.ts +28 -0
  29. package/dist/backend/backend/src/index.d.ts.map +1 -1
  30. package/dist/backend/backend/src/index.js +141 -35
  31. package/dist/backend/backend/src/index.js.map +1 -1
  32. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  33. package/dist/backend/backend/src/services/agent/agent-registration.service.js +7 -0
  34. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  35. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  36. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +11 -0
  37. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  38. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts +22 -0
  39. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js +39 -3
  41. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  42. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.d.ts +140 -0
  43. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.d.ts.map +1 -0
  44. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.js +267 -0
  45. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.js.map +1 -0
  46. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +117 -0
  47. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +165 -9
  49. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.d.ts +93 -0
  51. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.d.ts.map +1 -0
  52. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.js +138 -0
  53. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.js.map +1 -0
  54. package/dist/backend/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/decisions/decision-card.js +5 -1
  56. package/dist/backend/backend/src/services/decisions/decision-card.js.map +1 -1
  57. package/dist/backend/backend/src/services/decisions/decision.service.d.ts +43 -1
  58. package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  59. package/dist/backend/backend/src/services/decisions/decision.service.js +110 -7
  60. package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
  61. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts +2 -0
  62. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts.map +1 -1
  63. package/dist/backend/backend/src/services/decisions/decision.wiring.js +1 -0
  64. package/dist/backend/backend/src/services/decisions/decision.wiring.js.map +1 -1
  65. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.d.ts +59 -0
  66. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.d.ts.map +1 -0
  67. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.js +70 -0
  68. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.js.map +1 -0
  69. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +46 -1
  70. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  71. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +109 -0
  72. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  73. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts +2 -0
  74. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +6 -0
  76. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
  77. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +51 -1
  78. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  79. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +73 -3
  80. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  81. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.d.ts +168 -0
  82. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.d.ts.map +1 -0
  83. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.js +280 -0
  84. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.js.map +1 -0
  85. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +21 -0
  86. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/open-items/open-items.service.js +72 -3
  88. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.d.ts +153 -0
  90. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.d.ts.map +1 -0
  91. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.js +276 -0
  92. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.js.map +1 -0
  93. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +16 -0
  94. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +22 -2
  96. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
  97. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +9 -0
  98. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -1
  99. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js +11 -0
  100. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -1
  101. package/dist/backend/backend/src/services/slack/room-responder.d.ts +144 -0
  102. package/dist/backend/backend/src/services/slack/room-responder.d.ts.map +1 -0
  103. package/dist/backend/backend/src/services/slack/room-responder.js +236 -0
  104. package/dist/backend/backend/src/services/slack/room-responder.js.map +1 -0
  105. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts +11 -2
  106. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +22 -1
  108. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  109. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  110. package/dist/backend/backend/src/services/slack/slack-initializer.js +64 -2
  111. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  112. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts +8 -2
  113. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts.map +1 -1
  114. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.js +7 -4
  115. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.js.map +1 -1
  116. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +148 -2
  117. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  118. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +784 -231
  119. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  120. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts +27 -0
  121. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  122. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +52 -0
  123. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  124. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +30 -5
  125. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  126. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +41 -8
  127. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  128. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +1 -0
  129. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  130. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +8 -3
  131. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  132. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts +13 -1
  133. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -1
  134. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js +36 -3
  135. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
  136. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +54 -3
  137. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  138. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +117 -9
  139. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  140. package/dist/backend/backend/src/types/decision.types.d.ts +7 -0
  141. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  142. package/dist/backend/build-info.json +2 -2
  143. package/dist/cli/backend/src/constants.d.ts +158 -0
  144. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  145. package/dist/cli/backend/src/constants.js +158 -0
  146. package/dist/cli/backend/src/constants.js.map +1 -1
  147. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  148. package/dist/cli/backend/src/services/agent/agent-registration.service.js +7 -0
  149. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  150. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  151. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +11 -0
  152. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  153. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts +22 -0
  154. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  155. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js +39 -3
  156. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  157. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.d.ts +140 -0
  158. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.d.ts.map +1 -0
  159. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.js +267 -0
  160. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.js.map +1 -0
  161. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +117 -0
  162. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  163. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +165 -9
  164. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  165. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.d.ts +93 -0
  166. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.d.ts.map +1 -0
  167. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.js +138 -0
  168. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.js.map +1 -0
  169. package/dist/cli/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  170. package/dist/cli/backend/src/services/decisions/decision-card.js +5 -1
  171. package/dist/cli/backend/src/services/decisions/decision-card.js.map +1 -1
  172. package/dist/cli/backend/src/services/decisions/decision.service.d.ts +43 -1
  173. package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  174. package/dist/cli/backend/src/services/decisions/decision.service.js +110 -7
  175. package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
  176. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +46 -1
  177. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  178. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +109 -0
  179. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  180. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +51 -1
  181. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  182. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +73 -3
  183. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  184. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +21 -0
  185. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  186. package/dist/cli/backend/src/services/open-items/open-items.service.js +72 -3
  187. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  188. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +9 -0
  189. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -1
  190. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js +11 -0
  191. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -1
  192. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts +66 -0
  193. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -0
  194. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js +211 -0
  195. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js.map +1 -0
  196. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +113 -0
  197. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -0
  198. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js +257 -0
  199. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -0
  200. package/dist/cli/backend/src/services/slack/room-responder.d.ts +144 -0
  201. package/dist/cli/backend/src/services/slack/room-responder.d.ts.map +1 -0
  202. package/dist/cli/backend/src/services/slack/room-responder.js +236 -0
  203. package/dist/cli/backend/src/services/slack/room-responder.js.map +1 -0
  204. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts +11 -2
  205. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  206. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +22 -1
  207. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  208. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +148 -2
  209. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  210. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +784 -231
  211. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  212. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts +27 -0
  213. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  214. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +52 -0
  215. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  216. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +30 -5
  217. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  218. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +41 -8
  219. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  220. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +1 -0
  221. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  222. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +8 -3
  223. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  224. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts +13 -1
  225. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -1
  226. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js +36 -3
  227. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
  228. package/dist/cli/backend/src/types/decision.types.d.ts +7 -0
  229. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  230. package/package.json +1 -1
@@ -68,6 +68,12 @@ import { getSlackAutoWorkingService } from './services/slack/slack-auto-working.
68
68
  import { getSlackAgentDmService } from './services/slack/slack-agent-dm.service.js';
69
69
  import { sendBootAnnouncement, isFirstBoot, markBooted } from './services/boot/boot-announce.service.js';
70
70
  import { SubAgentMessageQueue } from './services/messaging/sub-agent-message-queue.service.js';
71
+ import { InProcessTurnFailureService, setInProcessTurnFailureService } from './services/agent/in-process-turn-failure.service.js';
72
+ import { LivenessMonitorService } from './services/monitoring/liveness-monitor.service.js';
73
+ import { getOwnerMessageWatchdog } from './services/messaging/owner-message-watchdog.service.js';
74
+ import { parseInboundOrigin } from './services/orc/orc-reply-route.service.js';
75
+ import { parseSlackThreadKey } from './services/slack/slack-thread-key.js';
76
+ import { LIVENESS_MONITOR_CONSTANTS } from './constants.js';
71
77
  import { InputBlockedRetryService } from './services/messaging/input-blocked-retry.service.js';
72
78
  import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, AUTO_UPDATE_CONSTANTS, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS, TICKET_CONSTANTS, UNASSIGNED_ROUTE_CONSTANTS, CLOUD_TALK_CONSTANTS, STANDING_ANSWERS_CONSTANTS, TICKET_AUTOPILOT_CONSTANTS, EXPERIMENT_CONSTANTS, WORK_ITEM_DESTINATION_CONSTANTS, CODEX_USAGE_SYNC_CONSTANTS, ANTIGRAVITY_USAGE_SYNC_CONSTANTS, OWNER_AUTH_CONSTANTS } from './constants.js';
73
79
  import { PtyActivityTrackerService } from './services/agent/pty-activity-tracker.service.js';
@@ -300,6 +306,8 @@ export class CrewlyServer {
300
306
  /** Tells the owner on Slack when this machine loses Crewly Cloud */
301
307
  cloudDisconnectNotice = null;
302
308
  conversationCloudSync = null;
309
+ /** Gaps in this backend's life are told to the owner (crewly#1015 §12) */
310
+ livenessMonitor = null;
303
311
  waitingItemsSync = null;
304
312
  /** Epoch ms of the last shutdown signal acted on (dedups process-group delivery) */
305
313
  lastShutdownSignalAt = 0;
@@ -1319,6 +1327,8 @@ export class CrewlyServer {
1319
1327
  });
1320
1328
  this.wireSafeRestart();
1321
1329
  this.wireInputBlockedRetry();
1330
+ this.wireInProcessTurnFailure();
1331
+ this.startLivenessMonitor();
1322
1332
  // Shared LiveReconcilerDataProvider instance used by both the
1323
1333
  // Reconciler service and the TeamHealthWatchdog data provider.
1324
1334
  // Sharing is required so the memory-pressure broadcast state
@@ -3038,7 +3048,15 @@ export class CrewlyServer {
3038
3048
  // WorkItems have all finished since must not be replayed (#836).
3039
3049
  const { isStaleDispatchNotice } = await import('./services/v3/workitem-dispatch.subscriber.js');
3040
3050
  const agentMessageQueue = SubAgentMessageQueue.getInstance();
3041
- agentMessageQueue.setStaleMessageCheck((data) => isStaleDispatchNotice(data, (id) => TaskPoolService.getInstance().findWorkItem(id)));
3051
+ agentMessageQueue.setStaleMessageCheck((data, sessionName) => isStaleDispatchNotice(data, (id) => TaskPoolService.getInstance().findWorkItem(id), (id) => dispatchSubscriber.isDelivered(id, sessionName)));
3052
+ // A dispatch notice delivered from the queue marks its WorkItems as
3053
+ // delivered to that agent, so a held brief for the same WorkItem is
3054
+ // dropped instead of briefing it twice (crewly#1015 follow-up).
3055
+ const { dispatchNoticeWorkItemIds } = await import('./services/v3/workitem-dispatch.subscriber.js');
3056
+ agentMessageQueue.setDeliveredListener((sessionName, data) => {
3057
+ for (const id of dispatchNoticeWorkItemIds(data) ?? [])
3058
+ dispatchSubscriber.noteDeliveredFromQueue(id, sessionName);
3059
+ });
3042
3060
  void agentMessageQueue.pruneStale().catch((pruneErr) => {
3043
3061
  this.logger.warn('Could not prune stale queued dispatch notices (non-critical)', {
3044
3062
  error: pruneErr instanceof Error ? pruneErr.message : String(pruneErr),
@@ -4267,7 +4285,7 @@ export class CrewlyServer {
4267
4285
  this.logMemoryUsage();
4268
4286
  // A crashing process should not linger for the drain; its in-flight
4269
4287
  // turns are still persisted and resumed after the restart.
4270
- this.shutdown({ reason: 'uncaughtException', drain: false });
4288
+ this.shutdown({ reason: 'uncaughtException', drain: false, crashDetail: error.message });
4271
4289
  });
4272
4290
  process.on('unhandledRejection', (reason, promise) => {
4273
4291
  const message = unhandledRejectionMessage(reason);
@@ -4287,7 +4305,7 @@ export class CrewlyServer {
4287
4305
  stack: reason instanceof Error ? reason.stack : undefined
4288
4306
  });
4289
4307
  this.logMemoryUsage();
4290
- this.shutdown({ reason: 'unhandledRejection', drain: false });
4308
+ this.shutdown({ reason: 'unhandledRejection', drain: false, crashDetail: message });
4291
4309
  });
4292
4310
  }
4293
4311
  /**
@@ -5142,6 +5160,11 @@ export class CrewlyServer {
5142
5160
  this.messageQueueService.enqueue({ content: text, conversationId: 'system', source: 'system_event' });
5143
5161
  return true;
5144
5162
  },
5163
+ // An answer the asker could not take now waits on its queue (crewly#1015 §9).
5164
+ queueForAgent: (session, text) => {
5165
+ SubAgentMessageQueue.getInstance().enqueue(session, text);
5166
+ return true;
5167
+ },
5145
5168
  currentWorkItemId: async (session) => {
5146
5169
  const items = await TaskPoolService.getInstance().getAllItems().catch(() => []);
5147
5170
  const mine = items
@@ -5388,6 +5411,105 @@ export class CrewlyServer {
5388
5411
  });
5389
5412
  }
5390
5413
  }
5414
+ /**
5415
+ * Tell someone about a problem with an agent's messages: the chat the
5416
+ * message came from (when its header names one), and the orchestrator —
5417
+ * which can reach the owner anywhere — unless the orchestrator itself is
5418
+ * the agent: then the owner directly over Slack, and the orchestrator's
5419
+ * own chat when Slack is not set up (or the notice could not be sent).
5420
+ *
5421
+ * @param sessionName - The agent the notice is about
5422
+ * @param text - The notice (English harness text)
5423
+ * @param opts - A sample message (its `[CHAT:…]` header), a kind for the orchestrator queue key, the Slack title for the orchestrator case
5424
+ */
5425
+ tellAboutAgent(sessionName, text, opts) {
5426
+ // In the chat the message came from, when it names one…
5427
+ const chat = opts.sample ? /^\s*\[CHAT:([^\]\s:]+)/.exec(opts.sample) : null;
5428
+ if (chat) {
5429
+ try {
5430
+ getChatV2Service().recordTurn({ channelId: chat[1], senderType: 'system', senderId: 'crewly', content: text, metadata: { source: 'system' } });
5431
+ }
5432
+ catch {
5433
+ // The channel may be gone; the orchestrator still hears below.
5434
+ }
5435
+ }
5436
+ // …and to the orchestrator, unless it is the one in trouble.
5437
+ if (sessionName !== ORCHESTRATOR_SESSION_NAME) {
5438
+ this.messageQueueService.enqueue({ content: `[SYSTEM]\n${text}\n[/SYSTEM]`, conversationId: `system:${opts.kind}:${sessionName}`, source: 'system_event' });
5439
+ return;
5440
+ }
5441
+ const slack = getSlackService();
5442
+ const viaSlack = slack.isConnected()
5443
+ ? slack
5444
+ .sendNotification({ type: 'project_update', title: opts.title, message: text, urgency: 'high', timestamp: new Date().toISOString() })
5445
+ .then((sent) => sent !== false, () => false)
5446
+ : Promise.resolve(false);
5447
+ void viaSlack.then((sent) => {
5448
+ if (sent || chat)
5449
+ return;
5450
+ this.tellOrchestratorChat(text);
5451
+ });
5452
+ }
5453
+ /**
5454
+ * Liveness monitor (crewly#1015 §12): a gap in this backend's life (the
5455
+ * computer asleep, a stuck event loop, a stop without a clean shutdown)
5456
+ * is told to the owner by Slack DM once it is back.
5457
+ */
5458
+ startLivenessMonitor() {
5459
+ try {
5460
+ const dm = new SlackReloginDmService(() => getSlackService(), undefined, (agentSession) => getSlackAgentIdentityService()?.getInstalled(agentSession)?.botToken ?? null);
5461
+ this.livenessMonitor = new LivenessMonitorService({
5462
+ storePath: path.join(this.config.crewlyHome, LIVENESS_MONITOR_CONSTANTS.STORE_FILENAME),
5463
+ notifyOwner: async (text) => !!(await dm.sendToOwner(text, null, { title: 'Crewly was offline' })),
5464
+ machineName: () => os.hostname().replace(/\.local$/, ''),
5465
+ });
5466
+ this.livenessMonitor.start();
5467
+ }
5468
+ catch (error) {
5469
+ this.logger.warn('Liveness monitor not started', { error: error instanceof Error ? error.message : String(error) });
5470
+ }
5471
+ }
5472
+ /**
5473
+ * Failed turns of in-process agents (crewly#1015 §2): one re-delivery,
5474
+ * then the owner messages the agent owes are parked by the watchdog (the
5475
+ * owner told once) and the failure is reported — a member's to the
5476
+ * orchestrator, the orchestrator's to the owner.
5477
+ */
5478
+ wireInProcessTurnFailure() {
5479
+ try {
5480
+ setInProcessTurnFailureService(new InProcessTurnFailureService({
5481
+ redeliver: (sessionName, message) => this.apiController.agentRegistrationService.sendMessageToAgent(sessionName, message),
5482
+ noteOwnerMessages: async (sessionName, detail, opts) => {
5483
+ const { getOwnerMessageWatchdog } = await import('./services/messaging/owner-message-watchdog.service.js');
5484
+ return (await getOwnerMessageWatchdog()?.noteTurnFailed(sessionName, detail, opts)) ?? 0;
5485
+ },
5486
+ isOwnerStopped: (sessionName) => isOwnerStopped(sessionName),
5487
+ isRunning: (sessionName) => this.apiController.agentRegistrationService.isInProcessRuntimeActive(sessionName),
5488
+ queueForAgent: (sessionName, message) => SubAgentMessageQueue.getInstance().enqueue(sessionName, message),
5489
+ answeredSince: (_sessionName, message, since) => {
5490
+ const origin = parseInboundOrigin(message);
5491
+ const watchdog = getOwnerMessageWatchdog();
5492
+ if (!origin || !watchdog)
5493
+ return false;
5494
+ const key = parseSlackThreadKey(origin.slackThreadKey);
5495
+ if (key)
5496
+ return watchdog.answeredSince(`slack:${key.slackChannelId}:${key.threadTs}`, since);
5497
+ if (origin.slackChannelId && origin.slackThreadTs)
5498
+ return watchdog.answeredSince(`slack:${origin.slackChannelId}:${origin.slackThreadTs}`, since);
5499
+ return watchdog.answeredSince(`chat:${origin.conversationId}:`, since);
5500
+ },
5501
+ resumeOwnerMessages: async (sessionName) => {
5502
+ const { getOwnerMessageWatchdog } = await import('./services/messaging/owner-message-watchdog.service.js');
5503
+ return (await getOwnerMessageWatchdog()?.resumeAfterRecovery(sessionName)) ?? 0;
5504
+ },
5505
+ report: (sessionName, text, sample) => this.tellAboutAgent(sessionName, text, { sample, kind: 'turn-failed', title: 'Orchestrator runs failing' }),
5506
+ displayName: (sessionName) => (sessionName === ORCHESTRATOR_SESSION_NAME ? 'The orchestrator' : sessionName),
5507
+ }));
5508
+ }
5509
+ catch (error) {
5510
+ this.logger.warn('In-process turn failure handling not wired', { error: error instanceof Error ? error.message : String(error) });
5511
+ }
5512
+ }
5391
5513
  /**
5392
5514
  * Messages the input guard held back (crewly#1014) are retried on a timer
5393
5515
  * while the agent is idle, and the owner/orchestrator is told once when an
@@ -5398,38 +5520,7 @@ export class CrewlyServer {
5398
5520
  wireInputBlockedRetry() {
5399
5521
  try {
5400
5522
  const queue = SubAgentMessageQueue.getInstance();
5401
- const tell = (sessionName, text, sample) => {
5402
- // In the chat the held message came from, when it names one…
5403
- const chat = sample ? /^\s*\[CHAT:([^\]\s:]+)/.exec(sample) : null;
5404
- if (chat) {
5405
- try {
5406
- getChatV2Service().recordTurn({ channelId: chat[1], senderType: 'system', senderId: 'crewly', content: text, metadata: { source: 'system' } });
5407
- }
5408
- catch {
5409
- // The channel may be gone; the orchestrator still hears below.
5410
- }
5411
- }
5412
- // …and to the orchestrator, which can reach the owner anywhere —
5413
- // unless the orchestrator itself is the one blocked: then the
5414
- // owner directly, over Slack, and in the orchestrator's own chat
5415
- // when Slack is not set up (or the notice could not be sent).
5416
- if (sessionName !== ORCHESTRATOR_SESSION_NAME) {
5417
- this.messageQueueService.enqueue({ content: `[SYSTEM]\n${text}\n[/SYSTEM]`, conversationId: `system:input-blocked:${sessionName}`, source: 'system_event' });
5418
- }
5419
- else {
5420
- const slack = getSlackService();
5421
- const viaSlack = slack.isConnected()
5422
- ? slack
5423
- .sendNotification({ type: 'project_update', title: 'Orchestrator input blocked', message: text, urgency: 'high', timestamp: new Date().toISOString() })
5424
- .then((sent) => sent !== false, () => false)
5425
- : Promise.resolve(false);
5426
- void viaSlack.then((sent) => {
5427
- if (sent || chat)
5428
- return;
5429
- this.tellOrchestratorChat(text);
5430
- });
5431
- }
5432
- };
5523
+ const tell = (sessionName, text, sample) => this.tellAboutAgent(sessionName, text, { sample, kind: 'input-blocked', title: 'Orchestrator input blocked' });
5433
5524
  InputBlockedRetryService.getInstance().setDeps({
5434
5525
  hasQueued: (session) => queue.hasPending(session),
5435
5526
  isIdle: (session) => this.activityMonitorService.getObservedWorkingStatus(session) !== 'in_progress',
@@ -5447,6 +5538,12 @@ export class CrewlyServer {
5447
5538
  tell(notice.sessionName, `Messages to ${notice.sessionName} are waiting: ${what}. Crewly will not type over it. Tried ${notice.refusals} times over ${minutes} min; it keeps retrying. Clear the agent's input (or answer its screen) to let them through.`, notice.message);
5448
5539
  },
5449
5540
  });
5541
+ // A WorkItem brief held by the restart drain gets its hand-over
5542
+ // (dispatcher dedup, fresh conversation) when it is delivered.
5543
+ queue.setHandOverPreparer(async (sessionName, workItemId, data) => {
5544
+ const { prepareWorkItemHandOver } = await import('./controllers/monitoring/terminal.controller.js');
5545
+ return prepareWorkItemHandOver(sessionName, workItemId, data);
5546
+ });
5450
5547
  queue.setDropListener((sessionName, dropped, reason) => {
5451
5548
  const why = reason === 'aged-out'
5452
5549
  ? 'they were older than the queue keeps after a restart'
@@ -5610,6 +5707,15 @@ export class CrewlyServer {
5610
5707
  }
5611
5708
  this.isShuttingDown = true;
5612
5709
  const exitCode = options.exitCode ?? PROCESS_EXIT_CODES.SUCCESS;
5710
+ // A shutdown on purpose: the next boot must not report an unclean stop.
5711
+ // A crash handler's shutdown is recorded as a crash, so the next boot
5712
+ // tells the owner (crewly#1015 §12).
5713
+ if (options.reason === 'uncaughtException' || options.reason === 'unhandledRejection') {
5714
+ this.livenessMonitor?.markCrash(options.crashDetail ? `${options.reason}: ${options.crashDetail}` : options.reason);
5715
+ }
5716
+ else {
5717
+ this.livenessMonitor?.markCleanShutdown();
5718
+ }
5613
5719
  this.logger.info('Shutting down Crewly server...', { reason: options.reason ?? 'unspecified' });
5614
5720
  AutoUpdateService.getInstance()?.stop();
5615
5721
  this.cloudDisconnectNotice?.stop();