crewly 1.6.1 → 1.6.3
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 +16 -0
- package/config/skills/agent/core/get-my-active-work/SKILL.md +101 -0
- package/config/skills/agent/core/get-my-active-work/execute.sh +122 -0
- package/config/skills/agent/core/record-learning/SKILL.md +29 -0
- package/config/skills/agent/core/reply-channel/SKILL.md +41 -0
- package/config/skills/agent/core/reply-channel/execute.sh +165 -0
- package/config/skills/agent/core/reply-channel/execute.test.sh +148 -0
- package/config/skills/agent/remote-browser/execute.sh +296 -14
- package/config/skills/agent/remote-browser/execute.test.sh +482 -0
- package/config/skills/orchestrator/send-message/SKILL.md +30 -7
- package/config/skills/orchestrator/team-health-scan/SKILL.md +98 -0
- package/config/skills/orchestrator/team-health-scan/execute.sh +44 -0
- package/config/skills/registry.json +62 -1
- package/config/slack-app-manifest.json +2 -1
- package/config/sops/developer/git-workflow.md +38 -3
- package/dist/backend/backend/src/constants.d.ts +69 -1
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +69 -2
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts +53 -0
- package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +92 -0
- package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +18 -1
- package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +68 -0
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.js +233 -5
- package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.routes.js +10 -1
- package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.js +8 -3
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +132 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +401 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +29 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +39 -0
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/chat-v2/index.d.ts +8 -0
- package/dist/backend/backend/src/controllers/chat-v2/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/chat-v2/index.js +8 -0
- package/dist/backend/backend/src/controllers/chat-v2/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +13 -13
- package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +74 -234
- package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +76 -15
- package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/request/request.controller.js +4 -6
- package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts +43 -0
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +200 -72
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +49 -0
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts +59 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.controller.js +127 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts +13 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.routes.js +20 -0
- package/dist/backend/backend/src/controllers/team-health/team-health.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts +9 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +233 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +40 -6
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +498 -0
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +759 -0
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +25 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +221 -58
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +9 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +35 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +8 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
- package/dist/backend/backend/src/services/agent/tmux-command.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/tmux-command.service.js +2 -1
- package/dist/backend/backend/src/services/agent/tmux-command.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
- package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +148 -3
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js +241 -2
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +13 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +26 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
- package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +161 -0
- package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-bridge.service.js +382 -2
- package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +105 -0
- package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js +232 -13
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +178 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +254 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts +25 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js +23 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +254 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +467 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts +43 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js +54 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/config.d.ts +100 -0
- package/dist/backend/backend/src/services/chat-v2/config.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/config.js +174 -0
- package/dist/backend/backend/src/services/chat-v2/config.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/index.d.ts +11 -0
- package/dist/backend/backend/src/services/chat-v2/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/index.js +12 -0
- package/dist/backend/backend/src/services/chat-v2/index.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +114 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +194 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +100 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +351 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +132 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +281 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/types.d.ts +295 -0
- package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/types.js +61 -0
- package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +113 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +179 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +131 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +227 -0
- package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +1 -0
- package/dist/backend/backend/src/services/core/config.service.js +3 -3
- package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.d.ts +22 -0
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +57 -0
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +69 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js +118 -0
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +275 -0
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +736 -0
- package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -0
- package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -2
- package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +123 -29
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
- package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
- package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/knowledge/learnings-index.service.js +304 -0
- package/dist/backend/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
- package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/knowledge/vector-store.service.js +24 -4
- package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +174 -0
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -0
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +375 -0
- package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -0
- package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +97 -0
- package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +1 -0
- package/dist/backend/backend/src/services/memory/learning-format.validator.js +209 -0
- package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +1 -0
- package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/vector-store.service.js +19 -4
- package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
- package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts +16 -5
- package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js +32 -5
- package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js.map +1 -1
- package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +157 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.service.js +229 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +141 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.types.js +18 -0
- package/dist/backend/backend/src/services/onboarding/onboarding.types.js.map +1 -0
- package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/pr-review/pr-review.service.js +1 -1
- package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +17 -1
- package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +39 -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 +158 -26
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +248 -6
- 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 +531 -51
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/team-health/index.d.ts +16 -0
- package/dist/backend/backend/src/services/team-health/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/index.js +16 -0
- package/dist/backend/backend/src/services/team-health/index.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts +52 -0
- package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +161 -0
- package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts +53 -0
- package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js +88 -0
- package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts +44 -0
- package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js +83 -0
- package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts +92 -0
- package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-alert-router.js +328 -0
- package/dist/backend/backend/src/services/team-health/team-health-alert-router.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-config.d.ts +41 -0
- package/dist/backend/backend/src/services/team-health/team-health-config.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-config.js +213 -0
- package/dist/backend/backend/src/services/team-health/team-health-config.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts +46 -0
- package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-detector.js +347 -0
- package/dist/backend/backend/src/services/team-health/team-health-detector.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-types.d.ts +154 -0
- package/dist/backend/backend/src/services/team-health/team-health-types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-types.js +94 -0
- package/dist/backend/backend/src/services/team-health/team-health-types.js.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts +111 -0
- package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js +226 -0
- package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js.map +1 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +148 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.js +545 -0
- package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -0
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +499 -0
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +1105 -0
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
- package/dist/backend/backend/src/services/v3/request.service.d.ts +22 -0
- package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.js +71 -0
- package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +1 -0
- package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/v3-data.service.js +22 -6
- package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.d.ts +19 -1
- package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.js +43 -0
- package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +22 -1
- 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/backend/src/types/review-reason.types.d.ts +63 -0
- package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/review-reason.types.js +50 -0
- package/dist/backend/backend/src/types/review-reason.types.js.map +1 -0
- package/dist/backend/backend/src/types/slack.types.d.ts +4 -1
- package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/slack.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/mission.types.d.ts +18 -0
- package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/mission.types.js +1 -0
- package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.js +25 -1
- package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
- package/dist/backend/backend/src/utils/team.utils.d.ts +38 -0
- package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/team.utils.js +45 -0
- package/dist/backend/backend/src/utils/team.utils.js.map +1 -0
- package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +195 -0
- package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -0
- package/dist/backend/backend/src/websocket/chat-v2.gateway.js +401 -0
- package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +37 -2
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.js +106 -5
- package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +69 -1
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +69 -2
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/core/config.service.js +3 -3
- package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.d.ts +22 -0
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.js +57 -0
- package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -2
- package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +123 -29
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
- package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/knowledge/vector-store.service.js +24 -4
- package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +22 -1
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.js +25 -1
- package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
- package/frontend/dist/assets/{index-70356616.js → index-7a4e7df5.js} +328 -326
- package/frontend/dist/assets/index-b7e59b2b.css +33 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +2 -1
- package/config/skills/orchestrator/recall/SKILL.md +0 -47
- package/config/skills/orchestrator/recall/execute.sh +0 -13
- package/config/skills/orchestrator/record-learning/SKILL.md +0 -47
- package/config/skills/orchestrator/record-learning/execute.sh +0 -13
- package/config/skills/orchestrator/remember/SKILL.md +0 -55
- package/config/skills/orchestrator/remember/execute.sh +0 -15
- package/frontend/dist/assets/index-6aaa0630.css +0 -33
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-Health-Watchdog (THW) Controller
|
|
3
|
+
*
|
|
4
|
+
* HTTP handlers for THW status, on-demand scan, and silence commands.
|
|
5
|
+
* Backs the orchestrator-facing `team-health-scan` skill (§6.5).
|
|
6
|
+
*
|
|
7
|
+
* Per Sam's etiquette nudge: this controller resolves the watchdog via
|
|
8
|
+
* the `getTeamHealthWatchdogSingleton()` accessor — NOT a module-load
|
|
9
|
+
* import — so /api/health can fail-soft when the singleton isn't ready.
|
|
10
|
+
*
|
|
11
|
+
* @module controllers/team-health/team-health.controller
|
|
12
|
+
*/
|
|
13
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
14
|
+
import { type TeamHealthWatchdogService } from '../../services/team-health/index.js';
|
|
15
|
+
/**
|
|
16
|
+
* Override the singleton accessor for tests. Pass `null` to clear.
|
|
17
|
+
* Production code should use `setTeamHealthWatchdogSingleton()` from
|
|
18
|
+
* `services/team-health` instead.
|
|
19
|
+
*
|
|
20
|
+
* @param service - The instance to use, or null to fall back to singleton
|
|
21
|
+
*/
|
|
22
|
+
export declare function setTeamHealthWatchdogService(service: TeamHealthWatchdogService | null): void;
|
|
23
|
+
/**
|
|
24
|
+
* Read the current watchdog service. Used internally by handlers; also
|
|
25
|
+
* exported for /api/health augmentation in index.ts.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getTeamHealthWatchdogService(): TeamHealthWatchdogService | null;
|
|
28
|
+
/**
|
|
29
|
+
* GET /api/team-health/scan
|
|
30
|
+
*
|
|
31
|
+
* Returns current verdicts (last sweep). Optional ?teamId=... filter.
|
|
32
|
+
*
|
|
33
|
+
* @param req - Express request with optional `teamId` query param
|
|
34
|
+
* @param res - Express response with verdicts payload
|
|
35
|
+
* @param next - Express next function for error forwarding
|
|
36
|
+
*/
|
|
37
|
+
export declare function getTeamHealthScan(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* POST /api/team-health/run
|
|
40
|
+
*
|
|
41
|
+
* Manually trigger one sweep on demand. Returns the result.
|
|
42
|
+
*
|
|
43
|
+
* @param _req - Express request (unused)
|
|
44
|
+
* @param res - Express response with TeamHealthSweepResult
|
|
45
|
+
* @param next - Express next function for error forwarding
|
|
46
|
+
*/
|
|
47
|
+
export declare function runTeamHealthSweep(_req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* POST /api/team-health/silence
|
|
50
|
+
*
|
|
51
|
+
* Apply a manual silence to a team. Body: { teamId, durationMs }.
|
|
52
|
+
* Used by the Slack 🔇 react handler.
|
|
53
|
+
*
|
|
54
|
+
* @param req - Express request with body { teamId, durationMs }
|
|
55
|
+
* @param res - Express response with success flag
|
|
56
|
+
* @param next - Express next function for error forwarding
|
|
57
|
+
*/
|
|
58
|
+
export declare function silenceTeamHealthAlerts(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
59
|
+
//# sourceMappingURL=team-health.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-health.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,qCAAqC,CAAC;AAK7C;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAE5F;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,yBAAyB,GAAG,IAAI,CAE/E;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-Health-Watchdog (THW) Controller
|
|
3
|
+
*
|
|
4
|
+
* HTTP handlers for THW status, on-demand scan, and silence commands.
|
|
5
|
+
* Backs the orchestrator-facing `team-health-scan` skill (§6.5).
|
|
6
|
+
*
|
|
7
|
+
* Per Sam's etiquette nudge: this controller resolves the watchdog via
|
|
8
|
+
* the `getTeamHealthWatchdogSingleton()` accessor — NOT a module-load
|
|
9
|
+
* import — so /api/health can fail-soft when the singleton isn't ready.
|
|
10
|
+
*
|
|
11
|
+
* @module controllers/team-health/team-health.controller
|
|
12
|
+
*/
|
|
13
|
+
import { getTeamHealthWatchdogSingleton, } from '../../services/team-health/index.js';
|
|
14
|
+
// Local override for tests — bypasses the singleton accessor when set.
|
|
15
|
+
let testOverride = null;
|
|
16
|
+
/**
|
|
17
|
+
* Override the singleton accessor for tests. Pass `null` to clear.
|
|
18
|
+
* Production code should use `setTeamHealthWatchdogSingleton()` from
|
|
19
|
+
* `services/team-health` instead.
|
|
20
|
+
*
|
|
21
|
+
* @param service - The instance to use, or null to fall back to singleton
|
|
22
|
+
*/
|
|
23
|
+
export function setTeamHealthWatchdogService(service) {
|
|
24
|
+
testOverride = service;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Read the current watchdog service. Used internally by handlers; also
|
|
28
|
+
* exported for /api/health augmentation in index.ts.
|
|
29
|
+
*/
|
|
30
|
+
export function getTeamHealthWatchdogService() {
|
|
31
|
+
return testOverride ?? getTeamHealthWatchdogSingleton();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* GET /api/team-health/scan
|
|
35
|
+
*
|
|
36
|
+
* Returns current verdicts (last sweep). Optional ?teamId=... filter.
|
|
37
|
+
*
|
|
38
|
+
* @param req - Express request with optional `teamId` query param
|
|
39
|
+
* @param res - Express response with verdicts payload
|
|
40
|
+
* @param next - Express next function for error forwarding
|
|
41
|
+
*/
|
|
42
|
+
export async function getTeamHealthScan(req, res, next) {
|
|
43
|
+
try {
|
|
44
|
+
const watchdog = getTeamHealthWatchdogService();
|
|
45
|
+
if (!watchdog) {
|
|
46
|
+
res.status(503).json({ success: false, error: 'TeamHealthWatchdog not initialized' });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const rawTeamId = req.query.teamId;
|
|
50
|
+
const teamId = typeof rawTeamId === 'string' && rawTeamId.length > 0 ? rawTeamId : undefined;
|
|
51
|
+
const verdicts = watchdog.getCurrentVerdicts(teamId);
|
|
52
|
+
const lastSweep = watchdog.getLastSweep();
|
|
53
|
+
res.json({
|
|
54
|
+
success: true,
|
|
55
|
+
data: {
|
|
56
|
+
verdicts,
|
|
57
|
+
lastSweep: lastSweep ? {
|
|
58
|
+
sweptAt: lastSweep.sweptAt,
|
|
59
|
+
durationMs: lastSweep.durationMs,
|
|
60
|
+
shadowMode: lastSweep.shadowMode,
|
|
61
|
+
} : null,
|
|
62
|
+
lastSweepAgeMs: watchdog.getLastSweepAgeMs(),
|
|
63
|
+
degraded: watchdog.isDegraded(),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
next(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* POST /api/team-health/run
|
|
73
|
+
*
|
|
74
|
+
* Manually trigger one sweep on demand. Returns the result.
|
|
75
|
+
*
|
|
76
|
+
* @param _req - Express request (unused)
|
|
77
|
+
* @param res - Express response with TeamHealthSweepResult
|
|
78
|
+
* @param next - Express next function for error forwarding
|
|
79
|
+
*/
|
|
80
|
+
export async function runTeamHealthSweep(_req, res, next) {
|
|
81
|
+
try {
|
|
82
|
+
const watchdog = getTeamHealthWatchdogService();
|
|
83
|
+
if (!watchdog) {
|
|
84
|
+
res.status(503).json({ success: false, error: 'TeamHealthWatchdog not initialized' });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const result = await watchdog.runOnce();
|
|
88
|
+
res.json({ success: true, data: result });
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
next(error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* POST /api/team-health/silence
|
|
96
|
+
*
|
|
97
|
+
* Apply a manual silence to a team. Body: { teamId, durationMs }.
|
|
98
|
+
* Used by the Slack 🔇 react handler.
|
|
99
|
+
*
|
|
100
|
+
* @param req - Express request with body { teamId, durationMs }
|
|
101
|
+
* @param res - Express response with success flag
|
|
102
|
+
* @param next - Express next function for error forwarding
|
|
103
|
+
*/
|
|
104
|
+
export async function silenceTeamHealthAlerts(req, res, next) {
|
|
105
|
+
try {
|
|
106
|
+
const watchdog = getTeamHealthWatchdogService();
|
|
107
|
+
if (!watchdog) {
|
|
108
|
+
res.status(503).json({ success: false, error: 'TeamHealthWatchdog not initialized' });
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const { teamId, durationMs } = req.body ?? {};
|
|
112
|
+
if (typeof teamId !== 'string' || teamId.length === 0) {
|
|
113
|
+
res.status(400).json({ success: false, error: 'teamId is required' });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (typeof durationMs !== 'number' || durationMs <= 0) {
|
|
117
|
+
res.status(400).json({ success: false, error: 'durationMs must be a positive number' });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
watchdog.silenceTeam(teamId, durationMs);
|
|
121
|
+
res.json({ success: true });
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
next(error);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=team-health.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-health.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-Health-Watchdog (THW) Routes
|
|
3
|
+
*
|
|
4
|
+
* @module controllers/team-health/team-health.routes
|
|
5
|
+
*/
|
|
6
|
+
import { Router } from 'express';
|
|
7
|
+
/**
|
|
8
|
+
* Create the team-health router.
|
|
9
|
+
*
|
|
10
|
+
* @returns Express router for /api/team-health
|
|
11
|
+
*/
|
|
12
|
+
export declare function createTeamHealthRouter(): Router;
|
|
13
|
+
//# sourceMappingURL=team-health.routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-health.routes.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAOjC;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAM/C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-Health-Watchdog (THW) Routes
|
|
3
|
+
*
|
|
4
|
+
* @module controllers/team-health/team-health.routes
|
|
5
|
+
*/
|
|
6
|
+
import { Router } from 'express';
|
|
7
|
+
import { getTeamHealthScan, runTeamHealthSweep, silenceTeamHealthAlerts, } from './team-health.controller.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create the team-health router.
|
|
10
|
+
*
|
|
11
|
+
* @returns Express router for /api/team-health
|
|
12
|
+
*/
|
|
13
|
+
export function createTeamHealthRouter() {
|
|
14
|
+
const router = Router();
|
|
15
|
+
router.get('/scan', getTeamHealthScan);
|
|
16
|
+
router.post('/run', runTeamHealthSweep);
|
|
17
|
+
router.post('/silence', silenceTeamHealthAlerts);
|
|
18
|
+
return router;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=team-health.routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-health.routes.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team-health/team-health.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACxC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -20,9 +20,18 @@ export declare class CrewlyServer {
|
|
|
20
20
|
private queueProcessorService;
|
|
21
21
|
private threadStatusQueueService;
|
|
22
22
|
private eventBusService;
|
|
23
|
+
/** BRIDGE-1: subscribes to autonomy events and creates WorkItems. */
|
|
24
|
+
private eventToWorkItemBridge;
|
|
25
|
+
/** LEARN-1: subscribes to terminal task / mission:replanned events and auto-records learnings. */
|
|
26
|
+
private autoLearningSubscriber;
|
|
27
|
+
/** INBOUND-1: subscribes to request:created and tracks 5/10 min SLA on respond_to_user WIs. */
|
|
28
|
+
private requestSlaSubscriber;
|
|
23
29
|
private notifyReconciliationService;
|
|
24
30
|
private systemResourceAlertService;
|
|
25
31
|
private reconcilerService;
|
|
32
|
+
private teamHealthWatchdog;
|
|
33
|
+
private chatV2Gateway;
|
|
34
|
+
private chatV2Dispatcher;
|
|
26
35
|
private isShuttingDown;
|
|
27
36
|
private healthMonitoringInterval;
|
|
28
37
|
constructor(config?: Partial<StartupConfig>);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":";AAyCA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":";AAyCA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA4HjD,qBAAa,YAAY;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAqE;IAEnF,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,uBAAuB,CAA2B;IAC1D,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,4BAA4B,CAAgC;IACpE,OAAO,CAAC,uBAAuB,CAA2B;IAC1D,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,qBAAqB,CAAyB;IACtD,OAAO,CAAC,wBAAwB,CAA4B;IAC5D,OAAO,CAAC,eAAe,CAAmB;IAC1C,qEAAqE;IACrE,OAAO,CAAC,qBAAqB,CAAsC;IACnE,kGAAkG;IAClG,OAAO,CAAC,sBAAsB,CAAuC;IACrE,+FAA+F;IAC/F,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,2BAA2B,CAA+B;IAClE,OAAO,CAAC,0BAA0B,CAA8B;IAChE,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,kBAAkB,CAA0C;IAKpE,OAAO,CAAC,aAAa,CAAuE;IAC5F,OAAO,CAAC,gBAAgB,CAET;IAGf,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,wBAAwB,CAA+B;gBAEnD,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC;IA2D3C,OAAO,CAAC,kBAAkB;IAqX1B,OAAO,CAAC,mBAAmB;IAmD3B,OAAO,CAAC,eAAe;IA6HvB,OAAO,CAAC,kBAAkB;IAwBpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAs/B5B;;;OAGG;YACW,2BAA2B;IA8BzC;;;OAGG;YACW,8BAA8B;IAsB5C;;;OAGG;YACW,gCAAgC;IAsB9C;;;OAGG;YACW,8BAA8B;IAsB5C;;;;OAIG;YACW,8BAA8B;IA2F5C;;;;;OAKG;YACW,iCAAiC;IA4G/C;;;;OAIG;YACW,2BAA2B;YA0B3B,qBAAqB;YAsBrB,eAAe;YAiCf,kBAAkB;IAgBhC,OAAO,CAAC,WAAW,CAAK;IAExB,OAAO,CAAC,sBAAsB;IAqD9B,OAAO,CAAC,qBAAqB;IAsC7B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0D1B;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAsH7B,OAAO,CAAC,cAAc;IAchB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkS/B,SAAS,IAAI,aAAa;CAG1B;AAeD,eAAe,YAAY,CAAC"}
|
|
@@ -32,6 +32,11 @@ import { initializeCloudIfConfigured } from './services/cloud/cloud-initializer.
|
|
|
32
32
|
import { MessageQueueService, QueueProcessorService, ResponseRouterService } from './services/messaging/index.js';
|
|
33
33
|
import { ThreadStatusQueueService } from './services/messaging/thread-status-queue.service.js';
|
|
34
34
|
import { EventBusService } from './services/event-bus/index.js';
|
|
35
|
+
import { EventToWorkItemBridge } from './services/event-bus/event-to-workitem-bridge.service.js';
|
|
36
|
+
import { AutoLearningSubscriber } from './services/memory/auto-learning.subscriber.js';
|
|
37
|
+
import { RequestSlaSubscriber, setRequestSlaSubscriber, } from './services/v3/request-sla.subscriber.js';
|
|
38
|
+
import { setRequestServiceEventBus, RequestService } from './services/v3/request.service.js';
|
|
39
|
+
import { getSlackService } from './services/slack/slack.service.js';
|
|
35
40
|
import { SlackThreadStoreService, setSlackThreadStore, getSlackThreadStore } from './services/slack/slack-thread-store.service.js';
|
|
36
41
|
import { GoogleChatThreadStoreService, setGchatThreadStore } from './services/messaging/gchat-thread-store.service.js';
|
|
37
42
|
import { SlackImageService, setSlackImageService } from './services/slack/slack-image.service.js';
|
|
@@ -67,6 +72,7 @@ import { setReconcilerService } from './controllers/reconciler/reconciler.contro
|
|
|
67
72
|
import { FissionGuardService } from './services/fission/fission-guard.service.js';
|
|
68
73
|
import { setFissionGuardService } from './controllers/fission/fission.controller.js';
|
|
69
74
|
import { TaskPoolService } from './services/task-pool/task-pool.service.js';
|
|
75
|
+
import { TeamHealthWatchdogService, LiveTeamHealthDataProvider, loadTeamHealthConfig, setTeamHealthWatchdogSingleton, getTeamHealthWatchdogSingleton, } from './services/team-health/index.js';
|
|
70
76
|
// ESM __dirname equivalent using import.meta.url
|
|
71
77
|
const __filename = fileURLToPath(import.meta.url);
|
|
72
78
|
const __dirname = path.dirname(__filename);
|
|
@@ -125,9 +131,21 @@ export class CrewlyServer {
|
|
|
125
131
|
queueProcessorService;
|
|
126
132
|
threadStatusQueueService;
|
|
127
133
|
eventBusService;
|
|
134
|
+
/** BRIDGE-1: subscribes to autonomy events and creates WorkItems. */
|
|
135
|
+
eventToWorkItemBridge = null;
|
|
136
|
+
/** LEARN-1: subscribes to terminal task / mission:replanned events and auto-records learnings. */
|
|
137
|
+
autoLearningSubscriber = null;
|
|
138
|
+
/** INBOUND-1: subscribes to request:created and tracks 5/10 min SLA on respond_to_user WIs. */
|
|
139
|
+
requestSlaSubscriber = null;
|
|
128
140
|
notifyReconciliationService;
|
|
129
141
|
systemResourceAlertService;
|
|
130
142
|
reconcilerService = null;
|
|
143
|
+
teamHealthWatchdog = null;
|
|
144
|
+
// Chat MVP Phase 1 — initialized lazily in `start()` after the HTTP
|
|
145
|
+
// server is created. Kept as fields so the shutdown path can close
|
|
146
|
+
// them cleanly and tests can reach in with a reference.
|
|
147
|
+
chatV2Gateway = null;
|
|
148
|
+
chatV2Dispatcher = null;
|
|
131
149
|
// Shutdown state
|
|
132
150
|
isShuttingDown = false;
|
|
133
151
|
healthMonitoringInterval = null;
|
|
@@ -231,6 +249,11 @@ export class CrewlyServer {
|
|
|
231
249
|
this.threadStatusQueueService = new ThreadStatusQueueService(this.config.crewlyHome);
|
|
232
250
|
responseRouter.setThreadStatusQueue(this.threadStatusQueueService);
|
|
233
251
|
this.queueProcessorService.setThreadStatusQueue(this.threadStatusQueueService);
|
|
252
|
+
// INBOUND-1.f1: Wire EventBus into the TaskPool singleton so addToPool
|
|
253
|
+
// can publish `workitem:queued` events. Must run before any code path
|
|
254
|
+
// triggers addToPool — the slack listener / TaskPool router below both
|
|
255
|
+
// depend on this for the auto-close path b chain. Idempotent.
|
|
256
|
+
TaskPoolService.getInstance().setEventBusService(this.eventBusService);
|
|
234
257
|
// Wire Task Pool router so [TASK]-prefixed messages route through the pool
|
|
235
258
|
this.queueProcessorService.setTaskPoolRouter(async (messageContent, targetSession) => {
|
|
236
259
|
const { createWorkItem } = await import('./types/v2/work-item.types.js');
|
|
@@ -277,6 +300,39 @@ export class CrewlyServer {
|
|
|
277
300
|
taskId: payload.taskId,
|
|
278
301
|
});
|
|
279
302
|
});
|
|
303
|
+
// BRIDGE-1: subscribe to autonomy events (task:done_by_worker,
|
|
304
|
+
// task:rejected, task:blocked, team:all_tasks_done, mission:*) and
|
|
305
|
+
// create the appropriate WorkItem(s) — verification WI for TL on
|
|
306
|
+
// done_by_worker, retry WI / escalation WI on rejected, review WI on
|
|
307
|
+
// blocked / mission events. See `event-to-workitem-bridge.service.ts`
|
|
308
|
+
// for idempotency contract + retry cap + cron-recursion guard.
|
|
309
|
+
this.eventToWorkItemBridge = EventToWorkItemBridge.boot(this.eventBusService);
|
|
310
|
+
this.eventToWorkItemBridge.start();
|
|
311
|
+
// LEARN-1: subscribe to terminal task / mission:replanned events and
|
|
312
|
+
// auto-record a learning entry via MemoryService.recordLearning. Closes
|
|
313
|
+
// the prompt-driven "agents-forget-to-record" gap. See
|
|
314
|
+
// `auto-learning.subscriber.ts` for category mapping + idempotency
|
|
315
|
+
// contract (V1) and the V7/V9 self-checks in the co-located test.
|
|
316
|
+
this.autoLearningSubscriber = AutoLearningSubscriber.boot(this.eventBusService);
|
|
317
|
+
this.autoLearningSubscriber.start();
|
|
318
|
+
// INBOUND-1: wire RequestService → bus, then subscribe SLA tracker.
|
|
319
|
+
// Order matters: setRequestServiceEventBus must run BEFORE any code
|
|
320
|
+
// path can call RequestService.create() — the slack listener at
|
|
321
|
+
// line ~370 is the first hot caller, but the slack service hasn't
|
|
322
|
+
// been initialised yet at this point in boot, so we're safe.
|
|
323
|
+
setRequestServiceEventBus(this.eventBusService);
|
|
324
|
+
this.requestSlaSubscriber = RequestSlaSubscriber.boot(this.eventBusService, RequestService.getInstance(), TaskPoolService.getInstance(), async ({ channelId, threadTs, messageText }) => {
|
|
325
|
+
// Production wiring of the 10-min escalation hook: nudge the user
|
|
326
|
+
// in the same Slack thread so they're never blind to the miss.
|
|
327
|
+
const slack = getSlackService();
|
|
328
|
+
await slack.sendMessage({
|
|
329
|
+
channelId,
|
|
330
|
+
threadTs,
|
|
331
|
+
text: messageText,
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
this.requestSlaSubscriber.start();
|
|
335
|
+
setRequestSlaSubscriber(this.requestSlaSubscriber);
|
|
280
336
|
// Initialize Slack thread store for persistent thread conversations
|
|
281
337
|
const slackThreadStore = new SlackThreadStoreService(this.config.crewlyHome);
|
|
282
338
|
setSlackThreadStore(slackThreadStore);
|
|
@@ -348,6 +404,68 @@ export class CrewlyServer {
|
|
|
348
404
|
}
|
|
349
405
|
reconcilerLogger.info('ReconcilerService initialized and wired to EventBus');
|
|
350
406
|
}
|
|
407
|
+
// Initialize Team-Health-Watchdog (THW) — Layer 4 liveness aggregator
|
|
408
|
+
// Lazy singleton wiring per Sam's etiquette nudge: no module-load
|
|
409
|
+
// side effects; controller and /api/health resolve via accessor.
|
|
410
|
+
{
|
|
411
|
+
const thwLogger = LoggerService.getInstance().createComponentLogger('TeamHealthInit');
|
|
412
|
+
try {
|
|
413
|
+
const config = loadTeamHealthConfig({
|
|
414
|
+
warn: (msg, meta) => thwLogger.warn(msg, meta ?? {}),
|
|
415
|
+
info: (msg, meta) => thwLogger.info(msg, meta ?? {}),
|
|
416
|
+
});
|
|
417
|
+
if (!config.enabled) {
|
|
418
|
+
thwLogger.info('TeamHealthWatchdog disabled by config; skipping init.');
|
|
419
|
+
}
|
|
420
|
+
else if (!this.reconcilerService) {
|
|
421
|
+
thwLogger.warn('Reconciler not available; skipping TeamHealthWatchdog init.');
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
const reconcilerProvider = new LiveReconcilerDataProvider();
|
|
425
|
+
const dataProvider = new LiveTeamHealthDataProvider({
|
|
426
|
+
reconcilerProvider,
|
|
427
|
+
getTeams: async () => StorageService.getInstance().getTeams(),
|
|
428
|
+
bootedAt: new Date(),
|
|
429
|
+
});
|
|
430
|
+
// Phase 0 alert sink: log-only. Slack delivery wires up
|
|
431
|
+
// in Phase 1 (per §G phasing). Shadow-mode is the
|
|
432
|
+
// default config.json setting, so this sink is mostly
|
|
433
|
+
// invoked for the recovery announcement path.
|
|
434
|
+
const alertSink = {
|
|
435
|
+
deliver: async (decision) => {
|
|
436
|
+
thwLogger.info('THW alert (Phase 0 log-only sink)', {
|
|
437
|
+
teamId: decision.detection.teamId,
|
|
438
|
+
verdict: decision.effectiveVerdict,
|
|
439
|
+
channel: decision.channel,
|
|
440
|
+
message: decision.message,
|
|
441
|
+
});
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
this.teamHealthWatchdog = new TeamHealthWatchdogService({
|
|
445
|
+
config,
|
|
446
|
+
dataProvider,
|
|
447
|
+
alertSink,
|
|
448
|
+
bootedAt: new Date(),
|
|
449
|
+
logger: {
|
|
450
|
+
info: (msg, meta) => thwLogger.info(msg, meta ?? {}),
|
|
451
|
+
warn: (msg, meta) => thwLogger.warn(msg, meta ?? {}),
|
|
452
|
+
error: (msg, meta) => thwLogger.error(msg, meta ?? {}),
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
setTeamHealthWatchdogSingleton(this.teamHealthWatchdog);
|
|
456
|
+
this.teamHealthWatchdog.start();
|
|
457
|
+
thwLogger.info('TeamHealthWatchdog initialized', {
|
|
458
|
+
shadowMode: config.shadowMode,
|
|
459
|
+
sweepIntervalMs: config.sweepIntervalMs,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
thwLogger.error('Failed to initialize TeamHealthWatchdog (continuing without it)', {
|
|
465
|
+
error: err instanceof Error ? err.message : String(err),
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
}
|
|
351
469
|
// Initialize Fission Guard Service
|
|
352
470
|
{
|
|
353
471
|
const fissionLogger = LoggerService.getInstance().createComponentLogger('FissionInit');
|
|
@@ -467,6 +585,18 @@ export class CrewlyServer {
|
|
|
467
585
|
version = process.env.npm_package_version || 'unknown';
|
|
468
586
|
}
|
|
469
587
|
}
|
|
588
|
+
// THW self-instrumentation (§F.3): surface last-sweep age + degraded
|
|
589
|
+
// flag so the watchdog-watchdog (§E.8) bubbles up here. Fail-soft
|
|
590
|
+
// per Sam's etiquette nudge — when the singleton isn't ready, return
|
|
591
|
+
// status:"warming" rather than 5xx.
|
|
592
|
+
const watchdog = getTeamHealthWatchdogSingleton();
|
|
593
|
+
const teamHealthBlock = watchdog
|
|
594
|
+
? {
|
|
595
|
+
status: watchdog.isDegraded() ? 'degraded' : (watchdog.isActive() ? 'ok' : 'inactive'),
|
|
596
|
+
last_sweep_age_ms: watchdog.getLastSweepAgeMs(),
|
|
597
|
+
shadowMode: watchdog.getLastSweep()?.shadowMode ?? null,
|
|
598
|
+
}
|
|
599
|
+
: { status: 'warming', last_sweep_age_ms: -1, shadowMode: null };
|
|
470
600
|
res.json({
|
|
471
601
|
status: 'healthy',
|
|
472
602
|
timestamp: new Date().toISOString(),
|
|
@@ -479,6 +609,7 @@ export class CrewlyServer {
|
|
|
479
609
|
active: agentCount,
|
|
480
610
|
total: agentCount,
|
|
481
611
|
},
|
|
612
|
+
team_health: teamHealthBlock,
|
|
482
613
|
});
|
|
483
614
|
});
|
|
484
615
|
// H5 quick entry static page (served regardless of headless mode)
|
|
@@ -788,6 +919,62 @@ export class CrewlyServer {
|
|
|
788
919
|
error: error instanceof Error ? error.message : String(error),
|
|
789
920
|
});
|
|
790
921
|
}
|
|
922
|
+
// Start chat-v2 WebSocket gateway + dispatcher (Phase 1 Chat MVP).
|
|
923
|
+
// The gateway fans `message`/`presence` frames to subscribers of
|
|
924
|
+
// `/ws/chat?channelId=...`. The dispatcher pushes user-origin
|
|
925
|
+
// messages into the bound agent session so it can reply via the
|
|
926
|
+
// `reply-channel` skill. See chat-v2.gateway.ts for the contract.
|
|
927
|
+
try {
|
|
928
|
+
const [{ ChatV2Gateway, devAnonymousTokenVerifier }, { ChatV2DispatcherService }, { ChatV2MentionResolver }, { getChatV2Service }, { setChatV2RealtimeDeps }, { verifyHs256Token },] = await Promise.all([
|
|
929
|
+
import('./websocket/chat-v2.gateway.js'),
|
|
930
|
+
import('./services/chat-v2/chat-v2.dispatcher.service.js'),
|
|
931
|
+
import('./services/chat-v2/chat-v2.mention-resolver.js'),
|
|
932
|
+
import('./services/chat-v2/chat-v2.singleton.js'),
|
|
933
|
+
import('./services/chat-v2/chat-v2.realtime-holder.js'),
|
|
934
|
+
import('./middleware/require-auth.middleware.js'),
|
|
935
|
+
]);
|
|
936
|
+
const chatService = getChatV2Service();
|
|
937
|
+
const jwtSecret = process.env['CREWLY_JWT_SECRET'];
|
|
938
|
+
const verifyToken = jwtSecret
|
|
939
|
+
? async (token) => {
|
|
940
|
+
if (!token)
|
|
941
|
+
return null;
|
|
942
|
+
const payload = verifyHs256Token(token, jwtSecret);
|
|
943
|
+
if (!payload?.sub)
|
|
944
|
+
return null;
|
|
945
|
+
return { userId: payload.sub };
|
|
946
|
+
}
|
|
947
|
+
: devAnonymousTokenVerifier;
|
|
948
|
+
const chatGateway = new ChatV2Gateway({ service: chatService, verifyToken });
|
|
949
|
+
chatGateway.attach(this.httpServer);
|
|
950
|
+
// Phase C BE.3 — inject the mention resolver so type='channel'
|
|
951
|
+
// messages fan out to @-mentioned recipients instead of
|
|
952
|
+
// short-circuiting with strategy='skip' at the dispatcher.
|
|
953
|
+
// Pattern matches LiveTeamHealthDataProvider wiring (~line 487):
|
|
954
|
+
// `getTeams: async () => StorageService.getInstance().getTeams()`.
|
|
955
|
+
const chatMentionResolver = new ChatV2MentionResolver({
|
|
956
|
+
loadTeams: async () => StorageService.getInstance().getTeams(),
|
|
957
|
+
});
|
|
958
|
+
const chatDispatcher = new ChatV2DispatcherService({
|
|
959
|
+
agentSink: this.apiController.agentRegistrationService,
|
|
960
|
+
mentionResolver: chatMentionResolver,
|
|
961
|
+
});
|
|
962
|
+
this.chatV2Gateway = chatGateway;
|
|
963
|
+
this.chatV2Dispatcher = chatDispatcher;
|
|
964
|
+
// The chat-v2 router mounted earlier reads realtime deps from
|
|
965
|
+
// this holder at request time, so it picks up broadcast +
|
|
966
|
+
// dispatch without a re-mount.
|
|
967
|
+
setChatV2RealtimeDeps({ gateway: chatGateway, dispatcher: chatDispatcher });
|
|
968
|
+
this.logger.info('chat-v2 WebSocket gateway + dispatcher started', {
|
|
969
|
+
path: '/ws/chat',
|
|
970
|
+
authMode: jwtSecret ? 'jwt' : 'dev-anonymous',
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
catch (error) {
|
|
974
|
+
this.logger.warn('Failed to start chat-v2 WS gateway (non-critical)', {
|
|
975
|
+
error: error instanceof Error ? error.message : String(error),
|
|
976
|
+
});
|
|
977
|
+
}
|
|
791
978
|
// Connect BrowserProxyService to Cloud Relay (lazy — does not block startup)
|
|
792
979
|
try {
|
|
793
980
|
const { BrowserProxyService } = await import('./services/browser/browser-proxy.service.js');
|
|
@@ -1893,10 +2080,30 @@ export class CrewlyServer {
|
|
|
1893
2080
|
// Catches direct orchestrator responses that finish within a single poll cycle
|
|
1894
2081
|
// and never trigger the EventBus agent:idle event
|
|
1895
2082
|
setInterval(() => this.autoCloseOpenRequests(), 2 * 60 * 1000);
|
|
2083
|
+
// V3: Mission OKR Reminders (every hour)
|
|
2084
|
+
// Scans active missions and sends Slack alerts for off-track KRs
|
|
2085
|
+
setInterval(async () => {
|
|
2086
|
+
try {
|
|
2087
|
+
const { MissionReminderService } = await import('./services/v3/mission-reminder.service.js');
|
|
2088
|
+
await MissionReminderService.getInstance().runSweep();
|
|
2089
|
+
}
|
|
2090
|
+
catch (err) {
|
|
2091
|
+
this.logger.warn('Mission OKR reminder sweep failed', { error: String(err) });
|
|
2092
|
+
}
|
|
2093
|
+
}, 60 * 60 * 1000);
|
|
1896
2094
|
// Purge done Requests and WorkItems older than 24h (every hour)
|
|
1897
2095
|
setInterval(() => this.purgeCompletedData(), 60 * 60 * 1000);
|
|
1898
2096
|
// Run once at startup after a short delay
|
|
1899
2097
|
setTimeout(() => this.purgeCompletedData(), 30 * 1000);
|
|
2098
|
+
setTimeout(async () => {
|
|
2099
|
+
try {
|
|
2100
|
+
const { MissionReminderService } = await import('./services/v3/mission-reminder.service.js');
|
|
2101
|
+
await MissionReminderService.getInstance().runSweep();
|
|
2102
|
+
}
|
|
2103
|
+
catch (err) {
|
|
2104
|
+
// Non-critical
|
|
2105
|
+
}
|
|
2106
|
+
}, 60 * 1000);
|
|
1900
2107
|
}
|
|
1901
2108
|
/**
|
|
1902
2109
|
* Removes done/cancelled Requests older than 24h from disk,
|
|
@@ -2217,12 +2424,38 @@ export class CrewlyServer {
|
|
|
2217
2424
|
this.reconcilerService.stop();
|
|
2218
2425
|
this.logger.info('Reconciler stopped');
|
|
2219
2426
|
}
|
|
2427
|
+
// Stop Team-Health-Watchdog sweep loop (Layer 4)
|
|
2428
|
+
if (this.teamHealthWatchdog) {
|
|
2429
|
+
this.teamHealthWatchdog.stop();
|
|
2430
|
+
this.logger.info('TeamHealthWatchdog stopped');
|
|
2431
|
+
}
|
|
2220
2432
|
// Stop NOTIFY reconciliation service
|
|
2221
2433
|
if (this.notifyReconciliationService) {
|
|
2222
2434
|
this.notifyReconciliationService.stop();
|
|
2223
2435
|
}
|
|
2224
2436
|
// Stop message queue processor
|
|
2225
2437
|
this.queueProcessorService.stop();
|
|
2438
|
+
// Stop the EventToWorkItemBridge BEFORE cleaning the event bus so
|
|
2439
|
+
// in-flight handler dispatches drain against a still-live bus.
|
|
2440
|
+
if (this.eventToWorkItemBridge) {
|
|
2441
|
+
this.eventToWorkItemBridge.stop();
|
|
2442
|
+
this.eventToWorkItemBridge = null;
|
|
2443
|
+
}
|
|
2444
|
+
// LEARN-1: stop the AutoLearningSubscriber on the same window as the
|
|
2445
|
+
// bridge so its in-flight recordLearning calls drain before the bus
|
|
2446
|
+
// is cleaned.
|
|
2447
|
+
if (this.autoLearningSubscriber) {
|
|
2448
|
+
this.autoLearningSubscriber.stop();
|
|
2449
|
+
this.autoLearningSubscriber = null;
|
|
2450
|
+
}
|
|
2451
|
+
// INBOUND-1: stop the SLA subscriber and unset the module-level
|
|
2452
|
+
// references so a follow-up start() doesn't see stale singletons.
|
|
2453
|
+
if (this.requestSlaSubscriber) {
|
|
2454
|
+
this.requestSlaSubscriber.stop();
|
|
2455
|
+
this.requestSlaSubscriber = null;
|
|
2456
|
+
}
|
|
2457
|
+
setRequestSlaSubscriber(null);
|
|
2458
|
+
setRequestServiceEventBus(null);
|
|
2226
2459
|
// Clean up event bus service
|
|
2227
2460
|
this.eventBusService.cleanup();
|
|
2228
2461
|
// Clean up schedulers
|