crewly 1.20.210 → 1.20.212

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 (246) hide show
  1. package/config/roles/orchestrator/prompt.md +1 -0
  2. package/config/skills/agent/core/app-data/SKILL.md +30 -1
  3. package/config/skills/agent/core/publish-app/SKILL.md +73 -6
  4. package/config/skills/agent/core/publish-app/execute.sh +125 -4
  5. package/config/skills/agent/core/publish-app/execute.test.sh +95 -4
  6. package/config/skills/agent/core/send-message/SKILL.md +9 -0
  7. package/config/skills/orchestrator/delegate-task/SKILL.md +9 -0
  8. package/config/skills/orchestrator/get-team-status/SKILL.md +9 -0
  9. package/config/skills/orchestrator/get-team-status/execute.sh +5 -1
  10. package/config/skills/orchestrator/send-message/SKILL.md +9 -0
  11. package/config/skills/orchestrator/start-agent/SKILL.md +9 -0
  12. package/config/skills/orchestrator/start-team/SKILL.md +9 -0
  13. package/config/skills/team-leader/assign-ticket/SKILL.md +9 -0
  14. package/config/skills/team-leader/delegate-task/SKILL.md +9 -0
  15. package/dist/backend/backend/src/constants.d.ts +78 -0
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +78 -0
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts +17 -1
  20. package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts.map +1 -1
  21. package/dist/backend/backend/src/controllers/apps/apps.controller.js +45 -8
  22. package/dist/backend/backend/src/controllers/apps/apps.controller.js.map +1 -1
  23. package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts +7 -0
  24. package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts.map +1 -1
  25. package/dist/backend/backend/src/controllers/apps/apps.routes.js +15 -1
  26. package/dist/backend/backend/src/controllers/apps/apps.routes.js.map +1 -1
  27. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +12 -0
  28. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  29. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +36 -1
  30. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  31. package/dist/backend/backend/src/controllers/request-types.d.ts +10 -1
  32. package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
  33. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +0 -36
  34. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  35. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +41 -1
  36. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  37. package/dist/backend/backend/src/controllers/team/team-pause.controller.d.ts +59 -0
  38. package/dist/backend/backend/src/controllers/team/team-pause.controller.d.ts.map +1 -0
  39. package/dist/backend/backend/src/controllers/team/team-pause.controller.js +161 -0
  40. package/dist/backend/backend/src/controllers/team/team-pause.controller.js.map +1 -0
  41. package/dist/backend/backend/src/controllers/team/team.controller.d.ts +14 -0
  42. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  43. package/dist/backend/backend/src/controllers/team/team.controller.js +78 -5
  44. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  45. package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
  46. package/dist/backend/backend/src/controllers/team/team.routes.js +7 -1
  47. package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
  48. package/dist/backend/backend/src/index.d.ts.map +1 -1
  49. package/dist/backend/backend/src/index.js +18 -1
  50. package/dist/backend/backend/src/index.js.map +1 -1
  51. package/dist/backend/backend/src/models/Team.d.ts +5 -1
  52. package/dist/backend/backend/src/models/Team.d.ts.map +1 -1
  53. package/dist/backend/backend/src/models/Team.js +8 -0
  54. package/dist/backend/backend/src/models/Team.js.map +1 -1
  55. package/dist/backend/backend/src/services/agent/owner-stopped.registry.d.ts +7 -2
  56. package/dist/backend/backend/src/services/agent/owner-stopped.registry.d.ts.map +1 -1
  57. package/dist/backend/backend/src/services/agent/owner-stopped.registry.js +9 -3
  58. package/dist/backend/backend/src/services/agent/owner-stopped.registry.js.map +1 -1
  59. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  60. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +3 -2
  61. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  62. package/dist/backend/backend/src/services/apps/app-open-link.d.ts +61 -0
  63. package/dist/backend/backend/src/services/apps/app-open-link.d.ts.map +1 -0
  64. package/dist/backend/backend/src/services/apps/app-open-link.js +112 -0
  65. package/dist/backend/backend/src/services/apps/app-open-link.js.map +1 -0
  66. package/dist/backend/backend/src/services/apps/app-wake-message.d.ts +44 -3
  67. package/dist/backend/backend/src/services/apps/app-wake-message.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/apps/app-wake-message.js +99 -7
  69. package/dist/backend/backend/src/services/apps/app-wake-message.js.map +1 -1
  70. package/dist/backend/backend/src/services/apps/app-wake.service.d.ts +29 -2
  71. package/dist/backend/backend/src/services/apps/app-wake.service.d.ts.map +1 -1
  72. package/dist/backend/backend/src/services/apps/app-wake.service.js +151 -21
  73. package/dist/backend/backend/src/services/apps/app-wake.service.js.map +1 -1
  74. package/dist/backend/backend/src/services/apps/apps-registry.service.d.ts +18 -0
  75. package/dist/backend/backend/src/services/apps/apps-registry.service.d.ts.map +1 -1
  76. package/dist/backend/backend/src/services/apps/apps-registry.service.js +14 -0
  77. package/dist/backend/backend/src/services/apps/apps-registry.service.js.map +1 -1
  78. package/dist/backend/backend/src/services/apps/apps.service.d.ts +261 -12
  79. package/dist/backend/backend/src/services/apps/apps.service.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/apps/apps.service.js +387 -30
  81. package/dist/backend/backend/src/services/apps/apps.service.js.map +1 -1
  82. package/dist/backend/backend/src/services/apps/apps.wiring.d.ts +15 -1
  83. package/dist/backend/backend/src/services/apps/apps.wiring.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/apps/apps.wiring.js +27 -7
  85. package/dist/backend/backend/src/services/apps/apps.wiring.js.map +1 -1
  86. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +17 -5
  88. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/core/logger.service.d.ts +5 -0
  90. package/dist/backend/backend/src/services/core/logger.service.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/core/logger.service.js +8 -0
  92. package/dist/backend/backend/src/services/core/logger.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  94. package/dist/backend/backend/src/services/core/storage.service.js +6 -0
  95. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  96. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +6 -0
  98. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
  99. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +12 -0
  100. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +59 -0
  102. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
  104. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +12 -6
  105. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
  106. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +5 -0
  108. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  109. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  110. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +4 -0
  111. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  112. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +22 -0
  114. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  115. package/dist/backend/backend/src/services/slack/slack-channel-members.d.ts +27 -0
  116. package/dist/backend/backend/src/services/slack/slack-channel-members.d.ts.map +1 -0
  117. package/dist/backend/backend/src/services/slack/slack-channel-members.js +54 -0
  118. package/dist/backend/backend/src/services/slack/slack-channel-members.js.map +1 -0
  119. package/dist/backend/backend/src/services/slack/slack-directory.service.d.ts.map +1 -1
  120. package/dist/backend/backend/src/services/slack/slack-directory.service.js +7 -2
  121. package/dist/backend/backend/src/services/slack/slack-directory.service.js.map +1 -1
  122. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  123. package/dist/backend/backend/src/services/slack/slack-initializer.js +3 -0
  124. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  125. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  126. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +19 -0
  127. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  128. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +48 -0
  129. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  130. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +155 -4
  131. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  132. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  133. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +3 -1
  134. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  135. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +11 -0
  136. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  137. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +36 -1
  138. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  139. package/dist/backend/backend/src/services/task-pool/untargeted-router.d.ts.map +1 -1
  140. package/dist/backend/backend/src/services/task-pool/untargeted-router.js +14 -6
  141. package/dist/backend/backend/src/services/task-pool/untargeted-router.js.map +1 -1
  142. package/dist/backend/backend/src/services/team/team-pause-command.d.ts +97 -0
  143. package/dist/backend/backend/src/services/team/team-pause-command.d.ts.map +1 -0
  144. package/dist/backend/backend/src/services/team/team-pause-command.js +177 -0
  145. package/dist/backend/backend/src/services/team/team-pause-command.js.map +1 -0
  146. package/dist/backend/backend/src/services/team/team-pause-notice.d.ts +43 -0
  147. package/dist/backend/backend/src/services/team/team-pause-notice.d.ts.map +1 -0
  148. package/dist/backend/backend/src/services/team/team-pause-notice.js +61 -0
  149. package/dist/backend/backend/src/services/team/team-pause-notice.js.map +1 -0
  150. package/dist/backend/backend/src/services/team/team-pause.registry.d.ts +167 -0
  151. package/dist/backend/backend/src/services/team/team-pause.registry.d.ts.map +1 -0
  152. package/dist/backend/backend/src/services/team/team-pause.registry.js +263 -0
  153. package/dist/backend/backend/src/services/team/team-pause.registry.js.map +1 -0
  154. package/dist/backend/backend/src/services/team/team-pause.service.d.ts +172 -0
  155. package/dist/backend/backend/src/services/team/team-pause.service.d.ts.map +1 -0
  156. package/dist/backend/backend/src/services/team/team-pause.service.js +254 -0
  157. package/dist/backend/backend/src/services/team/team-pause.service.js.map +1 -0
  158. package/dist/backend/backend/src/services/team/team-pause.wiring.d.ts +30 -0
  159. package/dist/backend/backend/src/services/team/team-pause.wiring.d.ts.map +1 -0
  160. package/dist/backend/backend/src/services/team/team-pause.wiring.js +48 -0
  161. package/dist/backend/backend/src/services/team/team-pause.wiring.js.map +1 -0
  162. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
  163. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +11 -0
  164. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
  165. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts +9 -0
  166. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts.map +1 -1
  167. package/dist/backend/backend/src/services/v3/trigger-engine.service.js +27 -2
  168. package/dist/backend/backend/src/services/v3/trigger-engine.service.js.map +1 -1
  169. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  170. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +7 -0
  171. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  172. package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
  173. package/dist/backend/backend/src/services/workflow/cron-task.service.js +14 -0
  174. package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
  175. package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
  176. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +5 -0
  177. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
  178. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  179. package/dist/backend/backend/src/services/workflow/scheduler.service.js +6 -0
  180. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  181. package/dist/backend/backend/src/types/index.d.ts +22 -0
  182. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  183. package/dist/backend/backend/src/types/index.js.map +1 -1
  184. package/dist/backend/build-info.json +2 -2
  185. package/dist/cli/backend/src/constants.d.ts +78 -0
  186. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  187. package/dist/cli/backend/src/constants.js +78 -0
  188. package/dist/cli/backend/src/constants.js.map +1 -1
  189. package/dist/cli/backend/src/models/Team.d.ts +5 -1
  190. package/dist/cli/backend/src/models/Team.d.ts.map +1 -1
  191. package/dist/cli/backend/src/models/Team.js +8 -0
  192. package/dist/cli/backend/src/models/Team.js.map +1 -1
  193. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  194. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +3 -2
  195. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  196. package/dist/cli/backend/src/services/apps/app-open-link.d.ts +61 -0
  197. package/dist/cli/backend/src/services/apps/app-open-link.d.ts.map +1 -0
  198. package/dist/cli/backend/src/services/apps/app-open-link.js +112 -0
  199. package/dist/cli/backend/src/services/apps/app-open-link.js.map +1 -0
  200. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  201. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +17 -5
  202. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  203. package/dist/cli/backend/src/services/core/logger.service.d.ts +5 -0
  204. package/dist/cli/backend/src/services/core/logger.service.d.ts.map +1 -1
  205. package/dist/cli/backend/src/services/core/logger.service.js +8 -0
  206. package/dist/cli/backend/src/services/core/logger.service.js.map +1 -1
  207. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  208. package/dist/cli/backend/src/services/core/storage.service.js +6 -0
  209. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  210. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  211. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +22 -0
  212. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  213. package/dist/cli/backend/src/services/slack/slack-directory.service.d.ts.map +1 -1
  214. package/dist/cli/backend/src/services/slack/slack-directory.service.js +7 -2
  215. package/dist/cli/backend/src/services/slack/slack-directory.service.js.map +1 -1
  216. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  217. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +19 -0
  218. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  219. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +48 -0
  220. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  221. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +155 -4
  222. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  223. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  224. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +3 -1
  225. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  226. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +11 -0
  227. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  228. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +36 -1
  229. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  230. package/dist/cli/backend/src/services/team/team-pause-notice.d.ts +43 -0
  231. package/dist/cli/backend/src/services/team/team-pause-notice.d.ts.map +1 -0
  232. package/dist/cli/backend/src/services/team/team-pause-notice.js +61 -0
  233. package/dist/cli/backend/src/services/team/team-pause-notice.js.map +1 -0
  234. package/dist/cli/backend/src/services/team/team-pause.registry.d.ts +167 -0
  235. package/dist/cli/backend/src/services/team/team-pause.registry.d.ts.map +1 -0
  236. package/dist/cli/backend/src/services/team/team-pause.registry.js +263 -0
  237. package/dist/cli/backend/src/services/team/team-pause.registry.js.map +1 -0
  238. package/dist/cli/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
  239. package/dist/cli/backend/src/services/workflow/cron-task.service.js +14 -0
  240. package/dist/cli/backend/src/services/workflow/cron-task.service.js.map +1 -1
  241. package/dist/cli/backend/src/types/index.d.ts +22 -0
  242. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  243. package/dist/cli/backend/src/types/index.js.map +1 -1
  244. package/frontend/dist/assets/{index-f64b333a.js → index-917db1b8.js} +279 -279
  245. package/frontend/dist/index.html +1 -1
  246. package/package.json +1 -1
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The Slack auto-reply for a paused agent (specs/2026-10-04-team-pause.md):
3
+ * an @mention or DM of a paused team's agent does not wake it; a short
4
+ * English line in the thread says why — at most once per thread.
5
+ *
6
+ * @module services/team/team-pause-notice
7
+ */
8
+ import { TEAM_PAUSE_CONSTANTS } from '../../constants.js';
9
+ import { pausedRefusalMessage } from './team-pause.registry.js';
10
+ /**
11
+ * The auto-reply text.
12
+ *
13
+ * @param info - The paused team
14
+ * @param agentName - Display name of the agent that was addressed
15
+ * @param options - `toAgent`: the author is another agent (it gets the refusal: file an issue / tell the orc)
16
+ * @returns Text
17
+ *
18
+ * @example
19
+ * pausedSlackNotice(info, 'Leo') // 'Leo is on Crewly, which the owner has paused, so Leo won't pick this up. …'
20
+ */
21
+ export function pausedSlackNotice(info, agentName, options = {}) {
22
+ if (options.toAgent)
23
+ return pausedRefusalMessage(info);
24
+ const until = info.pause.until ? ` (until ${info.pause.until})` : '';
25
+ return (`${agentName} is on ${info.teamName}, which the owner has paused${until}, so ${agentName} won't pick this up. ` +
26
+ `To bring the team back, DM the orc "resume ${info.teamName}".`);
27
+ }
28
+ /** Remembers which threads were already told (one notice per thread per team). */
29
+ export class PausedThreadNotices {
30
+ max;
31
+ told = new Set();
32
+ /**
33
+ * @param max - Threads remembered before the oldest are forgotten
34
+ */
35
+ constructor(max = TEAM_PAUSE_CONSTANTS.SLACK_NOTICE_MEMORY) {
36
+ this.max = max;
37
+ }
38
+ /**
39
+ * Claim the notice for a thread: true the first time, false after.
40
+ *
41
+ * @param channelId - Slack channel
42
+ * @param threadTs - Thread (root ts)
43
+ * @param teamId - Paused team
44
+ * @returns True when the notice should be posted now
45
+ */
46
+ claim(channelId, threadTs, teamId) {
47
+ const key = `${channelId}:${threadTs ?? ''}:${teamId}`;
48
+ if (this.told.has(key))
49
+ return false;
50
+ this.told.add(key);
51
+ if (this.told.size > this.max) {
52
+ const oldest = this.told.values().next().value;
53
+ if (oldest !== undefined)
54
+ this.told.delete(oldest);
55
+ }
56
+ return true;
57
+ }
58
+ }
59
+ /** Shared by the Slack paths so a thread is told once whichever path saw it. */
60
+ export const pausedThreadNotices = new PausedThreadNotices();
61
+ //# sourceMappingURL=team-pause-notice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-pause-notice.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team/team-pause-notice.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAuB,MAAM,0BAA0B,CAAC;AAErF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAoB,EAAE,SAAiB,EAAE,UAAiC,EAAE;IAC7G,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,OAAO,CACN,GAAG,SAAS,UAAU,IAAI,CAAC,QAAQ,+BAA+B,KAAK,QAAQ,SAAS,uBAAuB;QAC/G,8CAA8C,IAAI,CAAC,QAAQ,IAAI,CAC/D,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,MAAM,OAAO,mBAAmB;IAMF;IALZ,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE1C;;OAEG;IACH,YAA6B,MAAc,oBAAoB,CAAC,mBAAmB;QAAtD,QAAG,GAAH,GAAG,CAAmD;IAAG,CAAC;IAEvF;;;;;;;OAOG;IACH,KAAK,CAAC,SAAiB,EAAE,QAA4B,EAAE,MAAc;QACpE,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,QAAQ,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QACvD,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC/C,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Paused teams — the in-memory index every automation path consults
3
+ * (specs/2026-10-04-team-pause.md).
4
+ *
5
+ * The pause itself is stored on the team (`Team.paused`, persisted in the
6
+ * team's config.json), so it survives restarts. This module keeps a
7
+ * synchronous index of it — team id → pause, and every session name a
8
+ * member of a paused team may run under → team — because most of the gates
9
+ * (the reconciler's wake rule, the queued-message wake, the dispatcher's
10
+ * target planning) only have a session name and must not await storage.
11
+ *
12
+ * The index is rebuilt from storage: {@link syncPausedTeams} runs on every
13
+ * `StorageService.getTeams()` read and at boot, and {@link notePausedTeam}
14
+ * on every save. A pause whose `until` has passed counts as resumed at once,
15
+ * before the auto-resume sweep clears it from storage.
16
+ *
17
+ * Module-level and dependency-free (types and two utils only), so the team
18
+ * controller, the storage service and the services can share it without
19
+ * import cycles.
20
+ *
21
+ * @module services/team/team-pause.registry
22
+ */
23
+ import type { Team, TeamMember, TeamPauseState } from '../../types/index.js';
24
+ /** What the gates need to know about a paused team. */
25
+ export interface PausedTeamInfo {
26
+ teamId: string;
27
+ teamName: string;
28
+ /** GitHub repository for issues while paused (`owner/name`), when configured */
29
+ issueRepo?: string;
30
+ pause: TeamPauseState;
31
+ /** Every session name a member may run under (session, agent id, derived name) */
32
+ sessions: string[];
33
+ /** Member display names */
34
+ memberNames: string[];
35
+ }
36
+ /**
37
+ * Whether a pause is in force at `now` (set, and its `until` not reached).
38
+ *
39
+ * @param pause - The team's pause, if any
40
+ * @param now - Clock (ms)
41
+ * @returns True while paused
42
+ *
43
+ * @example
44
+ * isPauseActive({ pausedAt: '…', by: 'owner', until: '2099-01-01T00:00:00Z' }) // true
45
+ */
46
+ export declare function isPauseActive(pause: TeamPauseState | null | undefined, now?: number): boolean;
47
+ /**
48
+ * Whether a team object is paused now. Prefer this where the team is at
49
+ * hand: it reads the team itself, not the index.
50
+ *
51
+ * @param team - Team (only `paused` is read)
52
+ * @param now - Clock (ms)
53
+ * @returns True while paused
54
+ */
55
+ export declare function isTeamPausedNow(team: Pick<Team, 'paused'> | null | undefined, now?: number): boolean;
56
+ /**
57
+ * Every session name a member may run under: its live session, its
58
+ * permanent agent id, and the name the controller derives on start.
59
+ *
60
+ * @param teamName - Team display name
61
+ * @param member - Member
62
+ * @returns Distinct, non-empty session names
63
+ */
64
+ export declare function memberSessionKeys(teamName: string, member: Pick<TeamMember, 'sessionName' | 'agentId' | 'name' | 'id'>): string[];
65
+ /**
66
+ * Update the index for one team (after a save). A team that is not paused
67
+ * is removed from it.
68
+ *
69
+ * @param team - The saved team
70
+ */
71
+ export declare function notePausedTeam(team: Team | null | undefined): void;
72
+ /**
73
+ * Forget a deleted team.
74
+ *
75
+ * @param teamId - Deleted team
76
+ */
77
+ export declare function noteTeamDeleted(teamId: string): void;
78
+ /**
79
+ * Every team the index has seen (id and name), archived ones excluded.
80
+ *
81
+ * @returns Teams
82
+ */
83
+ export declare function listKnownTeams(): Array<{
84
+ id: string;
85
+ name: string;
86
+ }>;
87
+ /**
88
+ * Rebuild the index from a full team list (a storage read, boot).
89
+ *
90
+ * @param teams - Every stored team
91
+ */
92
+ export declare function syncPausedTeams(teams: readonly Team[]): void;
93
+ /**
94
+ * The paused team with this id, if its pause is in force.
95
+ *
96
+ * @param teamId - Team id
97
+ * @param now - Clock (ms)
98
+ * @returns Info, or null
99
+ */
100
+ export declare function pausedTeamById(teamId: string | null | undefined, now?: number): PausedTeamInfo | null;
101
+ /**
102
+ * Whether the team with this id is paused now.
103
+ *
104
+ * @param teamId - Team id
105
+ * @returns True while paused
106
+ */
107
+ export declare function isTeamIdPaused(teamId: string | null | undefined): boolean;
108
+ /**
109
+ * The paused team a session belongs to, if its pause is in force.
110
+ *
111
+ * @param session - Agent session (or agent id)
112
+ * @param now - Clock (ms)
113
+ * @returns Info, or null
114
+ */
115
+ export declare function pausedTeamOfSession(session: string | null | undefined, now?: number): PausedTeamInfo | null;
116
+ /**
117
+ * Whether a session belongs to a paused team.
118
+ *
119
+ * @param session - Agent session (or agent id)
120
+ * @returns True while its team is paused
121
+ *
122
+ * @example
123
+ * if (isSessionPaused(wi.target)) return false; // do not dispatch
124
+ */
125
+ export declare function isSessionPaused(session: string | null | undefined): boolean;
126
+ /**
127
+ * The paused team named by an id, a name (case-insensitive) or a member
128
+ * session — whatever an agent typed.
129
+ *
130
+ * @param ref - Team id, team name, or member session
131
+ * @returns Info, or null
132
+ */
133
+ export declare function pausedTeamByRef(ref: string | null | undefined): PausedTeamInfo | null;
134
+ /**
135
+ * Every team paused now.
136
+ *
137
+ * @param now - Clock (ms)
138
+ * @returns Infos
139
+ */
140
+ export declare function listPausedTeams(now?: number): PausedTeamInfo[];
141
+ /**
142
+ * Teams whose pause has an `until` that has passed (still stored as paused).
143
+ *
144
+ * @param now - Clock (ms)
145
+ * @returns Infos due for auto-resume
146
+ */
147
+ export declare function listExpiredPauses(now?: number): PausedTeamInfo[];
148
+ /**
149
+ * The refusal an agent gets when it targets a paused team (English: harness
150
+ * text rule).
151
+ *
152
+ * @param info - The paused team
153
+ * @param options - `callerIsOrc`: the orchestrator asked (it tells the owner, not itself)
154
+ * @returns Message
155
+ *
156
+ * @example
157
+ * pausedRefusalMessage({ teamName: 'Crewly', issueRepo: 'stevehuang0115/crewly' })
158
+ * // 'Crewly is paused by the owner. File a GitHub issue instead: `gh issue create -R stevehuang0115/crewly --title "…" --body "…"`'
159
+ */
160
+ export declare function pausedRefusalMessage(info: Pick<PausedTeamInfo, 'teamName' | 'issueRepo'> & {
161
+ pause?: TeamPauseState;
162
+ }, options?: {
163
+ callerIsOrc?: boolean;
164
+ }): string;
165
+ /** Clear the index (tests only). */
166
+ export declare function resetTeamPauseRegistryForTesting(): void;
167
+ //# sourceMappingURL=team-pause.registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-pause.registry.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team/team-pause.registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG7E,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;CACtB;AAOD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAKzG;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAEhH;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,EAAE,CAGjI;AAiCD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAQlE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAGpD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,CAK5D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,GAAE,MAAmB,GAAG,cAAc,GAAG,IAAI,CAIjH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,GAAE,MAAmB,GAAG,cAAc,GAAG,IAAI,CAIvH;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE3E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CASrF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAmB,GAAG,cAAc,EAAE,CAE1E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAmB,GAAG,cAAc,EAAE,CAE5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,cAAc,CAAA;CAAE,EACjF,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,CASR;AAED,oCAAoC;AACpC,wBAAgB,gCAAgC,IAAI,IAAI,CAIvD"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Paused teams — the in-memory index every automation path consults
3
+ * (specs/2026-10-04-team-pause.md).
4
+ *
5
+ * The pause itself is stored on the team (`Team.paused`, persisted in the
6
+ * team's config.json), so it survives restarts. This module keeps a
7
+ * synchronous index of it — team id → pause, and every session name a
8
+ * member of a paused team may run under → team — because most of the gates
9
+ * (the reconciler's wake rule, the queued-message wake, the dispatcher's
10
+ * target planning) only have a session name and must not await storage.
11
+ *
12
+ * The index is rebuilt from storage: {@link syncPausedTeams} runs on every
13
+ * `StorageService.getTeams()` read and at boot, and {@link notePausedTeam}
14
+ * on every save. A pause whose `until` has passed counts as resumed at once,
15
+ * before the auto-resume sweep clears it from storage.
16
+ *
17
+ * Module-level and dependency-free (types and two utils only), so the team
18
+ * controller, the storage service and the services can share it without
19
+ * import cycles.
20
+ *
21
+ * @module services/team/team-pause.registry
22
+ */
23
+ import { deriveMemberSessionName } from '../../utils/member-session-name.utils.js';
24
+ const pausedTeams = new Map();
25
+ const teamOfSession = new Map();
26
+ /** Every known team (id → name, archived), for the owner's Slack commands */
27
+ const knownTeams = new Map();
28
+ /**
29
+ * Whether a pause is in force at `now` (set, and its `until` not reached).
30
+ *
31
+ * @param pause - The team's pause, if any
32
+ * @param now - Clock (ms)
33
+ * @returns True while paused
34
+ *
35
+ * @example
36
+ * isPauseActive({ pausedAt: '…', by: 'owner', until: '2099-01-01T00:00:00Z' }) // true
37
+ */
38
+ export function isPauseActive(pause, now = Date.now()) {
39
+ if (!pause || !pause.pausedAt)
40
+ return false;
41
+ if (!pause.until)
42
+ return true;
43
+ const until = Date.parse(pause.until);
44
+ return Number.isNaN(until) || until > now;
45
+ }
46
+ /**
47
+ * Whether a team object is paused now. Prefer this where the team is at
48
+ * hand: it reads the team itself, not the index.
49
+ *
50
+ * @param team - Team (only `paused` is read)
51
+ * @param now - Clock (ms)
52
+ * @returns True while paused
53
+ */
54
+ export function isTeamPausedNow(team, now = Date.now()) {
55
+ return isPauseActive(team?.paused, now);
56
+ }
57
+ /**
58
+ * Every session name a member may run under: its live session, its
59
+ * permanent agent id, and the name the controller derives on start.
60
+ *
61
+ * @param teamName - Team display name
62
+ * @param member - Member
63
+ * @returns Distinct, non-empty session names
64
+ */
65
+ export function memberSessionKeys(teamName, member) {
66
+ const keys = [member.sessionName, member.agentId, member.id ? deriveMemberSessionName(teamName, member.name, member.id) : undefined];
67
+ return [...new Set(keys.filter((k) => typeof k === 'string' && k.length > 0))];
68
+ }
69
+ /**
70
+ * Build the index entry for a team (whether or not it is paused).
71
+ *
72
+ * @param team - Team with a pause
73
+ * @returns Entry
74
+ */
75
+ function entryOf(team) {
76
+ const sessions = new Set();
77
+ for (const m of team.members ?? [])
78
+ for (const k of memberSessionKeys(team.name, m))
79
+ sessions.add(k);
80
+ return {
81
+ teamId: team.id,
82
+ teamName: team.name || team.id,
83
+ ...(team.issueRepo ? { issueRepo: team.issueRepo } : {}),
84
+ pause: team.paused,
85
+ sessions: [...sessions],
86
+ memberNames: (team.members ?? []).map((m) => m.name).filter(Boolean),
87
+ };
88
+ }
89
+ /**
90
+ * Remove a team from the index.
91
+ *
92
+ * @param teamId - Team
93
+ */
94
+ function forget(teamId) {
95
+ const prev = pausedTeams.get(teamId);
96
+ if (!prev)
97
+ return;
98
+ for (const s of prev.sessions)
99
+ if (teamOfSession.get(s) === teamId)
100
+ teamOfSession.delete(s);
101
+ pausedTeams.delete(teamId);
102
+ }
103
+ /**
104
+ * Update the index for one team (after a save). A team that is not paused
105
+ * is removed from it.
106
+ *
107
+ * @param team - The saved team
108
+ */
109
+ export function notePausedTeam(team) {
110
+ if (!team?.id)
111
+ return;
112
+ knownTeams.set(team.id, { name: team.name || team.id, archived: !!team.archived });
113
+ forget(team.id);
114
+ if (!team.paused)
115
+ return;
116
+ const entry = entryOf(team);
117
+ pausedTeams.set(team.id, entry);
118
+ for (const s of entry.sessions)
119
+ teamOfSession.set(s, team.id);
120
+ }
121
+ /**
122
+ * Forget a deleted team.
123
+ *
124
+ * @param teamId - Deleted team
125
+ */
126
+ export function noteTeamDeleted(teamId) {
127
+ forget(teamId);
128
+ knownTeams.delete(teamId);
129
+ }
130
+ /**
131
+ * Every team the index has seen (id and name), archived ones excluded.
132
+ *
133
+ * @returns Teams
134
+ */
135
+ export function listKnownTeams() {
136
+ return [...knownTeams.entries()].filter(([, t]) => !t.archived).map(([id, t]) => ({ id, name: t.name }));
137
+ }
138
+ /**
139
+ * Rebuild the index from a full team list (a storage read, boot).
140
+ *
141
+ * @param teams - Every stored team
142
+ */
143
+ export function syncPausedTeams(teams) {
144
+ pausedTeams.clear();
145
+ teamOfSession.clear();
146
+ knownTeams.clear();
147
+ for (const team of teams)
148
+ notePausedTeam(team);
149
+ }
150
+ /**
151
+ * The paused team with this id, if its pause is in force.
152
+ *
153
+ * @param teamId - Team id
154
+ * @param now - Clock (ms)
155
+ * @returns Info, or null
156
+ */
157
+ export function pausedTeamById(teamId, now = Date.now()) {
158
+ if (!teamId)
159
+ return null;
160
+ const entry = pausedTeams.get(teamId);
161
+ return entry && isPauseActive(entry.pause, now) ? entry : null;
162
+ }
163
+ /**
164
+ * Whether the team with this id is paused now.
165
+ *
166
+ * @param teamId - Team id
167
+ * @returns True while paused
168
+ */
169
+ export function isTeamIdPaused(teamId) {
170
+ return pausedTeamById(teamId) !== null;
171
+ }
172
+ /**
173
+ * The paused team a session belongs to, if its pause is in force.
174
+ *
175
+ * @param session - Agent session (or agent id)
176
+ * @param now - Clock (ms)
177
+ * @returns Info, or null
178
+ */
179
+ export function pausedTeamOfSession(session, now = Date.now()) {
180
+ if (!session)
181
+ return null;
182
+ const teamId = teamOfSession.get(session);
183
+ return teamId ? pausedTeamById(teamId, now) : null;
184
+ }
185
+ /**
186
+ * Whether a session belongs to a paused team.
187
+ *
188
+ * @param session - Agent session (or agent id)
189
+ * @returns True while its team is paused
190
+ *
191
+ * @example
192
+ * if (isSessionPaused(wi.target)) return false; // do not dispatch
193
+ */
194
+ export function isSessionPaused(session) {
195
+ return pausedTeamOfSession(session) !== null;
196
+ }
197
+ /**
198
+ * The paused team named by an id, a name (case-insensitive) or a member
199
+ * session — whatever an agent typed.
200
+ *
201
+ * @param ref - Team id, team name, or member session
202
+ * @returns Info, or null
203
+ */
204
+ export function pausedTeamByRef(ref) {
205
+ if (!ref)
206
+ return null;
207
+ const byId = pausedTeamById(ref) ?? pausedTeamOfSession(ref);
208
+ if (byId)
209
+ return byId;
210
+ const want = ref.trim().toLowerCase();
211
+ for (const entry of pausedTeams.values()) {
212
+ if (entry.teamName.toLowerCase() === want && isPauseActive(entry.pause))
213
+ return entry;
214
+ }
215
+ return null;
216
+ }
217
+ /**
218
+ * Every team paused now.
219
+ *
220
+ * @param now - Clock (ms)
221
+ * @returns Infos
222
+ */
223
+ export function listPausedTeams(now = Date.now()) {
224
+ return [...pausedTeams.values()].filter((e) => isPauseActive(e.pause, now));
225
+ }
226
+ /**
227
+ * Teams whose pause has an `until` that has passed (still stored as paused).
228
+ *
229
+ * @param now - Clock (ms)
230
+ * @returns Infos due for auto-resume
231
+ */
232
+ export function listExpiredPauses(now = Date.now()) {
233
+ return [...pausedTeams.values()].filter((e) => !isPauseActive(e.pause, now));
234
+ }
235
+ /**
236
+ * The refusal an agent gets when it targets a paused team (English: harness
237
+ * text rule).
238
+ *
239
+ * @param info - The paused team
240
+ * @param options - `callerIsOrc`: the orchestrator asked (it tells the owner, not itself)
241
+ * @returns Message
242
+ *
243
+ * @example
244
+ * pausedRefusalMessage({ teamName: 'Crewly', issueRepo: 'stevehuang0115/crewly' })
245
+ * // 'Crewly is paused by the owner. File a GitHub issue instead: `gh issue create -R stevehuang0115/crewly --title "…" --body "…"`'
246
+ */
247
+ export function pausedRefusalMessage(info, options = {}) {
248
+ const until = info.pause?.until ? ` until ${info.pause.until}` : '';
249
+ const head = `${info.teamName} is paused by the owner${until}.`;
250
+ if (info.issueRepo) {
251
+ return `${head} File a GitHub issue instead: \`gh issue create -R ${info.issueRepo} --title "<short title>" --body "<what is needed and why>"\``;
252
+ }
253
+ return options.callerIsOrc
254
+ ? `${head} Do not hand it work or wake it. If this cannot wait until the owner resumes it, tell the owner.`
255
+ : `${head} Do not hand it work. Tell the orc what you need instead.`;
256
+ }
257
+ /** Clear the index (tests only). */
258
+ export function resetTeamPauseRegistryForTesting() {
259
+ pausedTeams.clear();
260
+ teamOfSession.clear();
261
+ knownTeams.clear();
262
+ }
263
+ //# sourceMappingURL=team-pause.registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-pause.registry.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team/team-pause.registry.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cron-task.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/workflow/cron-task.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cron-task.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/workflow/cron-task.service.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@
10
10
  *
11
11
  * @module services/workflow/cron-task.service
12
12
  */
13
+ import { isSessionPaused, isTeamIdPaused } from '../team/team-pause.registry.js';
13
14
  import * as path from 'path';
14
15
  import { existsSync } from 'fs';
15
16
  import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
@@ -798,6 +799,19 @@ export class CronTaskService {
798
799
  const nextRun = new Date(task.nextRunAt);
799
800
  if (nextRun > now)
800
801
  return false;
802
+ // A paused team's cron does not run (and does not start its agent):
803
+ // the slot is skipped and recorded (specs/2026-10-04-team-pause.md).
804
+ if (isSessionPaused(task.targetAgent) || isTeamIdPaused(task.targetTeamId)) {
805
+ this.logger.info('Skipping cron task — its team is paused by the owner', {
806
+ id: task.id,
807
+ target: task.targetAgent,
808
+ teamId: task.targetTeamId,
809
+ });
810
+ task.lastSkippedAt = now.toISOString();
811
+ task.lastSkipReason = 'team_paused';
812
+ task.nextRunAt = getNextRunTime(task.cronExpression, task.timezone, now);
813
+ return true;
814
+ }
801
815
  // Task is due — check agent status before executing
802
816
  let agentOnline = true;
803
817
  if (this.agentStatusCallback) {