crewly 1.13.0 → 1.13.1

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 (597) hide show
  1. package/config/skills/_common/complete-body-shape.test.sh +113 -0
  2. package/config/skills/_common/no-dangling-symlinks.test.sh +63 -0
  3. package/config/skills/_common/task-pool-body-shape.test.sh +471 -0
  4. package/config/skills/agent/core/accept-task/execute.sh +30 -5
  5. package/config/skills/agent/core/block-task/execute.sh +59 -6
  6. package/config/skills/agent/core/complete-task/SKILL.md +37 -5
  7. package/config/skills/agent/core/complete-task/execute.sh +40 -9
  8. package/config/skills/agent/core/complete-task/execute.test.sh +213 -0
  9. package/config/skills/agent/core/create-task/SKILL.md +33 -0
  10. package/config/skills/agent/core/create-task/execute.sh +82 -23
  11. package/config/skills/agent/core/delegate-task/execute.sh +46 -0
  12. package/config/skills/agent/core/get-team-norms/SKILL.md +1 -1
  13. package/config/skills/agent/core/get-team-norms/execute.sh +73 -2
  14. package/config/skills/agent/core/handoff-task/execute.sh +8 -1
  15. package/config/skills/agent/core/report-status/SKILL.md +26 -0
  16. package/config/skills/agent/core/report-status/execute.sh +40 -5
  17. package/config/skills/orchestrator/delegate-task/SKILL.md +1 -1
  18. package/config/skills/orchestrator/delegate-task/execute.sh +45 -11
  19. package/config/skills/orchestrator/delegate-task/execute.test.sh +153 -1
  20. package/config/skills/team-leader/aggregate-results/SKILL.md +1 -1
  21. package/config/skills/team-leader/decompose-goal/execute.sh +11 -16
  22. package/config/skills/team-leader/delegate-task/SKILL.md +14 -1
  23. package/config/skills/team-leader/delegate-task/execute.sh +132 -43
  24. package/config/skills/team-leader/delegate-task/execute.test.sh +180 -27
  25. package/config/vitest-exclude.constants.ts +56 -0
  26. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  27. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +18 -3
  28. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  29. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  30. package/dist/backend/backend/src/controllers/slack/slack.controller.js +18 -15
  31. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  32. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +6 -1
  33. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  34. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +19 -10
  35. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  36. package/dist/backend/backend/src/index.d.ts.map +1 -1
  37. package/dist/backend/backend/src/index.js +20 -0
  38. package/dist/backend/backend/src/index.js.map +1 -1
  39. package/dist/backend/backend/src/scripts/stamp-build.d.ts +25 -0
  40. package/dist/backend/backend/src/scripts/stamp-build.d.ts.map +1 -0
  41. package/dist/backend/backend/src/scripts/stamp-build.js +48 -0
  42. package/dist/backend/backend/src/scripts/stamp-build.js.map +1 -0
  43. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  44. package/dist/backend/backend/src/services/agent/agent-registration.service.js +25 -0
  45. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  46. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  47. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +9 -1
  48. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  49. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +42 -3
  50. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  51. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +22 -1
  52. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  53. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +15 -0
  54. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +40 -0
  56. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -1
  57. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +28 -3
  58. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  59. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +65 -8
  60. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  61. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +214 -4
  62. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  63. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +330 -48
  64. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  65. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +13 -1
  66. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  67. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +84 -5
  68. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  69. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +14 -0
  70. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  71. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +77 -3
  72. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  73. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +152 -7
  74. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +268 -36
  76. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  77. package/dist/backend/backend/src/services/v3/escalation-router.service.js +2 -2
  78. package/dist/backend/backend/src/services/v3/escalation-router.service.js.map +1 -1
  79. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +39 -2
  81. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -1
  82. package/dist/backend/backend/src/types/v2/index.d.ts +1 -1
  83. package/dist/backend/backend/src/types/v2/index.d.ts.map +1 -1
  84. package/dist/backend/backend/src/types/v2/index.js +1 -1
  85. package/dist/backend/backend/src/types/v2/index.js.map +1 -1
  86. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +181 -1
  87. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  88. package/dist/backend/backend/src/types/v2/work-item.types.js +104 -17
  89. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  90. package/dist/backend/backend/src/utils/build-provenance.d.ts +150 -0
  91. package/dist/backend/backend/src/utils/build-provenance.d.ts.map +1 -0
  92. package/dist/backend/backend/src/utils/build-provenance.js +211 -0
  93. package/dist/backend/backend/src/utils/build-provenance.js.map +1 -0
  94. package/dist/backend/build-info.json +4 -0
  95. package/dist/backend/config/vitest-exclude.constants.d.ts +53 -0
  96. package/dist/backend/config/vitest-exclude.constants.d.ts.map +1 -0
  97. package/dist/backend/config/vitest-exclude.constants.js +55 -0
  98. package/dist/backend/config/vitest-exclude.constants.js.map +1 -0
  99. package/dist/cli/backend/src/services/agent/active-work-briefing.service.d.ts +538 -0
  100. package/dist/cli/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  101. package/dist/cli/backend/src/services/agent/active-work-briefing.service.js +802 -0
  102. package/dist/cli/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  103. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.d.ts +240 -0
  104. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.d.ts.map +1 -0
  105. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.js +524 -0
  106. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.js.map +1 -0
  107. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +629 -0
  108. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -0
  109. package/dist/cli/backend/src/services/agent/agent-registration.service.js +4548 -0
  110. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -0
  111. package/dist/cli/backend/src/services/agent/agent-suspend.service.d.ts +118 -0
  112. package/dist/cli/backend/src/services/agent/agent-suspend.service.d.ts.map +1 -0
  113. package/dist/cli/backend/src/services/agent/agent-suspend.service.js +304 -0
  114. package/dist/cli/backend/src/services/agent/agent-suspend.service.js.map +1 -0
  115. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.d.ts +196 -0
  116. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -0
  117. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js +504 -0
  118. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js.map +1 -0
  119. package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts +97 -0
  120. package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -0
  121. package/dist/cli/backend/src/services/agent/claude-runtime.service.js +334 -0
  122. package/dist/cli/backend/src/services/agent/claude-runtime.service.js.map +1 -0
  123. package/dist/cli/backend/src/services/agent/codex-runtime.service.d.ts +47 -0
  124. package/dist/cli/backend/src/services/agent/codex-runtime.service.d.ts.map +1 -0
  125. package/dist/cli/backend/src/services/agent/codex-runtime.service.js +112 -0
  126. package/dist/cli/backend/src/services/agent/codex-runtime.service.js.map +1 -0
  127. package/dist/cli/backend/src/services/agent/context-window-monitor.service.d.ts +323 -0
  128. package/dist/cli/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -0
  129. package/dist/cli/backend/src/services/agent/context-window-monitor.service.js +1056 -0
  130. package/dist/cli/backend/src/services/agent/context-window-monitor.service.js.map +1 -0
  131. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +198 -0
  132. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -0
  133. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +816 -0
  134. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -0
  135. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts +155 -0
  136. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts.map +1 -0
  137. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.js +272 -0
  138. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.js.map +1 -0
  139. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts +91 -0
  140. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts.map +1 -0
  141. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js +120 -0
  142. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js.map +1 -0
  143. package/dist/cli/backend/src/services/agent/crewly-agent/types.d.ts +536 -0
  144. package/dist/cli/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -0
  145. package/dist/cli/backend/src/services/agent/crewly-agent/types.js +282 -0
  146. package/dist/cli/backend/src/services/agent/crewly-agent/types.js.map +1 -0
  147. package/dist/cli/backend/src/services/agent/disk-cleanup.service.d.ts +100 -0
  148. package/dist/cli/backend/src/services/agent/disk-cleanup.service.d.ts.map +1 -0
  149. package/dist/cli/backend/src/services/agent/disk-cleanup.service.js +149 -0
  150. package/dist/cli/backend/src/services/agent/disk-cleanup.service.js.map +1 -0
  151. package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts +130 -0
  152. package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -0
  153. package/dist/cli/backend/src/services/agent/gemini-runtime.service.js +758 -0
  154. package/dist/cli/backend/src/services/agent/gemini-runtime.service.js.map +1 -0
  155. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +216 -0
  156. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -0
  157. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +508 -0
  158. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -0
  159. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.d.ts +113 -0
  160. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.d.ts.map +1 -0
  161. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.js +161 -0
  162. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.js.map +1 -0
  163. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts +156 -0
  164. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -0
  165. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +641 -0
  166. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -0
  167. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts +295 -0
  168. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -0
  169. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +1166 -0
  170. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -0
  171. package/dist/cli/backend/src/services/agent/runtime-service.factory.d.ts +71 -0
  172. package/dist/cli/backend/src/services/agent/runtime-service.factory.d.ts.map +1 -0
  173. package/dist/cli/backend/src/services/agent/runtime-service.factory.js +174 -0
  174. package/dist/cli/backend/src/services/agent/runtime-service.factory.js.map +1 -0
  175. package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts +435 -0
  176. package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -0
  177. package/dist/cli/backend/src/services/ai/prompt-builder.service.js +1331 -0
  178. package/dist/cli/backend/src/services/ai/prompt-builder.service.js.map +1 -0
  179. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.d.ts +33 -0
  180. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.d.ts.map +1 -0
  181. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.js +70 -0
  182. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.js.map +1 -0
  183. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts +100 -0
  184. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -0
  185. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js +296 -0
  186. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -0
  187. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts +59 -0
  188. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts.map +1 -0
  189. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js +87 -0
  190. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -0
  191. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.d.ts +67 -0
  192. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.d.ts.map +1 -0
  193. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.js +84 -0
  194. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.js.map +1 -0
  195. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.d.ts +35 -0
  196. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.d.ts.map +1 -0
  197. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.js +50 -0
  198. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.js.map +1 -0
  199. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.d.ts +41 -0
  200. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.d.ts.map +1 -0
  201. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.js +95 -0
  202. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.js.map +1 -0
  203. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.d.ts +28 -0
  204. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.d.ts.map +1 -0
  205. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.js +47 -0
  206. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.js.map +1 -0
  207. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.d.ts +65 -0
  208. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.d.ts.map +1 -0
  209. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js +79 -0
  210. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js.map +1 -0
  211. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.d.ts +28 -0
  212. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.d.ts.map +1 -0
  213. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.js +55 -0
  214. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.js.map +1 -0
  215. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.d.ts +44 -0
  216. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.d.ts.map +1 -0
  217. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.js +120 -0
  218. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.js.map +1 -0
  219. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.d.ts +46 -0
  220. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.d.ts.map +1 -0
  221. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.js +44 -0
  222. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.js.map +1 -0
  223. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts +28 -0
  224. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts.map +1 -0
  225. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.js +46 -0
  226. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.js.map +1 -0
  227. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.d.ts +60 -0
  228. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.d.ts.map +1 -0
  229. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.js +104 -0
  230. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.js.map +1 -0
  231. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.d.ts +29 -0
  232. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.d.ts.map +1 -0
  233. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.js +50 -0
  234. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.js.map +1 -0
  235. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts +103 -0
  236. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -0
  237. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +383 -0
  238. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -0
  239. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.d.ts +34 -0
  240. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -0
  241. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.js +96 -0
  242. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -0
  243. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.d.ts +106 -0
  244. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.d.ts.map +1 -0
  245. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.js +167 -0
  246. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.js.map +1 -0
  247. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.d.ts +35 -0
  248. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.d.ts.map +1 -0
  249. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.js +50 -0
  250. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.js.map +1 -0
  251. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts +91 -0
  252. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -0
  253. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.js +411 -0
  254. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -0
  255. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts +62 -0
  256. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -0
  257. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +199 -0
  258. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -0
  259. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  260. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  261. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  262. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  263. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.d.ts +102 -0
  264. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.d.ts.map +1 -0
  265. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.js +229 -0
  266. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.js.map +1 -0
  267. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.d.ts +61 -0
  268. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.d.ts.map +1 -0
  269. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.js +197 -0
  270. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.js.map +1 -0
  271. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.d.ts +54 -0
  272. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.d.ts.map +1 -0
  273. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.js +149 -0
  274. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.js.map +1 -0
  275. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.d.ts +32 -0
  276. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.d.ts.map +1 -0
  277. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.js +69 -0
  278. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.js.map +1 -0
  279. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.d.ts +91 -0
  280. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.d.ts.map +1 -0
  281. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.js +136 -0
  282. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.js.map +1 -0
  283. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.d.ts +81 -0
  284. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.d.ts.map +1 -0
  285. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.js +135 -0
  286. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.js.map +1 -0
  287. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +737 -0
  288. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  289. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +1213 -0
  290. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  291. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  292. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  293. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  294. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  295. package/dist/cli/backend/src/services/chat-v2/config.d.ts +100 -0
  296. package/dist/cli/backend/src/services/chat-v2/config.d.ts.map +1 -0
  297. package/dist/cli/backend/src/services/chat-v2/config.js +174 -0
  298. package/dist/cli/backend/src/services/chat-v2/config.js.map +1 -0
  299. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.d.ts +118 -0
  300. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.d.ts.map +1 -0
  301. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.js +171 -0
  302. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.js.map +1 -0
  303. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.d.ts +188 -0
  304. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  305. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.js +317 -0
  306. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  307. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.d.ts +119 -0
  308. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  309. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.js +551 -0
  310. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  311. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts +208 -0
  312. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  313. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js +405 -0
  314. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  315. package/dist/cli/backend/src/services/chat-v2/types.d.ts +341 -0
  316. package/dist/cli/backend/src/services/chat-v2/types.d.ts.map +1 -0
  317. package/dist/cli/backend/src/services/chat-v2/types.js +61 -0
  318. package/dist/cli/backend/src/services/chat-v2/types.js.map +1 -0
  319. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.d.ts +37 -0
  320. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.d.ts.map +1 -0
  321. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.js +63 -0
  322. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.js.map +1 -0
  323. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.d.ts +335 -0
  324. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.d.ts.map +1 -0
  325. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.js +421 -0
  326. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.js.map +1 -0
  327. package/dist/cli/backend/src/services/mcp-client.d.ts +233 -0
  328. package/dist/cli/backend/src/services/mcp-client.d.ts.map +1 -0
  329. package/dist/cli/backend/src/services/mcp-client.js +302 -0
  330. package/dist/cli/backend/src/services/mcp-client.js.map +1 -0
  331. package/dist/cli/backend/src/services/memory/mission-context.service.d.ts +168 -0
  332. package/dist/cli/backend/src/services/memory/mission-context.service.d.ts.map +1 -0
  333. package/dist/cli/backend/src/services/memory/mission-context.service.js +365 -0
  334. package/dist/cli/backend/src/services/memory/mission-context.service.js.map +1 -0
  335. package/dist/cli/backend/src/services/memory/session-memory.service.d.ts +197 -0
  336. package/dist/cli/backend/src/services/memory/session-memory.service.d.ts.map +1 -0
  337. package/dist/cli/backend/src/services/memory/session-memory.service.js +369 -0
  338. package/dist/cli/backend/src/services/memory/session-memory.service.js.map +1 -0
  339. package/dist/cli/backend/src/services/memory/user-profile.service.d.ts +77 -0
  340. package/dist/cli/backend/src/services/memory/user-profile.service.d.ts.map +1 -0
  341. package/dist/cli/backend/src/services/memory/user-profile.service.js +171 -0
  342. package/dist/cli/backend/src/services/memory/user-profile.service.js.map +1 -0
  343. package/dist/cli/backend/src/services/memory/working-memory.service.d.ts +232 -0
  344. package/dist/cli/backend/src/services/memory/working-memory.service.d.ts.map +1 -0
  345. package/dist/cli/backend/src/services/memory/working-memory.service.js +417 -0
  346. package/dist/cli/backend/src/services/memory/working-memory.service.js.map +1 -0
  347. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +84 -0
  348. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -0
  349. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +136 -0
  350. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -0
  351. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts +358 -0
  352. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts.map +1 -0
  353. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js +755 -0
  354. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js.map +1 -0
  355. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +269 -0
  356. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -0
  357. package/dist/cli/backend/src/services/monitoring/token-usage.service.js +391 -0
  358. package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -0
  359. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.d.ts +132 -0
  360. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.d.ts.map +1 -0
  361. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.js +284 -0
  362. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.js.map +1 -0
  363. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.d.ts +70 -0
  364. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.d.ts.map +1 -0
  365. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.js +121 -0
  366. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.js.map +1 -0
  367. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.d.ts +130 -0
  368. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.d.ts.map +1 -0
  369. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.js +48 -0
  370. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.js.map +1 -0
  371. package/dist/cli/backend/src/services/observability/observability-db.d.ts +84 -0
  372. package/dist/cli/backend/src/services/observability/observability-db.d.ts.map +1 -0
  373. package/dist/cli/backend/src/services/observability/observability-db.js +165 -0
  374. package/dist/cli/backend/src/services/observability/observability-db.js.map +1 -0
  375. package/dist/cli/backend/src/services/onboarding/content-approval.service.d.ts +124 -0
  376. package/dist/cli/backend/src/services/onboarding/content-approval.service.d.ts.map +1 -0
  377. package/dist/cli/backend/src/services/onboarding/content-approval.service.js +256 -0
  378. package/dist/cli/backend/src/services/onboarding/content-approval.service.js.map +1 -0
  379. package/dist/cli/backend/src/services/onboarding/content-approval.types.d.ts +80 -0
  380. package/dist/cli/backend/src/services/onboarding/content-approval.types.d.ts.map +1 -0
  381. package/dist/cli/backend/src/services/onboarding/content-approval.types.js +16 -0
  382. package/dist/cli/backend/src/services/onboarding/content-approval.types.js.map +1 -0
  383. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.d.ts +142 -0
  384. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.d.ts.map +1 -0
  385. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.js +265 -0
  386. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.js.map +1 -0
  387. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.d.ts +231 -0
  388. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.d.ts.map +1 -0
  389. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.js +353 -0
  390. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.js.map +1 -0
  391. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.d.ts +157 -0
  392. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.d.ts.map +1 -0
  393. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.js +483 -0
  394. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.js.map +1 -0
  395. package/dist/cli/backend/src/services/orchestrator/index.d.ts +16 -0
  396. package/dist/cli/backend/src/services/orchestrator/index.d.ts.map +1 -0
  397. package/dist/cli/backend/src/services/orchestrator/index.js +16 -0
  398. package/dist/cli/backend/src/services/orchestrator/index.js.map +1 -0
  399. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +117 -0
  400. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -0
  401. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js +300 -0
  402. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -0
  403. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.d.ts +114 -0
  404. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.d.ts.map +1 -0
  405. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.js +195 -0
  406. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.js.map +1 -0
  407. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts +94 -0
  408. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -0
  409. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js +279 -0
  410. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -0
  411. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.d.ts +192 -0
  412. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.d.ts.map +1 -0
  413. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.js +395 -0
  414. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.js.map +1 -0
  415. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.d.ts +201 -0
  416. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.d.ts.map +1 -0
  417. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.js +396 -0
  418. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.js.map +1 -0
  419. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.d.ts +17 -0
  420. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.d.ts.map +1 -0
  421. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.js +30 -0
  422. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.js.map +1 -0
  423. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.d.ts +249 -0
  424. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.d.ts.map +1 -0
  425. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.js +569 -0
  426. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.js.map +1 -0
  427. package/dist/cli/backend/src/services/session/index.d.ts +47 -0
  428. package/dist/cli/backend/src/services/session/index.d.ts.map +1 -0
  429. package/dist/cli/backend/src/services/session/index.js +50 -0
  430. package/dist/cli/backend/src/services/session/index.js.map +1 -0
  431. package/dist/cli/backend/src/services/session/log-rotation.service.d.ts +163 -0
  432. package/dist/cli/backend/src/services/session/log-rotation.service.d.ts.map +1 -0
  433. package/dist/cli/backend/src/services/session/log-rotation.service.js +362 -0
  434. package/dist/cli/backend/src/services/session/log-rotation.service.js.map +1 -0
  435. package/dist/cli/backend/src/services/session/pty/index.d.ts +11 -0
  436. package/dist/cli/backend/src/services/session/pty/index.d.ts.map +1 -0
  437. package/dist/cli/backend/src/services/session/pty/index.js +11 -0
  438. package/dist/cli/backend/src/services/session/pty/index.js.map +1 -0
  439. package/dist/cli/backend/src/services/session/pty/pty-session-backend.d.ts +445 -0
  440. package/dist/cli/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -0
  441. package/dist/cli/backend/src/services/session/pty/pty-session-backend.js +804 -0
  442. package/dist/cli/backend/src/services/session/pty/pty-session-backend.js.map +1 -0
  443. package/dist/cli/backend/src/services/session/pty/pty-session.d.ts +252 -0
  444. package/dist/cli/backend/src/services/session/pty/pty-session.d.ts.map +1 -0
  445. package/dist/cli/backend/src/services/session/pty/pty-session.js +611 -0
  446. package/dist/cli/backend/src/services/session/pty/pty-session.js.map +1 -0
  447. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.d.ts +275 -0
  448. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.d.ts.map +1 -0
  449. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.js +403 -0
  450. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.js.map +1 -0
  451. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.d.ts +86 -0
  452. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.d.ts.map +1 -0
  453. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.js +214 -0
  454. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.js.map +1 -0
  455. package/dist/cli/backend/src/services/session/session-backend.factory.d.ts +127 -0
  456. package/dist/cli/backend/src/services/session/session-backend.factory.d.ts.map +1 -0
  457. package/dist/cli/backend/src/services/session/session-backend.factory.js +226 -0
  458. package/dist/cli/backend/src/services/session/session-backend.factory.js.map +1 -0
  459. package/dist/cli/backend/src/services/session/session-backend.interface.d.ts +390 -0
  460. package/dist/cli/backend/src/services/session/session-backend.interface.d.ts.map +1 -0
  461. package/dist/cli/backend/src/services/session/session-backend.interface.js +19 -0
  462. package/dist/cli/backend/src/services/session/session-backend.interface.js.map +1 -0
  463. package/dist/cli/backend/src/services/session/session-command-helper.d.ts +350 -0
  464. package/dist/cli/backend/src/services/session/session-command-helper.d.ts.map +1 -0
  465. package/dist/cli/backend/src/services/session/session-command-helper.js +810 -0
  466. package/dist/cli/backend/src/services/session/session-command-helper.js.map +1 -0
  467. package/dist/cli/backend/src/services/session/session-handoff.service.d.ts +307 -0
  468. package/dist/cli/backend/src/services/session/session-handoff.service.d.ts.map +1 -0
  469. package/dist/cli/backend/src/services/session/session-handoff.service.js +742 -0
  470. package/dist/cli/backend/src/services/session/session-handoff.service.js.map +1 -0
  471. package/dist/cli/backend/src/services/session/session-state-persistence.d.ts +231 -0
  472. package/dist/cli/backend/src/services/session/session-state-persistence.d.ts.map +1 -0
  473. package/dist/cli/backend/src/services/session/session-state-persistence.js +407 -0
  474. package/dist/cli/backend/src/services/session/session-state-persistence.js.map +1 -0
  475. package/dist/cli/backend/src/services/settings/role.service.d.ts +277 -0
  476. package/dist/cli/backend/src/services/settings/role.service.d.ts.map +1 -0
  477. package/dist/cli/backend/src/services/settings/role.service.js +728 -0
  478. package/dist/cli/backend/src/services/settings/role.service.js.map +1 -0
  479. package/dist/cli/backend/src/services/slack/cross-machine-message.service.d.ts +152 -0
  480. package/dist/cli/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -0
  481. package/dist/cli/backend/src/services/slack/cross-machine-message.service.js +354 -0
  482. package/dist/cli/backend/src/services/slack/cross-machine-message.service.js.map +1 -0
  483. package/dist/cli/backend/src/services/slack/slack-image.service.d.ts +114 -0
  484. package/dist/cli/backend/src/services/slack/slack-image.service.d.ts.map +1 -0
  485. package/dist/cli/backend/src/services/slack/slack-image.service.js +331 -0
  486. package/dist/cli/backend/src/services/slack/slack-image.service.js.map +1 -0
  487. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +499 -0
  488. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -0
  489. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +1928 -0
  490. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -0
  491. package/dist/cli/backend/src/services/slack/slack.service.d.ts +315 -0
  492. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -0
  493. package/dist/cli/backend/src/services/slack/slack.service.js +1094 -0
  494. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -0
  495. package/dist/cli/backend/src/services/sop/sop.service.d.ts +364 -0
  496. package/dist/cli/backend/src/services/sop/sop.service.d.ts.map +1 -0
  497. package/dist/cli/backend/src/services/sop/sop.service.js +734 -0
  498. package/dist/cli/backend/src/services/sop/sop.service.js.map +1 -0
  499. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +152 -7
  500. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  501. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +268 -36
  502. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  503. package/dist/cli/backend/src/services/v3/escalation-router.service.d.ts +178 -0
  504. package/dist/cli/backend/src/services/v3/escalation-router.service.d.ts.map +1 -0
  505. package/dist/cli/backend/src/services/v3/escalation-router.service.js +692 -0
  506. package/dist/cli/backend/src/services/v3/escalation-router.service.js.map +1 -0
  507. package/dist/cli/backend/src/services/v3/kr-tracking.service.d.ts +200 -0
  508. package/dist/cli/backend/src/services/v3/kr-tracking.service.d.ts.map +1 -0
  509. package/dist/cli/backend/src/services/v3/kr-tracking.service.js +482 -0
  510. package/dist/cli/backend/src/services/v3/kr-tracking.service.js.map +1 -0
  511. package/dist/cli/backend/src/services/v3/mission-executor.service.d.ts +117 -0
  512. package/dist/cli/backend/src/services/v3/mission-executor.service.d.ts.map +1 -0
  513. package/dist/cli/backend/src/services/v3/mission-executor.service.js +321 -0
  514. package/dist/cli/backend/src/services/v3/mission-executor.service.js.map +1 -0
  515. package/dist/cli/backend/src/services/v3/request-sla.subscriber.d.ts +610 -0
  516. package/dist/cli/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  517. package/dist/cli/backend/src/services/v3/request-sla.subscriber.js +1529 -0
  518. package/dist/cli/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  519. package/dist/cli/backend/src/services/v3/request-tracker.service.d.ts +78 -0
  520. package/dist/cli/backend/src/services/v3/request-tracker.service.d.ts.map +1 -0
  521. package/dist/cli/backend/src/services/v3/request-tracker.service.js +108 -0
  522. package/dist/cli/backend/src/services/v3/request-tracker.service.js.map +1 -0
  523. package/dist/cli/backend/src/services/v3/request.service.d.ts +295 -0
  524. package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -0
  525. package/dist/cli/backend/src/services/v3/request.service.js +534 -0
  526. package/dist/cli/backend/src/services/v3/request.service.js.map +1 -0
  527. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts +340 -0
  528. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts.map +1 -0
  529. package/dist/cli/backend/src/services/v3/v3-data.service.js +1113 -0
  530. package/dist/cli/backend/src/services/v3/v3-data.service.js.map +1 -0
  531. package/dist/cli/backend/src/types/cross-machine.types.d.ts +103 -0
  532. package/dist/cli/backend/src/types/cross-machine.types.d.ts.map +1 -0
  533. package/dist/cli/backend/src/types/cross-machine.types.js +47 -0
  534. package/dist/cli/backend/src/types/cross-machine.types.js.map +1 -0
  535. package/dist/cli/backend/src/types/intent-task.types.d.ts +402 -0
  536. package/dist/cli/backend/src/types/intent-task.types.d.ts.map +1 -0
  537. package/dist/cli/backend/src/types/intent-task.types.js +403 -0
  538. package/dist/cli/backend/src/types/intent-task.types.js.map +1 -0
  539. package/dist/cli/backend/src/types/orchestrator-state.types.d.ts +531 -0
  540. package/dist/cli/backend/src/types/orchestrator-state.types.d.ts.map +1 -0
  541. package/dist/cli/backend/src/types/orchestrator-state.types.js +110 -0
  542. package/dist/cli/backend/src/types/orchestrator-state.types.js.map +1 -0
  543. package/dist/cli/backend/src/types/v2/index.d.ts +30 -0
  544. package/dist/cli/backend/src/types/v2/index.d.ts.map +1 -0
  545. package/dist/cli/backend/src/types/v2/index.js +22 -0
  546. package/dist/cli/backend/src/types/v2/index.js.map +1 -0
  547. package/dist/cli/backend/src/types/v2/key-result.types.d.ts +279 -0
  548. package/dist/cli/backend/src/types/v2/key-result.types.d.ts.map +1 -0
  549. package/dist/cli/backend/src/types/v2/key-result.types.js +264 -0
  550. package/dist/cli/backend/src/types/v2/key-result.types.js.map +1 -0
  551. package/dist/cli/backend/src/types/v2/mission.types.d.ts +661 -0
  552. package/dist/cli/backend/src/types/v2/mission.types.d.ts.map +1 -0
  553. package/dist/cli/backend/src/types/v2/mission.types.js +713 -0
  554. package/dist/cli/backend/src/types/v2/mission.types.js.map +1 -0
  555. package/dist/cli/backend/src/types/v2/reconcile.types.d.ts +204 -0
  556. package/dist/cli/backend/src/types/v2/reconcile.types.d.ts.map +1 -0
  557. package/dist/cli/backend/src/types/v2/reconcile.types.js +121 -0
  558. package/dist/cli/backend/src/types/v2/reconcile.types.js.map +1 -0
  559. package/dist/cli/backend/src/types/v2/request.types.d.ts +192 -0
  560. package/dist/cli/backend/src/types/v2/request.types.d.ts.map +1 -0
  561. package/dist/cli/backend/src/types/v2/request.types.js +179 -0
  562. package/dist/cli/backend/src/types/v2/request.types.js.map +1 -0
  563. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +181 -1
  564. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  565. package/dist/cli/backend/src/types/v2/work-item.types.js +104 -17
  566. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  567. package/dist/cli/backend/src/types/v2/workspace.types.d.ts +157 -0
  568. package/dist/cli/backend/src/types/v2/workspace.types.d.ts.map +1 -0
  569. package/dist/cli/backend/src/types/v2/workspace.types.js +173 -0
  570. package/dist/cli/backend/src/types/v2/workspace.types.js.map +1 -0
  571. package/dist/cli/backend/src/utils/async.utils.d.ts +68 -0
  572. package/dist/cli/backend/src/utils/async.utils.d.ts.map +1 -0
  573. package/dist/cli/backend/src/utils/async.utils.js +80 -0
  574. package/dist/cli/backend/src/utils/async.utils.js.map +1 -0
  575. package/dist/cli/backend/src/utils/native-binding.utils.d.ts +128 -0
  576. package/dist/cli/backend/src/utils/native-binding.utils.d.ts.map +1 -0
  577. package/dist/cli/backend/src/utils/native-binding.utils.js +206 -0
  578. package/dist/cli/backend/src/utils/native-binding.utils.js.map +1 -0
  579. package/dist/cli/backend/src/websocket/chat.gateway.d.ts +142 -0
  580. package/dist/cli/backend/src/websocket/chat.gateway.d.ts.map +1 -0
  581. package/dist/cli/backend/src/websocket/chat.gateway.js +327 -0
  582. package/dist/cli/backend/src/websocket/chat.gateway.js.map +1 -0
  583. package/dist/cli/backend/src/websocket/terminal.gateway.d.ts +341 -0
  584. package/dist/cli/backend/src/websocket/terminal.gateway.d.ts.map +1 -0
  585. package/dist/cli/backend/src/websocket/terminal.gateway.js +933 -0
  586. package/dist/cli/backend/src/websocket/terminal.gateway.js.map +1 -0
  587. package/dist/cli/config/vitest-exclude.constants.d.ts +53 -0
  588. package/dist/cli/config/vitest-exclude.constants.d.ts.map +1 -0
  589. package/dist/cli/config/vitest-exclude.constants.js +55 -0
  590. package/dist/cli/config/vitest-exclude.constants.js.map +1 -0
  591. package/frontend/dist/assets/index-890d3f9d.js +4961 -0
  592. package/frontend/dist/index.html +1 -1
  593. package/package.json +2 -2
  594. package/packages/crewly-agent/src/runtime/agent-runner.service.test.ts +174 -30
  595. package/packages/crewly-agent/src/runtime/agent-runner.service.ts +121 -6
  596. package/packages/crewly-agent/src/runtime/types.ts +56 -5
  597. package/frontend/dist/assets/index-aa737fd3.js +0 -5254
