crewly 1.13.0 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (985) hide show
  1. package/config/constants.ts +8 -0
  2. package/config/roles/orchestrator/prompt.md +23 -0
  3. package/config/skills/_common/complete-body-shape.test.sh +113 -0
  4. package/config/skills/_common/no-dangling-symlinks.test.sh +63 -0
  5. package/config/skills/_common/task-pool-body-shape.test.sh +471 -0
  6. package/config/skills/agent/core/accept-task/execute.sh +30 -5
  7. package/config/skills/agent/core/block-task/execute.sh +59 -6
  8. package/config/skills/agent/core/complete-task/SKILL.md +37 -5
  9. package/config/skills/agent/core/complete-task/execute.sh +40 -9
  10. package/config/skills/agent/core/complete-task/execute.test.sh +213 -0
  11. package/config/skills/agent/core/create-task/SKILL.md +33 -0
  12. package/config/skills/agent/core/create-task/execute.sh +82 -23
  13. package/config/skills/agent/core/delegate-task/execute.sh +46 -0
  14. package/config/skills/agent/core/get-team-norms/SKILL.md +1 -1
  15. package/config/skills/agent/core/get-team-norms/execute.sh +73 -2
  16. package/config/skills/agent/core/handoff-task/execute.sh +8 -1
  17. package/config/skills/agent/core/reply-channel/SKILL.md +6 -0
  18. package/config/skills/agent/core/reply-channel/execute.sh +14 -2
  19. package/config/skills/agent/core/report-status/SKILL.md +26 -0
  20. package/config/skills/agent/core/report-status/execute.sh +40 -5
  21. package/config/skills/agent/core/slack-post/SKILL.md +126 -0
  22. package/config/skills/agent/core/slack-post/execute.sh +127 -0
  23. package/config/skills/agent/remote-browser/SKILL.md +178 -0
  24. package/config/skills/agent/xiaoyuzhoufm-transcript/SKILL.md +46 -22
  25. package/config/skills/agent/xiaoyuzhoufm-transcript/execute.sh +82 -214
  26. package/config/skills/agent/xiaoyuzhoufm-transcript/skill.json +3 -3
  27. package/config/skills/orchestrator/delegate-task/SKILL.md +1 -1
  28. package/config/skills/orchestrator/delegate-task/execute.sh +45 -11
  29. package/config/skills/orchestrator/delegate-task/execute.test.sh +153 -1
  30. package/config/skills/orchestrator/get-team-status/SKILL.md +5 -1
  31. package/config/skills/orchestrator/get-team-status/execute.sh +28 -2
  32. package/config/skills/team-leader/aggregate-results/SKILL.md +1 -1
  33. package/config/skills/team-leader/decompose-goal/execute.sh +11 -16
  34. package/config/skills/team-leader/delegate-task/SKILL.md +14 -1
  35. package/config/skills/team-leader/delegate-task/execute.sh +132 -43
  36. package/config/skills/team-leader/delegate-task/execute.test.sh +180 -27
  37. package/config/slack-app-manifest.json +7 -1
  38. package/config/vitest-exclude.constants.ts +56 -0
  39. package/dist/backend/backend/src/config/oauth.config.d.ts +93 -19
  40. package/dist/backend/backend/src/config/oauth.config.d.ts.map +1 -1
  41. package/dist/backend/backend/src/config/oauth.config.js +121 -19
  42. package/dist/backend/backend/src/config/oauth.config.js.map +1 -1
  43. package/dist/backend/backend/src/constants.d.ts +60 -0
  44. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  45. package/dist/backend/backend/src/constants.js +74 -0
  46. package/dist/backend/backend/src/constants.js.map +1 -1
  47. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  48. package/dist/backend/backend/src/controllers/chat/chat.controller.js +33 -4
  49. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  50. package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.d.ts.map +1 -1
  51. package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.js +27 -9
  52. package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.js.map +1 -1
  53. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  54. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +18 -3
  55. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  56. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  57. package/dist/backend/backend/src/controllers/slack/slack.controller.js +360 -15
  58. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  59. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +6 -1
  60. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  61. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +19 -10
  62. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  63. package/dist/backend/backend/src/index.d.ts.map +1 -1
  64. package/dist/backend/backend/src/index.js +43 -7
  65. package/dist/backend/backend/src/index.js.map +1 -1
  66. package/dist/backend/backend/src/scripts/stamp-build.d.ts +25 -0
  67. package/dist/backend/backend/src/scripts/stamp-build.d.ts.map +1 -0
  68. package/dist/backend/backend/src/scripts/stamp-build.js +48 -0
  69. package/dist/backend/backend/src/scripts/stamp-build.js.map +1 -0
  70. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  71. package/dist/backend/backend/src/services/agent/agent-registration.service.js +25 -0
  72. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  73. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  74. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +9 -1
  75. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  76. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +42 -3
  77. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  78. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +22 -1
  79. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  80. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +10 -0
  81. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  82. package/dist/backend/backend/src/services/agent/idle-detection.service.js +37 -0
  83. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  84. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +13 -11
  86. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  87. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +14 -0
  88. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  89. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +56 -0
  90. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  91. package/dist/backend/backend/src/services/browser/browser-services.registry.d.ts +63 -0
  92. package/dist/backend/backend/src/services/browser/browser-services.registry.d.ts.map +1 -0
  93. package/dist/backend/backend/src/services/browser/browser-services.registry.js +74 -0
  94. package/dist/backend/backend/src/services/browser/browser-services.registry.js.map +1 -0
  95. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +25 -1
  96. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +19 -7
  98. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  99. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +57 -0
  100. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +110 -1
  102. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +21 -0
  104. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +43 -0
  106. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  107. package/dist/backend/backend/src/services/core/storage.service.d.ts +6 -0
  108. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  109. package/dist/backend/backend/src/services/core/storage.service.js +1 -1
  110. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  111. package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.d.ts.map +1 -1
  112. package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js +6 -2
  113. package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js.map +1 -1
  114. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +15 -0
  115. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -1
  116. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +54 -0
  117. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -1
  118. package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.d.ts +8 -0
  119. package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.d.ts.map +1 -1
  120. package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.js +31 -3
  121. package/dist/backend/backend/src/services/orc/orc-delivery-enforcer.service.js.map +1 -1
  122. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +28 -3
  123. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  124. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +65 -8
  125. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  126. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +214 -4
  127. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  128. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +330 -48
  129. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  130. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +47 -1
  131. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  132. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +183 -15
  133. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  134. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +14 -0
  135. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  136. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +77 -3
  137. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  138. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.d.ts +209 -0
  139. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.d.ts.map +1 -0
  140. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.js +416 -0
  141. package/dist/backend/backend/src/services/slack/slack-agent-identity.service.js.map +1 -0
  142. package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts +124 -0
  143. package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts.map +1 -0
  144. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js +243 -0
  145. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js.map +1 -0
  146. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts +11 -0
  147. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  148. package/dist/backend/backend/src/services/slack/slack-initializer.js +56 -0
  149. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  150. package/dist/backend/backend/src/services/slack/slack-mention-resolver.d.ts +103 -0
  151. package/dist/backend/backend/src/services/slack/slack-mention-resolver.d.ts.map +1 -0
  152. package/dist/backend/backend/src/services/slack/slack-mention-resolver.js +197 -0
  153. package/dist/backend/backend/src/services/slack/slack-mention-resolver.js.map +1 -0
  154. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  155. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +18 -0
  156. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  157. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +329 -0
  158. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -0
  159. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +821 -0
  160. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -0
  161. package/dist/backend/backend/src/services/slack/slack.service.d.ts +116 -1
  162. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  163. package/dist/backend/backend/src/services/slack/slack.service.js +297 -3
  164. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  165. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +152 -7
  166. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  167. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +268 -36
  168. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  169. package/dist/backend/backend/src/services/v3/escalation-router.service.js +2 -2
  170. package/dist/backend/backend/src/services/v3/escalation-router.service.js.map +1 -1
  171. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -1
  172. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +39 -2
  173. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -1
  174. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +22 -0
  175. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  176. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +71 -0
  177. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  178. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts +20 -2
  179. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts.map +1 -1
  180. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js +27 -2
  181. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js.map +1 -1
  182. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.d.ts +15 -2
  183. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.d.ts.map +1 -1
  184. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.js +33 -7
  185. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.js.map +1 -1
  186. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts +37 -0
  187. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts.map +1 -1
  188. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js +74 -8
  189. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js.map +1 -1
  190. package/dist/backend/backend/src/types/slack.types.d.ts +87 -0
  191. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  192. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  193. package/dist/backend/backend/src/types/v2/index.d.ts +1 -1
  194. package/dist/backend/backend/src/types/v2/index.d.ts.map +1 -1
  195. package/dist/backend/backend/src/types/v2/index.js +1 -1
  196. package/dist/backend/backend/src/types/v2/index.js.map +1 -1
  197. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +181 -1
  198. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  199. package/dist/backend/backend/src/types/v2/work-item.types.js +104 -17
  200. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  201. package/dist/backend/backend/src/utils/build-provenance.d.ts +150 -0
  202. package/dist/backend/backend/src/utils/build-provenance.d.ts.map +1 -0
  203. package/dist/backend/backend/src/utils/build-provenance.js +211 -0
  204. package/dist/backend/backend/src/utils/build-provenance.js.map +1 -0
  205. package/dist/backend/build-info.json +4 -0
  206. package/dist/backend/config/constants.d.ts +8 -0
  207. package/dist/backend/config/constants.d.ts.map +1 -1
  208. package/dist/backend/config/constants.js +8 -0
  209. package/dist/backend/config/constants.js.map +1 -1
  210. package/dist/backend/config/vitest-exclude.constants.d.ts +53 -0
  211. package/dist/backend/config/vitest-exclude.constants.d.ts.map +1 -0
  212. package/dist/backend/config/vitest-exclude.constants.js +55 -0
  213. package/dist/backend/config/vitest-exclude.constants.js.map +1 -0
  214. package/dist/cli/backend/src/config/oauth.config.d.ts +93 -19
  215. package/dist/cli/backend/src/config/oauth.config.d.ts.map +1 -1
  216. package/dist/cli/backend/src/config/oauth.config.js +121 -19
  217. package/dist/cli/backend/src/config/oauth.config.js.map +1 -1
  218. package/dist/cli/backend/src/constants.d.ts +60 -0
  219. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  220. package/dist/cli/backend/src/constants.js +74 -0
  221. package/dist/cli/backend/src/constants.js.map +1 -1
  222. package/dist/cli/backend/src/services/agent/active-work-briefing.service.d.ts +538 -0
  223. package/dist/cli/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  224. package/dist/cli/backend/src/services/agent/active-work-briefing.service.js +802 -0
  225. package/dist/cli/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  226. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.d.ts +240 -0
  227. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.d.ts.map +1 -0
  228. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.js +524 -0
  229. package/dist/cli/backend/src/services/agent/agent-heartbeat.service.js.map +1 -0
  230. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +629 -0
  231. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -0
  232. package/dist/cli/backend/src/services/agent/agent-registration.service.js +4548 -0
  233. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -0
  234. package/dist/cli/backend/src/services/agent/agent-suspend.service.d.ts +118 -0
  235. package/dist/cli/backend/src/services/agent/agent-suspend.service.d.ts.map +1 -0
  236. package/dist/cli/backend/src/services/agent/agent-suspend.service.js +304 -0
  237. package/dist/cli/backend/src/services/agent/agent-suspend.service.js.map +1 -0
  238. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.d.ts +196 -0
  239. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -0
  240. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js +504 -0
  241. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js.map +1 -0
  242. package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts +97 -0
  243. package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -0
  244. package/dist/cli/backend/src/services/agent/claude-runtime.service.js +334 -0
  245. package/dist/cli/backend/src/services/agent/claude-runtime.service.js.map +1 -0
  246. package/dist/cli/backend/src/services/agent/codex-runtime.service.d.ts +47 -0
  247. package/dist/cli/backend/src/services/agent/codex-runtime.service.d.ts.map +1 -0
  248. package/dist/cli/backend/src/services/agent/codex-runtime.service.js +112 -0
  249. package/dist/cli/backend/src/services/agent/codex-runtime.service.js.map +1 -0
  250. package/dist/cli/backend/src/services/agent/context-window-monitor.service.d.ts +323 -0
  251. package/dist/cli/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -0
  252. package/dist/cli/backend/src/services/agent/context-window-monitor.service.js +1056 -0
  253. package/dist/cli/backend/src/services/agent/context-window-monitor.service.js.map +1 -0
  254. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +198 -0
  255. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -0
  256. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +816 -0
  257. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -0
  258. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts +155 -0
  259. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts.map +1 -0
  260. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.js +272 -0
  261. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-log-buffer.js.map +1 -0
  262. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts +91 -0
  263. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts.map +1 -0
  264. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js +120 -0
  265. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js.map +1 -0
  266. package/dist/cli/backend/src/services/agent/crewly-agent/types.d.ts +536 -0
  267. package/dist/cli/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -0
  268. package/dist/cli/backend/src/services/agent/crewly-agent/types.js +282 -0
  269. package/dist/cli/backend/src/services/agent/crewly-agent/types.js.map +1 -0
  270. package/dist/cli/backend/src/services/agent/disk-cleanup.service.d.ts +100 -0
  271. package/dist/cli/backend/src/services/agent/disk-cleanup.service.d.ts.map +1 -0
  272. package/dist/cli/backend/src/services/agent/disk-cleanup.service.js +149 -0
  273. package/dist/cli/backend/src/services/agent/disk-cleanup.service.js.map +1 -0
  274. package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts +130 -0
  275. package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -0
  276. package/dist/cli/backend/src/services/agent/gemini-runtime.service.js +758 -0
  277. package/dist/cli/backend/src/services/agent/gemini-runtime.service.js.map +1 -0
  278. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +216 -0
  279. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -0
  280. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +508 -0
  281. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -0
  282. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.d.ts +113 -0
  283. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.d.ts.map +1 -0
  284. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.js +161 -0
  285. package/dist/cli/backend/src/services/agent/pty-activity-tracker.service.js.map +1 -0
  286. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts +156 -0
  287. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -0
  288. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +641 -0
  289. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -0
  290. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts +295 -0
  291. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -0
  292. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +1166 -0
  293. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -0
  294. package/dist/cli/backend/src/services/agent/runtime-service.factory.d.ts +71 -0
  295. package/dist/cli/backend/src/services/agent/runtime-service.factory.d.ts.map +1 -0
  296. package/dist/cli/backend/src/services/agent/runtime-service.factory.js +174 -0
  297. package/dist/cli/backend/src/services/agent/runtime-service.factory.js.map +1 -0
  298. package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts +435 -0
  299. package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -0
  300. package/dist/cli/backend/src/services/ai/prompt-builder.service.js +1331 -0
  301. package/dist/cli/backend/src/services/ai/prompt-builder.service.js.map +1 -0
  302. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.d.ts +33 -0
  303. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.d.ts.map +1 -0
  304. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.js +70 -0
  305. package/dist/cli/backend/src/services/ai/prompt-modules/capability-overlay.module.js.map +1 -0
  306. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts +100 -0
  307. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -0
  308. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js +296 -0
  309. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -0
  310. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts +59 -0
  311. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts.map +1 -0
  312. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js +87 -0
  313. package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -0
  314. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.d.ts +67 -0
  315. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.d.ts.map +1 -0
  316. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.js +84 -0
  317. package/dist/cli/backend/src/services/ai/prompt-modules/default-execution-loop.module.js.map +1 -0
  318. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.d.ts +35 -0
  319. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.d.ts.map +1 -0
  320. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.js +50 -0
  321. package/dist/cli/backend/src/services/ai/prompt-modules/domain-sop.module.js.map +1 -0
  322. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.d.ts +41 -0
  323. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.d.ts.map +1 -0
  324. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.js +95 -0
  325. package/dist/cli/backend/src/services/ai/prompt-modules/expert-profile.module.js.map +1 -0
  326. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.d.ts +28 -0
  327. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.d.ts.map +1 -0
  328. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.js +47 -0
  329. package/dist/cli/backend/src/services/ai/prompt-modules/identity.module.js.map +1 -0
  330. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.d.ts +65 -0
  331. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.d.ts.map +1 -0
  332. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js +79 -0
  333. package/dist/cli/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js.map +1 -0
  334. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.d.ts +28 -0
  335. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.d.ts.map +1 -0
  336. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.js +55 -0
  337. package/dist/cli/backend/src/services/ai/prompt-modules/learning-reference.module.js.map +1 -0
  338. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.d.ts +44 -0
  339. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.d.ts.map +1 -0
  340. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.js +120 -0
  341. package/dist/cli/backend/src/services/ai/prompt-modules/lifecycle.module.js.map +1 -0
  342. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.d.ts +46 -0
  343. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.d.ts.map +1 -0
  344. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.js +44 -0
  345. package/dist/cli/backend/src/services/ai/prompt-modules/markdown-file-module.js.map +1 -0
  346. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts +28 -0
  347. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.d.ts.map +1 -0
  348. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.js +46 -0
  349. package/dist/cli/backend/src/services/ai/prompt-modules/memory-reference.module.js.map +1 -0
  350. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.d.ts +60 -0
  351. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.d.ts.map +1 -0
  352. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.js +104 -0
  353. package/dist/cli/backend/src/services/ai/prompt-modules/mission-context.module.js.map +1 -0
  354. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.d.ts +29 -0
  355. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.d.ts.map +1 -0
  356. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.js +50 -0
  357. package/dist/cli/backend/src/services/ai/prompt-modules/project-reference.module.js.map +1 -0
  358. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts +103 -0
  359. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -0
  360. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +383 -0
  361. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -0
  362. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.d.ts +34 -0
  363. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -0
  364. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.js +96 -0
  365. package/dist/cli/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -0
  366. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.d.ts +106 -0
  367. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.d.ts.map +1 -0
  368. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.js +167 -0
  369. package/dist/cli/backend/src/services/ai/prompt-modules/request-contract.module.js.map +1 -0
  370. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.d.ts +35 -0
  371. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.d.ts.map +1 -0
  372. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.js +50 -0
  373. package/dist/cli/backend/src/services/ai/prompt-modules/risk-policy.module.js.map +1 -0
  374. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts +91 -0
  375. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -0
  376. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.js +411 -0
  377. package/dist/cli/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -0
  378. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts +62 -0
  379. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -0
  380. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +199 -0
  381. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -0
  382. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  383. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  384. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  385. package/dist/cli/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  386. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.d.ts +102 -0
  387. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.d.ts.map +1 -0
  388. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.js +229 -0
  389. package/dist/cli/backend/src/services/ai/prompt-modules/soul.module.js.map +1 -0
  390. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.d.ts +61 -0
  391. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.d.ts.map +1 -0
  392. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.js +197 -0
  393. package/dist/cli/backend/src/services/ai/prompt-modules/team-norms.module.js.map +1 -0
  394. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.d.ts +54 -0
  395. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.d.ts.map +1 -0
  396. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.js +149 -0
  397. package/dist/cli/backend/src/services/ai/prompt-modules/team-reference.module.js.map +1 -0
  398. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.d.ts +32 -0
  399. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.d.ts.map +1 -0
  400. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.js +69 -0
  401. package/dist/cli/backend/src/services/ai/prompt-modules/user-profile-reference.module.js.map +1 -0
  402. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.d.ts +91 -0
  403. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.d.ts.map +1 -0
  404. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.js +136 -0
  405. package/dist/cli/backend/src/services/ai/prompt-modules/working-memory.module.js.map +1 -0
  406. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.d.ts +81 -0
  407. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.d.ts.map +1 -0
  408. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.js +135 -0
  409. package/dist/cli/backend/src/services/ai/self-improvement/growth-areas.service.js.map +1 -0
  410. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +292 -0
  411. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
  412. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +420 -0
  413. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
  414. package/dist/cli/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
  415. package/dist/cli/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
  416. package/dist/cli/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
  417. package/dist/cli/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
  418. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +794 -0
  419. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  420. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +1322 -0
  421. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  422. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  423. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  424. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  425. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  426. package/dist/cli/backend/src/services/chat-v2/config.d.ts +100 -0
  427. package/dist/cli/backend/src/services/chat-v2/config.d.ts.map +1 -0
  428. package/dist/cli/backend/src/services/chat-v2/config.js +174 -0
  429. package/dist/cli/backend/src/services/chat-v2/config.js.map +1 -0
  430. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.d.ts +118 -0
  431. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.d.ts.map +1 -0
  432. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.js +171 -0
  433. package/dist/cli/backend/src/services/chat-v2/legacy-dto.utils.js.map +1 -0
  434. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.d.ts +188 -0
  435. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  436. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.js +317 -0
  437. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  438. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.d.ts +119 -0
  439. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  440. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.js +551 -0
  441. package/dist/cli/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  442. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts +229 -0
  443. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  444. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js +448 -0
  445. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  446. package/dist/cli/backend/src/services/chat-v2/types.d.ts +341 -0
  447. package/dist/cli/backend/src/services/chat-v2/types.d.ts.map +1 -0
  448. package/dist/cli/backend/src/services/chat-v2/types.js +61 -0
  449. package/dist/cli/backend/src/services/chat-v2/types.js.map +1 -0
  450. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.d.ts +37 -0
  451. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.d.ts.map +1 -0
  452. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.js +63 -0
  453. package/dist/cli/backend/src/services/continuation/patterns/idle-patterns.js.map +1 -0
  454. package/dist/cli/backend/src/services/core/storage.service.d.ts +6 -0
  455. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  456. package/dist/cli/backend/src/services/core/storage.service.js +1 -1
  457. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  458. package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.d.ts.map +1 -1
  459. package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js +6 -2
  460. package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js.map +1 -1
  461. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.d.ts +335 -0
  462. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.d.ts.map +1 -0
  463. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.js +421 -0
  464. package/dist/cli/backend/src/services/intent-task/intent-classifier.rules.js.map +1 -0
  465. package/dist/cli/backend/src/services/mcp-client.d.ts +233 -0
  466. package/dist/cli/backend/src/services/mcp-client.d.ts.map +1 -0
  467. package/dist/cli/backend/src/services/mcp-client.js +302 -0
  468. package/dist/cli/backend/src/services/mcp-client.js.map +1 -0
  469. package/dist/cli/backend/src/services/memory/mission-context.service.d.ts +168 -0
  470. package/dist/cli/backend/src/services/memory/mission-context.service.d.ts.map +1 -0
  471. package/dist/cli/backend/src/services/memory/mission-context.service.js +365 -0
  472. package/dist/cli/backend/src/services/memory/mission-context.service.js.map +1 -0
  473. package/dist/cli/backend/src/services/memory/session-memory.service.d.ts +197 -0
  474. package/dist/cli/backend/src/services/memory/session-memory.service.d.ts.map +1 -0
  475. package/dist/cli/backend/src/services/memory/session-memory.service.js +369 -0
  476. package/dist/cli/backend/src/services/memory/session-memory.service.js.map +1 -0
  477. package/dist/cli/backend/src/services/memory/user-profile.service.d.ts +77 -0
  478. package/dist/cli/backend/src/services/memory/user-profile.service.d.ts.map +1 -0
  479. package/dist/cli/backend/src/services/memory/user-profile.service.js +171 -0
  480. package/dist/cli/backend/src/services/memory/user-profile.service.js.map +1 -0
  481. package/dist/cli/backend/src/services/memory/working-memory.service.d.ts +232 -0
  482. package/dist/cli/backend/src/services/memory/working-memory.service.d.ts.map +1 -0
  483. package/dist/cli/backend/src/services/memory/working-memory.service.js +417 -0
  484. package/dist/cli/backend/src/services/memory/working-memory.service.js.map +1 -0
  485. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +84 -0
  486. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -0
  487. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +136 -0
  488. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -0
  489. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts +358 -0
  490. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts.map +1 -0
  491. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js +755 -0
  492. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js.map +1 -0
  493. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +269 -0
  494. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -0
  495. package/dist/cli/backend/src/services/monitoring/token-usage.service.js +391 -0
  496. package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -0
  497. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.d.ts +132 -0
  498. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.d.ts.map +1 -0
  499. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.js +284 -0
  500. package/dist/cli/backend/src/services/observability/agent-behavior-log.service.js.map +1 -0
  501. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.d.ts +70 -0
  502. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.d.ts.map +1 -0
  503. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.js +121 -0
  504. package/dist/cli/backend/src/services/observability/agent-behavior-log.singleton.js.map +1 -0
  505. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.d.ts +130 -0
  506. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.d.ts.map +1 -0
  507. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.js +48 -0
  508. package/dist/cli/backend/src/services/observability/agent-behavior-log.types.js.map +1 -0
  509. package/dist/cli/backend/src/services/observability/observability-db.d.ts +84 -0
  510. package/dist/cli/backend/src/services/observability/observability-db.d.ts.map +1 -0
  511. package/dist/cli/backend/src/services/observability/observability-db.js +165 -0
  512. package/dist/cli/backend/src/services/observability/observability-db.js.map +1 -0
  513. package/dist/cli/backend/src/services/onboarding/content-approval.service.d.ts +124 -0
  514. package/dist/cli/backend/src/services/onboarding/content-approval.service.d.ts.map +1 -0
  515. package/dist/cli/backend/src/services/onboarding/content-approval.service.js +256 -0
  516. package/dist/cli/backend/src/services/onboarding/content-approval.service.js.map +1 -0
  517. package/dist/cli/backend/src/services/onboarding/content-approval.types.d.ts +80 -0
  518. package/dist/cli/backend/src/services/onboarding/content-approval.types.d.ts.map +1 -0
  519. package/dist/cli/backend/src/services/onboarding/content-approval.types.js +16 -0
  520. package/dist/cli/backend/src/services/onboarding/content-approval.types.js.map +1 -0
  521. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.d.ts +150 -0
  522. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.d.ts.map +1 -0
  523. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.js +293 -0
  524. package/dist/cli/backend/src/services/orc/orc-delivery-enforcer.service.js.map +1 -0
  525. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.d.ts +231 -0
  526. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.d.ts.map +1 -0
  527. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.js +353 -0
  528. package/dist/cli/backend/src/services/orchestrator/improvement-marker.service.js.map +1 -0
  529. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.d.ts +157 -0
  530. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.d.ts.map +1 -0
  531. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.js +483 -0
  532. package/dist/cli/backend/src/services/orchestrator/improvement-startup.service.js.map +1 -0
  533. package/dist/cli/backend/src/services/orchestrator/index.d.ts +16 -0
  534. package/dist/cli/backend/src/services/orchestrator/index.d.ts.map +1 -0
  535. package/dist/cli/backend/src/services/orchestrator/index.js +16 -0
  536. package/dist/cli/backend/src/services/orchestrator/index.js.map +1 -0
  537. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +117 -0
  538. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -0
  539. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js +300 -0
  540. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -0
  541. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.d.ts +114 -0
  542. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.d.ts.map +1 -0
  543. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.js +195 -0
  544. package/dist/cli/backend/src/services/orchestrator/orchestrator-setup.service.js.map +1 -0
  545. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts +94 -0
  546. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -0
  547. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js +279 -0
  548. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -0
  549. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.d.ts +192 -0
  550. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.d.ts.map +1 -0
  551. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.js +395 -0
  552. package/dist/cli/backend/src/services/orchestrator/safe-restart.service.js.map +1 -0
  553. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.d.ts +201 -0
  554. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.d.ts.map +1 -0
  555. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.js +396 -0
  556. package/dist/cli/backend/src/services/orchestrator/self-improvement.service.js.map +1 -0
  557. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.d.ts +17 -0
  558. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.d.ts.map +1 -0
  559. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.js +30 -0
  560. package/dist/cli/backend/src/services/orchestrator/slack-bridge-lazy.js.map +1 -0
  561. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.d.ts +249 -0
  562. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.d.ts.map +1 -0
  563. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.js +569 -0
  564. package/dist/cli/backend/src/services/orchestrator/state-persistence.service.js.map +1 -0
  565. package/dist/cli/backend/src/services/session/index.d.ts +47 -0
  566. package/dist/cli/backend/src/services/session/index.d.ts.map +1 -0
  567. package/dist/cli/backend/src/services/session/index.js +50 -0
  568. package/dist/cli/backend/src/services/session/index.js.map +1 -0
  569. package/dist/cli/backend/src/services/session/log-rotation.service.d.ts +163 -0
  570. package/dist/cli/backend/src/services/session/log-rotation.service.d.ts.map +1 -0
  571. package/dist/cli/backend/src/services/session/log-rotation.service.js +362 -0
  572. package/dist/cli/backend/src/services/session/log-rotation.service.js.map +1 -0
  573. package/dist/cli/backend/src/services/session/pty/index.d.ts +11 -0
  574. package/dist/cli/backend/src/services/session/pty/index.d.ts.map +1 -0
  575. package/dist/cli/backend/src/services/session/pty/index.js +11 -0
  576. package/dist/cli/backend/src/services/session/pty/index.js.map +1 -0
  577. package/dist/cli/backend/src/services/session/pty/pty-session-backend.d.ts +445 -0
  578. package/dist/cli/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -0
  579. package/dist/cli/backend/src/services/session/pty/pty-session-backend.js +804 -0
  580. package/dist/cli/backend/src/services/session/pty/pty-session-backend.js.map +1 -0
  581. package/dist/cli/backend/src/services/session/pty/pty-session.d.ts +252 -0
  582. package/dist/cli/backend/src/services/session/pty/pty-session.d.ts.map +1 -0
  583. package/dist/cli/backend/src/services/session/pty/pty-session.js +611 -0
  584. package/dist/cli/backend/src/services/session/pty/pty-session.js.map +1 -0
  585. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.d.ts +275 -0
  586. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.d.ts.map +1 -0
  587. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.js +403 -0
  588. package/dist/cli/backend/src/services/session/pty/pty-terminal-buffer.js.map +1 -0
  589. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.d.ts +86 -0
  590. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.d.ts.map +1 -0
  591. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.js +214 -0
  592. package/dist/cli/backend/src/services/session/runtime-pid-registry.service.js.map +1 -0
  593. package/dist/cli/backend/src/services/session/session-backend.factory.d.ts +127 -0
  594. package/dist/cli/backend/src/services/session/session-backend.factory.d.ts.map +1 -0
  595. package/dist/cli/backend/src/services/session/session-backend.factory.js +226 -0
  596. package/dist/cli/backend/src/services/session/session-backend.factory.js.map +1 -0
  597. package/dist/cli/backend/src/services/session/session-backend.interface.d.ts +390 -0
  598. package/dist/cli/backend/src/services/session/session-backend.interface.d.ts.map +1 -0
  599. package/dist/cli/backend/src/services/session/session-backend.interface.js +19 -0
  600. package/dist/cli/backend/src/services/session/session-backend.interface.js.map +1 -0
  601. package/dist/cli/backend/src/services/session/session-command-helper.d.ts +350 -0
  602. package/dist/cli/backend/src/services/session/session-command-helper.d.ts.map +1 -0
  603. package/dist/cli/backend/src/services/session/session-command-helper.js +810 -0
  604. package/dist/cli/backend/src/services/session/session-command-helper.js.map +1 -0
  605. package/dist/cli/backend/src/services/session/session-handoff.service.d.ts +307 -0
  606. package/dist/cli/backend/src/services/session/session-handoff.service.d.ts.map +1 -0
  607. package/dist/cli/backend/src/services/session/session-handoff.service.js +742 -0
  608. package/dist/cli/backend/src/services/session/session-handoff.service.js.map +1 -0
  609. package/dist/cli/backend/src/services/session/session-state-persistence.d.ts +231 -0
  610. package/dist/cli/backend/src/services/session/session-state-persistence.d.ts.map +1 -0
  611. package/dist/cli/backend/src/services/session/session-state-persistence.js +407 -0
  612. package/dist/cli/backend/src/services/session/session-state-persistence.js.map +1 -0
  613. package/dist/cli/backend/src/services/settings/role.service.d.ts +277 -0
  614. package/dist/cli/backend/src/services/settings/role.service.d.ts.map +1 -0
  615. package/dist/cli/backend/src/services/settings/role.service.js +728 -0
  616. package/dist/cli/backend/src/services/settings/role.service.js.map +1 -0
  617. package/dist/cli/backend/src/services/slack/cross-machine-message.service.d.ts +152 -0
  618. package/dist/cli/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -0
  619. package/dist/cli/backend/src/services/slack/cross-machine-message.service.js +354 -0
  620. package/dist/cli/backend/src/services/slack/cross-machine-message.service.js.map +1 -0
  621. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.d.ts +209 -0
  622. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.d.ts.map +1 -0
  623. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.js +416 -0
  624. package/dist/cli/backend/src/services/slack/slack-agent-identity.service.js.map +1 -0
  625. package/dist/cli/backend/src/services/slack/slack-image.service.d.ts +114 -0
  626. package/dist/cli/backend/src/services/slack/slack-image.service.d.ts.map +1 -0
  627. package/dist/cli/backend/src/services/slack/slack-image.service.js +331 -0
  628. package/dist/cli/backend/src/services/slack/slack-image.service.js.map +1 -0
  629. package/dist/cli/backend/src/services/slack/slack-mention-resolver.d.ts +103 -0
  630. package/dist/cli/backend/src/services/slack/slack-mention-resolver.d.ts.map +1 -0
  631. package/dist/cli/backend/src/services/slack/slack-mention-resolver.js +197 -0
  632. package/dist/cli/backend/src/services/slack/slack-mention-resolver.js.map +1 -0
  633. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +499 -0
  634. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -0
  635. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +1946 -0
  636. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -0
  637. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +329 -0
  638. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -0
  639. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +821 -0
  640. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -0
  641. package/dist/cli/backend/src/services/slack/slack.service.d.ts +430 -0
  642. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -0
  643. package/dist/cli/backend/src/services/slack/slack.service.js +1388 -0
  644. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -0
  645. package/dist/cli/backend/src/services/sop/sop.service.d.ts +364 -0
  646. package/dist/cli/backend/src/services/sop/sop.service.d.ts.map +1 -0
  647. package/dist/cli/backend/src/services/sop/sop.service.js +734 -0
  648. package/dist/cli/backend/src/services/sop/sop.service.js.map +1 -0
  649. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +152 -7
  650. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  651. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +268 -36
  652. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  653. package/dist/cli/backend/src/services/v3/escalation-router.service.d.ts +178 -0
  654. package/dist/cli/backend/src/services/v3/escalation-router.service.d.ts.map +1 -0
  655. package/dist/cli/backend/src/services/v3/escalation-router.service.js +692 -0
  656. package/dist/cli/backend/src/services/v3/escalation-router.service.js.map +1 -0
  657. package/dist/cli/backend/src/services/v3/kr-tracking.service.d.ts +200 -0
  658. package/dist/cli/backend/src/services/v3/kr-tracking.service.d.ts.map +1 -0
  659. package/dist/cli/backend/src/services/v3/kr-tracking.service.js +482 -0
  660. package/dist/cli/backend/src/services/v3/kr-tracking.service.js.map +1 -0
  661. package/dist/cli/backend/src/services/v3/mission-executor.service.d.ts +117 -0
  662. package/dist/cli/backend/src/services/v3/mission-executor.service.d.ts.map +1 -0
  663. package/dist/cli/backend/src/services/v3/mission-executor.service.js +321 -0
  664. package/dist/cli/backend/src/services/v3/mission-executor.service.js.map +1 -0
  665. package/dist/cli/backend/src/services/v3/request-sla.subscriber.d.ts +610 -0
  666. package/dist/cli/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  667. package/dist/cli/backend/src/services/v3/request-sla.subscriber.js +1529 -0
  668. package/dist/cli/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  669. package/dist/cli/backend/src/services/v3/request-tracker.service.d.ts +78 -0
  670. package/dist/cli/backend/src/services/v3/request-tracker.service.d.ts.map +1 -0
  671. package/dist/cli/backend/src/services/v3/request-tracker.service.js +108 -0
  672. package/dist/cli/backend/src/services/v3/request-tracker.service.js.map +1 -0
  673. package/dist/cli/backend/src/services/v3/request.service.d.ts +295 -0
  674. package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -0
  675. package/dist/cli/backend/src/services/v3/request.service.js +534 -0
  676. package/dist/cli/backend/src/services/v3/request.service.js.map +1 -0
  677. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts +340 -0
  678. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts.map +1 -0
  679. package/dist/cli/backend/src/services/v3/v3-data.service.js +1113 -0
  680. package/dist/cli/backend/src/services/v3/v3-data.service.js.map +1 -0
  681. package/dist/cli/backend/src/types/cross-machine.types.d.ts +103 -0
  682. package/dist/cli/backend/src/types/cross-machine.types.d.ts.map +1 -0
  683. package/dist/cli/backend/src/types/cross-machine.types.js +47 -0
  684. package/dist/cli/backend/src/types/cross-machine.types.js.map +1 -0
  685. package/dist/cli/backend/src/types/intent-task.types.d.ts +402 -0
  686. package/dist/cli/backend/src/types/intent-task.types.d.ts.map +1 -0
  687. package/dist/cli/backend/src/types/intent-task.types.js +403 -0
  688. package/dist/cli/backend/src/types/intent-task.types.js.map +1 -0
  689. package/dist/cli/backend/src/types/orchestrator-state.types.d.ts +531 -0
  690. package/dist/cli/backend/src/types/orchestrator-state.types.d.ts.map +1 -0
  691. package/dist/cli/backend/src/types/orchestrator-state.types.js +110 -0
  692. package/dist/cli/backend/src/types/orchestrator-state.types.js.map +1 -0
  693. package/dist/cli/backend/src/types/slack.types.d.ts +87 -0
  694. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
  695. package/dist/cli/backend/src/types/slack.types.js.map +1 -1
  696. package/dist/cli/backend/src/types/v2/index.d.ts +30 -0
  697. package/dist/cli/backend/src/types/v2/index.d.ts.map +1 -0
  698. package/dist/cli/backend/src/types/v2/index.js +22 -0
  699. package/dist/cli/backend/src/types/v2/index.js.map +1 -0
  700. package/dist/cli/backend/src/types/v2/key-result.types.d.ts +279 -0
  701. package/dist/cli/backend/src/types/v2/key-result.types.d.ts.map +1 -0
  702. package/dist/cli/backend/src/types/v2/key-result.types.js +264 -0
  703. package/dist/cli/backend/src/types/v2/key-result.types.js.map +1 -0
  704. package/dist/cli/backend/src/types/v2/mission.types.d.ts +661 -0
  705. package/dist/cli/backend/src/types/v2/mission.types.d.ts.map +1 -0
  706. package/dist/cli/backend/src/types/v2/mission.types.js +713 -0
  707. package/dist/cli/backend/src/types/v2/mission.types.js.map +1 -0
  708. package/dist/cli/backend/src/types/v2/reconcile.types.d.ts +204 -0
  709. package/dist/cli/backend/src/types/v2/reconcile.types.d.ts.map +1 -0
  710. package/dist/cli/backend/src/types/v2/reconcile.types.js +121 -0
  711. package/dist/cli/backend/src/types/v2/reconcile.types.js.map +1 -0
  712. package/dist/cli/backend/src/types/v2/request.types.d.ts +192 -0
  713. package/dist/cli/backend/src/types/v2/request.types.d.ts.map +1 -0
  714. package/dist/cli/backend/src/types/v2/request.types.js +179 -0
  715. package/dist/cli/backend/src/types/v2/request.types.js.map +1 -0
  716. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +181 -1
  717. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  718. package/dist/cli/backend/src/types/v2/work-item.types.js +104 -17
  719. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  720. package/dist/cli/backend/src/types/v2/workspace.types.d.ts +157 -0
  721. package/dist/cli/backend/src/types/v2/workspace.types.d.ts.map +1 -0
  722. package/dist/cli/backend/src/types/v2/workspace.types.js +173 -0
  723. package/dist/cli/backend/src/types/v2/workspace.types.js.map +1 -0
  724. package/dist/cli/backend/src/utils/async.utils.d.ts +68 -0
  725. package/dist/cli/backend/src/utils/async.utils.d.ts.map +1 -0
  726. package/dist/cli/backend/src/utils/async.utils.js +80 -0
  727. package/dist/cli/backend/src/utils/async.utils.js.map +1 -0
  728. package/dist/cli/backend/src/utils/native-binding.utils.d.ts +128 -0
  729. package/dist/cli/backend/src/utils/native-binding.utils.d.ts.map +1 -0
  730. package/dist/cli/backend/src/utils/native-binding.utils.js +206 -0
  731. package/dist/cli/backend/src/utils/native-binding.utils.js.map +1 -0
  732. package/dist/cli/backend/src/utils/team.utils.d.ts +40 -0
  733. package/dist/cli/backend/src/utils/team.utils.d.ts.map +1 -0
  734. package/dist/cli/backend/src/utils/team.utils.js +66 -0
  735. package/dist/cli/backend/src/utils/team.utils.js.map +1 -0
  736. package/dist/cli/backend/src/websocket/chat.gateway.d.ts +142 -0
  737. package/dist/cli/backend/src/websocket/chat.gateway.d.ts.map +1 -0
  738. package/dist/cli/backend/src/websocket/chat.gateway.js +327 -0
  739. package/dist/cli/backend/src/websocket/chat.gateway.js.map +1 -0
  740. package/dist/cli/backend/src/websocket/terminal.gateway.d.ts +341 -0
  741. package/dist/cli/backend/src/websocket/terminal.gateway.d.ts.map +1 -0
  742. package/dist/cli/backend/src/websocket/terminal.gateway.js +933 -0
  743. package/dist/cli/backend/src/websocket/terminal.gateway.js.map +1 -0
  744. package/dist/cli/cli/src/index.js +0 -0
  745. package/dist/cli/config/constants.d.ts +8 -0
  746. package/dist/cli/config/constants.d.ts.map +1 -1
  747. package/dist/cli/config/constants.js +8 -0
  748. package/dist/cli/config/constants.js.map +1 -1
  749. package/dist/cli/config/vitest-exclude.constants.d.ts +53 -0
  750. package/dist/cli/config/vitest-exclude.constants.d.ts.map +1 -0
  751. package/dist/cli/config/vitest-exclude.constants.js +55 -0
  752. package/dist/cli/config/vitest-exclude.constants.js.map +1 -0
  753. package/frontend/dist/assets/index-190a957f.js +4961 -0
  754. package/frontend/dist/assets/{index-8205ea5e.css → index-88feb412.css} +1 -1
  755. package/frontend/dist/index.html +2 -2
  756. package/package.json +2 -2
  757. package/packages/crewly-agent/src/runtime/agent-runner.service.test.ts +174 -30
  758. package/packages/crewly-agent/src/runtime/agent-runner.service.ts +121 -6
  759. package/packages/crewly-agent/src/runtime/types.ts +56 -5
  760. package/dist/backend/backend/src/controllers/knowledge/index.d.ts +0 -7
  761. package/dist/backend/backend/src/controllers/knowledge/index.d.ts.map +0 -1
  762. package/dist/backend/backend/src/controllers/knowledge/index.js +0 -7
  763. package/dist/backend/backend/src/controllers/knowledge/index.js.map +0 -1
  764. package/dist/backend/backend/src/controllers/knowledge/knowledge.controller.d.ts +0 -71
  765. package/dist/backend/backend/src/controllers/knowledge/knowledge.controller.d.ts.map +0 -1
  766. package/dist/backend/backend/src/controllers/knowledge/knowledge.controller.js +0 -237
  767. package/dist/backend/backend/src/controllers/knowledge/knowledge.controller.js.map +0 -1
  768. package/dist/backend/backend/src/controllers/knowledge/knowledge.routes.d.ts +0 -24
  769. package/dist/backend/backend/src/controllers/knowledge/knowledge.routes.d.ts.map +0 -1
  770. package/dist/backend/backend/src/controllers/knowledge/knowledge.routes.js +0 -34
  771. package/dist/backend/backend/src/controllers/knowledge/knowledge.routes.js.map +0 -1
  772. package/dist/backend/backend/src/controllers/scheduler/unified-scheduler.controller.d.ts +0 -91
  773. package/dist/backend/backend/src/controllers/scheduler/unified-scheduler.controller.d.ts.map +0 -1
  774. package/dist/backend/backend/src/controllers/scheduler/unified-scheduler.controller.js +0 -290
  775. package/dist/backend/backend/src/controllers/scheduler/unified-scheduler.controller.js.map +0 -1
  776. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +0 -169
  777. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +0 -1
  778. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +0 -1779
  779. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +0 -1
  780. package/dist/backend/backend/src/index.js.orc-bak-20260529 +0 -3130
  781. package/dist/backend/backend/src/routes/modules/unified-scheduler.routes.d.ts +0 -27
  782. package/dist/backend/backend/src/routes/modules/unified-scheduler.routes.d.ts.map +0 -1
  783. package/dist/backend/backend/src/routes/modules/unified-scheduler.routes.js +0 -40
  784. package/dist/backend/backend/src/routes/modules/unified-scheduler.routes.js.map +0 -1
  785. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +0 -513
  786. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +0 -1
  787. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +0 -1568
  788. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +0 -1
  789. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts +0 -86
  790. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts.map +0 -1
  791. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js +0 -147
  792. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js.map +0 -1
  793. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts +0 -68
  794. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts.map +0 -1
  795. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js +0 -131
  796. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js.map +0 -1
  797. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts +0 -130
  798. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts.map +0 -1
  799. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js +0 -263
  800. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js.map +0 -1
  801. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts +0 -74
  802. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts.map +0 -1
  803. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js +0 -140
  804. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js.map +0 -1
  805. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts +0 -29
  806. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +0 -1
  807. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +0 -279
  808. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +0 -1
  809. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +0 -340
  810. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +0 -1
  811. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +0 -1176
  812. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +0 -1
  813. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts +0 -79
  814. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts.map +0 -1
  815. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js +0 -145
  816. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js.map +0 -1
  817. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts +0 -79
  818. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts.map +0 -1
  819. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js +0 -218
  820. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js.map +0 -1
  821. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +0 -16
  822. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +0 -1
  823. package/dist/backend/backend/src/services/agent/crewly-agent/index.js +0 -16
  824. package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +0 -1
  825. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts +0 -135
  826. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts.map +0 -1
  827. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js +0 -185
  828. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js.map +0 -1
  829. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +0 -141
  830. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +0 -1
  831. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +0 -310
  832. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +0 -1
  833. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts +0 -91
  834. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts.map +0 -1
  835. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js +0 -143
  836. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js.map +0 -1
  837. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts +0 -103
  838. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts.map +0 -1
  839. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js +0 -256
  840. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js.map +0 -1
  841. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts +0 -143
  842. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts.map +0 -1
  843. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js +0 -264
  844. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js.map +0 -1
  845. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts +0 -13
  846. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts.map +0 -1
  847. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +0 -91
  848. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js.map +0 -1
  849. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +0 -135
  850. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +0 -1
  851. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +0 -1937
  852. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +0 -1
  853. package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts +0 -429
  854. package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts.map +0 -1
  855. package/dist/backend/backend/src/services/autonomous/auto-assign.service.js +0 -852
  856. package/dist/backend/backend/src/services/autonomous/auto-assign.service.js.map +0 -1
  857. package/dist/backend/backend/src/services/knowledge/embedding-provider.d.ts +0 -78
  858. package/dist/backend/backend/src/services/knowledge/embedding-provider.d.ts.map +0 -1
  859. package/dist/backend/backend/src/services/knowledge/embedding-provider.js +0 -179
  860. package/dist/backend/backend/src/services/knowledge/embedding-provider.js.map +0 -1
  861. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts +0 -118
  862. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +0 -1
  863. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +0 -241
  864. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +0 -1
  865. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.d.ts +0 -102
  866. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.d.ts.map +0 -1
  867. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.js +0 -118
  868. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.js.map +0 -1
  869. package/dist/backend/backend/src/services/knowledge/index.d.ts +0 -8
  870. package/dist/backend/backend/src/services/knowledge/index.d.ts.map +0 -1
  871. package/dist/backend/backend/src/services/knowledge/index.js +0 -8
  872. package/dist/backend/backend/src/services/knowledge/index.js.map +0 -1
  873. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +0 -241
  874. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +0 -1
  875. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +0 -590
  876. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +0 -1
  877. package/dist/backend/backend/src/services/knowledge/knowledge.service.d.ts +0 -153
  878. package/dist/backend/backend/src/services/knowledge/knowledge.service.d.ts.map +0 -1
  879. package/dist/backend/backend/src/services/knowledge/knowledge.service.js +0 -409
  880. package/dist/backend/backend/src/services/knowledge/knowledge.service.js.map +0 -1
  881. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts +0 -331
  882. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +0 -1
  883. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +0 -830
  884. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +0 -1
  885. package/dist/backend/backend/src/services/knowledge/wiki-compiler.service.d.ts +0 -115
  886. package/dist/backend/backend/src/services/knowledge/wiki-compiler.service.d.ts.map +0 -1
  887. package/dist/backend/backend/src/services/knowledge/wiki-compiler.service.js +0 -215
  888. package/dist/backend/backend/src/services/knowledge/wiki-compiler.service.js.map +0 -1
  889. package/dist/backend/backend/src/services/memory/embedding-provider.d.ts +0 -78
  890. package/dist/backend/backend/src/services/memory/embedding-provider.d.ts.map +0 -1
  891. package/dist/backend/backend/src/services/memory/embedding-provider.js +0 -185
  892. package/dist/backend/backend/src/services/memory/embedding-provider.js.map +0 -1
  893. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts +0 -331
  894. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +0 -1
  895. package/dist/backend/backend/src/services/memory/vector-store.service.js +0 -825
  896. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +0 -1
  897. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +0 -171
  898. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +0 -1
  899. package/dist/backend/backend/src/services/project/task-tracking.service.js +0 -725
  900. package/dist/backend/backend/src/services/project/task-tracking.service.js.map +0 -1
  901. package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts +0 -118
  902. package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts.map +0 -1
  903. package/dist/backend/backend/src/services/v3/project-task-watcher.service.js +0 -326
  904. package/dist/backend/backend/src/services/v3/project-task-watcher.service.js.map +0 -1
  905. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts +0 -74
  906. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts.map +0 -1
  907. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js +0 -154
  908. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js.map +0 -1
  909. package/dist/backend/backend/src/services/workflow/unified-scheduler.service.d.ts +0 -234
  910. package/dist/backend/backend/src/services/workflow/unified-scheduler.service.d.ts.map +0 -1
  911. package/dist/backend/backend/src/services/workflow/unified-scheduler.service.js +0 -636
  912. package/dist/backend/backend/src/services/workflow/unified-scheduler.service.js.map +0 -1
  913. package/dist/backend/backend/src/services/workflow/unified-scheduler.types.d.ts +0 -156
  914. package/dist/backend/backend/src/services/workflow/unified-scheduler.types.d.ts.map +0 -1
  915. package/dist/backend/backend/src/services/workflow/unified-scheduler.types.js +0 -81
  916. package/dist/backend/backend/src/services/workflow/unified-scheduler.types.js.map +0 -1
  917. package/dist/backend/backend/src/types/auto-assign.types.d.ts +0 -271
  918. package/dist/backend/backend/src/types/auto-assign.types.d.ts.map +0 -1
  919. package/dist/backend/backend/src/types/auto-assign.types.js +0 -136
  920. package/dist/backend/backend/src/types/auto-assign.types.js.map +0 -1
  921. package/dist/backend/backend/src/types/knowledge.types.d.ts +0 -195
  922. package/dist/backend/backend/src/types/knowledge.types.d.ts.map +0 -1
  923. package/dist/backend/backend/src/types/knowledge.types.js +0 -38
  924. package/dist/backend/backend/src/types/knowledge.types.js.map +0 -1
  925. package/dist/backend/backend/src/utils/esm-require.utils.d.ts +0 -111
  926. package/dist/backend/backend/src/utils/esm-require.utils.d.ts.map +0 -1
  927. package/dist/backend/backend/src/utils/esm-require.utils.js +0 -124
  928. package/dist/backend/backend/src/utils/esm-require.utils.js.map +0 -1
  929. package/dist/cli/backend/src/services/knowledge/embedding-provider.d.ts +0 -78
  930. package/dist/cli/backend/src/services/knowledge/embedding-provider.d.ts.map +0 -1
  931. package/dist/cli/backend/src/services/knowledge/embedding-provider.js +0 -179
  932. package/dist/cli/backend/src/services/knowledge/embedding-provider.js.map +0 -1
  933. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts +0 -118
  934. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +0 -1
  935. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +0 -241
  936. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +0 -1
  937. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.d.ts +0 -102
  938. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.d.ts.map +0 -1
  939. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.js +0 -118
  940. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.js.map +0 -1
  941. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts +0 -56
  942. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts.map +0 -1
  943. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js +0 -91
  944. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js.map +0 -1
  945. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +0 -241
  946. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +0 -1
  947. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +0 -590
  948. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +0 -1
  949. package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts +0 -153
  950. package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts.map +0 -1
  951. package/dist/cli/backend/src/services/knowledge/knowledge.service.js +0 -409
  952. package/dist/cli/backend/src/services/knowledge/knowledge.service.js.map +0 -1
  953. package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts +0 -159
  954. package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts.map +0 -1
  955. package/dist/cli/backend/src/services/knowledge/learnings-index.service.js +0 -304
  956. package/dist/cli/backend/src/services/knowledge/learnings-index.service.js.map +0 -1
  957. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts +0 -331
  958. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +0 -1
  959. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +0 -830
  960. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +0 -1
  961. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts +0 -115
  962. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts.map +0 -1
  963. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js +0 -215
  964. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js.map +0 -1
  965. package/dist/cli/backend/src/services/memory/embedding-provider.d.ts +0 -78
  966. package/dist/cli/backend/src/services/memory/embedding-provider.d.ts.map +0 -1
  967. package/dist/cli/backend/src/services/memory/embedding-provider.js +0 -179
  968. package/dist/cli/backend/src/services/memory/embedding-provider.js.map +0 -1
  969. package/dist/cli/backend/src/services/memory/vector-store.service.d.ts +0 -331
  970. package/dist/cli/backend/src/services/memory/vector-store.service.d.ts.map +0 -1
  971. package/dist/cli/backend/src/services/memory/vector-store.service.js +0 -814
  972. package/dist/cli/backend/src/services/memory/vector-store.service.js.map +0 -1
  973. package/dist/cli/backend/src/services/project/task-tracking.service.d.ts +0 -171
  974. package/dist/cli/backend/src/services/project/task-tracking.service.d.ts.map +0 -1
  975. package/dist/cli/backend/src/services/project/task-tracking.service.js +0 -725
  976. package/dist/cli/backend/src/services/project/task-tracking.service.js.map +0 -1
  977. package/dist/cli/backend/src/types/auto-assign.types.d.ts +0 -271
  978. package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +0 -1
  979. package/dist/cli/backend/src/types/auto-assign.types.js +0 -136
  980. package/dist/cli/backend/src/types/auto-assign.types.js.map +0 -1
  981. package/dist/cli/backend/src/types/knowledge.types.d.ts +0 -195
  982. package/dist/cli/backend/src/types/knowledge.types.d.ts.map +0 -1
  983. package/dist/cli/backend/src/types/knowledge.types.js +0 -38
  984. package/dist/cli/backend/src/types/knowledge.types.js.map +0 -1
  985. package/frontend/dist/assets/index-aa737fd3.js +0 -5254
