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.
- package/config/roles/orchestrator/prompt.md +1 -0
- package/config/skills/agent/core/app-data/SKILL.md +30 -1
- package/config/skills/agent/core/publish-app/SKILL.md +73 -6
- package/config/skills/agent/core/publish-app/execute.sh +125 -4
- package/config/skills/agent/core/publish-app/execute.test.sh +95 -4
- package/config/skills/agent/core/send-message/SKILL.md +9 -0
- package/config/skills/orchestrator/delegate-task/SKILL.md +9 -0
- package/config/skills/orchestrator/get-team-status/SKILL.md +9 -0
- package/config/skills/orchestrator/get-team-status/execute.sh +5 -1
- package/config/skills/orchestrator/send-message/SKILL.md +9 -0
- package/config/skills/orchestrator/start-agent/SKILL.md +9 -0
- package/config/skills/orchestrator/start-team/SKILL.md +9 -0
- package/config/skills/team-leader/assign-ticket/SKILL.md +9 -0
- package/config/skills/team-leader/delegate-task/SKILL.md +9 -0
- package/dist/backend/backend/src/constants.d.ts +78 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +78 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts +17 -1
- package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/apps/apps.controller.js +45 -8
- package/dist/backend/backend/src/controllers/apps/apps.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts +7 -0
- package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/apps/apps.routes.js +15 -1
- package/dist/backend/backend/src/controllers/apps/apps.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +12 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +36 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts +10 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +0 -36
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +41 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-pause.controller.d.ts +59 -0
- package/dist/backend/backend/src/controllers/team/team-pause.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team/team-pause.controller.js +161 -0
- package/dist/backend/backend/src/controllers/team/team-pause.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts +14 -0
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +78 -5
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +7 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +18 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/models/Team.d.ts +5 -1
- package/dist/backend/backend/src/models/Team.d.ts.map +1 -1
- package/dist/backend/backend/src/models/Team.js +8 -0
- package/dist/backend/backend/src/models/Team.js.map +1 -1
- package/dist/backend/backend/src/services/agent/owner-stopped.registry.d.ts +7 -2
- package/dist/backend/backend/src/services/agent/owner-stopped.registry.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/owner-stopped.registry.js +9 -3
- package/dist/backend/backend/src/services/agent/owner-stopped.registry.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +3 -2
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/apps/app-open-link.d.ts +61 -0
- package/dist/backend/backend/src/services/apps/app-open-link.d.ts.map +1 -0
- package/dist/backend/backend/src/services/apps/app-open-link.js +112 -0
- package/dist/backend/backend/src/services/apps/app-open-link.js.map +1 -0
- package/dist/backend/backend/src/services/apps/app-wake-message.d.ts +44 -3
- package/dist/backend/backend/src/services/apps/app-wake-message.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake-message.js +99 -7
- package/dist/backend/backend/src/services/apps/app-wake-message.js.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake.service.d.ts +29 -2
- package/dist/backend/backend/src/services/apps/app-wake.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/app-wake.service.js +151 -21
- package/dist/backend/backend/src/services/apps/app-wake.service.js.map +1 -1
- package/dist/backend/backend/src/services/apps/apps-registry.service.d.ts +18 -0
- package/dist/backend/backend/src/services/apps/apps-registry.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/apps-registry.service.js +14 -0
- package/dist/backend/backend/src/services/apps/apps-registry.service.js.map +1 -1
- package/dist/backend/backend/src/services/apps/apps.service.d.ts +261 -12
- package/dist/backend/backend/src/services/apps/apps.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/apps.service.js +387 -30
- package/dist/backend/backend/src/services/apps/apps.service.js.map +1 -1
- package/dist/backend/backend/src/services/apps/apps.wiring.d.ts +15 -1
- package/dist/backend/backend/src/services/apps/apps.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/apps.wiring.js +27 -7
- package/dist/backend/backend/src/services/apps/apps.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +17 -5
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/core/logger.service.d.ts +5 -0
- package/dist/backend/backend/src/services/core/logger.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/logger.service.js +8 -0
- package/dist/backend/backend/src/services/core/logger.service.js.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +6 -0
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +6 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +12 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +59 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +12 -6
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +5 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +4 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +22 -0
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-channel-members.d.ts +27 -0
- package/dist/backend/backend/src/services/slack/slack-channel-members.d.ts.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-channel-members.js +54 -0
- package/dist/backend/backend/src/services/slack/slack-channel-members.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-directory.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-directory.service.js +7 -2
- package/dist/backend/backend/src/services/slack/slack-directory.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +3 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +19 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +48 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +155 -4
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +3 -1
- package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +11 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +36 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/untargeted-router.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/untargeted-router.js +14 -6
- package/dist/backend/backend/src/services/task-pool/untargeted-router.js.map +1 -1
- package/dist/backend/backend/src/services/team/team-pause-command.d.ts +97 -0
- package/dist/backend/backend/src/services/team/team-pause-command.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause-command.js +177 -0
- package/dist/backend/backend/src/services/team/team-pause-command.js.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause-notice.d.ts +43 -0
- package/dist/backend/backend/src/services/team/team-pause-notice.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause-notice.js +61 -0
- package/dist/backend/backend/src/services/team/team-pause-notice.js.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause.registry.d.ts +167 -0
- package/dist/backend/backend/src/services/team/team-pause.registry.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause.registry.js +263 -0
- package/dist/backend/backend/src/services/team/team-pause.registry.js.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause.service.d.ts +172 -0
- package/dist/backend/backend/src/services/team/team-pause.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause.service.js +254 -0
- package/dist/backend/backend/src/services/team/team-pause.service.js.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause.wiring.d.ts +30 -0
- package/dist/backend/backend/src/services/team/team-pause.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team/team-pause.wiring.js +48 -0
- package/dist/backend/backend/src/services/team/team-pause.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +11 -0
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts +9 -0
- package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/trigger-engine.service.js +27 -2
- package/dist/backend/backend/src/services/v3/trigger-engine.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +7 -0
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/cron-task.service.js +14 -0
- package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +5 -0
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js +6 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +22 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +78 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +78 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/models/Team.d.ts +5 -1
- package/dist/cli/backend/src/models/Team.d.ts.map +1 -1
- package/dist/cli/backend/src/models/Team.js +8 -0
- package/dist/cli/backend/src/models/Team.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +3 -2
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/apps/app-open-link.d.ts +61 -0
- package/dist/cli/backend/src/services/apps/app-open-link.d.ts.map +1 -0
- package/dist/cli/backend/src/services/apps/app-open-link.js +112 -0
- package/dist/cli/backend/src/services/apps/app-open-link.js.map +1 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +17 -5
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/core/logger.service.d.ts +5 -0
- package/dist/cli/backend/src/services/core/logger.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/logger.service.js +8 -0
- package/dist/cli/backend/src/services/core/logger.service.js.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.js +6 -0
- package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +22 -0
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-directory.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-directory.service.js +7 -2
- package/dist/cli/backend/src/services/slack/slack-directory.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +19 -0
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +48 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +155 -4
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +3 -1
- package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +11 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +36 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/team/team-pause-notice.d.ts +43 -0
- package/dist/cli/backend/src/services/team/team-pause-notice.d.ts.map +1 -0
- package/dist/cli/backend/src/services/team/team-pause-notice.js +61 -0
- package/dist/cli/backend/src/services/team/team-pause-notice.js.map +1 -0
- package/dist/cli/backend/src/services/team/team-pause.registry.d.ts +167 -0
- package/dist/cli/backend/src/services/team/team-pause.registry.d.ts.map +1 -0
- package/dist/cli/backend/src/services/team/team-pause.registry.js +263 -0
- package/dist/cli/backend/src/services/team/team-pause.registry.js.map +1 -0
- package/dist/cli/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/workflow/cron-task.service.js +14 -0
- package/dist/cli/backend/src/services/workflow/cron-task.service.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +22 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/frontend/dist/assets/{index-f64b333a.js → index-917db1b8.js} +279 -279
- package/frontend/dist/index.html +1 -1
- 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":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"cron-task.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/workflow/cron-task.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,OAAO,KAAK,EACX,QAAQ,EAER,qBAAqB,EACrB,qBAAqB,EACrB,MAAM,gCAAgC,CAAC;AAqDxC;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,MAAM,GACR;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA8BxF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAUlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAwCzF;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,CA2E7F;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE5F;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE3F;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgC;IACvD,OAAO,CAAC,MAAM,CAAkB;IAChC,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,kDAAkD;IAClD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,iBAAiB,CAAoD;IAC7E,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,kBAAkB,CAAmC;gBAEjD,UAAU,CAAC,EAAE,MAAM;IAO/B;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,eAAe;IAOrC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAO5B;;;;;OAKG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;;;;;;;;;;;;OAaG;IACG,yBAAyB,IAAI,OAAO,CAAC,MAAM,CAAC;IAsElD;;;;;OAKG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIvE;;;;;;OAMG;IACH,sBAAsB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAI3D;;;;;OAKG;IACH,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAIzD;;;OAGG;IACH,KAAK,IAAI,IAAI;IAgBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;;;;;OAQG;IACG,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC;IA4CnD;;;;;;;;OAQG;YACW,YAAY;IA4B1B;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAmE/D;;;;;OAKG;IACG,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAarF;;;;;;OAMG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAc1G;;;;;OAKG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAK/C;;;;;;OAMG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA6ClF;;;;;OAKG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2B1C;;;;;OAKG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAapC;;;;;;;OAOG;YACW,kBAAkB;IA2LhC;;;;;OAKG;YACW,aAAa;IAI3B;;;;;;;;;;;;;;OAcG;YACW,SAAS;IA0BvB;;;;;OAKG;YACW,aAAa;IAO3B;;;;OAIG;YACW,eAAe;IAI7B;;;;OAIG;YACW,eAAe;IAO7B;;;;;OAKG;YACW,YAAY;IAiB1B;;;;;;OAMG;YACW,UAAU;CAoBxB"}
|
|
@@ -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) {
|