@@ -0,0 +1,1166 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as http from 'http';
3
+ import { LoggerService } from '../core/logger.service.js';
4
+ import { StorageService } from '../core/storage.service.js';
5
+ import { getSessionBackendSync, createSessionCommandHelper, } from '../session/index.js';
6
+ import { getSessionStatePersistence } from '../session/session-state-persistence.js';
7
+ import { RuntimeServiceFactory } from './runtime-service.factory.js';
8
+ import { SessionMemoryService } from '../memory/session-memory.service.js';
9
+ import { getTerminalGateway } from '../../websocket/terminal.gateway.js';
10
+ import { SHELL_PROMPT_PATTERNS } from '../continuation/patterns/idle-patterns.js';
11
+ import { PtyActivityTrackerService } from './pty-activity-tracker.service.js';
12
+ import { OrchestratorRestartService } from '../orchestrator/orchestrator-restart.service.js';
13
+ import * as crypto from 'crypto';
14
+ import { CREWLY_CONSTANTS, ORCHESTRATOR_SESSION_NAME, ORCHESTRATOR_ROLE, RUNTIME_EXIT_CONSTANTS, AGENT_SUSPEND_CONSTANTS, SESSION_COMMAND_DELAYS, RUNTIME_TYPES, GEMINI_FAILURE_PATTERNS, GEMINI_FORCE_RESTART_PATTERNS, GEMINI_DELIBERATION_PATTERN, GEMINI_DELIBERATION_THRESHOLD, GEMINI_TOOL_CHECK_LOOP_PATTERN, GEMINI_TOOL_CHECK_LOOP_THRESHOLD, GEMINI_TOOL_CHECK_LOOP_WINDOW_MS, CLAUDE_FATAL_PATTERNS, GEMINI_FAILURE_RETRY_CONSTANTS, GEMINI_READY_PATTERNS, WEB_CONSTANTS, AGENT_HEARTBEAT_MONITOR_CONSTANTS, } from '../../constants.js';
15
+ import { delay } from '../../utils/async.utils.js';
16
+ /**
17
+ * Service that monitors PTY sessions for runtime exit patterns.
18
+ *
19
+ * When an agent CLI (Claude Code, Gemini CLI, Codex CLI) exits inside a PTY
20
+ * session, the PTY shell itself stays alive. This service watches terminal
21
+ * output for runtime-specific exit patterns and reacts by:
22
+ *
23
+ * 1. Updating the agent status to `inactive`
24
+ * 2. Capturing session memory
25
+ * 3. Broadcasting WebSocket events to the frontend
26
+ * 4. Cancelling pending registration operations
27
+ *
28
+ * For Gemini CLI, the service also detects failure patterns (API errors,
29
+ * quota exhaustion, network issues) that indicate the CLI is stuck and
30
+ * needs recovery. These failure patterns bypass the shell prompt verification
31
+ * since the CLI may still be running but non-functional.
32
+ *
33
+ * For Claude Code, the service detects fatal API errors (e.g. thinking
34
+ * block corruption) that make the CLI permanently non-functional within
35
+ * the current session. These trigger immediate recovery without retry.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const monitor = RuntimeExitMonitorService.getInstance();
40
+ * monitor.startMonitoring('agent-dev-001', 'claude-code', 'developer');
41
+ * // ... later ...
42
+ * monitor.stopMonitoring('agent-dev-001');
43
+ * ```
44
+ */
45
+ export class RuntimeExitMonitorService {
46
+ static instance = null;
47
+ logger;
48
+ sessions = new Map();
49
+ onExitDetectedCallback;
50
+ agentRegistrationService = null;
51
+ eventBusService = null;
52
+ /**
53
+ * Restart timestamps per session, persisted across monitoring cycles.
54
+ * Unlike MonitoredSession (which is recreated on each startMonitoring call),
55
+ * this map survives agent restarts to prevent infinite restart loops
56
+ * when agents keep crashing (e.g. during network outages).
57
+ */
58
+ restartHistory = new Map();
59
+ constructor() {
60
+ this.logger = LoggerService.getInstance().createComponentLogger('RuntimeExitMonitorService');
61
+ }
62
+ /**
63
+ * Get the singleton instance.
64
+ */
65
+ static getInstance() {
66
+ if (!RuntimeExitMonitorService.instance) {
67
+ RuntimeExitMonitorService.instance = new RuntimeExitMonitorService();
68
+ }
69
+ return RuntimeExitMonitorService.instance;
70
+ }
71
+ /**
72
+ * Reset the singleton (for testing).
73
+ */
74
+ static resetInstance() {
75
+ if (RuntimeExitMonitorService.instance) {
76
+ RuntimeExitMonitorService.instance.destroy();
77
+ }
78
+ RuntimeExitMonitorService.instance = null;
79
+ }
80
+ /**
81
+ * Register a callback invoked when a runtime exit is detected.
82
+ * Used by AgentRegistrationService to cancel pending registrations.
83
+ *
84
+ * @param callback - Called with the sessionName on exit detection
85
+ */
86
+ setOnExitDetectedCallback(callback) {
87
+ this.onExitDetectedCallback = callback;
88
+ }
89
+ /**
90
+ * Set the AgentRegistrationService dependency for agent restart.
91
+ *
92
+ * @param service - The AgentRegistrationService instance
93
+ */
94
+ setAgentRegistrationService(service) {
95
+ this.agentRegistrationService = service;
96
+ }
97
+ /**
98
+ * Backwards-compatible no-op. Kept so `index.ts` compiles during the
99
+ * TaskTrackingService deletion window. In-progress task queries now
100
+ * read directly from TaskPoolService.
101
+ *
102
+ * @deprecated Will be removed in a follow-up. Do not call from new code.
103
+ */
104
+ setTaskTrackingService(_service) {
105
+ // intentionally empty
106
+ }
107
+ /**
108
+ * Set the EventBusService dependency for publishing agent lifecycle events.
109
+ *
110
+ * @param service - The EventBusService instance
111
+ */
112
+ setEventBusService(service) {
113
+ this.eventBusService = service;
114
+ }
115
+ /**
116
+ * Start monitoring a PTY session for runtime exit patterns.
117
+ *
118
+ * @param sessionName - PTY session name
119
+ * @param runtimeType - Agent runtime type (claude-code, gemini-cli, codex-cli)
120
+ * @param role - Agent role name
121
+ * @param teamId - Optional team identifier
122
+ * @param memberId - Optional member identifier
123
+ */
124
+ startMonitoring(sessionName, runtimeType, role, teamId, memberId) {
125
+ // Stop any existing monitoring for this session
126
+ if (this.sessions.has(sessionName)) {
127
+ this.stopMonitoring(sessionName);
128
+ }
129
+ const backend = getSessionBackendSync();
130
+ if (!backend) {
131
+ this.logger.warn('Cannot start monitoring: session backend not initialized', { sessionName });
132
+ return;
133
+ }
134
+ const helper = createSessionCommandHelper(backend);
135
+ const session = helper.getSession(sessionName);
136
+ if (!session) {
137
+ this.logger.warn('Cannot start monitoring: session not found', { sessionName });
138
+ return;
139
+ }
140
+ const monitored = {
141
+ sessionName,
142
+ runtimeType,
143
+ role,
144
+ memberId,
145
+ teamId,
146
+ buffer: '',
147
+ startedAt: Date.now(),
148
+ exitDetected: false,
149
+ confirmationInFlight: false,
150
+ unsubscribe: () => { },
151
+ geminiFailureRetries: 0,
152
+ toolCheckLoopTimestamps: [],
153
+ };
154
+ // Get exit patterns for this runtime type
155
+ let exitPatterns;
156
+ try {
157
+ const runtimeService = RuntimeServiceFactory.create(runtimeType, null, process.cwd());
158
+ exitPatterns = runtimeService.getExitPatterns();
159
+ }
160
+ catch {
161
+ this.logger.warn('Failed to get exit patterns, using empty set', { sessionName, runtimeType });
162
+ exitPatterns = [];
163
+ }
164
+ if (exitPatterns.length === 0) {
165
+ this.logger.debug('No exit patterns for runtime, skipping monitoring', { sessionName, runtimeType });
166
+ return;
167
+ }
168
+ // Subscribe to PTY output
169
+ const unsubscribe = session.onData((data) => {
170
+ this.handleData(sessionName, data, exitPatterns, helper);
171
+ });
172
+ monitored.unsubscribe = unsubscribe;
173
+ // Start periodic process-alive polling as a fallback.
174
+ // This catches exits that don't produce recognizable text patterns
175
+ // (e.g. context window exhaustion, SIGKILL, unexpected crashes).
176
+ monitored.processPollingInterval = setInterval(() => {
177
+ this.checkProcessAlive(sessionName, backend, helper);
178
+ }, RUNTIME_EXIT_CONSTANTS.PROCESS_POLL_INTERVAL_MS);
179
+ this.sessions.set(sessionName, monitored);
180
+ this.logger.info('Started runtime exit monitoring', {
181
+ sessionName,
182
+ runtimeType,
183
+ role,
184
+ patternCount: exitPatterns.length,
185
+ });
186
+ }
187
+ /**
188
+ * Stop monitoring a PTY session.
189
+ *
190
+ * Also prunes the restartHistory entry for this session if it has no
191
+ * recent timestamps within the cooldown window, preventing slow memory
192
+ * leak for terminated sessions.
193
+ *
194
+ * @param sessionName - PTY session name
195
+ */
196
+ stopMonitoring(sessionName) {
197
+ const monitored = this.sessions.get(sessionName);
198
+ if (!monitored) {
199
+ return;
200
+ }
201
+ if (monitored.debounceTimer) {
202
+ clearTimeout(monitored.debounceTimer);
203
+ }
204
+ if (monitored.processPollingInterval) {
205
+ clearInterval(monitored.processPollingInterval);
206
+ }
207
+ monitored.unsubscribe();
208
+ this.sessions.delete(sessionName);
209
+ // Fix 3: Clean up restartHistory for terminated sessions to prevent
210
+ // unbounded Map growth. Keep the entry only if it has recent timestamps
211
+ // within the cooldown window (they may still be needed if the session
212
+ // is restarted soon). Delete the entry entirely otherwise.
213
+ const timestamps = this.restartHistory.get(sessionName);
214
+ if (timestamps) {
215
+ const windowStart = Date.now() - AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS;
216
+ const recent = timestamps.filter(ts => ts > windowStart);
217
+ if (recent.length === 0) {
218
+ this.restartHistory.delete(sessionName);
219
+ }
220
+ else {
221
+ this.restartHistory.set(sessionName, recent);
222
+ }
223
+ }
224
+ this.logger.debug('Stopped runtime exit monitoring', { sessionName });
225
+ }
226
+ /**
227
+ * Check if a session is being monitored.
228
+ */
229
+ isMonitoring(sessionName) {
230
+ return this.sessions.has(sessionName);
231
+ }
232
+ /**
233
+ * Destroy all monitoring subscriptions.
234
+ */
235
+ destroy() {
236
+ const sessionNames = [...this.sessions.keys()];
237
+ for (const sessionName of sessionNames) {
238
+ this.stopMonitoring(sessionName);
239
+ }
240
+ this.restartHistory.clear();
241
+ this.logger.debug('All runtime exit monitors destroyed');
242
+ }
243
+ /**
244
+ * Handle incoming PTY data for a monitored session.
245
+ */
246
+ handleData(sessionName, data, exitPatterns, helper) {
247
+ const monitored = this.sessions.get(sessionName);
248
+ if (!monitored || monitored.exitDetected) {
249
+ return;
250
+ }
251
+ // Append to rolling buffer, cap at MAX_BUFFER_SIZE
252
+ monitored.buffer += data;
253
+ if (monitored.buffer.length > RUNTIME_EXIT_CONSTANTS.MAX_BUFFER_SIZE) {
254
+ monitored.buffer = monitored.buffer.slice(-RUNTIME_EXIT_CONSTANTS.MAX_BUFFER_SIZE);
255
+ }
256
+ // Skip pattern matching during startup grace period
257
+ if (Date.now() - monitored.startedAt < RUNTIME_EXIT_CONSTANTS.STARTUP_GRACE_PERIOD_MS) {
258
+ return;
259
+ }
260
+ // Test buffer against exit patterns
261
+ let matched = exitPatterns.some((pattern) => pattern.test(monitored.buffer));
262
+ // #188: Deliberation loop detection for Gemini CLI agents.
263
+ // Count occurrences of "Wait, I'll..." / "Actually, I'll..." in the buffer.
264
+ // A single occurrence is normal; 5+ in the visible buffer means the agent
265
+ // is stuck planning without executing tool calls and needs a restart.
266
+ if (!matched && monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI) {
267
+ const deliberationCount = monitored.buffer.split(GEMINI_DELIBERATION_PATTERN).length - 1;
268
+ if (deliberationCount >= GEMINI_DELIBERATION_THRESHOLD) {
269
+ this.logger.warn('Gemini deliberation loop detected, triggering recovery', {
270
+ sessionName,
271
+ deliberationCount,
272
+ threshold: GEMINI_DELIBERATION_THRESHOLD,
273
+ });
274
+ matched = true;
275
+ }
276
+ }
277
+ // #251: Tool-check loop detection for Gemini CLI agents.
278
+ // Detects "Ready. Final response." / "Wait, I will check if I should use mcp_"
279
+ // cycling through Chrome DevTools MCP tools without completing.
280
+ // Time-windowed: THRESHOLD matches within WINDOW_MS triggers force-stop.
281
+ if (!matched && monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI) {
282
+ if (GEMINI_TOOL_CHECK_LOOP_PATTERN.test(data)) {
283
+ const now = Date.now();
284
+ monitored.toolCheckLoopTimestamps.push(now);
285
+ // Prune timestamps outside the time window
286
+ const windowStart = now - GEMINI_TOOL_CHECK_LOOP_WINDOW_MS;
287
+ monitored.toolCheckLoopTimestamps = monitored.toolCheckLoopTimestamps.filter((ts) => ts >= windowStart);
288
+ if (monitored.toolCheckLoopTimestamps.length >= GEMINI_TOOL_CHECK_LOOP_THRESHOLD) {
289
+ this.logger.warn('Gemini tool-check loop detected (#251), force-stopping agent', {
290
+ sessionName,
291
+ matchCount: monitored.toolCheckLoopTimestamps.length,
292
+ threshold: GEMINI_TOOL_CHECK_LOOP_THRESHOLD,
293
+ windowMs: GEMINI_TOOL_CHECK_LOOP_WINDOW_MS,
294
+ });
295
+ matched = true;
296
+ }
297
+ }
298
+ }
299
+ if (!matched) {
300
+ return;
301
+ }
302
+ // Pattern matched — start debounce timer to confirm
303
+ if (monitored.debounceTimer) {
304
+ clearTimeout(monitored.debounceTimer);
305
+ }
306
+ monitored.debounceTimer = setTimeout(() => {
307
+ this.confirmAndReact(sessionName, helper);
308
+ }, RUNTIME_EXIT_CONSTANTS.CONFIRMATION_DELAY_MS);
309
+ }
310
+ /**
311
+ * Confirm exit by checking for a shell prompt, then react.
312
+ *
313
+ * Runtime-specific failure checks are gated by runtimeType so that
314
+ * patterns for one runtime cannot accidentally match another (e.g. a
315
+ * Codex exit matching Claude or Gemini patterns).
316
+ *
317
+ * For Gemini CLI failure patterns (API errors, quota exhaustion, etc.),
318
+ * the system retries with exponential backoff before declaring the agent
319
+ * dead. Gemini CLI often recovers automatically from transient API errors
320
+ * (RESOURCE_EXHAUSTED, UNAVAILABLE, Connection error). Only after
321
+ * MAX_RETRIES does the system proceed with the exit/restart flow.
322
+ *
323
+ * For Claude Code fatal patterns (thinking block corruption, etc.),
324
+ * the system skips retry and forces immediate recovery since these
325
+ * errors are permanently unrecoverable within the same session.
326
+ */
327
+ async confirmAndReact(sessionName, helper) {
328
+ const monitored = this.sessions.get(sessionName);
329
+ if (!monitored || monitored.exitDetected || monitored.confirmationInFlight) {
330
+ return;
331
+ }
332
+ monitored.confirmationInFlight = true;
333
+ try {
334
+ // Verify shell prompt is visible (avoids false positives)
335
+ const shellPromptConfirmed = this.verifyExitWithShellPrompt(sessionName, helper);
336
+ if (!shellPromptConfirmed) {
337
+ const runtimeSpecificMatch = await this.checkRuntimeSpecificFailure(sessionName, monitored, helper);
338
+ if (!runtimeSpecificMatch) {
339
+ this.logger.debug('Exit pattern matched but shell prompt not confirmed, ignoring', { sessionName });
340
+ return;
341
+ }
342
+ }
343
+ // Mark as detected to prevent double-processing
344
+ monitored.exitDetected = true;
345
+ // Identify which exit pattern triggered detection for diagnostics
346
+ let matchedPatternSource;
347
+ try {
348
+ const runtimeService = RuntimeServiceFactory.create(monitored.runtimeType, null, process.cwd());
349
+ const patterns = runtimeService.getExitPatterns();
350
+ const matched = patterns.find((p) => p.test(monitored.buffer));
351
+ matchedPatternSource = matched?.source;
352
+ }
353
+ catch {
354
+ // Non-critical — pattern name is best-effort diagnostics
355
+ }
356
+ this.logger.info('Runtime exit detected and confirmed', {
357
+ sessionName,
358
+ runtimeType: monitored.runtimeType,
359
+ role: monitored.role,
360
+ matchedPattern: matchedPatternSource,
361
+ bufferTail: monitored.buffer.slice(-500),
362
+ });
363
+ // Fire the exit-detected callback (used to cancel pending registrations)
364
+ this.fireExitDetectedCallback(sessionName);
365
+ // Try agent restart if it has in-progress tasks (non-orchestrator only).
366
+ // V3-only as of spec 2026-05-06-task-management-v1-deprecation.md:
367
+ // active tasks are read from TaskPoolService inside `tryAgentRestartWithTasks`.
368
+ if (monitored.role !== ORCHESTRATOR_ROLE && this.agentRegistrationService) {
369
+ const restarted = await this.tryAgentRestartWithTasks(sessionName, monitored);
370
+ if (restarted)
371
+ return;
372
+ }
373
+ // #228/#234: Auto-restart agents that exit idle (Claude Code + Codex CLI).
374
+ // These runtimes exit after task completion or idle timeout. Restart to keep available.
375
+ if ((monitored.runtimeType === 'claude-code' || monitored.runtimeType === 'codex-cli')
376
+ && monitored.role !== ORCHESTRATOR_ROLE
377
+ && this.agentRegistrationService && this.isAgentRestartAllowed(sessionName)) {
378
+ try {
379
+ this.logger.info('Agent idle/clean exit — auto-restarting to maintain availability', { sessionName, runtimeType: monitored.runtimeType });
380
+ await this.restartAgentWithTasks(sessionName, monitored, []);
381
+ this.recordAgentRestart(sessionName);
382
+ this.stopMonitoring(sessionName);
383
+ return;
384
+ }
385
+ catch (restartError) {
386
+ this.logger.warn('Agent idle restart failed, transitioning to inactive', {
387
+ sessionName,
388
+ error: restartError instanceof Error ? restartError.message : String(restartError),
389
+ });
390
+ }
391
+ }
392
+ // Orchestrator-specific restart
393
+ if (sessionName === ORCHESTRATOR_SESSION_NAME) {
394
+ const restarted = await this.tryOrchestratorRestart(sessionName, monitored);
395
+ if (restarted)
396
+ return;
397
+ }
398
+ // Normal inactive flow: update status, capture memory, broadcast
399
+ await this.transitionToInactive(sessionName, monitored);
400
+ // Cleanup this subscription
401
+ this.stopMonitoring(sessionName);
402
+ }
403
+ finally {
404
+ monitored.confirmationInFlight = false;
405
+ }
406
+ }
407
+ /**
408
+ * Check for runtime-specific failure patterns when shell prompt is not confirmed.
409
+ *
410
+ * Gated by runtimeType so patterns for one runtime cannot accidentally
411
+ * match another. Returns true if a runtime-specific failure was detected,
412
+ * or 'deferred' handling occurred (Gemini retry).
413
+ *
414
+ * @param sessionName - PTY session name
415
+ * @param monitored - Monitored session state
416
+ * @param helper - Session command helper
417
+ * @returns True if a runtime-specific failure was confirmed
418
+ */
419
+ async checkRuntimeSpecificFailure(sessionName, monitored, helper) {
420
+ if (monitored.runtimeType === RUNTIME_TYPES.CODEX_CLI) {
421
+ const isCodexInterrupted = /Conversation interrupted/i.test(monitored.buffer);
422
+ if (isCodexInterrupted) {
423
+ this.logger.warn('Codex interruption detected, proceeding with recovery flow', { sessionName });
424
+ return true;
425
+ }
426
+ }
427
+ else if (monitored.runtimeType === RUNTIME_TYPES.CLAUDE_CODE) {
428
+ const isClaudeFatal = CLAUDE_FATAL_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
429
+ if (isClaudeFatal) {
430
+ const detectedPattern = CLAUDE_FATAL_PATTERNS.find((p) => p.test(monitored.buffer))?.source;
431
+ this.logger.warn('Claude Code fatal error detected, forcing immediate recovery', {
432
+ sessionName,
433
+ detectedPattern,
434
+ });
435
+ return true;
436
+ }
437
+ }
438
+ else if (monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI) {
439
+ // #251: Tool-check loop is a confirmed failure — agent is alive but stuck
440
+ if (monitored.toolCheckLoopTimestamps.length >= GEMINI_TOOL_CHECK_LOOP_THRESHOLD) {
441
+ this.logger.warn('Gemini tool-check loop confirmed (#251), forcing recovery', { sessionName });
442
+ return true;
443
+ }
444
+ // #188: Deliberation loop is also a confirmed failure
445
+ const deliberationCount = monitored.buffer.split(GEMINI_DELIBERATION_PATTERN).length - 1;
446
+ if (deliberationCount >= GEMINI_DELIBERATION_THRESHOLD) {
447
+ this.logger.warn('Gemini deliberation loop confirmed (#188), forcing recovery', { sessionName });
448
+ return true;
449
+ }
450
+ const isGeminiFailure = GEMINI_FAILURE_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
451
+ const isGeminiForceRestart = GEMINI_FORCE_RESTART_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
452
+ if (isGeminiFailure || isGeminiForceRestart) {
453
+ if (isGeminiForceRestart) {
454
+ this.logger.warn('Gemini auto-update interruption detected, forcing recovery flow', { sessionName });
455
+ }
456
+ else {
457
+ const retryResult = await this.handleGeminiFailureWithRetry(sessionName, monitored, helper);
458
+ if (retryResult === 'recovered' || retryResult === 'deferred') {
459
+ return false; // Not a confirmed exit — caller should return early
460
+ }
461
+ }
462
+ return true;
463
+ }
464
+ }
465
+ return false;
466
+ }
467
+ /**
468
+ * Fire the onExitDetected callback safely.
469
+ *
470
+ * @param sessionName - PTY session name
471
+ */
472
+ fireExitDetectedCallback(sessionName) {
473
+ if (!this.onExitDetectedCallback)
474
+ return;
475
+ try {
476
+ this.onExitDetectedCallback(sessionName);
477
+ }
478
+ catch (error) {
479
+ this.logger.warn('onExitDetected callback error', {
480
+ sessionName,
481
+ error: error instanceof Error ? error.message : String(error),
482
+ });
483
+ }
484
+ }
485
+ /**
486
+ * Try to restart an agent that has in-progress tasks.
487
+ *
488
+ * @param sessionName - PTY session name
489
+ * @param monitored - Monitored session state
490
+ * @returns True if the agent was successfully restarted (caller should return)
491
+ */
492
+ async tryAgentRestartWithTasks(sessionName, monitored) {
493
+ try {
494
+ // V3-only as of spec 2026-05-06-task-management-v1-deprecation.md.
495
+ // Replaces TaskTrackingService.getTasksForTeamMember with V3 pool
496
+ // query filtered by `target` (session name) and projected to
497
+ // the legacy InProgressTask shape so the rest of this method
498
+ // (notifyOrchestratorOfFailure, restartAgentWithTasks) works
499
+ // unchanged.
500
+ const { TaskPoolService } = await import('../task-pool/task-pool.service.js');
501
+ const { projectWorkItemToInProgressTask } = await import('../v3/work-item-projection.js');
502
+ const items = await TaskPoolService.getInstance().getAllItems();
503
+ const tasks = items
504
+ .filter((wi) => wi.target === sessionName)
505
+ .map(projectWorkItemToInProgressTask);
506
+ const activeTasks = tasks.filter(t => t.status === 'assigned' || t.status === 'active' || t.status === 'pending_assignment');
507
+ if (activeTasks.length === 0)
508
+ return false;
509
+ if (!this.isAgentRestartAllowed(sessionName)) {
510
+ this.logger.warn('Agent restart cooldown active, skipping restart', {
511
+ sessionName,
512
+ activeTaskCount: activeTasks.length,
513
+ maxRestartsPerWindow: AGENT_HEARTBEAT_MONITOR_CONSTANTS.MAX_RESTARTS_PER_WINDOW,
514
+ cooldownWindowMs: AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS,
515
+ });
516
+ this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited_cooldown', activeTasks, false);
517
+ return false;
518
+ }
519
+ this.logger.info('Runtime exit with in-progress tasks, attempting restart', {
520
+ sessionName,
521
+ activeTaskCount: activeTasks.length,
522
+ });
523
+ try {
524
+ await this.restartAgentWithTasks(sessionName, monitored, activeTasks);
525
+ this.recordAgentRestart(sessionName);
526
+ this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, true);
527
+ this.stopMonitoring(sessionName);
528
+ return true;
529
+ }
530
+ catch (restartError) {
531
+ this.logger.warn('Agent restart after runtime exit failed, falling back to inactive', {
532
+ sessionName,
533
+ error: restartError instanceof Error ? restartError.message : String(restartError),
534
+ });
535
+ this.recordAgentRestart(sessionName);
536
+ this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, false);
537
+ return false;
538
+ }
539
+ }
540
+ catch (error) {
541
+ this.logger.warn('Failed to check in-progress tasks after runtime exit', {
542
+ sessionName,
543
+ error: error instanceof Error ? error.message : String(error),
544
+ });
545
+ return false;
546
+ }
547
+ }
548
+ /**
549
+ * Try to restart the orchestrator after runtime exit.
550
+ *
551
+ * Sets status to inactive before restart to prevent queue processor
552
+ * from delivering messages during postInitialize, captures session
553
+ * memory, and broadcasts restart status.
554
+ *
555
+ * @param sessionName - PTY session name (should be ORCHESTRATOR_SESSION_NAME)
556
+ * @param monitored - Monitored session state
557
+ * @returns True if orchestrator was successfully restarted (caller should return)
558
+ */
559
+ async tryOrchestratorRestart(sessionName, monitored) {
560
+ // Set status to inactive BEFORE restart so the queue processor
561
+ // doesn't deliver messages during postInitialize.
562
+ try {
563
+ const storageService = StorageService.getInstance();
564
+ await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
565
+ }
566
+ catch {
567
+ // Best-effort — continue with restart
568
+ }
569
+ // Capture session memory before restart
570
+ try {
571
+ const sessionMemoryService = SessionMemoryService.getInstance();
572
+ await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
573
+ }
574
+ catch (error) {
575
+ this.logger.warn('Failed to capture session memory before orchestrator restart', {
576
+ sessionName,
577
+ error: error instanceof Error ? error.message : String(error),
578
+ });
579
+ }
580
+ try {
581
+ const restartService = OrchestratorRestartService.getInstance();
582
+ const success = await restartService.attemptRestart();
583
+ if (success) {
584
+ this.logger.info('Orchestrator restarted after runtime exit', { sessionName });
585
+ // Broadcast STARTED (not ACTIVE) — agent becomes ACTIVE only
586
+ // after registration prompt is processed and MCP call completes.
587
+ try {
588
+ const terminalGateway = getTerminalGateway();
589
+ if (terminalGateway) {
590
+ terminalGateway.broadcastOrchestratorStatus({
591
+ sessionName,
592
+ agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.STARTED,
593
+ reason: 'runtime_exit_restart',
594
+ });
595
+ }
596
+ }
597
+ catch {
598
+ // Best-effort broadcast
599
+ }
600
+ this.stopMonitoring(sessionName);
601
+ return true;
602
+ }
603
+ this.logger.warn('Orchestrator restart after runtime exit failed or not allowed, falling back to inactive', {
604
+ sessionName,
605
+ });
606
+ }
607
+ catch (error) {
608
+ this.logger.warn('Orchestrator restart attempt threw error, falling back to inactive', {
609
+ sessionName,
610
+ error: error instanceof Error ? error.message : String(error),
611
+ });
612
+ }
613
+ return false;
614
+ }
615
+ /**
616
+ * Transition agent to inactive state: update storage, capture memory,
617
+ * publish events, and broadcast WebSocket status.
618
+ *
619
+ * @param sessionName - PTY session name
620
+ * @param monitored - Monitored session state
621
+ */
622
+ async transitionToInactive(sessionName, monitored, dropoutReason) {
623
+ // #235: Determine dropout reason from exit patterns if not provided
624
+ const reason = dropoutReason || this.inferDropoutReason(monitored);
625
+ // Update agent status to inactive
626
+ try {
627
+ const storageService = StorageService.getInstance();
628
+ await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE, reason);
629
+ this.logger.info('Agent status updated to inactive after runtime exit', { sessionName, dropoutReason: reason });
630
+ // Publish agent:inactive event to EventBus so orchestrator is notified
631
+ if (this.eventBusService) {
632
+ try {
633
+ await this.publishInactiveEvent(sessionName, monitored, storageService);
634
+ }
635
+ catch (eventError) {
636
+ this.logger.warn('Failed to publish agent:inactive event to EventBus', {
637
+ sessionName,
638
+ error: eventError instanceof Error ? eventError.message : String(eventError),
639
+ });
640
+ }
641
+ }
642
+ }
643
+ catch (error) {
644
+ this.logger.warn('Failed to update agent status after runtime exit', {
645
+ sessionName,
646
+ error: error instanceof Error ? error.message : String(error),
647
+ });
648
+ }
649
+ // Capture session memory (skip for orchestrator — already captured above)
650
+ if (sessionName !== ORCHESTRATOR_SESSION_NAME) {
651
+ try {
652
+ const sessionMemoryService = SessionMemoryService.getInstance();
653
+ await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
654
+ }
655
+ catch (error) {
656
+ this.logger.warn('Failed to capture session memory after runtime exit', {
657
+ sessionName,
658
+ error: error instanceof Error ? error.message : String(error),
659
+ });
660
+ }
661
+ }
662
+ // Broadcast WebSocket event
663
+ try {
664
+ const terminalGateway = getTerminalGateway();
665
+ if (terminalGateway) {
666
+ const statusPayload = {
667
+ sessionName,
668
+ agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE,
669
+ reason: 'runtime_exited',
670
+ };
671
+ if (sessionName === ORCHESTRATOR_SESSION_NAME) {
672
+ terminalGateway.broadcastOrchestratorStatus(statusPayload);
673
+ }
674
+ else {
675
+ terminalGateway.broadcastTeamMemberStatus(statusPayload);
676
+ }
677
+ }
678
+ }
679
+ catch (error) {
680
+ this.logger.warn('Failed to broadcast runtime exit event', {
681
+ sessionName,
682
+ error: error instanceof Error ? error.message : String(error),
683
+ });
684
+ }
685
+ }
686
+ /**
687
+ * Handle a Gemini CLI failure with exponential backoff retry.
688
+ *
689
+ * Waits with increasing delays and checks if the CLI recovers (returns
690
+ * to a ready prompt). Returns 'recovered' if the CLI is back,
691
+ * 'deferred' if retries remain (skip exit flow, re-check on next
692
+ * failure detection), or 'exhausted' if max retries have been reached.
693
+ *
694
+ * @param sessionName - PTY session name
695
+ * @param monitored - Monitored session state (retry counter is mutated)
696
+ * @param helper - Session command helper for terminal output capture
697
+ * @returns 'recovered' | 'deferred' | 'exhausted'
698
+ */
699
+ async handleGeminiFailureWithRetry(sessionName, monitored, helper) {
700
+ const detectedPattern = GEMINI_FAILURE_PATTERNS.find((p) => p.test(monitored.buffer))?.source;
701
+ monitored.geminiFailureRetries++;
702
+ const { MAX_RETRIES, INITIAL_BACKOFF_MS, MAX_BACKOFF_MS, BACKOFF_MULTIPLIER, RECOVERY_CHECK_LINES, } = GEMINI_FAILURE_RETRY_CONSTANTS;
703
+ if (monitored.geminiFailureRetries > MAX_RETRIES) {
704
+ this.logger.warn('Gemini CLI failure retries exhausted, proceeding with exit flow', {
705
+ sessionName,
706
+ retries: monitored.geminiFailureRetries,
707
+ maxRetries: MAX_RETRIES,
708
+ detectedPattern,
709
+ });
710
+ return 'exhausted';
711
+ }
712
+ // Exponential backoff: INITIAL * MULTIPLIER^(retry-1), capped at MAX
713
+ const backoffMs = Math.min(INITIAL_BACKOFF_MS * Math.pow(BACKOFF_MULTIPLIER, monitored.geminiFailureRetries - 1), MAX_BACKOFF_MS);
714
+ this.logger.info('Gemini CLI failure detected, waiting for recovery', {
715
+ sessionName,
716
+ retry: monitored.geminiFailureRetries,
717
+ maxRetries: MAX_RETRIES,
718
+ backoffMs,
719
+ detectedPattern,
720
+ });
721
+ // Clear the buffer so the same error text doesn't immediately re-trigger
722
+ monitored.buffer = '';
723
+ await delay(backoffMs);
724
+ // Check if the CLI has recovered by looking for ready prompt patterns
725
+ try {
726
+ const output = helper.capturePane(sessionName, RECOVERY_CHECK_LINES);
727
+ const hasRecovered = GEMINI_READY_PATTERNS.some((pattern) => output.includes(pattern));
728
+ if (hasRecovered) {
729
+ this.logger.info('Gemini CLI recovered after transient failure', {
730
+ sessionName,
731
+ retry: monitored.geminiFailureRetries,
732
+ detectedPattern,
733
+ });
734
+ monitored.geminiFailureRetries = 0;
735
+ return 'recovered';
736
+ }
737
+ this.logger.debug('Gemini CLI has not recovered yet after backoff', {
738
+ sessionName,
739
+ retry: monitored.geminiFailureRetries,
740
+ maxRetries: MAX_RETRIES,
741
+ });
742
+ }
743
+ catch (error) {
744
+ this.logger.warn('Error checking Gemini CLI recovery', {
745
+ sessionName,
746
+ error: error instanceof Error ? error.message : String(error),
747
+ });
748
+ }
749
+ // Not recovered but retries remain — defer to the next failure detection cycle.
750
+ // The buffer was cleared above, so a new failure must appear in terminal
751
+ // output to re-trigger this method.
752
+ if (monitored.geminiFailureRetries < MAX_RETRIES) {
753
+ return 'deferred';
754
+ }
755
+ return 'exhausted';
756
+ }
757
+ /**
758
+ * Restart an agent that exited while it had in-progress tasks.
759
+ *
760
+ * Mirrors the restart pattern from AgentHeartbeatMonitorService:
761
+ * 1. Save Claude session ID for resume
762
+ * 2. Kill old PTY session + clear PTY activity tracker
763
+ * 3. Pre-set session ID for resume
764
+ * 4. Recreate agent session via AgentRegistrationService
765
+ * 5. Broadcast restarted status via WebSocket
766
+ * 6. Re-deliver tasks asynchronously
767
+ *
768
+ * @param sessionName - PTY session name
769
+ * @param monitored - Monitored session state
770
+ * @param activeTasks - In-progress tasks to re-deliver
771
+ */
772
+ async restartAgentWithTasks(sessionName, monitored, activeTasks) {
773
+ const backend = getSessionBackendSync();
774
+ if (!backend || !this.agentRegistrationService) {
775
+ throw new Error('Missing dependencies for agent restart');
776
+ }
777
+ // Save Claude session ID before killing
778
+ let claudeSessionId;
779
+ try {
780
+ const persistence = getSessionStatePersistence();
781
+ claudeSessionId = persistence.getSessionId(sessionName);
782
+ }
783
+ catch {
784
+ this.logger.warn('Could not retrieve Claude session ID for restart', { sessionName });
785
+ }
786
+ // Kill old PTY session
787
+ if (backend.sessionExists(sessionName)) {
788
+ await backend.killSession(sessionName);
789
+ }
790
+ // Clear PTY activity tracker
791
+ PtyActivityTrackerService.getInstance().clearSession(sessionName);
792
+ // Pre-set session ID for resume
793
+ if (claudeSessionId) {
794
+ try {
795
+ const persistence = getSessionStatePersistence();
796
+ const metadata = persistence.getSessionMetadata(sessionName);
797
+ if (metadata) {
798
+ persistence.updateSessionId(sessionName, claudeSessionId);
799
+ }
800
+ }
801
+ catch {
802
+ this.logger.warn('Could not pre-set session ID for resume', { sessionName });
803
+ }
804
+ }
805
+ // Recreate agent session
806
+ const result = await this.agentRegistrationService.createAgentSession({
807
+ sessionName,
808
+ role: monitored.role,
809
+ teamId: monitored.teamId,
810
+ memberId: monitored.memberId,
811
+ });
812
+ if (!result.success) {
813
+ throw new Error(result.error || 'createAgentSession failed');
814
+ }
815
+ // Broadcast agent restarted event
816
+ const terminalGateway = getTerminalGateway();
817
+ if (terminalGateway) {
818
+ terminalGateway.broadcastTeamMemberStatus({
819
+ teamId: monitored.teamId,
820
+ memberId: monitored.memberId,
821
+ sessionName,
822
+ agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE,
823
+ });
824
+ }
825
+ this.logger.info('Agent restarted after runtime exit with in-progress tasks', {
826
+ sessionName,
827
+ activeTaskCount: activeTasks.length,
828
+ claudeSessionId: claudeSessionId ? '(resumed)' : '(fresh)',
829
+ });
830
+ // Re-deliver in-progress tasks (async, non-blocking)
831
+ this.redeliverTasks(sessionName, activeTasks).catch((err) => {
832
+ this.logger.error('Task re-delivery failed after runtime exit restart', {
833
+ sessionName,
834
+ error: err instanceof Error ? err.message : String(err),
835
+ });
836
+ });
837
+ }
838
+ /**
839
+ * Re-deliver in-progress tasks to a restarted agent.
840
+ *
841
+ * Waits for the agent to initialize, reads task files, and writes
842
+ * summaries into the agent's PTY session.
843
+ *
844
+ * @param sessionName - PTY session name
845
+ * @param activeTasks - Tasks to re-deliver
846
+ */
847
+ async redeliverTasks(sessionName, activeTasks) {
848
+ // Wait for agent initialization
849
+ await delay(AGENT_SUSPEND_CONSTANTS.REHYDRATION_TIMEOUT_MS);
850
+ const backend = getSessionBackendSync();
851
+ if (!backend || !backend.sessionExists(sessionName)) {
852
+ this.logger.warn('Agent session not found after restart, skipping task re-delivery', { sessionName });
853
+ return;
854
+ }
855
+ const session = backend.getSession(sessionName);
856
+ if (!session) {
857
+ return;
858
+ }
859
+ this.logger.info('Re-delivering tasks to restarted agent', {
860
+ sessionName,
861
+ taskCount: activeTasks.length,
862
+ });
863
+ for (const task of activeTasks) {
864
+ let taskContent = '';
865
+ try {
866
+ taskContent = await fs.readFile(task.taskFilePath, 'utf-8');
867
+ if (taskContent.length > 2000) {
868
+ taskContent = taskContent.slice(0, 2000) + '\n... (truncated)';
869
+ }
870
+ }
871
+ catch {
872
+ taskContent = '(task file not found)';
873
+ }
874
+ const message = [
875
+ '[TASK RE-DELIVERY] You were working on this task before your session was restarted:',
876
+ `Task: ${task.taskName}`,
877
+ `File: ${task.taskFilePath}`,
878
+ '---',
879
+ taskContent,
880
+ '---',
881
+ 'Please continue working on this task.',
882
+ ].join('\n');
883
+ // Write message and Enter as separate writes so that Enter is not
884
+ // swallowed by the terminal's bracketed paste mode.
885
+ session.write(message);
886
+ // Delay to let the terminal finish processing the paste, then send Enter
887
+ const pasteDelay = Math.min(SESSION_COMMAND_DELAYS.MESSAGE_DELAY + Math.ceil(message.length / 10), 5000);
888
+ await delay(pasteDelay);
889
+ session.write('\r');
890
+ // Delay between tasks to avoid flooding
891
+ await delay(2000);
892
+ }
893
+ this.logger.info('Task re-delivery complete', {
894
+ sessionName,
895
+ tasksDelivered: activeTasks.length,
896
+ });
897
+ }
898
+ /**
899
+ * Periodic check: is the runtime child process still alive?
900
+ *
901
+ * Uses the session backend's isChildProcessAlive() (pgrep -P <pid>)
902
+ * to determine if the CLI process has exited. This is a version-agnostic
903
+ * fallback that doesn't depend on any text the CLI prints.
904
+ *
905
+ * @param sessionName - PTY session name
906
+ * @param backend - Session backend for process checks
907
+ * @param helper - Session command helper for shell prompt verification
908
+ */
909
+ checkProcessAlive(sessionName, backend, helper) {
910
+ const monitored = this.sessions.get(sessionName);
911
+ if (!monitored || monitored.exitDetected) {
912
+ return;
913
+ }
914
+ // Skip during startup grace period (CLI may not have spawned yet)
915
+ if (Date.now() - monitored.startedAt < RUNTIME_EXIT_CONSTANTS.PROCESS_POLL_GRACE_PERIOD_MS) {
916
+ return;
917
+ }
918
+ // Check if the backend supports process-alive checks
919
+ if (!backend.isChildProcessAlive) {
920
+ return;
921
+ }
922
+ const isAlive = backend.isChildProcessAlive(sessionName);
923
+ if (isAlive) {
924
+ return;
925
+ }
926
+ // Process is not alive — verify with shell prompt before confirming
927
+ if (!this.verifyExitWithShellPrompt(sessionName, helper)) {
928
+ this.logger.debug('Process not alive but shell prompt not confirmed, skipping', { sessionName });
929
+ return;
930
+ }
931
+ this.logger.info('Runtime exit detected via process check (no child process)', {
932
+ sessionName,
933
+ runtimeType: monitored.runtimeType,
934
+ });
935
+ // Trigger the same exit flow as pattern-based detection
936
+ this.confirmAndReact(sessionName, helper).catch((error) => {
937
+ this.logger.warn('confirmAndReact error from process check', {
938
+ sessionName,
939
+ error: error instanceof Error ? error.message : String(error),
940
+ });
941
+ });
942
+ }
943
+ /**
944
+ * Verify that a shell prompt is visible in the terminal, confirming
945
+ * that the agent CLI has actually exited and returned to the shell.
946
+ */
947
+ verifyExitWithShellPrompt(sessionName, helper) {
948
+ try {
949
+ const output = helper.capturePane(sessionName);
950
+ return SHELL_PROMPT_PATTERNS.some((pattern) => pattern.test(output));
951
+ }
952
+ catch {
953
+ return false;
954
+ }
955
+ }
956
+ /**
957
+ * Check if an agent restart is allowed based on cooldown window.
958
+ * Prevents infinite restart loops when agents keep crashing (e.g. during
959
+ * network outages). Uses the same limits as AgentHeartbeatMonitorService.
960
+ *
961
+ * @param sessionName - PTY session name
962
+ * @returns True if restart is allowed, false if cooldown is active
963
+ */
964
+ isAgentRestartAllowed(sessionName) {
965
+ const now = Date.now();
966
+ const windowStart = now - AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS;
967
+ const timestamps = this.restartHistory.get(sessionName) || [];
968
+ // Prune old timestamps outside the cooldown window
969
+ const recent = timestamps.filter(ts => ts > windowStart);
970
+ this.restartHistory.set(sessionName, recent);
971
+ return recent.length < AGENT_HEARTBEAT_MONITOR_CONSTANTS.MAX_RESTARTS_PER_WINDOW;
972
+ }
973
+ /**
974
+ * Record a restart attempt for cooldown tracking.
975
+ *
976
+ * @param sessionName - PTY session name
977
+ */
978
+ recordAgentRestart(sessionName) {
979
+ const timestamps = this.restartHistory.get(sessionName) || [];
980
+ timestamps.push(Date.now());
981
+ this.restartHistory.set(sessionName, timestamps);
982
+ }
983
+ /**
984
+ * Classify an error reason as transient or persistent.
985
+ *
986
+ * Transient errors (connectivity, timeout, quota) may resolve on retry.
987
+ * Persistent errors (auth, config, crash loop) require manual intervention.
988
+ *
989
+ * @param reason - The failure reason string
990
+ * @returns 'TRANSIENT' | 'PERSISTENT' | 'UNKNOWN'
991
+ */
992
+ classifyError(reason) {
993
+ const transientPatterns = [
994
+ 'timeout', 'connectivity', 'connection', 'quota', 'RESOURCE_EXHAUSTED',
995
+ 'UNAVAILABLE', 'DEADLINE_EXCEEDED', 'network', 'INTERNAL',
996
+ ];
997
+ const persistentPatterns = [
998
+ 'auth', 'UNAUTHENTICATED', 'PERMISSION_DENIED', 'config',
999
+ 'crash', 'cooldown', 'corruption', 'thinking.*blocks',
1000
+ ];
1001
+ const lowerReason = reason.toLowerCase();
1002
+ if (transientPatterns.some(p => lowerReason.includes(p.toLowerCase()))) {
1003
+ return 'TRANSIENT';
1004
+ }
1005
+ if (persistentPatterns.some(p => new RegExp(p, 'i').test(reason))) {
1006
+ return 'PERSISTENT';
1007
+ }
1008
+ return 'UNKNOWN';
1009
+ }
1010
+ /**
1011
+ * Notify the orchestrator about an agent failure via the chat API (#129).
1012
+ *
1013
+ * Sends a structured failure notification with error classification so the
1014
+ * orchestrator can decide whether to restart the agent, reassign tasks,
1015
+ * or inform the user. This is fire-and-forget — failures are logged but
1016
+ * do not block the exit flow.
1017
+ *
1018
+ * @param sessionName - Failed agent's PTY session name
1019
+ * @param reason - Failure reason (runtime_exited, api_failure, etc.)
1020
+ * @param activeTasks - In-progress tasks the agent had, if any
1021
+ * @param restartSucceeded - Whether automatic restart succeeded
1022
+ */
1023
+ notifyOrchestratorOfFailure(sessionName, reason, activeTasks, restartSucceeded) {
1024
+ const errorClass = this.classifyError(reason);
1025
+ const taskSummary = activeTasks.length > 0
1026
+ ? activeTasks.map(t => `${t.taskName} (${t.status})`).join(', ')
1027
+ : '';
1028
+ const message = [
1029
+ `Agent failure notification: ${sessionName} became inactive.`,
1030
+ `Reason: ${reason}`,
1031
+ `Error classification: ${errorClass}`,
1032
+ activeTasks.length > 0 ? `Active tasks: ${taskSummary}` : 'No active tasks.',
1033
+ restartSucceeded
1034
+ ? 'Automatic restart succeeded — agent is recovering.'
1035
+ : 'Automatic restart FAILED — please restart the agent or reassign its tasks.',
1036
+ ].join('\n');
1037
+ // Send via chat API (fire-and-forget)
1038
+ const backend = getSessionBackendSync();
1039
+ if (!backend)
1040
+ return;
1041
+ const helper = createSessionCommandHelper(backend);
1042
+ const orchestratorSession = helper.getSession(ORCHESTRATOR_SESSION_NAME);
1043
+ if (!orchestratorSession) {
1044
+ this.logger.debug('Orchestrator session not found, skipping failure notification', { sessionName });
1045
+ return;
1046
+ }
1047
+ // Use the deliver endpoint for reliable delivery to the orchestrator
1048
+ const baseUrl = process.env.CREWLY_API_URL || `http://localhost:${WEB_CONSTANTS.PORTS.BACKEND}`;
1049
+ const body = JSON.stringify({
1050
+ message,
1051
+ force: true,
1052
+ });
1053
+ // Fire-and-forget HTTP call
1054
+ try {
1055
+ const url = new URL(`${baseUrl}/api/terminal/${ORCHESTRATOR_SESSION_NAME}/deliver`);
1056
+ const req = http.request(url, {
1057
+ method: 'POST',
1058
+ headers: {
1059
+ 'Content-Type': 'application/json',
1060
+ 'Content-Length': Buffer.byteLength(body).toString(),
1061
+ },
1062
+ });
1063
+ req.on('response', (res) => res.resume()); // Consume response to free socket
1064
+ req.on('error', (err) => {
1065
+ this.logger.debug('Failed to deliver failure notification to orchestrator (non-fatal)', {
1066
+ sessionName,
1067
+ error: err.message,
1068
+ });
1069
+ });
1070
+ req.write(body);
1071
+ req.end();
1072
+ }
1073
+ catch {
1074
+ // Non-fatal — notification delivery is best-effort
1075
+ }
1076
+ this.logger.info('Sent agent failure notification to orchestrator (#129)', {
1077
+ sessionName,
1078
+ reason,
1079
+ activeTaskCount: activeTasks.length,
1080
+ restartSucceeded,
1081
+ });
1082
+ }
1083
+ /**
1084
+ * #235: Infer dropout reason from the monitored session's buffer.
1085
+ *
1086
+ * @param monitored - Monitored session state
1087
+ * @returns Inferred dropout reason
1088
+ */
1089
+ inferDropoutReason(monitored) {
1090
+ const buffer = monitored.buffer.toLowerCase();
1091
+ // #251: Check for tool-check loop (time-windowed timestamps)
1092
+ if (monitored.toolCheckLoopTimestamps.length >= GEMINI_TOOL_CHECK_LOOP_THRESHOLD) {
1093
+ return 'loop_detected';
1094
+ }
1095
+ // #188: Check for deliberation loop
1096
+ const deliberationCount = buffer.split(GEMINI_DELIBERATION_PATTERN).length - 1;
1097
+ if (deliberationCount >= GEMINI_DELIBERATION_THRESHOLD) {
1098
+ return 'loop_detected';
1099
+ }
1100
+ if (buffer.includes('update') && (buffer.includes('restart') || buffer.includes('upgrade'))) {
1101
+ return 'update_exit';
1102
+ }
1103
+ if (buffer.includes('fatal') || buffer.includes('panic') || buffer.includes('segfault') || buffer.includes('killed')) {
1104
+ return 'crash';
1105
+ }
1106
+ if (buffer.includes('task') && (buffer.includes('complete') || buffer.includes('done') || buffer.includes('finished'))) {
1107
+ return 'task_complete';
1108
+ }
1109
+ return 'idle_exit';
1110
+ }
1111
+ /**
1112
+ * Publish agent:status_changed and agent:inactive events to the EventBus.
1113
+ *
1114
+ * Looks up team/member names from StorageService to build the full
1115
+ * AgentEvent. This mirrors the pattern used in TeamsJsonWatcherService.
1116
+ *
1117
+ * @param sessionName - PTY session name
1118
+ * @param monitored - Monitored session state with teamId/memberId
1119
+ * @param storageService - StorageService instance for team/member lookup
1120
+ */
1121
+ async publishInactiveEvent(sessionName, monitored, storageService) {
1122
+ if (!this.eventBusService) {
1123
+ return;
1124
+ }
1125
+ // Look up team and member names
1126
+ let teamName = '';
1127
+ let memberName = '';
1128
+ try {
1129
+ const result = await storageService.findMemberBySessionName(sessionName);
1130
+ if (result) {
1131
+ teamName = result.team.name;
1132
+ memberName = result.member.name;
1133
+ }
1134
+ }
1135
+ catch {
1136
+ // Best-effort — use empty names if lookup fails
1137
+ }
1138
+ const baseEvent = {
1139
+ id: crypto.randomUUID(),
1140
+ type: 'agent:status_changed',
1141
+ timestamp: new Date().toISOString(),
1142
+ teamId: monitored.teamId || '',
1143
+ teamName,
1144
+ memberId: monitored.memberId || '',
1145
+ memberName,
1146
+ sessionName,
1147
+ previousValue: CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE,
1148
+ newValue: CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE,
1149
+ changedField: 'agentStatus',
1150
+ };
1151
+ // Publish generic status_changed event
1152
+ this.eventBusService.publish(baseEvent);
1153
+ // Publish specific agent:inactive event
1154
+ this.eventBusService.publish({
1155
+ ...baseEvent,
1156
+ id: crypto.randomUUID(),
1157
+ type: 'agent:inactive',
1158
+ });
1159
+ this.logger.info('Published agent:inactive event to EventBus', {
1160
+ sessionName,
1161
+ teamId: monitored.teamId,
1162
+ memberId: monitored.memberId,
1163
+ });
1164
+ }
1165
+ }
1166
+ //# sourceMappingURL=runtime-exit-monitor.service.js.map