@@ -0,0 +1,1388 @@
1
+ /**
2
+ * Slack Service
3
+ *
4
+ * Manages Slack bot connection and messaging using Bolt SDK.
5
+ * Enables bidirectional communication between Slack and Crewly.
6
+ *
7
+ * @module services/slack
8
+ */
9
+ import { EventEmitter } from 'events';
10
+ import { createReadStream } from 'fs';
11
+ import { basename } from 'path';
12
+ import { isUserAllowed } from '../../types/slack.types.js';
13
+ import { CROSS_MACHINE_PREFIX } from '../../types/cross-machine.types.js';
14
+ import { SLACK_IMAGE_CONSTANTS, SLACK_FILE_UPLOAD_CONSTANTS, SLACK_DEDUP_CONSTANTS, SLACK_RECONNECT_CONSTANTS, SLACK_TEAM_CHANNEL_CONSTANTS, ORCHESTRATOR_SESSION_NAME } from '../../constants.js';
15
+ import { LoggerService } from '../core/logger.service.js';
16
+ import { ContentApprovalService } from '../onboarding/content-approval.service.js';
17
+ import { getAgentBehaviorLogService } from '../observability/agent-behavior-log.singleton.js';
18
+ /**
19
+ * Slack Service singleton instance
20
+ */
21
+ let slackServiceInstance = null;
22
+ /**
23
+ * SlackService class for managing Slack bot operations
24
+ */
25
+ export class SlackService extends EventEmitter {
26
+ logger = LoggerService.getInstance().createComponentLogger('SlackService');
27
+ app = null;
28
+ client = null;
29
+ config = null;
30
+ /** Bot user id from `auth.test`, cached by getBotUserId(). */
31
+ cachedBotUserId = null;
32
+ /** Lower-cased handle/display name → Slack user id, filled by findUserByHandle(). */
33
+ userHandleCache = new Map();
34
+ status = {
35
+ connected: false,
36
+ socketMode: false,
37
+ messagesSent: 0,
38
+ messagesReceived: 0,
39
+ };
40
+ conversationContexts = new Map();
41
+ /** Cached Bolt App constructor from the first successful dynamic import */
42
+ cachedAppConstructor = null;
43
+ /** Cached Bolt LogLevel enum from the first successful dynamic import */
44
+ cachedLogLevelEnum = null;
45
+ /**
46
+ * Message deduplication tracker.
47
+ * Maps a fingerprint (channelId:threadTs:textHash) to the timestamp it was sent.
48
+ * Prevents identical messages from being sent to the same thread within a time window.
49
+ */
50
+ recentMessageFingerprints = new Map();
51
+ /** Whether a reconnection attempt is currently in progress */
52
+ reconnecting = false;
53
+ /** Timer handle for the reconnection grace period */
54
+ reconnectGraceTimer = null;
55
+ /** Timer handle for the periodic health check */
56
+ healthCheckTimer = null;
57
+ /** Current consecutive reconnection attempt count */
58
+ reconnectAttempts = 0;
59
+ /** Whether the service has been intentionally shut down (skip auto-reconnect) */
60
+ intentionalDisconnect = false;
61
+ /** Timestamp of the last successful Slack API ping */
62
+ lastPingAt = 0;
63
+ /** Number of consecutive health-check ping failures */
64
+ consecutivePingFailures = 0;
65
+ /**
66
+ * Initialize the Slack service with configuration
67
+ *
68
+ * @param config - Slack bot configuration
69
+ * @returns Promise that resolves when connected
70
+ */
71
+ async initialize(config) {
72
+ this.config = config;
73
+ this.intentionalDisconnect = false;
74
+ this.reconnectAttempts = 0;
75
+ try {
76
+ // Dynamic import of @slack/bolt (CJS module requires default import handling).
77
+ // Cache the constructor and LogLevel on first import for reuse in reconnect.
78
+ const boltModule = await import('@slack/bolt');
79
+ const defaultExport = boltModule.default;
80
+ const App = (boltModule.App ?? defaultExport?.App);
81
+ const LogLevel = (boltModule.LogLevel ?? defaultExport?.LogLevel);
82
+ this.cachedAppConstructor = App;
83
+ this.cachedLogLevelEnum = LogLevel ?? null;
84
+ this.app = new App({
85
+ token: config.botToken,
86
+ appToken: config.appToken,
87
+ signingSecret: config.signingSecret,
88
+ socketMode: config.socketMode,
89
+ logLevel: LogLevel?.INFO ?? 'info',
90
+ });
91
+ this.client = this.app.client;
92
+ // Set up event handlers
93
+ this.setupEventHandlers();
94
+ // Start the app
95
+ if (config.socketMode) {
96
+ await this.app.start();
97
+ this.status.connected = true;
98
+ this.status.socketMode = true;
99
+ // Monitor SocketModeClient connection state for logging and status tracking
100
+ this.setupConnectionMonitoring();
101
+ this.emit('connected');
102
+ this.logger.info('Connected in Socket Mode');
103
+ }
104
+ }
105
+ catch (error) {
106
+ // Ensure partially initialized Bolt app is torn down to avoid
107
+ // lingering socket retries/background tasks after failed startup.
108
+ if (this.app) {
109
+ try {
110
+ await this.app.stop();
111
+ }
112
+ catch {
113
+ // Ignore shutdown errors during failed initialization
114
+ }
115
+ }
116
+ this.app = null;
117
+ this.client = null;
118
+ this.status.connected = false;
119
+ this.status.socketMode = false;
120
+ this.status.lastError = error.message;
121
+ this.status.lastErrorAt = new Date().toISOString();
122
+ this.emit('error', error);
123
+ throw error;
124
+ }
125
+ }
126
+ /**
127
+ * Set up Slack event handlers
128
+ */
129
+ setupEventHandlers() {
130
+ if (!this.app || !this.config)
131
+ return;
132
+ const config = this.config;
133
+ // Handle direct messages
134
+ this.app.message(async ({ message }) => {
135
+ // Allow messages with text or files (or both)
136
+ if (!message.text && (!message.files || message.files.length === 0))
137
+ return;
138
+ if (!message.user)
139
+ return;
140
+ // Bypass user permission check for cross-machine messages —
141
+ // these come from other bots and are authenticated by device ID,
142
+ // not Slack user ID. The CrossMachineMessageService handles its
143
+ // own security (device identity, target filtering, deduplication).
144
+ const isCrossMachine = message.text && message.text.startsWith(CROSS_MACHINE_PREFIX);
145
+ // Check user permissions (skip for cross-machine messages)
146
+ if (!isCrossMachine && !isUserAllowed(message.user, config)) {
147
+ this.logger.info('Unauthorized user', { userId: message.user });
148
+ return;
149
+ }
150
+ // Pass ALL files through; downstream services handle image vs non-image distinction
151
+ const allFiles = (message.files || []);
152
+ const imageFiles = allFiles.filter(f => f.mimetype?.startsWith('image/'));
153
+ const incomingMessage = {
154
+ id: message.ts || '',
155
+ type: 'message',
156
+ text: message.text || '',
157
+ userId: message.user,
158
+ channelId: message.channel,
159
+ threadTs: message.thread_ts,
160
+ ts: message.ts || '',
161
+ teamId: message.team || '',
162
+ eventTs: message.ts || '',
163
+ files: allFiles.length > 0 ? allFiles : undefined,
164
+ hasImages: imageFiles.length > 0,
165
+ hasFiles: allFiles.length > 0,
166
+ };
167
+ this.status.messagesReceived++;
168
+ this.status.lastEventAt = new Date().toISOString();
169
+ this.emit('message', incomingMessage);
170
+ });
171
+ // Handle @mentions
172
+ this.app.event('app_mention', async ({ event }) => {
173
+ if (!isUserAllowed(event.user, config)) {
174
+ this.logger.info('Unauthorized user mention', { userId: event.user });
175
+ return;
176
+ }
177
+ const incomingMessage = {
178
+ id: event.ts,
179
+ type: 'app_mention',
180
+ text: event.text,
181
+ userId: event.user,
182
+ channelId: event.channel,
183
+ threadTs: event.thread_ts,
184
+ ts: event.ts,
185
+ teamId: event.team || '',
186
+ eventTs: event.event_ts,
187
+ };
188
+ this.status.messagesReceived++;
189
+ this.status.lastEventAt = new Date().toISOString();
190
+ this.emit('message', incomingMessage);
191
+ });
192
+ // Handle content approval button clicks (Block Kit interactive actions)
193
+ this.app.action(/content_approval_(approve|reject)/, async ({ action, body, ack, respond }) => {
194
+ await ack();
195
+ const approvalId = action.value;
196
+ const actionType = action.action_id;
197
+ const slackUserName = body.user.name || body.user.username || body.user.id;
198
+ const channelId = body.channel?.id || body.container?.channel_id;
199
+ const messageTs = body.message?.ts || body.container?.message_ts;
200
+ if (!approvalId) {
201
+ await respond({ text: 'Error: Missing approval ID.', replace_original: false, response_type: 'ephemeral' });
202
+ return;
203
+ }
204
+ try {
205
+ const service = ContentApprovalService.getInstance();
206
+ const existing = service.get(approvalId);
207
+ if (!existing) {
208
+ await respond({ text: `Approval \`${approvalId.slice(0, 8)}\` not found.`, replace_original: false, response_type: 'ephemeral' });
209
+ return;
210
+ }
211
+ if (existing.status !== 'pending') {
212
+ await respond({
213
+ text: `This approval has already been ${existing.status} by ${existing.resolvedBy ?? 'someone'}.`,
214
+ replace_original: false,
215
+ response_type: 'ephemeral',
216
+ });
217
+ return;
218
+ }
219
+ const isApprove = actionType === 'content_approval_approve';
220
+ const result = isApprove
221
+ ? service.approve(approvalId, slackUserName)
222
+ : service.reject(approvalId, slackUserName);
223
+ if (!result) {
224
+ await respond({ text: 'Failed to resolve approval.', replace_original: false, response_type: 'ephemeral' });
225
+ return;
226
+ }
227
+ // Update the original message to replace buttons with status
228
+ const statusEmoji = isApprove ? '\u2705' : '\u274c';
229
+ const statusText = isApprove ? 'Approved' : 'Rejected';
230
+ const updatedText = `${statusEmoji} ${statusText} by @${slackUserName}`;
231
+ if (channelId && messageTs) {
232
+ const updatedBlocks = [
233
+ {
234
+ type: 'section',
235
+ text: { type: 'mrkdwn', text: `~${existing.content.slice(0, 200)}~` },
236
+ },
237
+ {
238
+ type: 'context',
239
+ elements: [
240
+ { type: 'mrkdwn', text: `${updatedText} \u2022 ${new Date().toLocaleString()}` },
241
+ ],
242
+ },
243
+ ];
244
+ await this.updateMessage(channelId, messageTs, updatedText, updatedBlocks);
245
+ }
246
+ this.emit('content_approval_resolved', {
247
+ approvalId,
248
+ action: isApprove ? 'approved' : 'rejected',
249
+ resolvedBy: slackUserName,
250
+ });
251
+ this.logger.info('Content approval resolved via Slack button', {
252
+ approvalId: approvalId.slice(0, 8),
253
+ action: statusText.toLowerCase(),
254
+ resolvedBy: slackUserName,
255
+ });
256
+ }
257
+ catch (err) {
258
+ this.logger.error('Content approval action handler error', {
259
+ approvalId: approvalId?.slice(0, 8),
260
+ error: err instanceof Error ? err.message : String(err),
261
+ });
262
+ await respond({
263
+ text: `Error processing approval: ${err instanceof Error ? err.message : 'Unknown error'}`,
264
+ replace_original: false,
265
+ response_type: 'ephemeral',
266
+ });
267
+ }
268
+ });
269
+ // Handle errors
270
+ this.app.error(async (error) => {
271
+ this.logger.error('Error', { error: error.message });
272
+ this.status.lastError = error.message;
273
+ this.status.lastErrorAt = new Date().toISOString();
274
+ this.emit('error', error);
275
+ });
276
+ }
277
+ /**
278
+ * Attach listeners to the underlying SocketModeClient to track
279
+ * connection lifecycle (disconnected, reconnecting, connected).
280
+ * Updates `status.connected` so health checks reflect actual state.
281
+ *
282
+ * The Bolt App stores the receiver at `app.receiver`, and the
283
+ * SocketModeReceiver exposes `client` (SocketModeClient), which
284
+ * is an EventEmitter emitting: connected, reconnecting, disconnected, close.
285
+ */
286
+ setupConnectionMonitoring() {
287
+ // Access the SocketModeClient from Bolt's internal receiver.
288
+ // This relies on Bolt's internal structure, so we guard with try/catch.
289
+ try {
290
+ const receiver = this.app?.receiver;
291
+ const socketClient = receiver?.client;
292
+ if (!socketClient) {
293
+ this.logger.warn('Could not access SocketModeClient for connection monitoring');
294
+ return;
295
+ }
296
+ // Issue #548 — `@slack/socket-mode`'s finity state machine throws
297
+ // `Unhandled event 'server explicit disconnect' in state 'connecting'`
298
+ // when Slack sends a disconnect signal during the reconnect
299
+ // handshake window. The throw is SYNCHRONOUS inside the WebSocket
300
+ // message callback (WebSocket.onMessage → SocketModeClient.
301
+ // onWebSocketMessage → finity.handle → throw) so it surfaces as
302
+ // an uncaughtException that takes the process down on v1 hosts
303
+ // (no pm2/systemd to restart). CrewlyNode1 went dark for ~21
304
+ // hours on 2026-05-14 from exactly this.
305
+ //
306
+ // Wrap `onWebSocketMessage` with a synchronous try/catch that
307
+ // swallows the unhandled-event throw, logs it as a recoverable
308
+ // event, and triggers the reconnect path. Other throws still
309
+ // surface normally — we only suppress the specific finity
310
+ // "Unhandled event" signature.
311
+ const wrappedClient = socketClient;
312
+ const originalOnMessage = wrappedClient.onWebSocketMessage;
313
+ if (typeof originalOnMessage === 'function') {
314
+ wrappedClient.onWebSocketMessage = (...args) => {
315
+ try {
316
+ return originalOnMessage.apply(socketClient, args);
317
+ }
318
+ catch (err) {
319
+ const msg = err instanceof Error ? err.message : String(err);
320
+ if (/Unhandled event/.test(msg)) {
321
+ this.logger.warn('Suppressed finity unhandled-event from SocketModeClient (issue #548) — triggering reconnect', {
322
+ error: msg,
323
+ });
324
+ this.status.connected = false;
325
+ this.status.lastError = `SocketMode finity throw: ${msg}`;
326
+ this.status.lastErrorAt = new Date().toISOString();
327
+ this.scheduleReconnect();
328
+ return undefined;
329
+ }
330
+ throw err;
331
+ }
332
+ };
333
+ this.logger.info('SocketModeClient.onWebSocketMessage wrapped for #548 finity-throw recovery');
334
+ }
335
+ else {
336
+ this.logger.warn('SocketModeClient.onWebSocketMessage not found — #548 finity-throw guard NOT installed');
337
+ }
338
+ socketClient.on('disconnected', () => {
339
+ this.status.connected = false;
340
+ this.status.lastError = 'Socket Mode connection lost';
341
+ this.status.lastErrorAt = new Date().toISOString();
342
+ this.logger.warn('Socket Mode disconnected');
343
+ this.emit('disconnected');
344
+ this.scheduleReconnect();
345
+ });
346
+ socketClient.on('reconnecting', () => {
347
+ this.status.connected = false;
348
+ this.logger.info('Socket Mode reconnecting (Bolt built-in)...');
349
+ });
350
+ socketClient.on('connected', () => {
351
+ this.status.connected = true;
352
+ this.reconnectAttempts = 0;
353
+ this.consecutivePingFailures = 0;
354
+ this.lastPingAt = Date.now();
355
+ this.cancelReconnectGrace();
356
+ this.logger.info('Socket Mode reconnected');
357
+ this.emit('connected');
358
+ });
359
+ socketClient.on('close', () => {
360
+ // 'close' fires on WebSocket close before reconnection kicks in
361
+ if (this.status.connected) {
362
+ this.status.connected = false;
363
+ this.logger.warn('Socket Mode WebSocket closed, awaiting reconnect...');
364
+ this.scheduleReconnect();
365
+ }
366
+ });
367
+ }
368
+ catch (err) {
369
+ this.logger.warn('Failed to set up connection monitoring', {
370
+ error: err instanceof Error ? err.message : String(err),
371
+ });
372
+ }
373
+ // Start periodic health check
374
+ this.startHealthCheck();
375
+ }
376
+ /**
377
+ * Start a periodic health check that verifies the Socket Mode connection
378
+ * is alive and triggers reconnection if it has silently died.
379
+ *
380
+ * Uses an active Slack API ping (auth.test) to detect half-open sockets
381
+ * that appear connected but are actually dead after WiFi/network drops.
382
+ */
383
+ startHealthCheck() {
384
+ this.stopHealthCheck();
385
+ this.lastPingAt = Date.now();
386
+ this.consecutivePingFailures = 0;
387
+ this.healthCheckTimer = setInterval(async () => {
388
+ if (this.intentionalDisconnect)
389
+ return;
390
+ // Case 1: Already known to be disconnected — trigger reconnect
391
+ if (!this.status.connected && !this.reconnecting) {
392
+ this.logger.warn('Health check: Socket Mode not connected and no reconnect in progress — triggering reconnect');
393
+ this.attemptReconnect();
394
+ return;
395
+ }
396
+ // Case 2: Status says connected — verify with an active API ping
397
+ if (this.status.connected && this.client && !this.reconnecting) {
398
+ try {
399
+ const pingPromise = this.client.auth.test();
400
+ const timeoutMs = SLACK_RECONNECT_CONSTANTS.PING_TIMEOUT_MS;
401
+ const timeoutPromise = new Promise((_, reject) => {
402
+ const timer = setTimeout(() => reject(new Error('Ping timeout')), timeoutMs);
403
+ // Clear timer if ping resolves first to prevent leak
404
+ pingPromise.then(() => clearTimeout(timer), () => clearTimeout(timer));
405
+ });
406
+ await Promise.race([pingPromise, timeoutPromise]);
407
+ // Ping succeeded — connection is truly alive
408
+ this.lastPingAt = Date.now();
409
+ this.consecutivePingFailures = 0;
410
+ }
411
+ catch (err) {
412
+ this.consecutivePingFailures++;
413
+ this.logger.warn('Health check ping failed', {
414
+ consecutiveFailures: this.consecutivePingFailures,
415
+ error: err instanceof Error ? err.message : String(err),
416
+ });
417
+ // After consecutive failures, declare connection dead and reconnect
418
+ if (this.consecutivePingFailures >= SLACK_RECONNECT_CONSTANTS.PING_FAILURES_BEFORE_RECONNECT) {
419
+ this.logger.warn('Health check: connection appears dead after consecutive ping failures — forcing reconnect', {
420
+ consecutiveFailures: this.consecutivePingFailures,
421
+ lastPingAt: new Date(this.lastPingAt).toISOString(),
422
+ });
423
+ this.status.connected = false;
424
+ this.consecutivePingFailures = 0;
425
+ this.attemptReconnect();
426
+ }
427
+ }
428
+ }
429
+ }, SLACK_RECONNECT_CONSTANTS.HEALTH_CHECK_INTERVAL_MS);
430
+ // Allow Node to exit even if health check timer is still active
431
+ if (this.healthCheckTimer && typeof this.healthCheckTimer === 'object' && 'unref' in this.healthCheckTimer) {
432
+ this.healthCheckTimer.unref();
433
+ }
434
+ }
435
+ /**
436
+ * Stop the periodic health check timer.
437
+ */
438
+ stopHealthCheck() {
439
+ if (this.healthCheckTimer) {
440
+ clearInterval(this.healthCheckTimer);
441
+ this.healthCheckTimer = null;
442
+ }
443
+ }
444
+ /**
445
+ * Schedule a reconnection attempt after a grace period.
446
+ * The grace period gives Bolt's built-in reconnect a chance to recover first.
447
+ * If the connection comes back within the grace period, the reconnect is cancelled.
448
+ */
449
+ scheduleReconnect() {
450
+ if (this.intentionalDisconnect || this.reconnecting || this.reconnectGraceTimer)
451
+ return;
452
+ this.logger.info('Scheduling reconnect after grace period', {
453
+ gracePeriodMs: SLACK_RECONNECT_CONSTANTS.GRACE_PERIOD_MS,
454
+ });
455
+ this.reconnectGraceTimer = setTimeout(() => {
456
+ this.reconnectGraceTimer = null;
457
+ if (!this.status.connected && !this.intentionalDisconnect) {
458
+ this.logger.warn('Grace period expired, Bolt reconnect did not recover — starting manual reconnect');
459
+ this.attemptReconnect();
460
+ }
461
+ }, SLACK_RECONNECT_CONSTANTS.GRACE_PERIOD_MS);
462
+ }
463
+ /**
464
+ * Cancel the reconnection grace period timer.
465
+ */
466
+ cancelReconnectGrace() {
467
+ if (this.reconnectGraceTimer) {
468
+ clearTimeout(this.reconnectGraceTimer);
469
+ this.reconnectGraceTimer = null;
470
+ }
471
+ }
472
+ /**
473
+ * Attempt to reconnect by tearing down the current Bolt app and
474
+ * re-initializing from scratch with the saved config.
475
+ * Uses exponential backoff between attempts.
476
+ */
477
+ async attemptReconnect() {
478
+ if (this.reconnecting || this.intentionalDisconnect || !this.config)
479
+ return;
480
+ const maxAttempts = SLACK_RECONNECT_CONSTANTS.MAX_ATTEMPTS;
481
+ if (maxAttempts > 0 && this.reconnectAttempts >= maxAttempts) {
482
+ this.logger.error('Max reconnection attempts reached, giving up', {
483
+ attempts: this.reconnectAttempts,
484
+ maxAttempts,
485
+ });
486
+ return;
487
+ }
488
+ this.reconnecting = true;
489
+ this.reconnectAttempts++;
490
+ const delay = Math.min(SLACK_RECONNECT_CONSTANTS.INITIAL_DELAY_MS * Math.pow(SLACK_RECONNECT_CONSTANTS.BACKOFF_MULTIPLIER, this.reconnectAttempts - 1), SLACK_RECONNECT_CONSTANTS.MAX_DELAY_MS);
491
+ this.logger.info('Reconnecting to Slack Socket Mode', {
492
+ attempt: this.reconnectAttempts,
493
+ delayMs: delay,
494
+ });
495
+ await new Promise(resolve => setTimeout(resolve, delay));
496
+ // Bail out if we reconnected or intentionally disconnected while waiting
497
+ if (this.status.connected || this.intentionalDisconnect) {
498
+ this.reconnecting = false;
499
+ return;
500
+ }
501
+ try {
502
+ // Guard: cached App constructor must be available from initialize()
503
+ if (!this.cachedAppConstructor) {
504
+ throw new Error('App constructor not cached — initialize() must be called before reconnect');
505
+ }
506
+ // Tear down existing app
507
+ if (this.app) {
508
+ try {
509
+ await this.app.stop();
510
+ }
511
+ catch {
512
+ // Ignore teardown errors
513
+ }
514
+ this.app = null;
515
+ this.client = null;
516
+ }
517
+ // Re-initialize using cached constructor (avoids stale dynamic import issues)
518
+ const App = this.cachedAppConstructor;
519
+ const LogLevel = this.cachedLogLevelEnum;
520
+ this.app = new App({
521
+ token: this.config.botToken,
522
+ appToken: this.config.appToken,
523
+ signingSecret: this.config.signingSecret,
524
+ socketMode: this.config.socketMode,
525
+ logLevel: LogLevel?.INFO ?? 'info',
526
+ });
527
+ this.client = this.app.client;
528
+ this.setupEventHandlers();
529
+ await this.app.start();
530
+ this.status.connected = true;
531
+ this.status.socketMode = true;
532
+ this.reconnectAttempts = 0;
533
+ this.reconnecting = false;
534
+ this.consecutivePingFailures = 0;
535
+ this.lastPingAt = Date.now();
536
+ this.setupConnectionMonitoring();
537
+ this.emit('connected');
538
+ this.logger.info('Successfully reconnected to Slack Socket Mode');
539
+ }
540
+ catch (error) {
541
+ this.reconnecting = false;
542
+ const errorMessage = error instanceof Error ? error.message : String(error);
543
+ this.status.lastError = `Reconnect failed: ${errorMessage}`;
544
+ this.status.lastErrorAt = new Date().toISOString();
545
+ // Classify error: fatal errors stop the loop, transient errors retry
546
+ if (this.isFatalReconnectError(error)) {
547
+ this.logger.error('Fatal reconnection error — stopping retry loop', {
548
+ attempt: this.reconnectAttempts,
549
+ error: errorMessage,
550
+ });
551
+ this.emit('error', error instanceof Error ? error : new Error(errorMessage));
552
+ return;
553
+ }
554
+ this.logger.error('Transient reconnection error — will retry', {
555
+ attempt: this.reconnectAttempts,
556
+ error: errorMessage,
557
+ });
558
+ // Schedule next attempt — the health check will also retry if this doesn't fire
559
+ if (!this.intentionalDisconnect) {
560
+ this.scheduleReconnect();
561
+ }
562
+ }
563
+ }
564
+ /**
565
+ * Classify whether a reconnection error is fatal (non-recoverable)
566
+ * or transient (may succeed on retry).
567
+ *
568
+ * Fatal errors: missing constructor, invalid config, auth errors.
569
+ * Transient errors: network timeouts, temporary server errors.
570
+ *
571
+ * @param error - The error caught during reconnection
572
+ * @returns True if the error is fatal and retrying would be futile
573
+ */
574
+ isFatalReconnectError(error) {
575
+ const message = error instanceof Error ? error.message : String(error);
576
+ const lowerMessage = message.toLowerCase();
577
+ /** Patterns that indicate a non-recoverable configuration or code error */
578
+ const fatalPatterns = [
579
+ 'not a constructor',
580
+ 'is not a function',
581
+ 'constructor not cached',
582
+ 'invalid_auth',
583
+ 'token_revoked',
584
+ 'account_inactive',
585
+ 'missing required',
586
+ 'config',
587
+ ];
588
+ return fatalPatterns.some(pattern => lowerMessage.includes(pattern));
589
+ }
590
+ /**
591
+ * Send a message to Slack with content-based deduplication.
592
+ *
593
+ * Generates a fingerprint from (channelId, threadTs, text) and suppresses
594
+ * duplicate sends within a configurable time window (default 30s).
595
+ * This is the single chokepoint for all Slack message sends — skill delivery,
596
+ * bridge fallback, and direct API calls all converge here.
597
+ *
598
+ * @param message - Message to send
599
+ * @returns Promise with message timestamp (empty string if deduplicated)
600
+ */
601
+ async sendMessage(message) {
602
+ if (!this.client) {
603
+ throw new Error('Slack client not initialized');
604
+ }
605
+ // Content-based deduplication: suppress identical messages within time window
606
+ const fingerprint = this.buildMessageFingerprint(message);
607
+ const now = Date.now();
608
+ const lastSentAt = this.recentMessageFingerprints.get(fingerprint);
609
+ if (lastSentAt !== undefined && (now - lastSentAt) < SLACK_DEDUP_CONSTANTS.DEDUP_WINDOW_MS) {
610
+ this.logger.info('Slack message deduplicated — identical message sent recently', {
611
+ channelId: message.channelId,
612
+ threadTs: message.threadTs,
613
+ ageMs: now - lastSentAt,
614
+ });
615
+ return '';
616
+ }
617
+ try {
618
+ const result = await this.client.chat.postMessage({
619
+ channel: message.channelId,
620
+ text: message.text,
621
+ thread_ts: message.threadTs,
622
+ blocks: message.blocks,
623
+ attachments: message.attachments,
624
+ unfurl_links: message.unfurlLinks,
625
+ unfurl_media: message.unfurlMedia,
626
+ // Per-agent identity for team channels. A real agent bot token wins
627
+ // (the message is posted by that bot user); otherwise the cosmetic
628
+ // username/icon override. Only sent when set so the orchestrator's
629
+ // plain posts keep the app's default bot identity.
630
+ ...(message.botToken
631
+ ? { token: message.botToken }
632
+ : {
633
+ ...(message.username ? { username: message.username } : {}),
634
+ ...(message.iconEmoji
635
+ ? { icon_emoji: message.iconEmoji }
636
+ : message.iconUrl
637
+ ? { icon_url: message.iconUrl }
638
+ : {}),
639
+ }),
640
+ });
641
+ this.status.messagesSent++;
642
+ // Track this fingerprint for future dedup
643
+ this.trackMessageFingerprint(fingerprint, now);
644
+ // Mirror the outbound reply into chat-v2 so the Slack thread shows both
645
+ // sides ("收和发") in the consolidated chat. Best-effort, thread-only.
646
+ if (message.threadTs && !message.skipChatV2Mirror) {
647
+ void this.recordOutboundToChatV2(message);
648
+ }
649
+ return result.ts || '';
650
+ }
651
+ catch (error) {
652
+ this.logger.error('Send message error', { error: error instanceof Error ? error.message : String(error) });
653
+ // F14: record slack.delivery.failed event (best-effort — never
654
+ // changes retry semantics or throws). The wrapper swallows
655
+ // construction errors and `record()` itself swallows DB errors.
656
+ try {
657
+ const errMessage = error instanceof Error ? error.message : String(error);
658
+ getAgentBehaviorLogService()?.record({
659
+ type: 'slack.delivery.failed',
660
+ agent: '',
661
+ thread: `${message.channelId}:${message.threadTs ?? ''}`,
662
+ reason: 'api_error',
663
+ details: {
664
+ errorMessage: errMessage,
665
+ textLength: (message.text ?? '').length,
666
+ hasBlocks: Array.isArray(message.blocks) && message.blocks.length > 0,
667
+ },
668
+ });
669
+ }
670
+ catch {
671
+ /* observability is best-effort — never block the original throw */
672
+ }
673
+ throw error;
674
+ }
675
+ }
676
+ /**
677
+ * Mirror an outbound Slack reply into the canonical chat-v2 store so the
678
+ * Slack thread shows both inbound (user) and outbound (agent) messages in
679
+ * the consolidated /team-chat surface. Records against the SAME channel the
680
+ * inbound persisted to — `synthesizeSlackConversationId(channelId, threadTs)`.
681
+ *
682
+ * Best-effort: dynamic imports + try/catch so a chat-v2 failure never
683
+ * affects Slack delivery. Only called for threaded replies (threadTs set).
684
+ *
685
+ * @param message - The outbound Slack message that was just sent.
686
+ */
687
+ async recordOutboundToChatV2(message) {
688
+ try {
689
+ if (!message.channelId || !message.threadTs || !(message.text ?? '').trim())
690
+ return;
691
+ const [{ getChatV2Service }, { synthesizeSlackConversationId, slackOutboundClientMessageId }] = await Promise.all([
692
+ import('../chat-v2/chat-v2.singleton.js'),
693
+ import('../chat-v2/legacy-dto.utils.js'),
694
+ ]);
695
+ const chatV2 = getChatV2Service();
696
+ const conversationId = synthesizeSlackConversationId(message.channelId, message.threadTs);
697
+ const channel = chatV2.ensureChannelForLegacyConversation({
698
+ conversationId,
699
+ agentSession: ORCHESTRATOR_SESSION_NAME,
700
+ });
701
+ chatV2.recordTurn({
702
+ channelId: channel.id,
703
+ senderType: 'agent',
704
+ senderId: channel.agentSession || ORCHESTRATOR_SESSION_NAME,
705
+ content: message.text,
706
+ // Shared idempotency key with the /slack/send bookkeeping path so the
707
+ // same reply isn't persisted twice (duplicate bubbles in the merged
708
+ // Orchestrator timeline).
709
+ clientMessageId: slackOutboundClientMessageId(message.channelId, message.threadTs, message.text),
710
+ metadata: {
711
+ source: 'slack',
712
+ slackChannelId: message.channelId,
713
+ slackThreadTs: message.threadTs,
714
+ },
715
+ });
716
+ }
717
+ catch (err) {
718
+ this.logger.warn('Failed to mirror outbound Slack message to chat-v2', {
719
+ error: err instanceof Error ? err.message : String(err),
720
+ });
721
+ }
722
+ }
723
+ /**
724
+ * Build a deduplication fingerprint for a Slack message.
725
+ * Combines channelId, threadTs, and a simple hash of the message text.
726
+ *
727
+ * @param message - Outgoing Slack message
728
+ * @returns Fingerprint string
729
+ */
730
+ buildMessageFingerprint(message) {
731
+ // Simple string hash (djb2) — fast and sufficient for dedup
732
+ let hash = 5381;
733
+ const text = message.text || '';
734
+ for (let i = 0; i < text.length; i++) {
735
+ hash = ((hash << 5) + hash + text.charCodeAt(i)) | 0;
736
+ }
737
+ // Two agents saying the same thing in the same thread are two messages,
738
+ // so the sender identity is part of the key.
739
+ const sender = message.botToken ? `bot:${message.botToken.slice(-8)}` : message.username || '';
740
+ return `${message.channelId}:${message.threadTs || ''}:${sender}:${hash}`;
741
+ }
742
+ /**
743
+ * Track a message fingerprint and evict stale entries.
744
+ *
745
+ * @param fingerprint - Message fingerprint to track
746
+ * @param timestamp - Current timestamp in ms
747
+ */
748
+ trackMessageFingerprint(fingerprint, timestamp) {
749
+ this.recentMessageFingerprints.set(fingerprint, timestamp);
750
+ // Evict expired entries and enforce size limit
751
+ if (this.recentMessageFingerprints.size > SLACK_DEDUP_CONSTANTS.MAX_TRACKED_MESSAGES) {
752
+ const windowMs = SLACK_DEDUP_CONSTANTS.DEDUP_WINDOW_MS;
753
+ for (const [key, ts] of this.recentMessageFingerprints) {
754
+ if (timestamp - ts > windowMs) {
755
+ this.recentMessageFingerprints.delete(key);
756
+ }
757
+ }
758
+ // If still over limit after expiry cleanup, drop oldest
759
+ if (this.recentMessageFingerprints.size > SLACK_DEDUP_CONSTANTS.MAX_TRACKED_MESSAGES) {
760
+ const firstKey = this.recentMessageFingerprints.keys().next().value;
761
+ if (firstKey !== undefined) {
762
+ this.recentMessageFingerprints.delete(firstKey);
763
+ }
764
+ }
765
+ }
766
+ }
767
+ /**
768
+ * Send a notification to the default channel
769
+ *
770
+ * @param notification - Notification to send
771
+ */
772
+ async sendNotification(notification) {
773
+ const targetChannelId = notification.channelId || this.config?.defaultChannelId;
774
+ if (!targetChannelId) {
775
+ this.logger.warn('No channel configured for notification');
776
+ return;
777
+ }
778
+ const blocks = this.formatNotificationBlocks(notification);
779
+ await this.sendMessage({
780
+ channelId: targetChannelId,
781
+ text: `${notification.title}: ${notification.message}`,
782
+ blocks,
783
+ threadTs: notification.threadTs,
784
+ });
785
+ }
786
+ /**
787
+ * Format notification as Slack blocks
788
+ *
789
+ * @param notification - Notification to format
790
+ * @returns Slack blocks for the notification
791
+ */
792
+ formatNotificationBlocks(notification) {
793
+ const urgencyEmoji = {
794
+ low: ':white_circle:',
795
+ normal: ':large_blue_circle:',
796
+ high: ':large_orange_circle:',
797
+ critical: ':red_circle:',
798
+ };
799
+ const blocks = [
800
+ {
801
+ type: 'header',
802
+ text: {
803
+ type: 'plain_text',
804
+ text: `${urgencyEmoji[notification.urgency]} ${notification.title}`,
805
+ emoji: true,
806
+ },
807
+ },
808
+ {
809
+ type: 'section',
810
+ text: {
811
+ type: 'mrkdwn',
812
+ text: notification.message,
813
+ },
814
+ },
815
+ ];
816
+ // Context block elements are text objects where `text` is a plain string.
817
+ // Using type assertion because SlackElement.text is typed as SlackTextObject
818
+ // but Slack API context elements use text objects directly as elements.
819
+ blocks.push({
820
+ type: 'context',
821
+ elements: [
822
+ {
823
+ type: 'mrkdwn',
824
+ text: `Sent at ${new Date(notification.timestamp).toLocaleString()}`,
825
+ },
826
+ ],
827
+ });
828
+ return blocks;
829
+ }
830
+ /**
831
+ * Update a message
832
+ *
833
+ * @param channelId - Channel ID
834
+ * @param messageTs - Message timestamp
835
+ * @param text - New text
836
+ * @param blocks - Optional new blocks
837
+ */
838
+ async updateMessage(channelId, messageTs, text, blocks) {
839
+ if (!this.client) {
840
+ throw new Error('Slack client not initialized');
841
+ }
842
+ await this.client.chat.update({
843
+ channel: channelId,
844
+ ts: messageTs,
845
+ text,
846
+ blocks,
847
+ });
848
+ }
849
+ /**
850
+ * Add a reaction to a message
851
+ *
852
+ * @param channelId - Channel ID
853
+ * @param messageTs - Message timestamp
854
+ * @param emoji - Emoji name (without colons)
855
+ */
856
+ async addReaction(channelId, messageTs, emoji) {
857
+ if (!this.client) {
858
+ throw new Error('Slack client not initialized');
859
+ }
860
+ await this.client.reactions.add({
861
+ channel: channelId,
862
+ timestamp: messageTs,
863
+ name: emoji,
864
+ });
865
+ }
866
+ /**
867
+ * Get or create conversation context for a thread
868
+ *
869
+ * @param threadTs - Thread timestamp
870
+ * @param channelId - Channel ID
871
+ * @param userId - User ID
872
+ * @returns Conversation context
873
+ */
874
+ getConversationContext(threadTs, channelId, userId) {
875
+ const key = `${channelId}:${threadTs}`;
876
+ // NOTE: This is intentionally NOT `synthesizeSlackConversationId`
877
+ // (chat-v2/legacy-dto.utils.ts). That helper produces the chat-v2
878
+ // channel id by replacing the single dot in the Slack ts. The id
879
+ // built here is for an in-memory `SlackConversationContext` map keyed
880
+ // by a broader sanitized form (any non-alphanumeric → `-`) and may
881
+ // diverge from the chat-v2 channel id by design. Do not "unify" —
882
+ // see the 2026-05-15 review of PR #547 for the discussion.
883
+ const conversationId = `slack-${channelId}-${threadTs}`.replace(/[^A-Za-z0-9_-]/g, '-');
884
+ let context = this.conversationContexts.get(key);
885
+ if (!context) {
886
+ context = {
887
+ threadTs,
888
+ channelId,
889
+ userId,
890
+ conversationId,
891
+ startedAt: new Date().toISOString(),
892
+ lastActivityAt: new Date().toISOString(),
893
+ messageCount: 0,
894
+ };
895
+ this.conversationContexts.set(key, context);
896
+ }
897
+ else if (context.conversationId !== conversationId) {
898
+ context.conversationId = conversationId;
899
+ }
900
+ context.lastActivityAt = new Date().toISOString();
901
+ context.messageCount++;
902
+ return context;
903
+ }
904
+ /**
905
+ * Get service status
906
+ *
907
+ * @returns Current service status
908
+ */
909
+ getStatus() {
910
+ return { ...this.status };
911
+ }
912
+ /**
913
+ * Check if service is connected
914
+ *
915
+ * @returns True if connected
916
+ */
917
+ isConnected() {
918
+ return this.status.connected;
919
+ }
920
+ /**
921
+ * Get the bot token used to initialize the Slack client.
922
+ * Required for downloading private files from Slack.
923
+ *
924
+ * @returns The bot token string, or null if not initialized
925
+ */
926
+ getBotToken() {
927
+ return this.config?.botToken || null;
928
+ }
929
+ /**
930
+ * Resolve the bot user's Slack id (`U…`) via `auth.test`, cached after the
931
+ * first call. Team-channel routing uses it to ignore `<@bot>` mentions in
932
+ * inbound text and to invite the bot into linked channels.
933
+ *
934
+ * @returns The bot user id, or null when not connected or the API omits it
935
+ */
936
+ async getBotUserId() {
937
+ if (this.cachedBotUserId)
938
+ return this.cachedBotUserId;
939
+ if (!this.client)
940
+ return null;
941
+ try {
942
+ const res = await this.client.auth.test();
943
+ const id = res?.user_id ?? null;
944
+ if (id)
945
+ this.cachedBotUserId = id;
946
+ return id;
947
+ }
948
+ catch (error) {
949
+ this.logger.warn('auth.test failed while resolving bot user id', {
950
+ error: error instanceof Error ? error.message : String(error),
951
+ });
952
+ return null;
953
+ }
954
+ }
955
+ /**
956
+ * Create a public Slack channel. When Slack reports `name_taken`, the
957
+ * existing channel of that name is looked up and returned instead, so a
958
+ * team whose channel already exists (e.g. after a re-install) links to
959
+ * it rather than failing.
960
+ *
961
+ * Requires the `channels:manage` scope (and `channels:read` for the
962
+ * name-taken fallback).
963
+ *
964
+ * @param name - Channel name without `#`, already sanitised by the caller
965
+ * @returns The created (or pre-existing) channel
966
+ * @throws Error when the client is not initialised or Slack refuses
967
+ */
968
+ async createChannel(name) {
969
+ const conversations = this.requireConversationsApi();
970
+ try {
971
+ const res = await conversations.create({ name, is_private: false });
972
+ const channel = SlackService.toChannelInfo(res.channel);
973
+ if (!channel)
974
+ throw new Error('conversations.create returned no channel');
975
+ return channel;
976
+ }
977
+ catch (error) {
978
+ if (SlackService.slackErrorCode(error) === 'name_taken') {
979
+ const existing = await this.findChannelByName(name);
980
+ if (existing) {
981
+ // The bot may not be in a channel it did not create; joining is
982
+ // idempotent and needed before it can post or read there.
983
+ await this.joinChannel(existing.id).catch(() => undefined);
984
+ return existing;
985
+ }
986
+ }
987
+ throw error;
988
+ }
989
+ }
990
+ /**
991
+ * Find a public or private channel by exact name (case-insensitive),
992
+ * paging through `conversations.list`.
993
+ *
994
+ * @param name - Channel name without `#`
995
+ * @returns The channel, or null when no channel has that name
996
+ */
997
+ async findChannelByName(name) {
998
+ const conversations = this.requireConversationsApi();
999
+ const wanted = name.toLowerCase();
1000
+ let cursor;
1001
+ // Bounded paging so a pathological workspace cannot spin forever.
1002
+ for (let page = 0; page < 20; page++) {
1003
+ const res = await conversations.list({
1004
+ types: 'public_channel,private_channel',
1005
+ limit: 200,
1006
+ cursor,
1007
+ exclude_archived: false,
1008
+ });
1009
+ for (const raw of res.channels ?? []) {
1010
+ if ((raw.name ?? '').toLowerCase() === wanted) {
1011
+ return SlackService.toChannelInfo(raw);
1012
+ }
1013
+ }
1014
+ cursor = res.response_metadata?.next_cursor || undefined;
1015
+ if (!cursor)
1016
+ break;
1017
+ }
1018
+ return null;
1019
+ }
1020
+ /**
1021
+ * Fetch a channel by id.
1022
+ *
1023
+ * @param channelId - Slack channel id
1024
+ * @returns The channel, or null when Slack reports `channel_not_found`
1025
+ */
1026
+ async getChannelInfo(channelId) {
1027
+ const conversations = this.requireConversationsApi();
1028
+ try {
1029
+ const res = await conversations.info({ channel: channelId });
1030
+ return SlackService.toChannelInfo(res.channel);
1031
+ }
1032
+ catch (error) {
1033
+ if (SlackService.slackErrorCode(error) === 'channel_not_found')
1034
+ return null;
1035
+ throw error;
1036
+ }
1037
+ }
1038
+ /**
1039
+ * Join a public channel as the bot (idempotent). Requires `channels:join`.
1040
+ *
1041
+ * @param channelId - Slack channel id
1042
+ */
1043
+ async joinChannel(channelId) {
1044
+ const conversations = this.requireConversationsApi();
1045
+ await conversations.join({ channel: channelId });
1046
+ }
1047
+ /**
1048
+ * Invite users (or other bots) into a channel the bot is a member of.
1049
+ *
1050
+ * @param channelId - Slack channel id
1051
+ * @param userIds - Slack user ids to invite
1052
+ */
1053
+ async inviteToChannel(channelId, userIds) {
1054
+ if (userIds.length === 0)
1055
+ return;
1056
+ const conversations = this.requireConversationsApi();
1057
+ await conversations.invite({ channel: channelId, users: userIds.join(',') });
1058
+ }
1059
+ /**
1060
+ * Set a channel's purpose line. Requires `channels:manage`.
1061
+ *
1062
+ * @param channelId - Slack channel id
1063
+ * @param purpose - Purpose text (Slack caps it at 250 chars)
1064
+ */
1065
+ async setChannelPurpose(channelId, purpose) {
1066
+ const conversations = this.requireConversationsApi();
1067
+ await conversations.setPurpose({
1068
+ channel: channelId,
1069
+ purpose: purpose.slice(0, SLACK_TEAM_CHANNEL_CONSTANTS.MAX_PURPOSE_LENGTH),
1070
+ });
1071
+ }
1072
+ /**
1073
+ * Archive a channel. `already_archived` is treated as success so the
1074
+ * team-deleted path is idempotent.
1075
+ *
1076
+ * @param channelId - Slack channel id
1077
+ */
1078
+ async archiveChannel(channelId) {
1079
+ const conversations = this.requireConversationsApi();
1080
+ try {
1081
+ await conversations.archive({ channel: channelId });
1082
+ }
1083
+ catch (error) {
1084
+ const code = SlackService.slackErrorCode(error);
1085
+ if (code === 'already_archived' || code === 'channel_not_found')
1086
+ return;
1087
+ throw error;
1088
+ }
1089
+ }
1090
+ /**
1091
+ * Open (or reuse) the DM channel with a person and return its id.
1092
+ *
1093
+ * Requires `im:write` on the token used. Pass `botToken` to open the DM as
1094
+ * an agent's own bot user — that is a different conversation from the one
1095
+ * the default Crewly bot has with the same person.
1096
+ *
1097
+ * @param userId - Slack user id of the person (`U…` / `W…`)
1098
+ * @param botToken - Optional per-call token override
1099
+ * @returns The DM channel id (`D…`)
1100
+ * @throws Error when the client is not initialised or Slack refuses
1101
+ */
1102
+ async openDirectMessage(userId, botToken) {
1103
+ const conversations = this.requireConversationsApi();
1104
+ const res = await conversations.open({
1105
+ users: userId,
1106
+ ...(botToken ? { token: botToken } : {}),
1107
+ });
1108
+ const id = res.channel?.id;
1109
+ if (!id)
1110
+ throw new Error(`conversations.open returned no channel for ${userId}`);
1111
+ return id;
1112
+ }
1113
+ /**
1114
+ * Resolve an `@handle` (or display / real name) to a Slack user id by
1115
+ * scanning the directory. Results are cached for the process lifetime —
1116
+ * handles change rarely and the listing is expensive.
1117
+ *
1118
+ * Bots and deactivated accounts are skipped so `@sam` never resolves to a
1119
+ * bot that happens to share the name.
1120
+ *
1121
+ * @param handle - Handle without `@`, case-insensitive
1122
+ * @returns The user id, or null when nobody matches
1123
+ * @throws Error when the client is not initialised or lacks `users:read`
1124
+ */
1125
+ async findUserByHandle(handle) {
1126
+ const wanted = (handle ?? '').trim().replace(/^@/, '').toLowerCase();
1127
+ if (!wanted)
1128
+ return null;
1129
+ const cached = this.userHandleCache.get(wanted);
1130
+ if (cached)
1131
+ return cached;
1132
+ if (!this.client)
1133
+ throw new Error('Slack client not initialized');
1134
+ const list = this.client.users.list;
1135
+ if (!list)
1136
+ throw new Error('Slack client has no users.list API');
1137
+ let cursor;
1138
+ // Bounded paging: a very large workspace should fail loudly rather than
1139
+ // spin through the whole directory on every miss.
1140
+ for (let page = 0; page < 20; page++) {
1141
+ const res = await list({ limit: 200, cursor });
1142
+ for (const member of res.members ?? []) {
1143
+ if (!member.id || member.deleted || member.is_bot)
1144
+ continue;
1145
+ const names = [member.name, member.profile?.display_name, member.profile?.real_name, member.real_name]
1146
+ .filter((n) => !!n)
1147
+ .map((n) => n.toLowerCase());
1148
+ for (const n of names) {
1149
+ if (!this.userHandleCache.has(n))
1150
+ this.userHandleCache.set(n, member.id);
1151
+ }
1152
+ if (names.includes(wanted))
1153
+ return member.id;
1154
+ }
1155
+ cursor = res.response_metadata?.next_cursor || undefined;
1156
+ if (!cursor)
1157
+ break;
1158
+ }
1159
+ return null;
1160
+ }
1161
+ /**
1162
+ * The conversations API of the live client, or throw when Slack is not
1163
+ * initialised. Centralised so every channel helper reports the same
1164
+ * error text.
1165
+ */
1166
+ requireConversationsApi() {
1167
+ if (!this.client) {
1168
+ throw new Error('Slack client not initialized');
1169
+ }
1170
+ if (!this.client.conversations) {
1171
+ throw new Error('Slack client has no conversations API');
1172
+ }
1173
+ return this.client.conversations;
1174
+ }
1175
+ /**
1176
+ * Extract Slack's machine-readable error code (`name_taken`,
1177
+ * `channel_not_found`, …) from a thrown Web API error.
1178
+ *
1179
+ * @param error - The caught value
1180
+ * @returns The code, or null when the error carries none
1181
+ */
1182
+ static slackErrorCode(error) {
1183
+ const data = error?.data;
1184
+ return typeof data?.error === 'string' ? data.error : null;
1185
+ }
1186
+ /**
1187
+ * Normalise a raw conversations-API channel object.
1188
+ *
1189
+ * @param raw - Slack's channel object
1190
+ * @returns The trimmed descriptor, or null when the id is missing
1191
+ */
1192
+ static toChannelInfo(raw) {
1193
+ if (!raw?.id)
1194
+ return null;
1195
+ return {
1196
+ id: raw.id,
1197
+ name: raw.name ?? '',
1198
+ isArchived: raw.is_archived === true,
1199
+ isPrivate: raw.is_private === true,
1200
+ };
1201
+ }
1202
+ /**
1203
+ * Upload an image file to a Slack channel.
1204
+ *
1205
+ * Delegates to the shared upload-with-retry logic.
1206
+ * Kept as a separate public method for backward compatibility
1207
+ * with callers that use the image-specific endpoint.
1208
+ *
1209
+ * @param options - Upload configuration
1210
+ * @returns Object with the uploaded file ID
1211
+ * @throws Error if the client is not initialized or upload fails
1212
+ */
1213
+ async uploadImage(options) {
1214
+ return this.uploadWithRetry(options, SLACK_IMAGE_CONSTANTS);
1215
+ }
1216
+ /**
1217
+ * Upload any supported file to a Slack channel.
1218
+ *
1219
+ * Delegates to the shared upload-with-retry logic.
1220
+ * Works for PDFs, images, documents, and other file types supported by Slack.
1221
+ *
1222
+ * @param options - Upload configuration
1223
+ * @returns Object with the uploaded file ID
1224
+ * @throws Error if the client is not initialized or upload fails
1225
+ */
1226
+ async uploadFile(options) {
1227
+ return this.uploadWithRetry(options, SLACK_FILE_UPLOAD_CONSTANTS);
1228
+ }
1229
+ /**
1230
+ * Shared upload logic with retry/backoff for Slack rate limits.
1231
+ *
1232
+ * Reads the file from disk and uploads via files.uploadV2.
1233
+ * Retries on 429 responses with exponential backoff capped at 60s.
1234
+ *
1235
+ * @param options - Upload configuration (channel, path, filename, etc.)
1236
+ * @param constants - Constants object providing UPLOAD_MAX_RETRIES and UPLOAD_DEFAULT_BACKOFF_MS
1237
+ * @returns Object with the uploaded file ID
1238
+ * @throws Error if the client is not initialized, retries exhausted, or a non-rate-limit error occurs
1239
+ */
1240
+ async uploadWithRetry(options, constants) {
1241
+ if (!this.client) {
1242
+ throw new Error('Slack client not initialized');
1243
+ }
1244
+ const filename = options.filename || basename(options.filePath);
1245
+ const maxRetries = constants.UPLOAD_MAX_RETRIES;
1246
+ const MAX_BACKOFF_MS = 60_000;
1247
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1248
+ const fileStream = createReadStream(options.filePath);
1249
+ try {
1250
+ const result = await this.client.files.uploadV2({
1251
+ channel_id: options.channelId,
1252
+ file: fileStream,
1253
+ filename,
1254
+ title: options.title,
1255
+ initial_comment: options.initialComment,
1256
+ thread_ts: options.threadTs,
1257
+ });
1258
+ this.status.messagesSent++;
1259
+ return { fileId: result.files?.[0]?.id };
1260
+ }
1261
+ catch (error) {
1262
+ fileStream.destroy();
1263
+ const isRateLimit = this.isRateLimitError(error);
1264
+ if (isRateLimit && attempt < maxRetries) {
1265
+ const rawMs = this.extractRetryAfterMs(error) || constants.UPLOAD_DEFAULT_BACKOFF_MS;
1266
+ const retryAfterMs = Math.min(rawMs, MAX_BACKOFF_MS);
1267
+ this.logger.warn('Upload rate-limited (429), retrying', { retryAfterMs, attempt: attempt + 1, maxRetries });
1268
+ await new Promise(resolve => setTimeout(resolve, retryAfterMs));
1269
+ continue;
1270
+ }
1271
+ this.logger.error('Upload error', { error: error instanceof Error ? error.message : String(error) });
1272
+ throw error;
1273
+ }
1274
+ }
1275
+ throw new Error('Upload failed after maximum retries');
1276
+ }
1277
+ /**
1278
+ * Check if an error is a Slack 429 rate limit error.
1279
+ *
1280
+ * @param error - The caught error
1281
+ * @returns True if the error represents a 429 rate limit response
1282
+ */
1283
+ isRateLimitError(error) {
1284
+ if (error && typeof error === 'object') {
1285
+ const err = error;
1286
+ // @slack/web-api throws errors with code 'slack_webapi_rate_limited_error'
1287
+ if (err.code === 'slack_webapi_rate_limited_error')
1288
+ return true;
1289
+ // Also check for status 429 in case of raw HTTP errors
1290
+ if (err.statusCode === 429 || err.status === 429)
1291
+ return true;
1292
+ }
1293
+ return false;
1294
+ }
1295
+ /**
1296
+ * Extract the retry-after delay from a Slack rate limit error.
1297
+ *
1298
+ * @param error - The caught error
1299
+ * @returns Retry delay in milliseconds, or null if not found
1300
+ */
1301
+ extractRetryAfterMs(error) {
1302
+ if (error && typeof error === 'object') {
1303
+ const err = error;
1304
+ // @slack/web-api attaches retryAfter (seconds) to the error
1305
+ if (typeof err.retryAfter === 'number') {
1306
+ return err.retryAfter * 1000;
1307
+ }
1308
+ // Check headers in case of raw response
1309
+ const headers = err.headers;
1310
+ if (headers?.['retry-after']) {
1311
+ const seconds = parseInt(headers['retry-after'], 10);
1312
+ if (!isNaN(seconds))
1313
+ return seconds * 1000;
1314
+ }
1315
+ }
1316
+ return null;
1317
+ }
1318
+ /**
1319
+ * Disconnect from Slack
1320
+ */
1321
+ async disconnect() {
1322
+ this.intentionalDisconnect = true;
1323
+ this.cancelReconnectGrace();
1324
+ this.stopHealthCheck();
1325
+ if (this.app) {
1326
+ await this.app.stop();
1327
+ this.status.connected = false;
1328
+ this.emit('disconnected');
1329
+ this.logger.info('Disconnected');
1330
+ }
1331
+ }
1332
+ /**
1333
+ * Get file info from Slack via the files.info API.
1334
+ * Requires the bot token to have `files:read` scope.
1335
+ *
1336
+ * @param fileId - Slack file ID (e.g., F0123ABC456)
1337
+ * @returns Object with private download URLs
1338
+ * @throws Error if the client is not initialized or API call fails
1339
+ */
1340
+ async getFileInfo(fileId) {
1341
+ if (!this.client) {
1342
+ throw new Error('Slack client not initialized');
1343
+ }
1344
+ const result = await this.client.files.info({ file: fileId });
1345
+ return {
1346
+ url_private: result.file?.url_private || '',
1347
+ url_private_download: result.file?.url_private_download || '',
1348
+ };
1349
+ }
1350
+ /**
1351
+ * Get user info from Slack
1352
+ *
1353
+ * @param userId - Slack user ID
1354
+ * @returns User info object
1355
+ */
1356
+ async getUserInfo(userId) {
1357
+ if (!this.client) {
1358
+ throw new Error('Slack client not initialized');
1359
+ }
1360
+ const result = await this.client.users.info({ user: userId });
1361
+ return {
1362
+ name: result.user?.name || userId,
1363
+ realName: result.user?.real_name || userId,
1364
+ email: result.user?.profile?.email,
1365
+ };
1366
+ }
1367
+ }
1368
+ /**
1369
+ * Get the SlackService singleton instance
1370
+ *
1371
+ * @returns SlackService instance
1372
+ */
1373
+ export function getSlackService() {
1374
+ if (!slackServiceInstance) {
1375
+ slackServiceInstance = new SlackService();
1376
+ }
1377
+ return slackServiceInstance;
1378
+ }
1379
+ /**
1380
+ * Reset the SlackService instance (for testing)
1381
+ */
1382
+ export function resetSlackService() {
1383
+ if (slackServiceInstance) {
1384
+ slackServiceInstance.disconnect().catch(() => { });
1385
+ slackServiceInstance = null;
1386
+ }
1387
+ }
1388
+ //# sourceMappingURL=slack.service.js.map