crewly 1.2.4 → 1.2.6

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 (286) hide show
  1. package/LICENSE +1 -1
  2. package/config/constants.ts +4 -2
  3. package/config/roles/auditor/prompt.md +84 -0
  4. package/config/roles/orchestrator/prompt.md +62 -7
  5. package/config/runtime_scripts/runtime-config.json +5 -5
  6. package/config/skills/orchestrator/cancel-all-schedules/execute.sh +24 -0
  7. package/config/skills/orchestrator/cancel-all-schedules/instructions.md +23 -0
  8. package/config/skills/orchestrator/cancel-all-schedules/skill.json +17 -0
  9. package/config/skills/orchestrator/list-schedules/execute.sh +19 -0
  10. package/config/skills/orchestrator/list-schedules/instructions.md +24 -0
  11. package/config/skills/orchestrator/list-schedules/skill.json +12 -0
  12. package/dist/backend/backend/src/constants.d.ts +53 -13
  13. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  14. package/dist/backend/backend/src/constants.js +54 -16
  15. package/dist/backend/backend/src/constants.js.map +1 -1
  16. package/dist/backend/backend/src/controllers/auditor/auditor.controller.d.ts +37 -0
  17. package/dist/backend/backend/src/controllers/auditor/auditor.controller.d.ts.map +1 -0
  18. package/dist/backend/backend/src/controllers/auditor/auditor.controller.js +64 -0
  19. package/dist/backend/backend/src/controllers/auditor/auditor.controller.js.map +1 -0
  20. package/dist/backend/backend/src/controllers/auditor/auditor.routes.d.ts +15 -0
  21. package/dist/backend/backend/src/controllers/auditor/auditor.routes.d.ts.map +1 -0
  22. package/dist/backend/backend/src/controllers/auditor/auditor.routes.js +23 -0
  23. package/dist/backend/backend/src/controllers/auditor/auditor.routes.js.map +1 -0
  24. package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.d.ts +23 -0
  25. package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.d.ts.map +1 -0
  26. package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.js +42 -0
  27. package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.js.map +1 -0
  28. package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.d.ts +56 -0
  29. package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.d.ts.map +1 -0
  30. package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.js +173 -0
  31. package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.js.map +1 -0
  32. package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.d.ts +22 -0
  33. package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.d.ts.map +1 -0
  34. package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.js +33 -0
  35. package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.js.map +1 -0
  36. package/dist/backend/backend/src/controllers/cloud/admin/index.d.ts +7 -0
  37. package/dist/backend/backend/src/controllers/cloud/admin/index.d.ts.map +1 -0
  38. package/dist/backend/backend/src/controllers/cloud/admin/index.js +7 -0
  39. package/dist/backend/backend/src/controllers/cloud/admin/index.js.map +1 -0
  40. package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.d.ts +1 -1
  41. package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.js +5 -5
  42. package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.js.map +1 -1
  43. package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
  44. package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +0 -3
  45. package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
  46. package/dist/backend/backend/src/controllers/cloud/index.d.ts +0 -5
  47. package/dist/backend/backend/src/controllers/cloud/index.d.ts.map +1 -1
  48. package/dist/backend/backend/src/controllers/cloud/index.js +0 -5
  49. package/dist/backend/backend/src/controllers/cloud/index.js.map +1 -1
  50. package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts +6 -45
  51. package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts.map +1 -1
  52. package/dist/backend/backend/src/controllers/cloud/relay.controller.js +6 -165
  53. package/dist/backend/backend/src/controllers/cloud/relay.controller.js.map +1 -1
  54. package/dist/backend/backend/src/controllers/cloud/relay.routes.d.ts +5 -9
  55. package/dist/backend/backend/src/controllers/cloud/relay.routes.d.ts.map +1 -1
  56. package/dist/backend/backend/src/controllers/cloud/relay.routes.js +11 -21
  57. package/dist/backend/backend/src/controllers/cloud/relay.routes.js.map +1 -1
  58. package/dist/backend/backend/src/controllers/cloud/tasks/index.d.ts +5 -2
  59. package/dist/backend/backend/src/controllers/cloud/tasks/index.d.ts.map +1 -1
  60. package/dist/backend/backend/src/controllers/cloud/tasks/index.js +5 -2
  61. package/dist/backend/backend/src/controllers/cloud/tasks/index.js.map +1 -1
  62. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts +6 -2
  63. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts.map +1 -1
  64. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js +12 -8
  65. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js.map +1 -1
  66. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  67. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +32 -4
  68. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  69. package/dist/backend/backend/src/controllers/payment/payment.controller.d.ts +16 -5
  70. package/dist/backend/backend/src/controllers/payment/payment.controller.d.ts.map +1 -1
  71. package/dist/backend/backend/src/controllers/payment/payment.controller.js +6 -6
  72. package/dist/backend/backend/src/controllers/payment/payment.controller.js.map +1 -1
  73. package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts +6 -2
  74. package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts.map +1 -1
  75. package/dist/backend/backend/src/controllers/payment/payment.routes.js +22 -8
  76. package/dist/backend/backend/src/controllers/payment/payment.routes.js.map +1 -1
  77. package/dist/backend/backend/src/controllers/payment/payment.types.d.ts +1 -1
  78. package/dist/backend/backend/src/controllers/payment/payment.types.d.ts.map +1 -1
  79. package/dist/backend/backend/src/controllers/payment/payment.types.js +1 -1
  80. package/dist/backend/backend/src/controllers/payment/payment.types.js.map +1 -1
  81. package/dist/backend/backend/src/controllers/request-types.d.ts +2 -2
  82. package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
  83. package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts +19 -0
  84. package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts.map +1 -1
  85. package/dist/backend/backend/src/controllers/system/scheduler.controller.js +51 -0
  86. package/dist/backend/backend/src/controllers/system/scheduler.controller.js.map +1 -1
  87. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  88. package/dist/backend/backend/src/controllers/team/team.controller.js +13 -5
  89. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  90. package/dist/backend/backend/src/controllers/template/template.controller.d.ts.map +1 -1
  91. package/dist/backend/backend/src/controllers/template/template.controller.js +2 -2
  92. package/dist/backend/backend/src/controllers/template/template.controller.js.map +1 -1
  93. package/dist/backend/backend/src/index.d.ts.map +1 -1
  94. package/dist/backend/backend/src/index.js +31 -30
  95. package/dist/backend/backend/src/index.js.map +1 -1
  96. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  97. package/dist/backend/backend/src/routes/api.routes.js +4 -12
  98. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  99. package/dist/backend/backend/src/routes/modules/log-rotation.routes.d.ts +8 -0
  100. package/dist/backend/backend/src/routes/modules/log-rotation.routes.d.ts.map +1 -0
  101. package/dist/backend/backend/src/routes/modules/log-rotation.routes.js +62 -0
  102. package/dist/backend/backend/src/routes/modules/log-rotation.routes.js.map +1 -0
  103. package/dist/backend/backend/src/routes/modules/scheduler.routes.d.ts.map +1 -1
  104. package/dist/backend/backend/src/routes/modules/scheduler.routes.js +2 -0
  105. package/dist/backend/backend/src/routes/modules/scheduler.routes.js.map +1 -1
  106. package/dist/backend/backend/src/scripts/run-log-rotation.d.ts +3 -0
  107. package/dist/backend/backend/src/scripts/run-log-rotation.d.ts.map +1 -0
  108. package/dist/backend/backend/src/scripts/run-log-rotation.js +31 -0
  109. package/dist/backend/backend/src/scripts/run-log-rotation.js.map +1 -0
  110. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +10 -0
  111. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  112. package/dist/backend/backend/src/services/agent/agent-registration.service.js +85 -1
  113. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  114. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts +150 -0
  115. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -0
  116. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js +307 -0
  117. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js.map +1 -0
  118. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +105 -0
  119. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -0
  120. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +199 -0
  121. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -0
  122. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts +68 -0
  123. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts.map +1 -0
  124. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js +131 -0
  125. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js.map +1 -0
  126. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts +29 -0
  127. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -0
  128. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +229 -0
  129. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -0
  130. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +127 -0
  131. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -0
  132. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +242 -0
  133. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -0
  134. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts +95 -0
  135. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts.map +1 -0
  136. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.js +130 -0
  137. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.js.map +1 -0
  138. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +14 -0
  139. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +1 -0
  140. package/dist/backend/backend/src/services/agent/crewly-agent/index.js +14 -0
  141. package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +1 -0
  142. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +57 -0
  143. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -0
  144. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +93 -0
  145. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -0
  146. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts +13 -0
  147. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts.map +1 -0
  148. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +91 -0
  149. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js.map +1 -0
  150. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +29 -0
  151. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -0
  152. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +519 -0
  153. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -0
  154. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +159 -0
  155. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -0
  156. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +63 -0
  157. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -0
  158. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +56 -1
  159. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  160. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +273 -215
  161. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  162. package/dist/backend/backend/src/services/agent/runtime-service.factory.js +8 -8
  163. package/dist/backend/backend/src/services/agent/runtime-service.factory.js.map +1 -1
  164. package/dist/backend/backend/src/services/chat/chat.service.d.ts +7 -1
  165. package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
  166. package/dist/backend/backend/src/services/chat/chat.service.js +14 -5
  167. package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
  168. package/dist/backend/backend/src/services/cloud/admin-seed.service.d.ts +18 -0
  169. package/dist/backend/backend/src/services/cloud/admin-seed.service.d.ts.map +1 -0
  170. package/dist/backend/backend/src/services/cloud/admin-seed.service.js +50 -0
  171. package/dist/backend/backend/src/services/cloud/admin-seed.service.js.map +1 -0
  172. package/dist/backend/backend/src/services/cloud/cloud-features.d.ts +19 -0
  173. package/dist/backend/backend/src/services/cloud/cloud-features.d.ts.map +1 -0
  174. package/dist/backend/backend/src/services/cloud/cloud-features.js +23 -0
  175. package/dist/backend/backend/src/services/cloud/cloud-features.js.map +1 -0
  176. package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.d.ts +3 -3
  177. package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.d.ts.map +1 -1
  178. package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.js +10 -6
  179. package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.js.map +1 -1
  180. package/dist/backend/backend/src/services/cloud/mongodb.service.d.ts +45 -0
  181. package/dist/backend/backend/src/services/cloud/mongodb.service.d.ts.map +1 -0
  182. package/dist/backend/backend/src/services/cloud/mongodb.service.js +76 -0
  183. package/dist/backend/backend/src/services/cloud/mongodb.service.js.map +1 -0
  184. package/dist/backend/backend/src/services/cloud/relay-server.service.d.ts +0 -2
  185. package/dist/backend/backend/src/services/cloud/relay-server.service.d.ts.map +1 -1
  186. package/dist/backend/backend/src/services/cloud/relay-server.service.js +7 -36
  187. package/dist/backend/backend/src/services/cloud/relay-server.service.js.map +1 -1
  188. package/dist/backend/backend/src/services/continuation/continuation.service.d.ts.map +1 -1
  189. package/dist/backend/backend/src/services/continuation/continuation.service.js +5 -10
  190. package/dist/backend/backend/src/services/continuation/continuation.service.js.map +1 -1
  191. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +10 -2
  192. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  193. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +47 -12
  194. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  195. package/dist/backend/backend/src/services/mcp-server.js +1 -1
  196. package/dist/backend/backend/src/services/mcp-server.js.map +1 -1
  197. package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts.map +1 -1
  198. package/dist/backend/backend/src/services/messaging/message-queue.service.js +1 -0
  199. package/dist/backend/backend/src/services/messaging/message-queue.service.js.map +1 -1
  200. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  201. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +22 -4
  202. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  203. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  204. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +6 -0
  205. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  206. package/dist/backend/backend/src/services/payment/stripe.service.d.ts +4 -43
  207. package/dist/backend/backend/src/services/payment/stripe.service.d.ts.map +1 -1
  208. package/dist/backend/backend/src/services/payment/stripe.service.js +56 -180
  209. package/dist/backend/backend/src/services/payment/stripe.service.js.map +1 -1
  210. package/dist/backend/backend/src/services/session/index.d.ts +2 -0
  211. package/dist/backend/backend/src/services/session/index.d.ts.map +1 -1
  212. package/dist/backend/backend/src/services/session/index.js +2 -0
  213. package/dist/backend/backend/src/services/session/index.js.map +1 -1
  214. package/dist/backend/backend/src/services/session/log-rotation.service.d.ts +163 -0
  215. package/dist/backend/backend/src/services/session/log-rotation.service.d.ts.map +1 -0
  216. package/dist/backend/backend/src/services/session/log-rotation.service.js +362 -0
  217. package/dist/backend/backend/src/services/session/log-rotation.service.js.map +1 -0
  218. package/dist/backend/backend/src/services/settings/settings.service.js +1 -1
  219. package/dist/backend/backend/src/services/settings/settings.service.js.map +1 -1
  220. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +11 -0
  221. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  222. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +83 -1
  223. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  224. package/dist/backend/backend/src/services/template/template.service.d.ts +9 -44
  225. package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -1
  226. package/dist/backend/backend/src/services/template/template.service.js +7 -80
  227. package/dist/backend/backend/src/services/template/template.service.js.map +1 -1
  228. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +35 -0
  229. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  230. package/dist/backend/backend/src/services/workflow/scheduler.service.js +133 -0
  231. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  232. package/dist/backend/backend/src/types/chat.types.d.ts +1 -1
  233. package/dist/backend/backend/src/types/chat.types.d.ts.map +1 -1
  234. package/dist/backend/backend/src/types/chat.types.js +21 -17
  235. package/dist/backend/backend/src/types/chat.types.js.map +1 -1
  236. package/dist/backend/backend/src/types/event-bus.types.d.ts +31 -0
  237. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  238. package/dist/backend/backend/src/types/event-bus.types.js +50 -0
  239. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  240. package/dist/backend/backend/src/types/index.d.ts +1 -1
  241. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  242. package/dist/backend/backend/src/types/messaging.types.d.ts +4 -0
  243. package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
  244. package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
  245. package/dist/backend/backend/src/types/settings.types.d.ts +1 -1
  246. package/dist/backend/backend/src/types/settings.types.d.ts.map +1 -1
  247. package/dist/backend/backend/src/types/settings.types.js +4 -4
  248. package/dist/backend/backend/src/types/settings.types.js.map +1 -1
  249. package/dist/backend/backend/src/types/team-template.types.d.ts +2 -2
  250. package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
  251. package/dist/backend/backend/src/types/team-template.types.js +1 -1
  252. package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
  253. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +4 -4
  254. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  255. package/dist/backend/backend/src/websocket/terminal.gateway.js +9 -6
  256. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  257. package/dist/backend/config/constants.d.ts +4 -2
  258. package/dist/backend/config/constants.d.ts.map +1 -1
  259. package/dist/backend/config/constants.js +4 -2
  260. package/dist/backend/config/constants.js.map +1 -1
  261. package/dist/cli/backend/src/constants.d.ts +53 -13
  262. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  263. package/dist/cli/backend/src/constants.js +54 -16
  264. package/dist/cli/backend/src/constants.js.map +1 -1
  265. package/dist/cli/backend/src/services/mcp-server.js +1 -1
  266. package/dist/cli/backend/src/services/mcp-server.js.map +1 -1
  267. package/dist/cli/backend/src/types/chat.types.d.ts +1 -1
  268. package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -1
  269. package/dist/cli/backend/src/types/chat.types.js +21 -17
  270. package/dist/cli/backend/src/types/chat.types.js.map +1 -1
  271. package/dist/cli/backend/src/types/index.d.ts +1 -1
  272. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  273. package/dist/cli/backend/src/types/settings.types.d.ts +1 -1
  274. package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -1
  275. package/dist/cli/backend/src/types/settings.types.js +4 -4
  276. package/dist/cli/backend/src/types/settings.types.js.map +1 -1
  277. package/dist/cli/config/constants.d.ts +4 -2
  278. package/dist/cli/config/constants.d.ts.map +1 -1
  279. package/dist/cli/config/constants.js +4 -2
  280. package/dist/cli/config/constants.js.map +1 -1
  281. package/frontend/dist/assets/index-3558d1a2.js +4919 -0
  282. package/frontend/dist/assets/index-4c4dcc31.css +33 -0
  283. package/frontend/dist/index.html +2 -2
  284. package/package.json +15 -9
  285. package/frontend/dist/assets/index-510ab719.css +0 -33
  286. package/frontend/dist/assets/index-935cd846.js +0 -4961
