crewly 1.20.106 → 1.20.107
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/README.md +22 -12
- package/config/constants.ts +43 -0
- package/config/index.ts +2 -0
- package/config/skills/_common/lib.sh +55 -2
- package/config/skills/_common/lib.test.sh +58 -1
- package/config/skills/_common/task-pool-body-shape.test.sh +60 -0
- package/config/skills/agent/core/cancel-followup/execute.sh +18 -3
- package/config/skills/agent/core/cancel-followup/execute.test.sh +73 -0
- package/config/skills/agent/core/complete-task/execute.sh +1 -1
- package/config/skills/agent/core/create-intent-tasks/execute.sh +1 -1
- package/config/skills/agent/core/create-task/SKILL.md +1 -0
- package/config/skills/agent/core/create-task/execute.sh +10 -0
- package/config/skills/agent/core/decompose-intent/execute.sh +1 -1
- package/config/skills/agent/core/handoff-task/execute.sh +1 -1
- package/config/skills/agent/core/list-my-followups/SKILL.md +1 -1
- package/config/skills/agent/core/list-my-followups/execute.sh +25 -3
- package/config/skills/agent/core/list-my-followups/execute.test.sh +72 -0
- package/config/skills/agent/core/poll-tasks/execute.sh +3 -3
- package/config/skills/agent/core/reply-channel/SKILL.md +1 -1
- package/config/skills/agent/core/report-progress/execute.sh +1 -1
- package/config/skills/agent/core/report-status/execute.sh +1 -1
- package/config/skills/agent/core/slack-post/SKILL.md +1 -1
- package/config/skills/agent/core/update-intent-task/execute.sh +1 -1
- package/config/skills/agent/marketing/brand-onboarding/execute.sh +1 -1
- package/config/skills/agent/marketing/submit-for-approval/execute.sh +1 -1
- package/config/skills/agent/remote-browser/SOP-google-flow-video.md +1 -1
- package/config/skills/agent/remote-browser/execute.sh +33 -1
- package/config/skills/agent/remote-browser/execute.test.sh +62 -0
- package/config/skills/agent/screenshot-compare/execute.sh +1 -1
- package/config/skills/agent/transcribe-audio/SKILL.md +1 -1
- package/config/skills/agent/transcribe-audio/execute.sh +1 -1
- package/config/skills/agent/transcribe-audio/instructions.md +1 -1
- package/config/skills/orchestrator/delegate-task/SKILL.md +1 -1
- package/config/skills/orchestrator/get-tasks/SKILL.md +7 -1
- package/config/skills/orchestrator/get-tasks/execute.sh +51 -28
- package/config/skills/orchestrator/get-tasks/execute.test.sh +67 -0
- package/config/skills/orchestrator/heartbeat/execute.sh +2 -2
- package/config/skills/orchestrator/list-missions/execute.sh +1 -1
- package/config/skills/orchestrator/list-missions/execute.test.sh +38 -11
- package/config/skills/team-leader/decompose-goal/SKILL.md +1 -0
- package/config/skills/team-leader/decompose-goal/execute.sh +17 -2
- package/config/skills/team-leader/delegate-task/SKILL.md +1 -0
- package/config/skills/team-leader/delegate-task/execute.sh +6 -2
- package/dist/backend/backend/src/constants.d.ts +199 -2
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +190 -3
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +33 -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 +176 -9
- package/dist/backend/backend/src/controllers/browser/browser.controller.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 +38 -35
- 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 +10 -45
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +40 -89
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/session/session.controller.d.ts +2 -1
- package/dist/backend/backend/src/controllers/session/session.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/session/session.controller.js +21 -0
- package/dist/backend/backend/src/controllers/session/session.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +51 -3
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/restart-readiness.controller.d.ts +23 -0
- package/dist/backend/backend/src/controllers/system/restart-readiness.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/system/restart-readiness.controller.js +35 -0
- package/dist/backend/backend/src/controllers/system/restart-readiness.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts +5 -3
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.js +27 -6
- package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.routes.js +3 -0
- package/dist/backend/backend/src/controllers/system/system.routes.js.map +1 -1
- 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 +29 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.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 +86 -6
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.d.ts +41 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.js +135 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.d.ts +18 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.js +25 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts +70 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +352 -71
- 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 +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/scripts/leaked-stub-teams.lib.d.ts +128 -0
- package/dist/backend/backend/src/scripts/leaked-stub-teams.lib.d.ts.map +1 -0
- package/dist/backend/backend/src/scripts/leaked-stub-teams.lib.js +200 -0
- package/dist/backend/backend/src/scripts/leaked-stub-teams.lib.js.map +1 -0
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +2 -2
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +3 -1
- package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +4 -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 +61 -4
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +30 -0
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js +62 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +2 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +0 -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 +0 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.d.ts +65 -1
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.js +113 -10
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/restore-filter.d.ts +12 -0
- package/dist/backend/backend/src/services/agent/restore-filter.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/restore-filter.js +19 -0
- package/dist/backend/backend/src/services/agent/restore-filter.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +3 -2
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.d.ts +28 -0
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.js +34 -0
- package/dist/backend/backend/src/services/agent/runtime-startup-blocked.error.js.map +1 -0
- package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +57 -5
- 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 +98 -18
- 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 +12 -1
- 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 +25 -4
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts +2 -1
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js +5 -1
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-session.service.d.ts +38 -0
- package/dist/backend/backend/src/services/browser/browser-session.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-session.service.js +34 -0
- package/dist/backend/backend/src/services/browser/browser-session.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +6 -0
- 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 +5 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.js +7 -2
- package/dist/backend/backend/src/services/chat-v2/chat-v2.relay-adapter.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +23 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +58 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.d.ts +63 -0
- package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.js +72 -0
- package/dist/backend/backend/src/services/chat-v2/owner-inbound.utils.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +10 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +15 -0
- package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +6 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
- package/dist/backend/backend/src/services/core/retry.util.d.ts +5 -0
- package/dist/backend/backend/src/services/core/retry.util.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/retry.util.js +2 -2
- package/dist/backend/backend/src/services/core/retry.util.js.map +1 -1
- package/dist/backend/backend/src/services/factory.service.js +3 -3
- package/dist/backend/backend/src/services/factory.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/google-chat-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/google-chat-initializer.js +24 -1
- package/dist/backend/backend/src/services/messaging/google-chat-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +9 -0
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +55 -0
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +7 -0
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +12 -0
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/thread-status-queue.service.d.ts +36 -1
- package/dist/backend/backend/src/services/messaging/thread-status-queue.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/thread-status-queue.service.js +90 -2
- package/dist/backend/backend/src/services/messaging/thread-status-queue.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/commitment-approval-guard.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/commitment-approval-guard.js +22 -16
- package/dist/backend/backend/src/services/orchestrator/commitment-approval-guard.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.js +11 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +9 -9
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +189 -0
- package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js +246 -0
- package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -0
- package/dist/backend/backend/src/services/restart/interrupted-turns.d.ts +153 -0
- package/dist/backend/backend/src/services/restart/interrupted-turns.d.ts.map +1 -0
- package/dist/backend/backend/src/services/restart/interrupted-turns.js +279 -0
- package/dist/backend/backend/src/services/restart/interrupted-turns.js.map +1 -0
- package/dist/backend/backend/src/services/restart/restart-drain.service.d.ts +176 -0
- package/dist/backend/backend/src/services/restart/restart-drain.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/restart/restart-drain.service.js +298 -0
- package/dist/backend/backend/src/services/restart/restart-drain.service.js.map +1 -0
- package/dist/backend/backend/src/services/restart/turn-probe.d.ts +52 -0
- package/dist/backend/backend/src/services/restart/turn-probe.d.ts.map +1 -0
- package/dist/backend/backend/src/services/restart/turn-probe.js +61 -0
- package/dist/backend/backend/src/services/restart/turn-probe.js.map +1 -0
- package/dist/backend/backend/src/services/session/pty/node-pty-install.utils.d.ts +70 -0
- package/dist/backend/backend/src/services/session/pty/node-pty-install.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/session/pty/node-pty-install.utils.js +105 -0
- package/dist/backend/backend/src/services/session/pty/node-pty-install.utils.js.map +1 -0
- package/dist/backend/backend/src/services/session/pty/pty-session.d.ts +2 -0
- package/dist/backend/backend/src/services/session/pty/pty-session.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.js +53 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.js.map +1 -1
- package/dist/backend/backend/src/services/session/session-binding.d.ts +125 -0
- package/dist/backend/backend/src/services/session/session-binding.d.ts.map +1 -0
- package/dist/backend/backend/src/services/session/session-binding.js +183 -0
- package/dist/backend/backend/src/services/session/session-binding.js.map +1 -0
- package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/session-handoff.service.js +19 -0
- package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts +10 -0
- 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 +37 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.d.ts +4 -3
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.js +4 -3
- package/dist/backend/backend/src/services/slack/slack-cloud-config.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts +72 -7
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +185 -23
- 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 +4 -45
- 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 +57 -190
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-source-preference.service.d.ts +59 -0
- package/dist/backend/backend/src/services/slack/slack-source-preference.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-source-preference.service.js +69 -0
- package/dist/backend/backend/src/services/slack/slack-source-preference.service.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +18 -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 +64 -3
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +33 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +129 -4
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/pool-archive-migration.d.ts +108 -0
- package/dist/backend/backend/src/services/task-pool/pool-archive-migration.d.ts.map +1 -0
- package/dist/backend/backend/src/services/task-pool/pool-archive-migration.js +193 -0
- package/dist/backend/backend/src/services/task-pool/pool-archive-migration.js.map +1 -0
- package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts +15 -0
- package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/pool-storage.js +30 -0
- package/dist/backend/backend/src/services/task-pool/pool-storage.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +41 -1
- 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 +55 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.d.ts +7 -0
- package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.js +32 -1
- package/dist/backend/backend/src/services/telegram/telegram-orchestrator-bridge.js.map +1 -1
- 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 +4 -3
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js +12 -0
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.d.ts +7 -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 +17 -0
- package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts +279 -0
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js +458 -0
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js.map +1 -0
- package/dist/backend/backend/src/services/v3/ticket-intake.service.d.ts +376 -0
- package/dist/backend/backend/src/services/v3/ticket-intake.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/ticket-intake.service.js +566 -0
- package/dist/backend/backend/src/services/v3/ticket-intake.service.js.map +1 -0
- package/dist/backend/backend/src/services/v3/tl-auto-verify.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/tl-auto-verify.service.js +3 -3
- package/dist/backend/backend/src/services/v3/tl-auto-verify.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts +28 -4
- 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 +40 -10
- 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 +1 -0
- 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 +3 -3
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/types/slack.types.d.ts +29 -0
- 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/thread-status.types.d.ts +26 -0
- package/dist/backend/backend/src/types/thread-status.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/thread-status.types.js +17 -0
- package/dist/backend/backend/src/types/thread-status.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/index.d.ts +3 -2
- package/dist/backend/backend/src/types/v2/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/index.js +1 -1
- package/dist/backend/backend/src/types/v2/index.js.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.d.ts +39 -3
- package/dist/backend/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.js +11 -2
- package/dist/backend/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/ticket.types.d.ts +173 -0
- package/dist/backend/backend/src/types/v2/ticket.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/v2/ticket.types.js +203 -0
- package/dist/backend/backend/src/types/v2/ticket.types.js.map +1 -0
- package/dist/backend/backend/src/utils/agent-caller.utils.d.ts +26 -0
- package/dist/backend/backend/src/utils/agent-caller.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/agent-caller.utils.js +40 -3
- package/dist/backend/backend/src/utils/agent-caller.utils.js.map +1 -1
- package/dist/backend/backend/src/utils/gemini-auth-settings.d.ts +62 -0
- package/dist/backend/backend/src/utils/gemini-auth-settings.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/gemini-auth-settings.js +104 -0
- package/dist/backend/backend/src/utils/gemini-auth-settings.js.map +1 -0
- package/dist/backend/backend/src/utils/local-api-url.utils.d.ts +56 -0
- package/dist/backend/backend/src/utils/local-api-url.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/local-api-url.utils.js +80 -0
- package/dist/backend/backend/src/utils/local-api-url.utils.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/backend/config/constants.d.ts +40 -0
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +41 -0
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/backend/config/index.d.ts +4 -2
- package/dist/backend/config/index.d.ts.map +1 -1
- package/dist/backend/config/index.js +2 -2
- package/dist/backend/config/index.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +199 -2
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +190 -3
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/active-work-briefing.service.d.ts +2 -2
- package/dist/cli/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/active-work-briefing.service.js +3 -1
- package/dist/cli/backend/src/services/agent/active-work-briefing.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +4 -0
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js +61 -4
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts +30 -0
- package/dist/cli/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/claude-runtime.service.js +62 -1
- package/dist/cli/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +2 -1
- package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/crewly-agent/types.d.ts +0 -2
- package/dist/cli/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/crewly-agent/types.js +0 -2
- package/dist/cli/backend/src/services/agent/crewly-agent/types.js.map +1 -1
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts +65 -1
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.js +113 -10
- package/dist/cli/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +3 -2
- package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.d.ts +28 -0
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.d.ts.map +1 -0
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.js +34 -0
- package/dist/cli/backend/src/services/agent/runtime-startup-blocked.error.js.map +1 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +6 -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 +5 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +23 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +58 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts +10 -0
- package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js +15 -0
- package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +7 -0
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +12 -0
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts +36 -1
- package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js +90 -2
- package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js.map +1 -1
- package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +189 -0
- package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js +246 -0
- package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -0
- package/dist/cli/backend/src/services/restart/restart-drain.service.d.ts +176 -0
- package/dist/cli/backend/src/services/restart/restart-drain.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/restart/restart-drain.service.js +298 -0
- package/dist/cli/backend/src/services/restart/restart-drain.service.js.map +1 -0
- package/dist/cli/backend/src/services/session/pty/node-pty-install.utils.d.ts +70 -0
- package/dist/cli/backend/src/services/session/pty/node-pty-install.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/services/session/pty/node-pty-install.utils.js +105 -0
- package/dist/cli/backend/src/services/session/pty/node-pty-install.utils.js.map +1 -0
- package/dist/cli/backend/src/services/session/pty/pty-session.d.ts +2 -0
- package/dist/cli/backend/src/services/session/pty/pty-session.d.ts.map +1 -1
- package/dist/cli/backend/src/services/session/pty/pty-session.js +53 -1
- package/dist/cli/backend/src/services/session/pty/pty-session.js.map +1 -1
- package/dist/cli/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/session/session-handoff.service.js +19 -0
- package/dist/cli/backend/src/services/session/session-handoff.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts +10 -0
- 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 +37 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +4 -45
- 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 +57 -190
- 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 +18 -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 +64 -3
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts +33 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.js +129 -4
- package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts +15 -0
- package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/pool-storage.js +30 -0
- package/dist/cli/backend/src/services/task-pool/pool-storage.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +41 -1
- 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 +55 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.d.ts +7 -0
- package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.js +17 -0
- package/dist/cli/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts +279 -0
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -0
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js +458 -0
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js.map +1 -0
- package/dist/cli/backend/src/services/v3/ticket-intake.service.d.ts +376 -0
- package/dist/cli/backend/src/services/v3/ticket-intake.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/v3/ticket-intake.service.js +566 -0
- package/dist/cli/backend/src/services/v3/ticket-intake.service.js.map +1 -0
- package/dist/cli/backend/src/types/slack.types.d.ts +29 -0
- package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/slack.types.js.map +1 -1
- package/dist/cli/backend/src/types/thread-status.types.d.ts +26 -0
- package/dist/cli/backend/src/types/thread-status.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/thread-status.types.js +17 -0
- package/dist/cli/backend/src/types/thread-status.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/index.d.ts +3 -2
- package/dist/cli/backend/src/types/v2/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/index.js +1 -1
- package/dist/cli/backend/src/types/v2/index.js.map +1 -1
- package/dist/cli/backend/src/types/v2/request.types.d.ts +39 -3
- package/dist/cli/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/request.types.js +11 -2
- package/dist/cli/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/ticket.types.d.ts +173 -0
- package/dist/cli/backend/src/types/v2/ticket.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/v2/ticket.types.js +203 -0
- package/dist/cli/backend/src/types/v2/ticket.types.js.map +1 -0
- package/dist/cli/backend/src/utils/gemini-auth-settings.d.ts +62 -0
- package/dist/cli/backend/src/utils/gemini-auth-settings.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/gemini-auth-settings.js +104 -0
- package/dist/cli/backend/src/utils/gemini-auth-settings.js.map +1 -0
- package/dist/cli/backend/src/utils/local-api-url.utils.d.ts +56 -0
- package/dist/cli/backend/src/utils/local-api-url.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/local-api-url.utils.js +80 -0
- package/dist/cli/backend/src/utils/local-api-url.utils.js.map +1 -0
- package/dist/cli/cli/src/commands/doctor.d.ts +73 -2
- package/dist/cli/cli/src/commands/doctor.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/doctor.js +250 -8
- package/dist/cli/cli/src/commands/doctor.js.map +1 -1
- package/dist/cli/cli/src/commands/install.js +2 -0
- package/dist/cli/cli/src/commands/install.js.map +1 -1
- package/dist/cli/cli/src/commands/onboard.d.ts +68 -0
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +149 -18
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/dist/cli/cli/src/commands/service.d.ts +6 -0
- package/dist/cli/cli/src/commands/service.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/service.js +152 -50
- package/dist/cli/cli/src/commands/service.js.map +1 -1
- package/dist/cli/cli/src/commands/start.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/start.js +25 -80
- package/dist/cli/cli/src/commands/start.js.map +1 -1
- package/dist/cli/cli/src/commands/status.d.ts +17 -1
- package/dist/cli/cli/src/commands/status.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/status.js +133 -68
- package/dist/cli/cli/src/commands/status.js.map +1 -1
- package/dist/cli/cli/src/commands/stop.d.ts +28 -1
- package/dist/cli/cli/src/commands/stop.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/stop.js +260 -100
- package/dist/cli/cli/src/commands/stop.js.map +1 -1
- package/dist/cli/cli/src/index.js +3 -2
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/cli/src/scripts/ensure-node-pty.d.ts +68 -0
- package/dist/cli/cli/src/scripts/ensure-node-pty.d.ts.map +1 -0
- package/dist/cli/cli/src/scripts/ensure-node-pty.js +167 -0
- package/dist/cli/cli/src/scripts/ensure-node-pty.js.map +1 -0
- package/dist/cli/cli/src/utils/backend-status.d.ts +175 -0
- package/dist/cli/cli/src/utils/backend-status.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/backend-status.js +322 -0
- package/dist/cli/cli/src/utils/backend-status.js.map +1 -0
- package/dist/cli/cli/src/utils/marketplace.d.ts +31 -2
- package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/marketplace.js +78 -20
- package/dist/cli/cli/src/utils/marketplace.js.map +1 -1
- package/dist/cli/cli/src/utils/native-toolchain.d.ts +53 -8
- package/dist/cli/cli/src/utils/native-toolchain.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/native-toolchain.js +107 -15
- package/dist/cli/cli/src/utils/native-toolchain.js.map +1 -1
- package/dist/cli/cli/src/utils/process-cleanup.d.ts +38 -6
- package/dist/cli/cli/src/utils/process-cleanup.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/process-cleanup.js +83 -53
- package/dist/cli/cli/src/utils/process-cleanup.js.map +1 -1
- package/dist/cli/cli/src/utils/runtime-auth.d.ts +130 -0
- package/dist/cli/cli/src/utils/runtime-auth.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/runtime-auth.js +248 -0
- package/dist/cli/cli/src/utils/runtime-auth.js.map +1 -0
- package/dist/cli/cli/src/utils/safe-shutdown.d.ts +137 -0
- package/dist/cli/cli/src/utils/safe-shutdown.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/safe-shutdown.js +236 -0
- package/dist/cli/cli/src/utils/safe-shutdown.js.map +1 -0
- package/dist/cli/config/constants.d.ts +40 -0
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +41 -0
- package/dist/cli/config/constants.js.map +1 -1
- package/dist/cli/config/index.d.ts +4 -2
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -2
- package/dist/cli/config/index.js.map +1 -1
- package/frontend/dist/assets/{index-488339c1.js → index-f7b99e81.js} +222 -222
- package/frontend/dist/index.html +1 -1
- package/package.json +4 -4
|
@@ -16,6 +16,7 @@ import { fileURLToPath } from 'url';
|
|
|
16
16
|
import { StorageService, TmuxService, SchedulerService, MessageSchedulerService, ActivityMonitorService, TeamActivityWebSocketService, TeamsJsonWatcherService, } from './services/index.js';
|
|
17
17
|
import { getSessionBackend, getSessionBackendSync, getSessionStatePersistence, destroySessionBackend, PtySessionBackend, } from './services/session/index.js';
|
|
18
18
|
import { RuntimePidRegistry } from './services/session/runtime-pid-registry.service.js';
|
|
19
|
+
import { removeCrewlyAgentFile, resolvePersistedSessions, selectAutoRestoreSessions } from './services/session/session-binding.js';
|
|
19
20
|
import { ApiController } from './controllers/api.controller.js';
|
|
20
21
|
import { createApiRoutes } from './routes/api.routes.js';
|
|
21
22
|
import { TerminalGateway, setTerminalGateway } from './websocket/terminal.gateway.js';
|
|
@@ -57,7 +58,15 @@ import { setRequestServiceEventBus, RequestService } from './services/v3/request
|
|
|
57
58
|
import { getSlackService } from './services/slack/slack.service.js';
|
|
58
59
|
import { sendBootAnnouncement, isFirstBoot, markBooted } from './services/boot/boot-announce.service.js';
|
|
59
60
|
import { SubAgentMessageQueue } from './services/messaging/sub-agent-message-queue.service.js';
|
|
60
|
-
import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS } from './constants.js';
|
|
61
|
+
import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS } from './constants.js';
|
|
62
|
+
import { PtyActivityTrackerService } from './services/agent/pty-activity-tracker.service.js';
|
|
63
|
+
import { InFlightTurnTracker } from './services/restart/in-flight-turn-tracker.service.js';
|
|
64
|
+
import { TicketIntakeService, setTicketIntakeService, resolveTicketIdForSession, } from './services/v3/ticket-intake.service.js';
|
|
65
|
+
import { createChatV2ReceiptSink } from './services/v3/ticket-channel-hooks.js';
|
|
66
|
+
import { runPoolArchiveMigration } from './services/task-pool/pool-archive-migration.js';
|
|
67
|
+
import { createPtyTurnProbe } from './services/restart/turn-probe.js';
|
|
68
|
+
import { RestartDrainService, resolveRestartDrainMs } from './services/restart/restart-drain.service.js';
|
|
69
|
+
import { interruptedTurnsPath, loadInterruptedTurns, saveInterruptedTurns, writeInterruptedTurns, resumeInterruptedTurns, } from './services/restart/interrupted-turns.js';
|
|
61
70
|
import { DeviceIdentityService } from './services/cloud/device-identity.service.js';
|
|
62
71
|
import { SlackThreadStoreService, setSlackThreadStore, getSlackThreadStore } from './services/slack/slack-thread-store.service.js';
|
|
63
72
|
import { GoogleChatThreadStoreService, setGchatThreadStore } from './services/messaging/gchat-thread-store.service.js';
|
|
@@ -86,6 +95,7 @@ import { ContextWindowMonitorService } from './services/agent/context-window-mon
|
|
|
86
95
|
import { OAuthReloginMonitorService } from './services/agent/oauth-relogin-monitor.service.js';
|
|
87
96
|
import { getChatV2Service } from './services/chat-v2/chat-v2.singleton.js';
|
|
88
97
|
import { findPackageRoot } from './utils/package-root.js';
|
|
98
|
+
import { getLocalApiBaseUrl, setLocalApiPort } from './utils/local-api-url.utils.js';
|
|
89
99
|
import { assertBuildProvenance } from './utils/build-provenance.js';
|
|
90
100
|
import { isNativeBindingFatalError } from './utils/native-binding.utils.js';
|
|
91
101
|
import { VersionCheckService } from './services/system/version-check.service.js';
|
|
@@ -101,7 +111,7 @@ import { FissionGuardService, createFailOpenBudgetChecker } from './services/fis
|
|
|
101
111
|
import { BudgetService } from './services/autonomous/budget.service.js';
|
|
102
112
|
import { setFissionGuardService } from './controllers/fission/fission.controller.js';
|
|
103
113
|
import { TaskPoolService } from './services/task-pool/task-pool.service.js';
|
|
104
|
-
import {
|
|
114
|
+
import { sessionsToRestore } from './services/agent/restore-filter.js';
|
|
105
115
|
import { ProjectMemoryService } from './services/memory/project-memory.service.js';
|
|
106
116
|
import { TaskHistorySubscriber } from './services/memory/task-history.subscriber.js';
|
|
107
117
|
import { TeamHealthWatchdogService, LiveTeamHealthDataProvider, loadTeamHealthConfig, setTeamHealthWatchdogSingleton, getTeamHealthWatchdogSingleton, } from './services/team-health/index.js';
|
|
@@ -192,6 +202,10 @@ export class CrewlyServer {
|
|
|
192
202
|
chatV2Dispatcher = null;
|
|
193
203
|
// Shutdown state
|
|
194
204
|
isShuttingDown = false;
|
|
205
|
+
/** Epoch ms of the last shutdown signal acted on (dedups process-group delivery) */
|
|
206
|
+
lastShutdownSignalAt = 0;
|
|
207
|
+
/** Interrupted turns loaded at boot, resumed once their agents are back */
|
|
208
|
+
interruptedTurnsAtBoot = [];
|
|
195
209
|
healthMonitoringInterval = null;
|
|
196
210
|
constructor(config) {
|
|
197
211
|
// Resolve ~ to actual home directory
|
|
@@ -206,7 +220,7 @@ export class CrewlyServer {
|
|
|
206
220
|
};
|
|
207
221
|
const defaultAgentmuxHome = config?.crewlyHome || process.env.CREWLY_HOME || '~/.crewly';
|
|
208
222
|
this.config = {
|
|
209
|
-
webPort: config?.webPort || parseIntWithFallback(process.env.WEB_PORT,
|
|
223
|
+
webPort: config?.webPort || parseIntWithFallback(process.env.WEB_PORT, WEB_CONSTANTS.PORTS.BACKEND, 'WEB_PORT'),
|
|
210
224
|
crewlyHome: resolveHomePath(defaultAgentmuxHome),
|
|
211
225
|
defaultCheckInterval: config?.defaultCheckInterval ||
|
|
212
226
|
parseIntWithFallback(process.env.DEFAULT_CHECK_INTERVAL, 30, 'DEFAULT_CHECK_INTERVAL'),
|
|
@@ -216,6 +230,9 @@ export class CrewlyServer {
|
|
|
216
230
|
process.env[API_SECURITY_CONSTANTS.ENV.BIND_HOST] ||
|
|
217
231
|
API_SECURITY_CONSTANTS.DEFAULT_BIND_HOST,
|
|
218
232
|
};
|
|
233
|
+
// Single source of truth for "where is this instance's API": agents get
|
|
234
|
+
// it as CREWLY_API_URL and internal self-calls use it (#777).
|
|
235
|
+
setLocalApiPort(this.config.webPort);
|
|
219
236
|
this.app = express();
|
|
220
237
|
this.httpServer = createServer(this.app);
|
|
221
238
|
this.io = new SocketIOServer(this.httpServer, {
|
|
@@ -367,6 +384,53 @@ export class CrewlyServer {
|
|
|
367
384
|
// that data. The setter is duck-typed on IWorkItemQueryable so
|
|
368
385
|
// neither side needs a static import of the other.
|
|
369
386
|
RequestService.getInstance().setTaskPoolService(TaskPoolService.getInstance());
|
|
387
|
+
// Ticket loop (specs/ticket-loop.md, Phase 1): the single intake for
|
|
388
|
+
// owner messages on every channel, the chat-v2 receipt poster (the
|
|
389
|
+
// Slack one is wired in slack-initializer once Slack is up), and the
|
|
390
|
+
// WorkItem → ticket link through the creating agent's in-flight turn.
|
|
391
|
+
// Failure-isolated: tickets are an addition — messages are delivered
|
|
392
|
+
// whether or not this is wired.
|
|
393
|
+
try {
|
|
394
|
+
const ticketIntake = new TicketIntakeService({
|
|
395
|
+
requests: RequestService.getInstance(),
|
|
396
|
+
findWorkItem: (id) => TaskPoolService.getInstance().findWorkItem(id),
|
|
397
|
+
});
|
|
398
|
+
ticketIntake.setReceiptSink('chat-v2', createChatV2ReceiptSink({
|
|
399
|
+
chat: {
|
|
400
|
+
recordTurn: (input) => getChatV2Service().recordTurn(input),
|
|
401
|
+
updateSystemMessage: (id, content, patch) => getChatV2Service().updateSystemMessage(id, content, patch),
|
|
402
|
+
},
|
|
403
|
+
// Lazy, like the rest of the chat-v2 realtime wiring (the gateway
|
|
404
|
+
// only exists once the HTTP server is up).
|
|
405
|
+
broadcast: (message) => {
|
|
406
|
+
void Promise.all([
|
|
407
|
+
import('./services/chat-v2/chat-v2.realtime-holder.js'),
|
|
408
|
+
import('./websocket/chat-v2.gateway.js'),
|
|
409
|
+
])
|
|
410
|
+
.then(([{ getChatV2RealtimeDeps }, { buildMessageEvent }]) => {
|
|
411
|
+
getChatV2RealtimeDeps().gateway?.broadcast(message.channelId, buildMessageEvent(message.channelId, message));
|
|
412
|
+
})
|
|
413
|
+
.catch(() => undefined);
|
|
414
|
+
},
|
|
415
|
+
}));
|
|
416
|
+
setTicketIntakeService(ticketIntake);
|
|
417
|
+
TaskPoolService.getInstance().setTicketResolver((sessionName) => resolveTicketIdForSession(InFlightTurnTracker.getInstance(), sessionName));
|
|
418
|
+
}
|
|
419
|
+
catch (ticketBootErr) {
|
|
420
|
+
this.logger.error('Ticket intake boot failed — messages are still delivered, no tickets filed', {
|
|
421
|
+
error: ticketBootErr instanceof Error ? ticketBootErr.message : String(ticketBootErr),
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
// Ticket loop §4: one-time archive of old WorkItems (marker file makes
|
|
425
|
+
// it run once). Through the pool's own storage cache, so no later
|
|
426
|
+
// flush can write the archived items back. Never deletes.
|
|
427
|
+
void runPoolArchiveMigration(TaskPoolService.getInstance().getStorage(), {
|
|
428
|
+
logger: LoggerService.getInstance().createComponentLogger('PoolArchive'),
|
|
429
|
+
}).catch((archiveErr) => {
|
|
430
|
+
this.logger.warn('Task pool one-time archive failed (pool left as is; retried next boot)', {
|
|
431
|
+
error: archiveErr instanceof Error ? archiveErr.message : String(archiveErr),
|
|
432
|
+
});
|
|
433
|
+
});
|
|
370
434
|
// Atlas 2026-05-23 fix: wire the agent-liveness gate so claimFromPool /
|
|
371
435
|
// claimSpecificItem refuse to put a WI into `running` when the requesting
|
|
372
436
|
// agent's session is dead. delegate-task's "self-heal fix #1" used to
|
|
@@ -856,6 +920,7 @@ export class CrewlyServer {
|
|
|
856
920
|
}
|
|
857
921
|
}
|
|
858
922
|
});
|
|
923
|
+
this.wireSafeRestart();
|
|
859
924
|
// Shared LiveReconcilerDataProvider instance used by both the
|
|
860
925
|
// Reconciler service and the TeamHealthWatchdog data provider.
|
|
861
926
|
// Sharing is required so the memory-pressure broadcast state
|
|
@@ -1058,7 +1123,7 @@ export class CrewlyServer {
|
|
|
1058
1123
|
// CORS — allow Cloud Console frontend and localhost OSS instances
|
|
1059
1124
|
const CORS_ALLOWED_ORIGINS = process.env['CORS_ALLOWED_ORIGINS']
|
|
1060
1125
|
? process.env['CORS_ALLOWED_ORIGINS'].split(',')
|
|
1061
|
-
: ['https://crewlyai.com', 'https://www.crewlyai.com',
|
|
1126
|
+
: ['https://crewlyai.com', 'https://www.crewlyai.com', getLocalApiBaseUrl(), 'http://localhost:3000'];
|
|
1062
1127
|
this.app.use(cors({
|
|
1063
1128
|
origin: process.env.NODE_ENV === 'production'
|
|
1064
1129
|
? CORS_ALLOWED_ORIGINS
|
|
@@ -1330,7 +1395,7 @@ export class CrewlyServer {
|
|
|
1330
1395
|
command: sessionInfo.command,
|
|
1331
1396
|
args: sessionInfo.args,
|
|
1332
1397
|
env: sessionInfo.env,
|
|
1333
|
-
}, sessionInfo.runtimeType, sessionInfo.role, sessionInfo.teamId);
|
|
1398
|
+
}, sessionInfo.runtimeType, sessionInfo.role, sessionInfo.teamId, sessionInfo.memberId);
|
|
1334
1399
|
if (sessionInfo.claudeSessionId) {
|
|
1335
1400
|
persistence.updateSessionId(sessionInfo.name, sessionInfo.claudeSessionId);
|
|
1336
1401
|
}
|
|
@@ -1339,6 +1404,7 @@ export class CrewlyServer {
|
|
|
1339
1404
|
count: savedState.sessions.length,
|
|
1340
1405
|
sessionsWithResumeId: savedState.sessions.filter(s => s.claudeSessionId).length,
|
|
1341
1406
|
});
|
|
1407
|
+
await this.pruneUnboundPersistedSessions(savedState.sessions);
|
|
1342
1408
|
}
|
|
1343
1409
|
}
|
|
1344
1410
|
catch (loadError) {
|
|
@@ -1529,24 +1595,20 @@ export class CrewlyServer {
|
|
|
1529
1595
|
// The capturer is injected rather than imported by the session
|
|
1530
1596
|
// service so transport selection (direct WS vs relay) stays in
|
|
1531
1597
|
// one place — here and in the browser controller.
|
|
1532
|
-
const { getBrowserSessions } = await import('./services/browser/browser-session.service.js');
|
|
1598
|
+
const { getBrowserSessions, createBoundTabCapturer } = await import('./services/browser/browser-session.service.js');
|
|
1533
1599
|
const browserSessions = getBrowserSessions();
|
|
1534
|
-
browserSessions.setCapturer(
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
}
|
|
1544
|
-
else {
|
|
1600
|
+
browserSessions.setCapturer(createBoundTabCapturer({
|
|
1601
|
+
getBoundTabId: (agentSession) => browserBridge.getBinding(agentSession)?.tabId,
|
|
1602
|
+
sendScreenshot: async (params) => {
|
|
1603
|
+
const { BrowserProxyService } = await import('./services/browser/browser-proxy.service.js');
|
|
1604
|
+
const proxy = BrowserProxyService.getInstance();
|
|
1605
|
+
if (browserBridge.isConnected())
|
|
1606
|
+
return browserBridge.sendCommand('screenshot', params);
|
|
1607
|
+
if (proxy.isAvailable())
|
|
1608
|
+
return proxy.sendCommand('screenshot', params);
|
|
1545
1609
|
return null;
|
|
1546
|
-
}
|
|
1547
|
-
|
|
1548
|
-
return result ?? null;
|
|
1549
|
-
});
|
|
1610
|
+
},
|
|
1611
|
+
}));
|
|
1550
1612
|
browserSessions.start();
|
|
1551
1613
|
// Let the browser controller reach agents, so taking the wheel
|
|
1552
1614
|
// and answering a held action actually tell the agent what
|
|
@@ -2401,10 +2463,16 @@ export class CrewlyServer {
|
|
|
2401
2463
|
error: err instanceof Error ? err.message : String(err),
|
|
2402
2464
|
});
|
|
2403
2465
|
}
|
|
2466
|
+
// Turns a previous shutdown cut off (see services/restart). Loaded
|
|
2467
|
+
// before restore so their agents count as having work in hand.
|
|
2468
|
+
this.loadInterruptedTurnsAtBoot();
|
|
2404
2469
|
// Auto-start orchestrator if enabled in settings
|
|
2405
2470
|
await this.autoStartOrchestratorIfEnabled();
|
|
2406
2471
|
// Auto-restore agent sessions that were running before the last shutdown
|
|
2407
2472
|
await this.autoRestoreAgentSessionsIfEnabled();
|
|
2473
|
+
// Re-deliver interrupted turns now that their agents are coming back.
|
|
2474
|
+
// Background: the orchestrator may take minutes to register.
|
|
2475
|
+
void this.resumeInterruptedTurnsAfterBoot();
|
|
2408
2476
|
// #166: Auto-recover in-progress tasks after restart.
|
|
2409
2477
|
// #196: Skip tasks older than 1 hour to avoid re-sending stale work.
|
|
2410
2478
|
// V3-only as of spec 2026-05-06-task-management-v1-deprecation.md —
|
|
@@ -2713,6 +2781,9 @@ export class CrewlyServer {
|
|
|
2713
2781
|
maxAttempts: MAX_AUTOSTART_ATTEMPTS,
|
|
2714
2782
|
backoffMs: AUTOSTART_BACKOFF_MS,
|
|
2715
2783
|
isSuccess: r => r.success,
|
|
2784
|
+
// A start-up blocked on the user (Claude Code as root, or never
|
|
2785
|
+
// set up) cannot succeed on retry: stop and report it once.
|
|
2786
|
+
shouldStop: r => r.errorCode === CLAUDE_STARTUP_CONSTANTS.BLOCKED_ERROR_CODE,
|
|
2716
2787
|
onRetry: ({ attempt, maxAttempts, retryInMs, result: r }) => {
|
|
2717
2788
|
this.logger.warn('Auto-start orchestrator failed to create session — retrying', {
|
|
2718
2789
|
error: r.error,
|
|
@@ -2728,8 +2799,11 @@ export class CrewlyServer {
|
|
|
2728
2799
|
// a benign skip. The orchestrator stays inactive; recovery now
|
|
2729
2800
|
// falls to the reconciler's hybrid-wake on the next queued
|
|
2730
2801
|
// inbound WorkItem (#679 routing fix).
|
|
2731
|
-
this.logger.error(
|
|
2802
|
+
this.logger.error(result.errorCode === CLAUDE_STARTUP_CONSTANTS.BLOCKED_ERROR_CODE
|
|
2803
|
+
? 'Auto-start orchestrator BLOCKED — needs user action; orchestrator is INACTIVE'
|
|
2804
|
+
: 'Auto-start orchestrator FAILED after all retries — orchestrator is INACTIVE', {
|
|
2732
2805
|
error: result.error,
|
|
2806
|
+
errorCode: result.errorCode,
|
|
2733
2807
|
attempts: MAX_AUTOSTART_ATTEMPTS,
|
|
2734
2808
|
});
|
|
2735
2809
|
return;
|
|
@@ -2812,6 +2886,43 @@ export class CrewlyServer {
|
|
|
2812
2886
|
// Don't fail startup if auto-start fails
|
|
2813
2887
|
}
|
|
2814
2888
|
}
|
|
2889
|
+
/**
|
|
2890
|
+
* Drop persisted team sessions whose name no team member is bound to.
|
|
2891
|
+
*
|
|
2892
|
+
* session-state.json caches what was running; the team config is the
|
|
2893
|
+
* source of truth for each member's session name. An entry left under a
|
|
2894
|
+
* member's old name (it was renamed) would otherwise stay in the Resume
|
|
2895
|
+
* dialog and could be relaunched, running the member twice. Each unbound
|
|
2896
|
+
* entry is unregistered (rewriting the state file without it) and its
|
|
2897
|
+
* generated Claude Code agent file is removed. Failure to read the teams,
|
|
2898
|
+
* or an empty team list, prunes nothing.
|
|
2899
|
+
*
|
|
2900
|
+
* @param sessions - Entries loaded from session-state.json.
|
|
2901
|
+
*/
|
|
2902
|
+
async pruneUnboundPersistedSessions(sessions) {
|
|
2903
|
+
try {
|
|
2904
|
+
const teams = await this.storageService.getTeams();
|
|
2905
|
+
// No teams at all is indistinguishable from a failed read: prune
|
|
2906
|
+
// nothing rather than drop every member's resume entry.
|
|
2907
|
+
if (teams.length === 0)
|
|
2908
|
+
return;
|
|
2909
|
+
const { unbound, rebound } = resolvePersistedSessions(sessions, teams);
|
|
2910
|
+
if (unbound.length === 0)
|
|
2911
|
+
return;
|
|
2912
|
+
const persistence = getSessionStatePersistence();
|
|
2913
|
+
const byName = new Map(sessions.map((s) => [s.name, s]));
|
|
2914
|
+
for (const name of unbound) {
|
|
2915
|
+
persistence.unregisterSession(name);
|
|
2916
|
+
await removeCrewlyAgentFile(byName.get(name)?.cwd, name);
|
|
2917
|
+
}
|
|
2918
|
+
this.logger.warn('Pruned persisted sessions whose name no team member is bound to', { unbound, rebound });
|
|
2919
|
+
}
|
|
2920
|
+
catch (error) {
|
|
2921
|
+
this.logger.warn('Could not check persisted sessions against team bindings (nothing pruned)', {
|
|
2922
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2923
|
+
});
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2815
2926
|
/**
|
|
2816
2927
|
* Auto-restore agent sessions that were running before the last shutdown.
|
|
2817
2928
|
* Loads persisted session state and calls createAgentSession() for each
|
|
@@ -2843,41 +2954,50 @@ export class CrewlyServer {
|
|
|
2843
2954
|
return false;
|
|
2844
2955
|
return true;
|
|
2845
2956
|
});
|
|
2846
|
-
//
|
|
2847
|
-
//
|
|
2848
|
-
//
|
|
2849
|
-
//
|
|
2850
|
-
// back. Now: only restore a session if the pool has at least one
|
|
2851
|
-
// non-terminal WorkItem with `target === sessionName`. Idle
|
|
2852
|
-
// agents stay dead until orc dispatches new work, at which point
|
|
2853
|
-
// the dispatcher / wake path raises them on demand.
|
|
2957
|
+
// Relaunch team members only under the session name the team config
|
|
2958
|
+
// binds them to: a persisted entry under a stale name (the member was
|
|
2959
|
+
// renamed) is rebound through its memberId or dropped, never launched
|
|
2960
|
+
// under the stale name. Then gate by task-pool work.
|
|
2854
2961
|
//
|
|
2855
|
-
//
|
|
2856
|
-
//
|
|
2857
|
-
//
|
|
2858
|
-
//
|
|
2859
|
-
|
|
2962
|
+
// Work gate: only restore a session with work in hand (see
|
|
2963
|
+
// restore-filter) or whose turn the last restart cut off. Idle agents
|
|
2964
|
+
// stay down until work or a message wakes them (PR #574/#585).
|
|
2965
|
+
// Safety valve: if the pool lookup throws (e.g. SQLite not yet open
|
|
2966
|
+
// during early boot), skip the gate rather than strand work.
|
|
2967
|
+
let teams = null;
|
|
2860
2968
|
try {
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
});
|
|
2875
|
-
}
|
|
2876
|
-
agentSessions = filtered;
|
|
2969
|
+
teams = await this.storageService.getTeams();
|
|
2970
|
+
}
|
|
2971
|
+
catch (bindErr) {
|
|
2972
|
+
this.logger.warn('Auto-restore could not read team bindings; restoring only non-team sessions', {
|
|
2973
|
+
error: bindErr instanceof Error ? bindErr.message : String(bindErr),
|
|
2974
|
+
});
|
|
2975
|
+
}
|
|
2976
|
+
let targets = null;
|
|
2977
|
+
try {
|
|
2978
|
+
const allItems = await TaskPoolService.getInstance().getAllItems();
|
|
2979
|
+
// Work in hand only: active statuses, touched recently (see restore-filter),
|
|
2980
|
+
// plus agents whose turn the last restart cut off.
|
|
2981
|
+
targets = sessionsToRestore(allItems, this.interruptedTurnsAtBoot.map((t) => t.sessionName));
|
|
2877
2982
|
}
|
|
2878
2983
|
catch (poolErr) {
|
|
2879
2984
|
this.logger.warn('Auto-restore could not query task pool; falling back to restoring every persisted session', { error: poolErr instanceof Error ? poolErr.message : String(poolErr) });
|
|
2880
2985
|
}
|
|
2986
|
+
const selection = selectAutoRestoreSessions({ sessions: baselineSessions, teams, targets });
|
|
2987
|
+
if (selection.unbound.length > 0) {
|
|
2988
|
+
this.logger.warn('Not auto-restoring sessions whose name no team member is bound to', {
|
|
2989
|
+
unbound: selection.unbound,
|
|
2990
|
+
rebound: selection.rebound,
|
|
2991
|
+
});
|
|
2992
|
+
}
|
|
2993
|
+
if (selection.skippedNoWork.length > 0) {
|
|
2994
|
+
this.logger.info('Skipping auto-restore for sessions with no work in hand (idle agents stay down until work or a message wakes them)', {
|
|
2995
|
+
skippedCount: selection.skippedNoWork.length,
|
|
2996
|
+
skipped: selection.skippedNoWork.slice(0, 20),
|
|
2997
|
+
truncated: selection.skippedNoWork.length > 20,
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
const agentSessions = selection.sessions;
|
|
2881
3001
|
if (agentSessions.length === 0) {
|
|
2882
3002
|
this.logger.info('No persisted agent sessions to restore (all idle, no pending WorkItems)');
|
|
2883
3003
|
return;
|
|
@@ -3132,25 +3252,14 @@ export class CrewlyServer {
|
|
|
3132
3252
|
sigintCount = 0;
|
|
3133
3253
|
registerSignalHandlers() {
|
|
3134
3254
|
this.logger.info('Registering signal handlers...');
|
|
3135
|
-
process.on('SIGTERM', () =>
|
|
3136
|
-
|
|
3137
|
-
this.shutdown();
|
|
3138
|
-
});
|
|
3139
|
-
process.on('SIGINT', () => {
|
|
3140
|
-
this.sigintCount++;
|
|
3141
|
-
if (this.sigintCount === 1) {
|
|
3142
|
-
this.logger.info('Received SIGINT signal (Ctrl+C) - shutting down gracefully. Press Ctrl+C again to force exit.');
|
|
3143
|
-
this.shutdown();
|
|
3144
|
-
}
|
|
3145
|
-
else {
|
|
3146
|
-
this.logger.info('Received second SIGINT - forcing immediate exit');
|
|
3147
|
-
process.exit(1);
|
|
3148
|
-
}
|
|
3149
|
-
});
|
|
3255
|
+
process.on('SIGTERM', () => this.handleShutdownSignal('SIGTERM'));
|
|
3256
|
+
process.on('SIGINT', () => this.handleShutdownSignal('SIGINT'));
|
|
3150
3257
|
process.on('uncaughtException', (error) => {
|
|
3151
3258
|
this.logger.error('Uncaught exception', { error: error.message, stack: error.stack });
|
|
3152
3259
|
this.logMemoryUsage();
|
|
3153
|
-
|
|
3260
|
+
// A crashing process should not linger for the drain; its in-flight
|
|
3261
|
+
// turns are still persisted and resumed after the restart.
|
|
3262
|
+
this.shutdown({ reason: 'uncaughtException', drain: false });
|
|
3154
3263
|
});
|
|
3155
3264
|
process.on('unhandledRejection', (reason, promise) => {
|
|
3156
3265
|
const message = unhandledRejectionMessage(reason);
|
|
@@ -3170,9 +3279,168 @@ export class CrewlyServer {
|
|
|
3170
3279
|
stack: reason instanceof Error ? reason.stack : undefined
|
|
3171
3280
|
});
|
|
3172
3281
|
this.logMemoryUsage();
|
|
3173
|
-
this.shutdown();
|
|
3282
|
+
this.shutdown({ reason: 'unhandledRejection', drain: false });
|
|
3174
3283
|
});
|
|
3175
3284
|
}
|
|
3285
|
+
/**
|
|
3286
|
+
* Handle SIGTERM / SIGINT with safe-restart semantics.
|
|
3287
|
+
*
|
|
3288
|
+
* - First signal: graceful shutdown, which first drains in-flight agent turns.
|
|
3289
|
+
* - A repeat within SIGNAL_DEDUP_WINDOW_MS is the same request arriving twice
|
|
3290
|
+
* (Ctrl+C reaches the whole process group, and the CLI parent forwards it
|
|
3291
|
+
* too) and is ignored.
|
|
3292
|
+
* - A later repeat during the drain skips the wait; interrupted turns are
|
|
3293
|
+
* persisted and resumed after the restart.
|
|
3294
|
+
* - A later SIGINT after the drain forces an immediate exit, as before.
|
|
3295
|
+
*
|
|
3296
|
+
* @param signal - The signal received
|
|
3297
|
+
*/
|
|
3298
|
+
handleShutdownSignal(signal) {
|
|
3299
|
+
const now = Date.now();
|
|
3300
|
+
if (!this.isShuttingDown) {
|
|
3301
|
+
this.lastShutdownSignalAt = now;
|
|
3302
|
+
this.logger.info(`Received ${signal} — shutting down; in-flight agent turns are drained first. Send ${signal} again to stop waiting.`);
|
|
3303
|
+
void this.shutdown({ reason: signal });
|
|
3304
|
+
return;
|
|
3305
|
+
}
|
|
3306
|
+
if (now - this.lastShutdownSignalAt < SAFE_RESTART.SIGNAL_DEDUP_WINDOW_MS) {
|
|
3307
|
+
this.logger.debug(`Duplicate ${signal} ignored (same shutdown request)`);
|
|
3308
|
+
return;
|
|
3309
|
+
}
|
|
3310
|
+
this.lastShutdownSignalAt = now;
|
|
3311
|
+
if (RestartDrainService.getInstance().requestSkip(`second ${signal}`)) {
|
|
3312
|
+
return;
|
|
3313
|
+
}
|
|
3314
|
+
if (signal === 'SIGINT') {
|
|
3315
|
+
this.sigintCount++;
|
|
3316
|
+
this.logger.info('Received another SIGINT after the drain - forcing immediate exit');
|
|
3317
|
+
process.exit(1);
|
|
3318
|
+
}
|
|
3319
|
+
this.logger.info(`Received ${signal} while shutdown is already past the drain; continuing`);
|
|
3320
|
+
}
|
|
3321
|
+
/**
|
|
3322
|
+
* Wire the safe-restart pieces: the turn probe, idle-event re-probing,
|
|
3323
|
+
* readiness queue counting, and the graceful-shutdown hook used by
|
|
3324
|
+
* POST /api/system/restart.
|
|
3325
|
+
*/
|
|
3326
|
+
wireSafeRestart() {
|
|
3327
|
+
const tracker = InFlightTurnTracker.getInstance();
|
|
3328
|
+
const activity = PtyActivityTrackerService.getInstance();
|
|
3329
|
+
tracker.setProbe(createPtyTurnProbe({
|
|
3330
|
+
getBackend: () => getSessionBackendSync(),
|
|
3331
|
+
getIdleTimeMs: (sessionName) => (activity.hasActivity(sessionName) ? activity.getIdleTimeMs(sessionName) : null),
|
|
3332
|
+
}));
|
|
3333
|
+
tracker.attachEventSource(this.eventBusService);
|
|
3334
|
+
const drain = RestartDrainService.getInstance();
|
|
3335
|
+
drain.setQueueCounter(() => this.messageQueueService.pendingCount + SubAgentMessageQueue.getInstance().getTotalQueued());
|
|
3336
|
+
drain.setShutdownHandler((request) => this.shutdown({ reason: request.reason, exitCode: request.exitCode }));
|
|
3337
|
+
}
|
|
3338
|
+
/**
|
|
3339
|
+
* Load interrupted turns left by the previous shutdown (fresh ones only).
|
|
3340
|
+
*/
|
|
3341
|
+
loadInterruptedTurnsAtBoot() {
|
|
3342
|
+
try {
|
|
3343
|
+
const file = interruptedTurnsPath(this.config.crewlyHome);
|
|
3344
|
+
const { fresh, dropped } = loadInterruptedTurns(file);
|
|
3345
|
+
this.interruptedTurnsAtBoot = fresh;
|
|
3346
|
+
if (dropped > 0) {
|
|
3347
|
+
this.logger.info('Dropped stale interrupted turns from the previous run', { dropped });
|
|
3348
|
+
}
|
|
3349
|
+
if (fresh.length > 0) {
|
|
3350
|
+
this.logger.info('Found turns interrupted by the last restart; their agents will be restored and resumed', {
|
|
3351
|
+
count: fresh.length,
|
|
3352
|
+
sessions: [...new Set(fresh.map((t) => t.sessionName))],
|
|
3353
|
+
});
|
|
3354
|
+
}
|
|
3355
|
+
else if (dropped > 0) {
|
|
3356
|
+
writeInterruptedTurns(file, []);
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
catch (error) {
|
|
3360
|
+
this.logger.warn('Could not read interrupted turns (non-fatal)', {
|
|
3361
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3362
|
+
});
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
/**
|
|
3366
|
+
* Re-deliver the turns the previous shutdown cut off, then clear the file.
|
|
3367
|
+
* The file is rewritten after each entry so a restart during this pass
|
|
3368
|
+
* neither loses nor repeats work.
|
|
3369
|
+
*/
|
|
3370
|
+
async resumeInterruptedTurnsAfterBoot() {
|
|
3371
|
+
const entries = this.interruptedTurnsAtBoot;
|
|
3372
|
+
if (entries.length === 0)
|
|
3373
|
+
return;
|
|
3374
|
+
this.interruptedTurnsAtBoot = [];
|
|
3375
|
+
const file = interruptedTurnsPath(this.config.crewlyHome);
|
|
3376
|
+
const registration = this.apiController.agentRegistrationService;
|
|
3377
|
+
try {
|
|
3378
|
+
const summary = await resumeInterruptedTurns(entries, {
|
|
3379
|
+
orchestratorSession: ORCHESTRATOR_SESSION_NAME,
|
|
3380
|
+
isSessionRunning: (name) => Boolean(getSessionBackendSync()?.sessionExists(name)) || Boolean(registration.getInProcessRuntime(name)),
|
|
3381
|
+
enqueue: (input) => {
|
|
3382
|
+
this.messageQueueService.enqueue(input);
|
|
3383
|
+
},
|
|
3384
|
+
sendMessageToAgent: (name, text) => registration.sendMessageToAgent(name, text),
|
|
3385
|
+
waitForOrchestratorActive: async () => {
|
|
3386
|
+
const deadline = Date.now() + SAFE_RESTART.RESUME_ORC_READY_TIMEOUT_MS;
|
|
3387
|
+
while (Date.now() < deadline) {
|
|
3388
|
+
if (this.isShuttingDown)
|
|
3389
|
+
return false;
|
|
3390
|
+
const status = await this.storageService.getOrchestratorStatus().catch(() => null);
|
|
3391
|
+
if (status?.agentStatus === CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE)
|
|
3392
|
+
return true;
|
|
3393
|
+
await new Promise((resolve) => setTimeout(resolve, SAFE_RESTART.RESUME_ORC_POLL_MS));
|
|
3394
|
+
}
|
|
3395
|
+
return false;
|
|
3396
|
+
},
|
|
3397
|
+
onEntryHandled: (_entry, remaining) => {
|
|
3398
|
+
try {
|
|
3399
|
+
writeInterruptedTurns(file, remaining);
|
|
3400
|
+
}
|
|
3401
|
+
catch {
|
|
3402
|
+
// Best-effort bookkeeping; the in-memory pass continues.
|
|
3403
|
+
}
|
|
3404
|
+
},
|
|
3405
|
+
logger: this.logger,
|
|
3406
|
+
});
|
|
3407
|
+
this.logger.info('Interrupted-turn resume complete', { ...summary });
|
|
3408
|
+
}
|
|
3409
|
+
catch (error) {
|
|
3410
|
+
this.logger.warn('Interrupted-turn resume failed (non-fatal)', {
|
|
3411
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3412
|
+
});
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
/**
|
|
3416
|
+
* Drain in-flight agent turns before the rest of shutdown, and persist
|
|
3417
|
+
* whatever is still mid-turn when the drain ends.
|
|
3418
|
+
*
|
|
3419
|
+
* @param reason - Why we are shutting down (signal or caller)
|
|
3420
|
+
* @param drainEnabled - False to skip the wait (crash paths)
|
|
3421
|
+
*/
|
|
3422
|
+
async drainInFlightTurns(reason, drainEnabled) {
|
|
3423
|
+
try {
|
|
3424
|
+
const drain = RestartDrainService.getInstance();
|
|
3425
|
+
drain.pauseDelivery(reason);
|
|
3426
|
+
const timeoutMs = drainEnabled ? resolveRestartDrainMs(process.env) : 0;
|
|
3427
|
+
const result = await drain.drain({ timeoutMs });
|
|
3428
|
+
if (result.remaining.length > 0) {
|
|
3429
|
+
const saved = saveInterruptedTurns(interruptedTurnsPath(this.config.crewlyHome), result.remaining, `${reason}: ${result.outcome}`);
|
|
3430
|
+
this.logger.warn('Persisted interrupted agent turns for resume after restart', {
|
|
3431
|
+
outcome: result.outcome,
|
|
3432
|
+
sessions: result.remaining.map((t) => t.sessionName),
|
|
3433
|
+
entries: saved,
|
|
3434
|
+
});
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
catch (error) {
|
|
3438
|
+
// Never let the drain block shutdown.
|
|
3439
|
+
this.logger.error('Restart drain failed; continuing shutdown', {
|
|
3440
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3176
3444
|
startHealthMonitoring() {
|
|
3177
3445
|
this.logger.info('Starting health monitoring...');
|
|
3178
3446
|
// Monitor memory usage every 30 seconds
|
|
@@ -3418,14 +3686,27 @@ export class CrewlyServer {
|
|
|
3418
3686
|
this.logger.warn('High memory usage detected', { heapUsedMB: heapUsed });
|
|
3419
3687
|
}
|
|
3420
3688
|
}
|
|
3421
|
-
|
|
3689
|
+
/**
|
|
3690
|
+
* Gracefully shut the server down.
|
|
3691
|
+
*
|
|
3692
|
+
* Drains in-flight agent turns first (see services/restart), while the
|
|
3693
|
+
* HTTP API is still up so agents can finish and reply; everything after
|
|
3694
|
+
* that runs under the hard force-exit timer.
|
|
3695
|
+
*
|
|
3696
|
+
* @param options - reason (for logs), drain=false to skip the wait, exitCode for process.exit
|
|
3697
|
+
*/
|
|
3698
|
+
async shutdown(options = {}) {
|
|
3422
3699
|
// Prevent double shutdown
|
|
3423
3700
|
if (this.isShuttingDown) {
|
|
3424
3701
|
this.logger.info('Shutdown already in progress, skipping...');
|
|
3425
3702
|
return;
|
|
3426
3703
|
}
|
|
3427
3704
|
this.isShuttingDown = true;
|
|
3428
|
-
|
|
3705
|
+
const exitCode = options.exitCode ?? PROCESS_EXIT_CODES.SUCCESS;
|
|
3706
|
+
this.logger.info('Shutting down Crewly server...', { reason: options.reason ?? 'unspecified' });
|
|
3707
|
+
// Safe restart: stop delivering, wait for agents mid-turn, persist the rest.
|
|
3708
|
+
// Runs before the force-exit timer below, which only bounds the teardown.
|
|
3709
|
+
await this.drainInFlightTurns(options.reason ?? 'shutdown', options.drain !== false);
|
|
3429
3710
|
// Set a hard timeout to force exit if graceful shutdown takes too long.
|
|
3430
3711
|
// Use SIGKILL on self as the ultimate fallback — this is uncatchable and
|
|
3431
3712
|
// guarantees death even if native node-pty handles keep the event loop alive.
|
|
@@ -3719,7 +4000,7 @@ export class CrewlyServer {
|
|
|
3719
4000
|
setTimeout(resolve, 3000);
|
|
3720
4001
|
});
|
|
3721
4002
|
clearTimeout(forceExitTimeout);
|
|
3722
|
-
process.exit(
|
|
4003
|
+
process.exit(exitCode);
|
|
3723
4004
|
}
|
|
3724
4005
|
catch (error) {
|
|
3725
4006
|
this.logger.error('Error during shutdown', { error: error instanceof Error ? error.message : String(error) });
|