crewly 1.20.355 → 1.20.358

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 (393) hide show
  1. package/config/constants.ts +11 -0
  2. package/config/roles/team-leader/prompt.md +1 -1
  3. package/config/roles/team-leader/tl-addon.md +1 -1
  4. package/config/skills/team-leader/delegate-task/SKILL.md +23 -1
  5. package/config/skills/team-leader/delegate-task/execute.sh +44 -1
  6. package/config/skills/team-leader/delegate-task/execute.test.sh +95 -1
  7. package/dist/backend/backend/src/constants.d.ts +319 -17
  8. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  9. package/dist/backend/backend/src/constants.js +322 -17
  10. package/dist/backend/backend/src/constants.js.map +1 -1
  11. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
  12. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +10 -0
  13. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
  14. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
  15. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +7 -0
  16. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js.map +1 -1
  17. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  18. package/dist/backend/backend/src/controllers/team/team.controller.js +5 -0
  19. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  20. package/dist/backend/backend/src/index.d.ts +15 -0
  21. package/dist/backend/backend/src/index.d.ts.map +1 -1
  22. package/dist/backend/backend/src/index.js +138 -15
  23. package/dist/backend/backend/src/index.js.map +1 -1
  24. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +21 -2
  25. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  26. package/dist/backend/backend/src/services/agent/agent-registration.service.js +100 -3
  27. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  28. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts +34 -1
  29. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js +69 -13
  31. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  32. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +8 -0
  33. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/agent/idle-detection.service.js +26 -2
  35. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  36. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +9 -1
  37. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +60 -4
  39. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
  40. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts +22 -0
  41. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts.map +1 -1
  42. package/dist/backend/backend/src/services/agent/resource-mode-protection.js +33 -0
  43. package/dist/backend/backend/src/services/agent/resource-mode-protection.js.map +1 -1
  44. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +59 -3
  45. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  46. package/dist/backend/backend/src/services/agent/resource-mode.service.js +108 -10
  47. package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
  48. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +44 -3
  49. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  50. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +126 -11
  51. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  52. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +2 -0
  53. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  54. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +9 -1
  55. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  56. package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts +23 -0
  57. package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/harness/harness-relogin.service.js +47 -6
  59. package/dist/backend/backend/src/services/harness/harness-relogin.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts +150 -0
  61. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js +319 -0
  63. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js.map +1 -0
  64. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +9 -7
  65. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -1
  66. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +19 -17
  67. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -1
  68. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/memory/memory.service.js +11 -0
  70. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  71. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts +104 -0
  72. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -0
  73. package/dist/backend/backend/src/services/memory/startup-briefing.service.js +302 -0
  74. package/dist/backend/backend/src/services/memory/startup-briefing.service.js.map +1 -0
  75. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +14 -2
  76. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
  77. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +21 -4
  78. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
  79. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +33 -1
  80. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
  81. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js +69 -4
  82. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
  83. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.d.ts +24 -1
  84. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.js +54 -3
  86. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.js.map +1 -1
  87. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  88. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +10 -1
  89. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  90. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +8 -0
  91. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  92. package/dist/backend/backend/src/services/open-items/open-items.service.js +33 -0
  93. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  94. package/dist/backend/backend/src/services/open-items/open-items.wiring.js +2 -2
  95. package/dist/backend/backend/src/services/open-items/open-items.wiring.js.map +1 -1
  96. package/dist/backend/backend/src/services/open-items/question-card-gate.d.ts +49 -0
  97. package/dist/backend/backend/src/services/open-items/question-card-gate.d.ts.map +1 -0
  98. package/dist/backend/backend/src/services/open-items/question-card-gate.js +77 -0
  99. package/dist/backend/backend/src/services/open-items/question-card-gate.js.map +1 -0
  100. package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts +9 -0
  101. package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts.map +1 -1
  102. package/dist/backend/backend/src/services/orc/owner-completion-report.service.js +16 -2
  103. package/dist/backend/backend/src/services/orc/owner-completion-report.service.js.map +1 -1
  104. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +10 -0
  106. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
  107. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +2 -0
  108. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  109. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +17 -0
  110. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  111. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +7 -0
  112. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +22 -10
  114. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  115. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.d.ts +30 -0
  116. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.d.ts.map +1 -0
  117. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.js +48 -0
  118. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.js.map +1 -0
  119. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +8 -0
  120. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  121. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +29 -8
  122. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  123. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts +16 -0
  124. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
  125. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js +23 -0
  126. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
  127. package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts +2 -1
  128. package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -1
  129. package/dist/backend/backend/src/services/runtime-fallback/reset-time.js +3 -2
  130. package/dist/backend/backend/src/services/runtime-fallback/reset-time.js.map +1 -1
  131. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts +128 -5
  132. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -1
  133. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +320 -38
  134. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -1
  135. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts +23 -0
  136. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -1
  137. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +48 -3
  138. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -1
  139. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +78 -0
  140. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -1
  141. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js +159 -1
  142. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -1
  143. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.d.ts +63 -0
  144. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.d.ts.map +1 -0
  145. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.js +104 -0
  146. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.js.map +1 -0
  147. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.d.ts +166 -0
  148. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.d.ts.map +1 -0
  149. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.js +207 -0
  150. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.js.map +1 -0
  151. package/dist/backend/backend/src/services/slack/agent-coordination.d.ts +119 -0
  152. package/dist/backend/backend/src/services/slack/agent-coordination.d.ts.map +1 -0
  153. package/dist/backend/backend/src/services/slack/agent-coordination.js +174 -0
  154. package/dist/backend/backend/src/services/slack/agent-coordination.js.map +1 -0
  155. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  156. package/dist/backend/backend/src/services/slack/slack-initializer.js +7 -0
  157. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  158. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +167 -0
  159. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  160. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +619 -9
  161. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  162. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts +22 -0
  163. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  164. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +49 -12
  165. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  166. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +7 -0
  167. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  168. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +25 -4
  169. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  170. package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +21 -1
  171. package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -1
  172. package/dist/backend/backend/src/services/team-move/team-move-chat.js +54 -2
  173. package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -1
  174. package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +9 -4
  175. package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -1
  176. package/dist/backend/backend/src/services/team-move/team-move-exporter.js +32 -10
  177. package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -1
  178. package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +19 -0
  179. package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -1
  180. package/dist/backend/backend/src/services/team-move/team-move-importer.js +78 -3
  181. package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -1
  182. package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -1
  183. package/dist/backend/backend/src/services/team-move/team-move-runtime.js +8 -0
  184. package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -1
  185. package/dist/backend/backend/src/services/team-move/team-move-transcripts.d.ts +106 -0
  186. package/dist/backend/backend/src/services/team-move/team-move-transcripts.d.ts.map +1 -0
  187. package/dist/backend/backend/src/services/team-move/team-move-transcripts.js +212 -0
  188. package/dist/backend/backend/src/services/team-move/team-move-transcripts.js.map +1 -0
  189. package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +20 -0
  190. package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -1
  191. package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -1
  192. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts +2 -2
  193. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
  194. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +11 -4
  195. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
  196. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  197. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +13 -0
  198. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  199. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts.map +1 -1
  200. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js +3 -0
  201. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js.map +1 -1
  202. package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts.map +1 -1
  203. package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js +4 -1
  204. package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js.map +1 -1
  205. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts.map +1 -1
  206. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js +4 -0
  207. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js.map +1 -1
  208. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +33 -4
  209. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  210. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js +75 -7
  211. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  212. package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts.map +1 -1
  213. package/dist/backend/backend/src/services/wiki/wiki-lint.service.js +3 -1
  214. package/dist/backend/backend/src/services/wiki/wiki-lint.service.js.map +1 -1
  215. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts +116 -0
  216. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts.map +1 -0
  217. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js +227 -0
  218. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js.map +1 -0
  219. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts +142 -0
  220. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -0
  221. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js +222 -0
  222. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js.map +1 -0
  223. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts +93 -0
  224. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts.map +1 -0
  225. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js +142 -0
  226. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js.map +1 -0
  227. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts +104 -0
  228. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts.map +1 -0
  229. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js +192 -0
  230. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js.map +1 -0
  231. package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts +3 -2
  232. package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts.map +1 -1
  233. package/dist/backend/backend/src/services/wiki/wiki-query.service.js +23 -39
  234. package/dist/backend/backend/src/services/wiki/wiki-query.service.js.map +1 -1
  235. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.d.ts +105 -0
  236. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.d.ts.map +1 -0
  237. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.js +195 -0
  238. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.js.map +1 -0
  239. package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/wiki/wiki-recent.service.js +3 -0
  241. package/dist/backend/backend/src/services/wiki/wiki-recent.service.js.map +1 -1
  242. package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts +28 -5
  243. package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -1
  244. package/dist/backend/backend/src/services/wiki/wiki-search.service.js +96 -25
  245. package/dist/backend/backend/src/services/wiki/wiki-search.service.js.map +1 -1
  246. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.d.ts +11 -0
  247. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.d.ts.map +1 -1
  248. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.js +17 -1
  249. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.js.map +1 -1
  250. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +22 -0
  251. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  252. package/dist/backend/backend/src/services/workflow/scheduler.service.js +35 -1
  253. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  254. package/dist/backend/backend/src/types/index.d.ts +12 -0
  255. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  256. package/dist/backend/backend/src/types/index.js.map +1 -1
  257. package/dist/backend/backend/src/types/team-template.types.d.ts +1 -0
  258. package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
  259. package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
  260. package/dist/backend/build-info.json +2 -2
  261. package/dist/backend/config/constants.d.ts +11 -0
  262. package/dist/backend/config/constants.d.ts.map +1 -1
  263. package/dist/backend/config/constants.js +11 -0
  264. package/dist/backend/config/constants.js.map +1 -1
  265. package/dist/cli/backend/src/constants.d.ts +319 -17
  266. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  267. package/dist/cli/backend/src/constants.js +322 -17
  268. package/dist/cli/backend/src/constants.js.map +1 -1
  269. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +21 -2
  270. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  271. package/dist/cli/backend/src/services/agent/agent-registration.service.js +100 -3
  272. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  273. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts +34 -1
  274. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  275. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js +69 -13
  276. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  277. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +9 -1
  278. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  279. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +60 -4
  280. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
  281. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +59 -3
  282. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  283. package/dist/cli/backend/src/services/agent/resource-mode.service.js +108 -10
  284. package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
  285. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +44 -3
  286. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  287. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +126 -11
  288. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  289. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +2 -0
  290. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  291. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +9 -1
  292. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  293. package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts +23 -0
  294. package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
  295. package/dist/cli/backend/src/services/harness/harness-relogin.service.js +47 -6
  296. package/dist/cli/backend/src/services/harness/harness-relogin.service.js.map +1 -1
  297. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  298. package/dist/cli/backend/src/services/memory/memory.service.js +11 -0
  299. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  300. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts +104 -0
  301. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -0
  302. package/dist/cli/backend/src/services/memory/startup-briefing.service.js +302 -0
  303. package/dist/cli/backend/src/services/memory/startup-briefing.service.js.map +1 -0
  304. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +33 -1
  305. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
  306. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js +69 -4
  307. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
  308. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  309. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +10 -1
  310. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  311. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +8 -0
  312. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  313. package/dist/cli/backend/src/services/open-items/open-items.service.js +33 -0
  314. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  315. package/dist/cli/backend/src/services/open-items/question-card-gate.d.ts +49 -0
  316. package/dist/cli/backend/src/services/open-items/question-card-gate.d.ts.map +1 -0
  317. package/dist/cli/backend/src/services/open-items/question-card-gate.js +77 -0
  318. package/dist/cli/backend/src/services/open-items/question-card-gate.js.map +1 -0
  319. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +2 -0
  320. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  321. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js +17 -0
  322. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  323. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts +7 -0
  324. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  325. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js +22 -10
  326. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  327. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts +16 -0
  328. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
  329. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js +23 -0
  330. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
  331. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts +2 -1
  332. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -1
  333. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js +3 -2
  334. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js.map +1 -1
  335. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +78 -0
  336. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -1
  337. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js +159 -1
  338. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -1
  339. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.d.ts +63 -0
  340. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.d.ts.map +1 -0
  341. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.js +104 -0
  342. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.js.map +1 -0
  343. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.d.ts +166 -0
  344. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.d.ts.map +1 -0
  345. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.js +207 -0
  346. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.js.map +1 -0
  347. package/dist/cli/backend/src/services/slack/agent-coordination.d.ts +119 -0
  348. package/dist/cli/backend/src/services/slack/agent-coordination.d.ts.map +1 -0
  349. package/dist/cli/backend/src/services/slack/agent-coordination.js +174 -0
  350. package/dist/cli/backend/src/services/slack/agent-coordination.js.map +1 -0
  351. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +167 -0
  352. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  353. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +619 -9
  354. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  355. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts +22 -0
  356. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  357. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +49 -12
  358. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  359. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +7 -0
  360. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  361. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +25 -4
  362. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  363. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +33 -4
  364. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  365. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js +75 -7
  366. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  367. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts +142 -0
  368. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -0
  369. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js +222 -0
  370. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js.map +1 -0
  371. package/dist/cli/backend/src/services/wiki/wiki-recent.service.d.ts +51 -0
  372. package/dist/cli/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -0
  373. package/dist/cli/backend/src/services/wiki/wiki-recent.service.js +105 -0
  374. package/dist/cli/backend/src/services/wiki/wiki-recent.service.js.map +1 -0
  375. package/dist/cli/backend/src/services/wiki/wiki-search.service.d.ts +28 -5
  376. package/dist/cli/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -1
  377. package/dist/cli/backend/src/services/wiki/wiki-search.service.js +96 -25
  378. package/dist/cli/backend/src/services/wiki/wiki-search.service.js.map +1 -1
  379. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.d.ts +11 -0
  380. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.d.ts.map +1 -1
  381. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.js +17 -1
  382. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.js.map +1 -1
  383. package/dist/cli/backend/src/types/index.d.ts +12 -0
  384. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  385. package/dist/cli/backend/src/types/index.js.map +1 -1
  386. package/dist/cli/backend/src/types/team-template.types.d.ts +1 -0
  387. package/dist/cli/backend/src/types/team-template.types.d.ts.map +1 -1
  388. package/dist/cli/backend/src/types/team-template.types.js.map +1 -1
  389. package/dist/cli/config/constants.d.ts +11 -0
  390. package/dist/cli/config/constants.d.ts.map +1 -1
  391. package/dist/cli/config/constants.js +11 -0
  392. package/dist/cli/config/constants.js.map +1 -1
  393. package/package.json +1 -1
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Usage-limit state per agent session — "this agent's runtime is out of
3
+ * usage until …". Process-wide and dependency-free (like the spend-cap gate)
4
+ * so the hot paths can ask it cheaply: the orchestrator restart service and
5
+ * heartbeat monitor (no restarts while limited), delivery (no waiting on a
6
+ * prompt that will not come, messages held), dispatch, and the status APIs.
7
+ *
8
+ * Why (2026-10-16): the orchestrator sat on Claude Code's weekly-limit menu
9
+ * for ~38 hours. Crewly kept waiting for its prompt every ~17s, restarted it
10
+ * 12 times in 15 minutes, and `GET /api/orchestrator/status` said "active and
11
+ * ready" the whole time.
12
+ *
13
+ * Fed by the login/screen monitor (screen sweep + live output) through
14
+ * {@link markUsageLimited}. A state lifts on its own at the reset time (plus
15
+ * a short grace), or after {@link USAGE_LIMIT_STATE_CONSTANTS.NO_RESET_BACKOFF_MS}
16
+ * when no reset time was given; it is set again if the limit is still there.
17
+ * It is lifted early ({@link liftUsageLimit}) as soon as the agent works
18
+ * again: a finished turn or tool call (Claude Code hooks), or fresh live
19
+ * output that is not a limit message.
20
+ * It is held in memory only: it describes the live screen, and after a Crewly
21
+ * restart the screen is read again.
22
+ *
23
+ * Distinct from the runtime fallback's account-wide "exhausted runtime"
24
+ * record: that one moves agents to another runtime; this one says what a
25
+ * given session is doing right now. A session moved to another runtime is
26
+ * cleared ({@link clearUsageLimit}).
27
+ *
28
+ * @module services/runtime-fallback/usage-limit-state
29
+ */
30
+ import { RUNTIME_FALLBACK_CONSTANTS, USAGE_LIMIT_STATE_CONSTANTS } from '../../constants.js';
31
+ const states = new Map();
32
+ /**
33
+ * When a state with this reset time may be tried again.
34
+ *
35
+ * @param resetAt - Reset time (ms), or null
36
+ * @param now - Current time (ms)
37
+ * @returns Epoch ms
38
+ */
39
+ function retryAtFor(resetAt, now) {
40
+ return resetAt !== null
41
+ ? resetAt + USAGE_LIMIT_STATE_CONSTANTS.RESET_GRACE_MS
42
+ : now + USAGE_LIMIT_STATE_CONSTANTS.NO_RESET_BACKOFF_MS;
43
+ }
44
+ /**
45
+ * Record that a session is out of usage. A state already in force keeps its
46
+ * first-detection time; a reset time seen later replaces the backoff, and a
47
+ * later detection without one does not extend it.
48
+ *
49
+ * @param input - Session, runtime, rule, reset time, source
50
+ * @param now - Current time (ms)
51
+ * @returns The state and whether it is new (not in force before this call)
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * markUsageLimited({ sessionName: 'crewly-orc', runtime: 'claude-code', ruleId: 'claude.hit_your_limit', resetAt, source: 'menu' });
56
+ * ```
57
+ */
58
+ export function markUsageLimited(input, now = Date.now()) {
59
+ const existing = usageLimitOf(input.sessionName, now);
60
+ // A reset in the past or implausibly far ahead (an old dated message read
61
+ // as next year's) is not trusted: back off instead.
62
+ const resetAt = input.resetAt !== null && input.resetAt > now && input.resetAt - now <= USAGE_LIMIT_STATE_CONSTANTS.MAX_RESET_AHEAD_MS
63
+ ? input.resetAt
64
+ : null;
65
+ const until = resetAt !== null ? new Date(resetAt).toISOString() : undefined;
66
+ if (existing) {
67
+ if (until && existing.until !== until) {
68
+ existing.until = until;
69
+ existing.retryAt = new Date(retryAtFor(resetAt, now)).toISOString();
70
+ }
71
+ if (input.runtime && !existing.runtime)
72
+ existing.runtime = input.runtime;
73
+ if (input.source === 'menu')
74
+ existing.source = 'menu';
75
+ existing.lastSeenAt = new Date(now).toISOString();
76
+ return { info: existing, isNew: false };
77
+ }
78
+ const info = {
79
+ sessionName: input.sessionName,
80
+ runtime: input.runtime,
81
+ ruleId: input.ruleId,
82
+ source: input.source,
83
+ detectedAt: new Date(now).toISOString(),
84
+ lastSeenAt: new Date(now).toISOString(),
85
+ ...(until ? { until } : {}),
86
+ retryAt: new Date(retryAtFor(resetAt, now)).toISOString(),
87
+ };
88
+ states.set(input.sessionName, info);
89
+ return { info, isNew: true };
90
+ }
91
+ /**
92
+ * The usage-limit state in force for a session. A state past its retry time
93
+ * is dropped. Never throws.
94
+ *
95
+ * @param sessionName - Agent session
96
+ * @param now - Current time (ms)
97
+ * @returns The state, or null when the session may run
98
+ */
99
+ export function usageLimitOf(sessionName, now = Date.now()) {
100
+ const info = states.get(sessionName);
101
+ if (!info)
102
+ return null;
103
+ if (Date.parse(info.retryAt) <= now) {
104
+ states.delete(sessionName);
105
+ return null;
106
+ }
107
+ return info;
108
+ }
109
+ /**
110
+ * Milliseconds until a usage-limited session may be tried again.
111
+ *
112
+ * @param info - The state
113
+ * @param now - Current time (ms)
114
+ * @returns Milliseconds (at least 0)
115
+ */
116
+ export function usageLimitRemainingMs(info, now = Date.now()) {
117
+ return Math.max(0, Date.parse(info.retryAt) - now);
118
+ }
119
+ /**
120
+ * Note that Crewly answered the usage-limit menu of a session.
121
+ *
122
+ * @param sessionName - Agent session
123
+ * @param now - Current time (ms)
124
+ */
125
+ export function noteUsageLimitMenuAnswered(sessionName, now = Date.now()) {
126
+ const info = usageLimitOf(sessionName, now);
127
+ if (info)
128
+ info.menuAnsweredAt = new Date(now).toISOString();
129
+ }
130
+ /**
131
+ * Forget a session's usage-limit state (it moved to another runtime, or the
132
+ * owner changed its runtime).
133
+ *
134
+ * @param sessionName - Agent session
135
+ * @returns True when a state was in force
136
+ */
137
+ export function clearUsageLimit(sessionName) {
138
+ return states.delete(sessionName);
139
+ }
140
+ /**
141
+ * Lift a session's usage-limit state because the agent works again: it
142
+ * finished a turn, or wrote fresh output that is not a limit message.
143
+ * Activity within {@link USAGE_LIMIT_STATE_CONSTANTS.LIFT_GRACE_MS} of the
144
+ * limit last being seen, or of Crewly answering its menu, is the repaint of
145
+ * that screen and does not count.
146
+ *
147
+ * @param sessionName - Agent session
148
+ * @param now - Current time (ms)
149
+ * @returns The lifted state, or null when none was in force or it was too soon
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * if (liftUsageLimit('crewly-orc')) logger.info('Orchestrator works again');
154
+ * ```
155
+ */
156
+ export function liftUsageLimit(sessionName, now = Date.now()) {
157
+ const info = usageLimitOf(sessionName, now);
158
+ if (!info)
159
+ return null;
160
+ const lastSeen = Math.max(Date.parse(info.lastSeenAt), info.menuAnsweredAt ? Date.parse(info.menuAnsweredAt) : 0);
161
+ if (now - lastSeen < USAGE_LIMIT_STATE_CONSTANTS.LIFT_GRACE_MS)
162
+ return null;
163
+ states.delete(sessionName);
164
+ return info;
165
+ }
166
+ /**
167
+ * Every session that is usage-limited now.
168
+ *
169
+ * @param now - Current time (ms)
170
+ * @returns States
171
+ */
172
+ export function listUsageLimited(now = Date.now()) {
173
+ return [...states.keys()].map((s) => usageLimitOf(s, now)).filter((i) => i !== null);
174
+ }
175
+ /**
176
+ * The status-API view of a session's state (`usageLimited`), or undefined.
177
+ *
178
+ * @param sessionName - Agent session
179
+ * @param now - Current time (ms)
180
+ * @returns View, or undefined when the session is not limited
181
+ */
182
+ export function usageLimitedView(sessionName, now = Date.now()) {
183
+ const info = usageLimitOf(sessionName, now);
184
+ if (!info)
185
+ return undefined;
186
+ return { ...(info.until ? { until: info.until } : {}), retryAt: info.retryAt, detectedAt: info.detectedAt, runtime: info.runtime };
187
+ }
188
+ /**
189
+ * One-line, owner-facing reason, e.g. "Orchestrator is out of Claude usage
190
+ * until 2026-10-17T00:00:00.000Z".
191
+ *
192
+ * @param name - Who is limited ("Orchestrator", "Ella")
193
+ * @param info - The state
194
+ * @returns Reason text
195
+ */
196
+ export function usageLimitReason(name, info) {
197
+ const runtime = info.runtime ? RUNTIME_FALLBACK_CONSTANTS.SHORT_LABELS[info.runtime] ?? info.runtime : null;
198
+ const what = runtime ? `out of ${runtime} usage` : 'out of usage';
199
+ return info.until
200
+ ? `${name} is ${what} until ${info.until}`
201
+ : `${name} is ${what} (reset time unknown; trying again at ${info.retryAt})`;
202
+ }
203
+ /** Forget every state (tests). */
204
+ export function resetUsageLimitState() {
205
+ states.clear();
206
+ }
207
+ //# sourceMappingURL=usage-limit-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-limit-state.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/usage-limit-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Agent-to-agent coordination in Slack rooms (crewly#1340).
3
+ *
4
+ * 2026-10-16, #content-team: Ella, Max and Sam — all on the owner's Mac —
5
+ * posted 20+ top-level Slack messages to each other in 90 minutes ("@Max
6
+ * CREW-718 step 1 of 2 done…", "@Sam Got it, going with your first
7
+ * option…", "@Sam 1.0.217 is live…"). Each one was a new unread for the
8
+ * owner, who does not need that discussion; internal ticket ids leaked into
9
+ * every post; and Ella sent Sam the same conclusion three times.
10
+ *
11
+ * The model is a company group chat: whoever the room asked is the room's
12
+ * one voice; it reaches its helpers privately, and posts one update when
13
+ * their result is in. The pure pieces of that live here:
14
+ * - {@link classifyAgentAddressing}: whom an agent's room post is for —
15
+ * only agents on this machine (stays inside Crewly), agents elsewhere
16
+ * (Slack, in a thread), or anyone else (unchanged);
17
+ * - {@link stripTicketIds}: internal ticket ids out of anything an agent
18
+ * posts to Slack, for real ticket prefixes only;
19
+ * - {@link CoordinationDedupe}: the same agent sending a near-identical
20
+ * message to the same recipients in the same room within 15 minutes.
21
+ *
22
+ * @module services/slack/agent-coordination
23
+ */
24
+ /** Whom an agent's room post addresses. */
25
+ export type AgentAddressing =
26
+ /** Only agents running on this machine: delivered inside Crewly, never posted to Slack. */
27
+ 'local-only'
28
+ /** Only agents, at least one on another machine: Slack is the only way there, in a thread. */
29
+ | 'cross-machine'
30
+ /** No agent @'d, or a person / broadcast / name nobody knows: posted as before. */
31
+ | 'other';
32
+ /** What the room knows about the names an agent post @'s. */
33
+ export interface AgentAddressingInput {
34
+ /** Agents @'d that run on this machine (sessions) */
35
+ localAgents: readonly string[];
36
+ /** Agents @'d that run on another machine (sessions or names) */
37
+ remoteAgents: readonly string[];
38
+ /** @-tokens or native ids that are neither: a person, or a name nobody knows */
39
+ others: readonly string[];
40
+ /** A person addressed by name without an @ ("Steve, …"), or @here/@channel */
41
+ addressesPeople: boolean;
42
+ }
43
+ /**
44
+ * Whom an agent's post addresses. Anything that may be for a person — a
45
+ * person's name, a broadcast, a name that matched nobody — keeps today's
46
+ * behaviour: the owner must never miss a message meant for them.
47
+ *
48
+ * @param input - The resolved names
49
+ * @returns The addressing class
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * classifyAgentAddressing({ localAgents: ['max'], remoteAgents: [], others: [], addressesPeople: false }); // 'local-only'
54
+ * classifyAgentAddressing({ localAgents: ['max'], remoteAgents: ['rex'], others: [], addressesPeople: false }); // 'cross-machine'
55
+ * classifyAgentAddressing({ localAgents: ['max'], remoteAgents: [], others: ['Steve'], addressesPeople: false }); // 'other'
56
+ * ```
57
+ */
58
+ export declare function classifyAgentAddressing(input: AgentAddressingInput): AgentAddressing;
59
+ /**
60
+ * The real ticket prefixes, normalised: upper case, two to ten letters or
61
+ * digits starting with a letter. One-letter prefixes (the `T` fallback,
62
+ * decisions' `D`) are left out — "T-5" or "D-3" in prose is too often not
63
+ * a ticket.
64
+ *
65
+ * @param prefixes - Prefixes as configured (project ticket counters, `TKT`)
66
+ * @returns Unique prefixes, longest first
67
+ */
68
+ export declare function normaliseTicketPrefixes(prefixes: readonly string[]): string[];
69
+ /**
70
+ * Take internal ticket ids out of a Slack post. Tickets are the harness's
71
+ * bookkeeping; the owner never sees their ids or mechanics.
72
+ *
73
+ * Only ids with a real prefix are touched, so "UTF-8", "GPT-6" or "ISO-27001"
74
+ * stay. An id that is part of a path, branch or URL ("fix/CREW-12",
75
+ * "/blog/CREW-12") stays too. A parenthetical of ids goes with its brackets,
76
+ * a leading "CREW-718:" with its colon, and a preposition left dangling
77
+ * before punctuation ("for CREW-718.") goes with the id.
78
+ *
79
+ * @param text - The post
80
+ * @param prefixes - Real ticket prefixes
81
+ * @returns The post without ticket ids (the original when nothing would be left)
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * stripTicketIds('@Max CREW-718 step 1 of 2 done', ['CREW']); // '@Max step 1 of 2 done'
86
+ * stripTicketIds('the fix (CREW-718) is live', ['CREW']); // 'the fix is live'
87
+ * stripTicketIds('UTF-8 and GPT-6', ['CREW']); // unchanged
88
+ * ```
89
+ */
90
+ export declare function stripTicketIds(text: string, prefixes: readonly string[]): string;
91
+ /**
92
+ * Drops an agent's near-identical repeat to the same recipients in the same
93
+ * room within {@link AGENT_COORDINATION_CONSTANTS.DUPLICATE_WINDOW_MS} — Ella
94
+ * sent Sam one conclusion three times in six minutes (2026-10-16).
95
+ * In memory: a restart forgets, which only lets one repeat through.
96
+ */
97
+ export declare class CoordinationDedupe {
98
+ private readonly windowMs;
99
+ private readonly threshold;
100
+ private readonly sent;
101
+ /**
102
+ * @param windowMs - How long a message counts as recent
103
+ * @param threshold - Similarity (0..1) at which two messages are one
104
+ */
105
+ constructor(windowMs?: number, threshold?: number);
106
+ /**
107
+ * Whether this message repeats one the same agent sent the same recipients
108
+ * here recently. A message that is not a repeat is remembered.
109
+ *
110
+ * @param room - Room id
111
+ * @param sender - Sending agent
112
+ * @param recipients - Addressed agents
113
+ * @param text - The message
114
+ * @param now - Current time (ms)
115
+ * @returns True for a repeat (drop it)
116
+ */
117
+ isRepeat(room: string, sender: string, recipients: readonly string[], text: string, now: number): boolean;
118
+ }
119
+ //# sourceMappingURL=agent-coordination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-coordination.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/agent-coordination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,2CAA2C;AAC3C,MAAM,MAAM,eAAe;AACzB,2FAA2F;AACzF,YAAY;AACd,8FAA8F;GAC5F,eAAe;AACjB,mFAAmF;GACjF,OAAO,CAAC;AAEZ,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,iEAAiE;IACjE,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,gFAAgF;IAChF,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,8EAA8E;IAC9E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,eAAe,CAKpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAO7E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAoBhF;AAQD;;;;;GAKG;AACH,qBAAa,kBAAkB;IAQ3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAR5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IAEvD;;;OAGG;gBAEgB,QAAQ,GAAE,MAAyD,EACnE,SAAS,GAAE,MAA0D;IAGxF;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;CAc1G"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Agent-to-agent coordination in Slack rooms (crewly#1340).
3
+ *
4
+ * 2026-10-16, #content-team: Ella, Max and Sam — all on the owner's Mac —
5
+ * posted 20+ top-level Slack messages to each other in 90 minutes ("@Max
6
+ * CREW-718 step 1 of 2 done…", "@Sam Got it, going with your first
7
+ * option…", "@Sam 1.0.217 is live…"). Each one was a new unread for the
8
+ * owner, who does not need that discussion; internal ticket ids leaked into
9
+ * every post; and Ella sent Sam the same conclusion three times.
10
+ *
11
+ * The model is a company group chat: whoever the room asked is the room's
12
+ * one voice; it reaches its helpers privately, and posts one update when
13
+ * their result is in. The pure pieces of that live here:
14
+ * - {@link classifyAgentAddressing}: whom an agent's room post is for —
15
+ * only agents on this machine (stays inside Crewly), agents elsewhere
16
+ * (Slack, in a thread), or anyone else (unchanged);
17
+ * - {@link stripTicketIds}: internal ticket ids out of anything an agent
18
+ * posts to Slack, for real ticket prefixes only;
19
+ * - {@link CoordinationDedupe}: the same agent sending a near-identical
20
+ * message to the same recipients in the same room within 15 minutes.
21
+ *
22
+ * @module services/slack/agent-coordination
23
+ */
24
+ import { questionSimilarity } from '../open-items/open-item-card.js';
25
+ import { AGENT_COORDINATION_CONSTANTS } from '../../constants.js';
26
+ /**
27
+ * Whom an agent's post addresses. Anything that may be for a person — a
28
+ * person's name, a broadcast, a name that matched nobody — keeps today's
29
+ * behaviour: the owner must never miss a message meant for them.
30
+ *
31
+ * @param input - The resolved names
32
+ * @returns The addressing class
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * classifyAgentAddressing({ localAgents: ['max'], remoteAgents: [], others: [], addressesPeople: false }); // 'local-only'
37
+ * classifyAgentAddressing({ localAgents: ['max'], remoteAgents: ['rex'], others: [], addressesPeople: false }); // 'cross-machine'
38
+ * classifyAgentAddressing({ localAgents: ['max'], remoteAgents: [], others: ['Steve'], addressesPeople: false }); // 'other'
39
+ * ```
40
+ */
41
+ export function classifyAgentAddressing(input) {
42
+ if (input.addressesPeople || input.others.length > 0)
43
+ return 'other';
44
+ if (input.remoteAgents.length > 0)
45
+ return 'cross-machine';
46
+ if (input.localAgents.length > 0)
47
+ return 'local-only';
48
+ return 'other';
49
+ }
50
+ /**
51
+ * The real ticket prefixes, normalised: upper case, two to ten letters or
52
+ * digits starting with a letter. One-letter prefixes (the `T` fallback,
53
+ * decisions' `D`) are left out — "T-5" or "D-3" in prose is too often not
54
+ * a ticket.
55
+ *
56
+ * @param prefixes - Prefixes as configured (project ticket counters, `TKT`)
57
+ * @returns Unique prefixes, longest first
58
+ */
59
+ export function normaliseTicketPrefixes(prefixes) {
60
+ const clean = new Set();
61
+ for (const p of prefixes) {
62
+ const up = (p ?? '').trim().toUpperCase();
63
+ if (/^[A-Z][A-Z0-9]{1,9}$/.test(up))
64
+ clean.add(up);
65
+ }
66
+ return [...clean].sort((a, b) => b.length - a.length || a.localeCompare(b));
67
+ }
68
+ /**
69
+ * Take internal ticket ids out of a Slack post. Tickets are the harness's
70
+ * bookkeeping; the owner never sees their ids or mechanics.
71
+ *
72
+ * Only ids with a real prefix are touched, so "UTF-8", "GPT-6" or "ISO-27001"
73
+ * stay. An id that is part of a path, branch or URL ("fix/CREW-12",
74
+ * "/blog/CREW-12") stays too. A parenthetical of ids goes with its brackets,
75
+ * a leading "CREW-718:" with its colon, and a preposition left dangling
76
+ * before punctuation ("for CREW-718.") goes with the id.
77
+ *
78
+ * @param text - The post
79
+ * @param prefixes - Real ticket prefixes
80
+ * @returns The post without ticket ids (the original when nothing would be left)
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * stripTicketIds('@Max CREW-718 step 1 of 2 done', ['CREW']); // '@Max step 1 of 2 done'
85
+ * stripTicketIds('the fix (CREW-718) is live', ['CREW']); // 'the fix is live'
86
+ * stripTicketIds('UTF-8 and GPT-6', ['CREW']); // unchanged
87
+ * ```
88
+ */
89
+ export function stripTicketIds(text, prefixes) {
90
+ const list = normaliseTicketPrefixes(prefixes);
91
+ if (!text || list.length === 0)
92
+ return text;
93
+ const id = `(?<![\\p{L}\\p{N}_/.#-])(?:${list.join('|')})-\\d+(?![\\p{L}\\p{N}_/-])`;
94
+ if (!new RegExp(id, 'u').test(text))
95
+ return text;
96
+ let out = text
97
+ // "(CREW-718)", "(CREW-718, CREW-719)"
98
+ .replace(new RegExp(`[ \\t]*\\(\\s*${id}(?:\\s*(?:,|/|&|and)\\s*${id})*\\s*\\)`, 'gu'), '')
99
+ // "CREW-718: …", "CREW-718 — …"
100
+ .replace(new RegExp(`${id}[ \\t]*[::—–][ \\t]*`, 'gu'), '')
101
+ // "for CREW-718." / "on CREW-718," — the preposition goes too
102
+ .replace(new RegExp(`[ \\t]+(?:[Ff]or|[Oo]n|[Ii]n|[Uu]nder|[Aa]bout|[Oo]f|[Rr]e)[ \\t]+${id}(?=[ \\t]*(?:[.,;:!?)]|$))`, 'gmu'), '')
103
+ // A bare id, with the space after it ("@Max CREW-718 step" → "@Max step")
104
+ .replace(new RegExp(`${id}[ \\t]?`, 'gu'), '');
105
+ out = out
106
+ .replace(/(\S)[ \t]{2,}(?=\S)/gu, '$1 ')
107
+ .replace(/[ \t]+([.,;:!?)])/gu, '$1')
108
+ .replace(/\([ \t]*\)/gu, '')
109
+ .replace(/[ \t]+$/gmu, '');
110
+ return out.trim().length > 0 ? out : text;
111
+ }
112
+ /**
113
+ * Drops an agent's near-identical repeat to the same recipients in the same
114
+ * room within {@link AGENT_COORDINATION_CONSTANTS.DUPLICATE_WINDOW_MS} — Ella
115
+ * sent Sam one conclusion three times in six minutes (2026-10-16).
116
+ * In memory: a restart forgets, which only lets one repeat through.
117
+ */
118
+ export class CoordinationDedupe {
119
+ windowMs;
120
+ threshold;
121
+ sent = new Map();
122
+ /**
123
+ * @param windowMs - How long a message counts as recent
124
+ * @param threshold - Similarity (0..1) at which two messages are one
125
+ */
126
+ constructor(windowMs = AGENT_COORDINATION_CONSTANTS.DUPLICATE_WINDOW_MS, threshold = AGENT_COORDINATION_CONSTANTS.DUPLICATE_SIMILARITY) {
127
+ this.windowMs = windowMs;
128
+ this.threshold = threshold;
129
+ }
130
+ /**
131
+ * Whether this message repeats one the same agent sent the same recipients
132
+ * here recently. A message that is not a repeat is remembered.
133
+ *
134
+ * @param room - Room id
135
+ * @param sender - Sending agent
136
+ * @param recipients - Addressed agents
137
+ * @param text - The message
138
+ * @param now - Current time (ms)
139
+ * @returns True for a repeat (drop it)
140
+ */
141
+ isRepeat(room, sender, recipients, text, now) {
142
+ const key = `${room}|${sender}|${[...new Set(recipients)].sort().join(',')}`;
143
+ const body = comparable(text);
144
+ const recent = (this.sent.get(key) ?? []).filter((e) => now - e.at <= this.windowMs);
145
+ const repeat = body.length > 0 && recent.some((e) => questionSimilarity(e.text, body) >= this.threshold);
146
+ if (!repeat)
147
+ recent.push({ text: body, at: now });
148
+ if (recent.length > 0)
149
+ this.sent.set(key, recent.slice(-AGENT_COORDINATION_CONSTANTS.DUPLICATE_HISTORY));
150
+ else
151
+ this.sent.delete(key);
152
+ if (this.sent.size > AGENT_COORDINATION_CONSTANTS.DUPLICATE_MAX_KEYS) {
153
+ const oldest = this.sent.keys().next().value;
154
+ if (oldest !== undefined)
155
+ this.sent.delete(oldest);
156
+ }
157
+ return repeat;
158
+ }
159
+ }
160
+ /**
161
+ * A message as compared for repeats: without @-mentions and Slack ids, so
162
+ * "@Sam X" and "@Sam @Max X" compare on X.
163
+ *
164
+ * @param text - Message
165
+ * @returns Comparable text
166
+ */
167
+ function comparable(text) {
168
+ return (text ?? '')
169
+ .replace(/<[@#!][^>]*>/g, ' ')
170
+ .replace(/(?<![\w])@[\p{L}\p{N}_.-]+/gu, ' ')
171
+ .replace(/\s+/g, ' ')
172
+ .trim();
173
+ }
174
+ //# sourceMappingURL=agent-coordination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-coordination.js","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/agent-coordination.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"slack-initializer.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slack-initializer.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"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"}
@@ -897,6 +897,13 @@ export async function startSlackTeamChannels() {
897
897
  typing,
898
898
  autoWorking,
899
899
  isLocalAgent: (agentSession) => getSlackService().isLocalAgent?.(agentSession) ?? false,
900
+ // Ticket ids never reach Slack (crewly#1340): the real prefixes in use.
901
+ ticketPrefixes: async () => {
902
+ const { listTicketPrefixes } = await import('../project-tickets/ticket-prefixes.js');
903
+ return listTicketPrefixes({
904
+ listProjectPaths: async () => (await StorageService.getInstance().getProjects()).map((p) => p.path).filter((p) => !!p),
905
+ });
906
+ },
900
907
  isAgentAwake: (agentSession) => sessionBackendExists(agentSession),
901
908
  getOwnerUserId: () => getSlackCloudConfigService()?.getConfig()?.workspace.installedBy || null,
902
909
  resolveInstanceId: async () => getSlackInstanceRegistryService()?.resolveInstanceId() ?? null,