@@ -185,6 +185,10 @@ export class RuntimeExitMonitorService {
185
185
  /**
186
186
  * Stop monitoring a PTY session.
187
187
  *
188
+ * Also prunes the restartHistory entry for this session if it has no
189
+ * recent timestamps within the cooldown window, preventing slow memory
190
+ * leak for terminated sessions.
191
+ *
188
192
  * @param sessionName - PTY session name
189
193
  */
190
194
  stopMonitoring(sessionName) {
@@ -200,6 +204,21 @@ export class RuntimeExitMonitorService {
200
204
  }
201
205
  monitored.unsubscribe();
202
206
  this.sessions.delete(sessionName);
207
+ // Fix 3: Clean up restartHistory for terminated sessions to prevent
208
+ // unbounded Map growth. Keep the entry only if it has recent timestamps
209
+ // within the cooldown window (they may still be needed if the session
210
+ // is restarted soon). Delete the entry entirely otherwise.
211
+ const timestamps = this.restartHistory.get(sessionName);
212
+ if (timestamps) {
213
+ const windowStart = Date.now() - AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS;
214
+ const recent = timestamps.filter(ts => ts > windowStart);
215
+ if (recent.length === 0) {
216
+ this.restartHistory.delete(sessionName);
217
+ }
218
+ else {
219
+ this.restartHistory.set(sessionName, recent);
220
+ }
221
+ }
203
222
  this.logger.debug('Stopped runtime exit monitoring', { sessionName });
204
223
  }
205
224
  /**
@@ -252,6 +271,10 @@ export class RuntimeExitMonitorService {
252
271
  /**
253
272
  * Confirm exit by checking for a shell prompt, then react.
254
273
  *
274
+ * Runtime-specific failure checks are gated by runtimeType so that
275
+ * patterns for one runtime cannot accidentally match another (e.g. a
276
+ * Codex exit matching Claude or Gemini patterns).
277
+ *
255
278
  * For Gemini CLI failure patterns (API errors, quota exhaustion, etc.),
256
279
  * the system retries with exponential backoff before declaring the agent
257
280
  * dead. Gemini CLI often recovers automatically from transient API errors
@@ -272,58 +295,11 @@ export class RuntimeExitMonitorService {
272
295
  // Verify shell prompt is visible (avoids false positives)
273
296
  const shellPromptConfirmed = this.verifyExitWithShellPrompt(sessionName, helper);
274
297
  if (!shellPromptConfirmed) {
275
- // Codex: "Conversation interrupted" indicates the run was aborted and
276
- // often leaves the agent stranded without completion callbacks. Treat it
277
- // as an actionable runtime failure even if shell prompt isn't visible.
278
- const isCodexInterrupted = monitored.runtimeType === RUNTIME_TYPES.CODEX_CLI
279
- && /Conversation interrupted/i.test(monitored.buffer);
280
- if (isCodexInterrupted) {
281
- this.logger.warn('Codex interruption detected, proceeding with recovery flow', {
282
- sessionName,
283
- });
284
- // fall through to exit/restart handling below
285
- }
286
- // Claude Code: detect fatal API errors that make the CLI permanently
287
- // non-functional (e.g. thinking block corruption). These are unrecoverable
288
- // — no retry will help, immediate restart is required.
289
- const isClaudeFatal = monitored.runtimeType === RUNTIME_TYPES.CLAUDE_CODE
290
- && CLAUDE_FATAL_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
291
- if (isClaudeFatal) {
292
- const detectedPattern = CLAUDE_FATAL_PATTERNS.find((p) => p.test(monitored.buffer))?.source;
293
- this.logger.warn('Claude Code fatal error detected, forcing immediate recovery', {
294
- sessionName,
295
- detectedPattern,
296
- });
297
- // fall through to exit/restart handling below (no retry)
298
- }
299
- // For Gemini CLI: detect either retryable failure patterns or forced
300
- // restart/update markers that require immediate recovery handling.
301
- const isGeminiFailure = monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI
302
- && GEMINI_FAILURE_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
303
- const isGeminiForceRestart = monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI
304
- && GEMINI_FORCE_RESTART_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
305
- if (!isGeminiFailure && !isGeminiForceRestart && !isCodexInterrupted && !isClaudeFatal) {
298
+ const runtimeSpecificMatch = await this.checkRuntimeSpecificFailure(sessionName, monitored, helper);
299
+ if (!runtimeSpecificMatch) {
306
300
  this.logger.debug('Exit pattern matched but shell prompt not confirmed, ignoring', { sessionName });
307
301
  return;
308
302
  }
309
- if (isGeminiFailure || isGeminiForceRestart) {
310
- // Some Gemini failures are transient; others (auto-update/restart)
311
- // should trigger immediate recovery and task re-delivery.
312
- if (isGeminiForceRestart) {
313
- this.logger.warn('Gemini auto-update interruption detected, forcing recovery flow', {
314
- sessionName,
315
- });
316
- }
317
- else {
318
- // Retry with exponential backoff before declaring exit.
319
- // Gemini CLI can recover from transient API errors automatically.
320
- const retryResult = await this.handleGeminiFailureWithRetry(sessionName, monitored, helper);
321
- if (retryResult === 'recovered' || retryResult === 'deferred') {
322
- return;
323
- }
324
- // retryResult === 'exhausted' — fall through to exit flow
325
- }
326
- }
327
303
  }
328
304
  // Mark as detected to prevent double-processing
329
305
  monitored.exitDetected = true;
@@ -333,199 +309,281 @@ export class RuntimeExitMonitorService {
333
309
  role: monitored.role,
334
310
  });
335
311
  // Fire the exit-detected callback (used to cancel pending registrations)
336
- if (this.onExitDetectedCallback) {
337
- try {
338
- this.onExitDetectedCallback(sessionName);
339
- }
340
- catch (error) {
341
- this.logger.warn('onExitDetected callback error', {
342
- sessionName,
343
- error: error instanceof Error ? error.message : String(error),
344
- });
345
- }
346
- }
347
- // Check for in-progress tasks — restart agent if any exist (non-orchestrator only)
312
+ this.fireExitDetectedCallback(sessionName);
313
+ // Try agent restart if it has in-progress tasks (non-orchestrator only)
348
314
  if (monitored.role !== ORCHESTRATOR_ROLE && this.agentRegistrationService && this.taskTrackingService) {
349
- try {
350
- const tasks = await this.taskTrackingService.getTasksForTeamMember(monitored.memberId || '');
351
- const activeTasks = tasks.filter(t => t.status === 'assigned' || t.status === 'active' || t.status === 'pending_assignment');
352
- if (activeTasks.length > 0) {
353
- // Check cooldown before attempting restart to prevent infinite
354
- // restart loops (e.g. during network outages where agents keep crashing)
355
- if (!this.isAgentRestartAllowed(sessionName)) {
356
- this.logger.warn('Agent restart cooldown active, skipping restart', {
357
- sessionName,
358
- activeTaskCount: activeTasks.length,
359
- maxRestartsPerWindow: AGENT_HEARTBEAT_MONITOR_CONSTANTS.MAX_RESTARTS_PER_WINDOW,
360
- cooldownWindowMs: AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS,
361
- });
362
- this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited_cooldown', activeTasks, false);
363
- // Fall through to normal inactive flow
364
- }
365
- else {
366
- this.logger.info('Runtime exit with in-progress tasks, attempting restart', {
367
- sessionName,
368
- activeTaskCount: activeTasks.length,
369
- });
370
- try {
371
- await this.restartAgentWithTasks(sessionName, monitored, activeTasks);
372
- this.recordAgentRestart(sessionName);
373
- // Notify orchestrator that agent was restarted (#129)
374
- this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, true);
375
- // Cleanup this subscription (restart succeeded, skip inactive flow)
376
- this.stopMonitoring(sessionName);
377
- return;
378
- }
379
- catch (restartError) {
380
- this.logger.warn('Agent restart after runtime exit failed, falling back to inactive', {
381
- sessionName,
382
- error: restartError instanceof Error ? restartError.message : String(restartError),
383
- });
384
- // Record the attempt even on failure to prevent rapid retry loops
385
- this.recordAgentRestart(sessionName);
386
- // Notify orchestrator that restart failed — needs manual intervention (#129)
387
- this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, false);
388
- // Fall through to normal inactive flow
389
- }
390
- }
391
- }
392
- }
393
- catch (error) {
394
- this.logger.warn('Failed to check in-progress tasks after runtime exit', {
395
- sessionName,
396
- error: error instanceof Error ? error.message : String(error),
397
- });
398
- // Fall through to normal inactive flow
399
- }
315
+ const restarted = await this.tryAgentRestartWithTasks(sessionName, monitored);
316
+ if (restarted)
317
+ return;
400
318
  }
401
- // Orchestrator-specific restart: attempt auto-restart when runtime exits
319
+ // Orchestrator-specific restart
402
320
  if (sessionName === ORCHESTRATOR_SESSION_NAME) {
403
- // CRITICAL: Set status to inactive BEFORE restart so the queue
404
- // processor doesn't deliver messages during postInitialize.
405
- // Without this, the old 'active' status persists in storage and
406
- // the queue processor sends chat messages that get concatenated
407
- // into /directory add commands in the new Gemini CLI session.
408
- try {
409
- const storageService = StorageService.getInstance();
410
- await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
411
- }
412
- catch {
413
- // Best-effort — continue with restart
414
- }
415
- // Capture session memory before restart
416
- try {
417
- const sessionMemoryService = SessionMemoryService.getInstance();
418
- await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
419
- }
420
- catch (error) {
421
- this.logger.warn('Failed to capture session memory before orchestrator restart', {
422
- sessionName,
423
- error: error instanceof Error ? error.message : String(error),
424
- });
321
+ const restarted = await this.tryOrchestratorRestart(sessionName, monitored);
322
+ if (restarted)
323
+ return;
324
+ }
325
+ // Normal inactive flow: update status, capture memory, broadcast
326
+ await this.transitionToInactive(sessionName, monitored);
327
+ // Cleanup this subscription
328
+ this.stopMonitoring(sessionName);
329
+ }
330
+ finally {
331
+ monitored.confirmationInFlight = false;
332
+ }
333
+ }
334
+ /**
335
+ * Check for runtime-specific failure patterns when shell prompt is not confirmed.
336
+ *
337
+ * Gated by runtimeType so patterns for one runtime cannot accidentally
338
+ * match another. Returns true if a runtime-specific failure was detected,
339
+ * or 'deferred' handling occurred (Gemini retry).
340
+ *
341
+ * @param sessionName - PTY session name
342
+ * @param monitored - Monitored session state
343
+ * @param helper - Session command helper
344
+ * @returns True if a runtime-specific failure was confirmed
345
+ */
346
+ async checkRuntimeSpecificFailure(sessionName, monitored, helper) {
347
+ if (monitored.runtimeType === RUNTIME_TYPES.CODEX_CLI) {
348
+ const isCodexInterrupted = /Conversation interrupted/i.test(monitored.buffer);
349
+ if (isCodexInterrupted) {
350
+ this.logger.warn('Codex interruption detected, proceeding with recovery flow', { sessionName });
351
+ return true;
352
+ }
353
+ }
354
+ else if (monitored.runtimeType === RUNTIME_TYPES.CLAUDE_CODE) {
355
+ const isClaudeFatal = CLAUDE_FATAL_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
356
+ if (isClaudeFatal) {
357
+ const detectedPattern = CLAUDE_FATAL_PATTERNS.find((p) => p.test(monitored.buffer))?.source;
358
+ this.logger.warn('Claude Code fatal error detected, forcing immediate recovery', {
359
+ sessionName,
360
+ detectedPattern,
361
+ });
362
+ return true;
363
+ }
364
+ }
365
+ else if (monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI) {
366
+ const isGeminiFailure = GEMINI_FAILURE_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
367
+ const isGeminiForceRestart = GEMINI_FORCE_RESTART_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
368
+ if (isGeminiFailure || isGeminiForceRestart) {
369
+ if (isGeminiForceRestart) {
370
+ this.logger.warn('Gemini auto-update interruption detected, forcing recovery flow', { sessionName });
425
371
  }
426
- try {
427
- const restartService = OrchestratorRestartService.getInstance();
428
- const success = await restartService.attemptRestart();
429
- if (success) {
430
- this.logger.info('Orchestrator restarted after runtime exit', { sessionName });
431
- // Broadcast restarted status as STARTED (not ACTIVE).
432
- // The agent becomes ACTIVE only after the registration prompt
433
- // is fully processed and the MCP registration call completes.
434
- // Broadcasting ACTIVE prematurely causes the queue processor
435
- // to deliver messages during postInitialize.
436
- try {
437
- const terminalGateway = getTerminalGateway();
438
- if (terminalGateway) {
439
- terminalGateway.broadcastOrchestratorStatus({
440
- sessionName,
441
- agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.STARTED,
442
- reason: 'runtime_exit_restart',
443
- });
444
- }
445
- }
446
- catch {
447
- // Best-effort broadcast
448
- }
449
- this.stopMonitoring(sessionName);
450
- return;
372
+ else {
373
+ const retryResult = await this.handleGeminiFailureWithRetry(sessionName, monitored, helper);
374
+ if (retryResult === 'recovered' || retryResult === 'deferred') {
375
+ return false; // Not a confirmed exit — caller should return early
451
376
  }
452
- this.logger.warn('Orchestrator restart after runtime exit failed or not allowed, falling back to inactive', {
453
- sessionName,
454
- });
455
- }
456
- catch (error) {
457
- this.logger.warn('Orchestrator restart attempt threw error, falling back to inactive', {
458
- sessionName,
459
- error: error instanceof Error ? error.message : String(error),
460
- });
461
377
  }
462
- // Fall through to normal inactive flow
378
+ return true;
379
+ }
380
+ }
381
+ return false;
382
+ }
383
+ /**
384
+ * Fire the onExitDetected callback safely.
385
+ *
386
+ * @param sessionName - PTY session name
387
+ */
388
+ fireExitDetectedCallback(sessionName) {
389
+ if (!this.onExitDetectedCallback)
390
+ return;
391
+ try {
392
+ this.onExitDetectedCallback(sessionName);
393
+ }
394
+ catch (error) {
395
+ this.logger.warn('onExitDetected callback error', {
396
+ sessionName,
397
+ error: error instanceof Error ? error.message : String(error),
398
+ });
399
+ }
400
+ }
401
+ /**
402
+ * Try to restart an agent that has in-progress tasks.
403
+ *
404
+ * @param sessionName - PTY session name
405
+ * @param monitored - Monitored session state
406
+ * @returns True if the agent was successfully restarted (caller should return)
407
+ */
408
+ async tryAgentRestartWithTasks(sessionName, monitored) {
409
+ try {
410
+ const tasks = await this.taskTrackingService.getTasksForTeamMember(monitored.memberId || '');
411
+ const activeTasks = tasks.filter(t => t.status === 'assigned' || t.status === 'active' || t.status === 'pending_assignment');
412
+ if (activeTasks.length === 0)
413
+ return false;
414
+ if (!this.isAgentRestartAllowed(sessionName)) {
415
+ this.logger.warn('Agent restart cooldown active, skipping restart', {
416
+ sessionName,
417
+ activeTaskCount: activeTasks.length,
418
+ maxRestartsPerWindow: AGENT_HEARTBEAT_MONITOR_CONSTANTS.MAX_RESTARTS_PER_WINDOW,
419
+ cooldownWindowMs: AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS,
420
+ });
421
+ this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited_cooldown', activeTasks, false);
422
+ return false;
463
423
  }
464
- // Update agent status to inactive
424
+ this.logger.info('Runtime exit with in-progress tasks, attempting restart', {
425
+ sessionName,
426
+ activeTaskCount: activeTasks.length,
427
+ });
465
428
  try {
466
- const storageService = StorageService.getInstance();
467
- await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
468
- this.logger.info('Agent status updated to inactive after runtime exit', { sessionName });
469
- // Publish agent:inactive event to EventBus so orchestrator is notified
470
- if (this.eventBusService) {
471
- try {
472
- await this.publishInactiveEvent(sessionName, monitored, storageService);
473
- }
474
- catch (eventError) {
475
- this.logger.warn('Failed to publish agent:inactive event to EventBus', {
429
+ await this.restartAgentWithTasks(sessionName, monitored, activeTasks);
430
+ this.recordAgentRestart(sessionName);
431
+ this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, true);
432
+ this.stopMonitoring(sessionName);
433
+ return true;
434
+ }
435
+ catch (restartError) {
436
+ this.logger.warn('Agent restart after runtime exit failed, falling back to inactive', {
437
+ sessionName,
438
+ error: restartError instanceof Error ? restartError.message : String(restartError),
439
+ });
440
+ this.recordAgentRestart(sessionName);
441
+ this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, false);
442
+ return false;
443
+ }
444
+ }
445
+ catch (error) {
446
+ this.logger.warn('Failed to check in-progress tasks after runtime exit', {
447
+ sessionName,
448
+ error: error instanceof Error ? error.message : String(error),
449
+ });
450
+ return false;
451
+ }
452
+ }
453
+ /**
454
+ * Try to restart the orchestrator after runtime exit.
455
+ *
456
+ * Sets status to inactive before restart to prevent queue processor
457
+ * from delivering messages during postInitialize, captures session
458
+ * memory, and broadcasts restart status.
459
+ *
460
+ * @param sessionName - PTY session name (should be ORCHESTRATOR_SESSION_NAME)
461
+ * @param monitored - Monitored session state
462
+ * @returns True if orchestrator was successfully restarted (caller should return)
463
+ */
464
+ async tryOrchestratorRestart(sessionName, monitored) {
465
+ // Set status to inactive BEFORE restart so the queue processor
466
+ // doesn't deliver messages during postInitialize.
467
+ try {
468
+ const storageService = StorageService.getInstance();
469
+ await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
470
+ }
471
+ catch {
472
+ // Best-effort — continue with restart
473
+ }
474
+ // Capture session memory before restart
475
+ try {
476
+ const sessionMemoryService = SessionMemoryService.getInstance();
477
+ await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
478
+ }
479
+ catch (error) {
480
+ this.logger.warn('Failed to capture session memory before orchestrator restart', {
481
+ sessionName,
482
+ error: error instanceof Error ? error.message : String(error),
483
+ });
484
+ }
485
+ try {
486
+ const restartService = OrchestratorRestartService.getInstance();
487
+ const success = await restartService.attemptRestart();
488
+ if (success) {
489
+ this.logger.info('Orchestrator restarted after runtime exit', { sessionName });
490
+ // Broadcast STARTED (not ACTIVE) — agent becomes ACTIVE only
491
+ // after registration prompt is processed and MCP call completes.
492
+ try {
493
+ const terminalGateway = getTerminalGateway();
494
+ if (terminalGateway) {
495
+ terminalGateway.broadcastOrchestratorStatus({
476
496
  sessionName,
477
- error: eventError instanceof Error ? eventError.message : String(eventError),
497
+ agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.STARTED,
498
+ reason: 'runtime_exit_restart',
478
499
  });
479
500
  }
480
501
  }
502
+ catch {
503
+ // Best-effort broadcast
504
+ }
505
+ this.stopMonitoring(sessionName);
506
+ return true;
481
507
  }
482
- catch (error) {
483
- this.logger.warn('Failed to update agent status after runtime exit', {
484
- sessionName,
485
- error: error instanceof Error ? error.message : String(error),
486
- });
487
- }
488
- // Capture session memory (skip for orchestrator — already captured above)
489
- if (sessionName !== ORCHESTRATOR_SESSION_NAME) {
508
+ this.logger.warn('Orchestrator restart after runtime exit failed or not allowed, falling back to inactive', {
509
+ sessionName,
510
+ });
511
+ }
512
+ catch (error) {
513
+ this.logger.warn('Orchestrator restart attempt threw error, falling back to inactive', {
514
+ sessionName,
515
+ error: error instanceof Error ? error.message : String(error),
516
+ });
517
+ }
518
+ return false;
519
+ }
520
+ /**
521
+ * Transition agent to inactive state: update storage, capture memory,
522
+ * publish events, and broadcast WebSocket status.
523
+ *
524
+ * @param sessionName - PTY session name
525
+ * @param monitored - Monitored session state
526
+ */
527
+ async transitionToInactive(sessionName, monitored) {
528
+ // Update agent status to inactive
529
+ try {
530
+ const storageService = StorageService.getInstance();
531
+ await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
532
+ this.logger.info('Agent status updated to inactive after runtime exit', { sessionName });
533
+ // Publish agent:inactive event to EventBus so orchestrator is notified
534
+ if (this.eventBusService) {
490
535
  try {
491
- const sessionMemoryService = SessionMemoryService.getInstance();
492
- await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
536
+ await this.publishInactiveEvent(sessionName, monitored, storageService);
493
537
  }
494
- catch (error) {
495
- this.logger.warn('Failed to capture session memory after runtime exit', {
538
+ catch (eventError) {
539
+ this.logger.warn('Failed to publish agent:inactive event to EventBus', {
496
540
  sessionName,
497
- error: error instanceof Error ? error.message : String(error),
541
+ error: eventError instanceof Error ? eventError.message : String(eventError),
498
542
  });
499
543
  }
500
544
  }
501
- // Broadcast WebSocket event
545
+ }
546
+ catch (error) {
547
+ this.logger.warn('Failed to update agent status after runtime exit', {
548
+ sessionName,
549
+ error: error instanceof Error ? error.message : String(error),
550
+ });
551
+ }
552
+ // Capture session memory (skip for orchestrator — already captured above)
553
+ if (sessionName !== ORCHESTRATOR_SESSION_NAME) {
502
554
  try {
503
- const terminalGateway = getTerminalGateway();
504
- if (terminalGateway) {
505
- const statusPayload = {
506
- sessionName,
507
- agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE,
508
- reason: 'runtime_exited',
509
- };
510
- if (sessionName === ORCHESTRATOR_SESSION_NAME) {
511
- terminalGateway.broadcastOrchestratorStatus(statusPayload);
512
- }
513
- else {
514
- terminalGateway.broadcastTeamMemberStatus(statusPayload);
515
- }
516
- }
555
+ const sessionMemoryService = SessionMemoryService.getInstance();
556
+ await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
517
557
  }
518
558
  catch (error) {
519
- this.logger.warn('Failed to broadcast runtime exit event', {
559
+ this.logger.warn('Failed to capture session memory after runtime exit', {
520
560
  sessionName,
521
561
  error: error instanceof Error ? error.message : String(error),
522
562
  });
523
563
  }
524
- // Cleanup this subscription
525
- this.stopMonitoring(sessionName);
526
564
  }
527
- finally {
528
- monitored.confirmationInFlight = false;
565
+ // Broadcast WebSocket event
566
+ try {
567
+ const terminalGateway = getTerminalGateway();
568
+ if (terminalGateway) {
569
+ const statusPayload = {
570
+ sessionName,
571
+ agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE,
572
+ reason: 'runtime_exited',
573
+ };
574
+ if (sessionName === ORCHESTRATOR_SESSION_NAME) {
575
+ terminalGateway.broadcastOrchestratorStatus(statusPayload);
576
+ }
577
+ else {
578
+ terminalGateway.broadcastTeamMemberStatus(statusPayload);
579
+ }
580
+ }
581
+ }
582
+ catch (error) {
583
+ this.logger.warn('Failed to broadcast runtime exit event', {
584
+ sessionName,
585
+ error: error instanceof Error ? error.message : String(error),
586
+ });
529
587
  }
530
588
  }
531
589
  /**