crewly 1.2.4 → 1.2.6
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/LICENSE +1 -1
- package/config/constants.ts +4 -2
- package/config/roles/auditor/prompt.md +84 -0
- package/config/roles/orchestrator/prompt.md +62 -7
- package/config/runtime_scripts/runtime-config.json +5 -5
- package/config/skills/orchestrator/cancel-all-schedules/execute.sh +24 -0
- package/config/skills/orchestrator/cancel-all-schedules/instructions.md +23 -0
- package/config/skills/orchestrator/cancel-all-schedules/skill.json +17 -0
- package/config/skills/orchestrator/list-schedules/execute.sh +19 -0
- package/config/skills/orchestrator/list-schedules/instructions.md +24 -0
- package/config/skills/orchestrator/list-schedules/skill.json +12 -0
- package/dist/backend/backend/src/constants.d.ts +53 -13
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +54 -16
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/auditor/auditor.controller.d.ts +37 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.controller.js +64 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.routes.d.ts +15 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.routes.js +23 -0
- package/dist/backend/backend/src/controllers/auditor/auditor.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.d.ts +23 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.js +42 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin-auth.middleware.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.d.ts +56 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.js +173 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.d.ts +22 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.js +33 -0
- package/dist/backend/backend/src/controllers/cloud/admin/admin.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/index.d.ts +7 -0
- package/dist/backend/backend/src/controllers/cloud/admin/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/admin/index.js +7 -0
- package/dist/backend/backend/src/controllers/cloud/admin/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.d.ts +1 -1
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.js +5 -5
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +0 -3
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/index.d.ts +0 -5
- package/dist/backend/backend/src/controllers/cloud/index.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/index.js +0 -5
- package/dist/backend/backend/src/controllers/cloud/index.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts +6 -45
- package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/relay.controller.js +6 -165
- package/dist/backend/backend/src/controllers/cloud/relay.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/relay.routes.d.ts +5 -9
- package/dist/backend/backend/src/controllers/cloud/relay.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/relay.routes.js +11 -21
- package/dist/backend/backend/src/controllers/cloud/relay.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/tasks/index.d.ts +5 -2
- package/dist/backend/backend/src/controllers/cloud/tasks/index.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/tasks/index.js +5 -2
- package/dist/backend/backend/src/controllers/cloud/tasks/index.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts +6 -2
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js +12 -8
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +32 -4
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.controller.d.ts +16 -5
- package/dist/backend/backend/src/controllers/payment/payment.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.controller.js +6 -6
- package/dist/backend/backend/src/controllers/payment/payment.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts +6 -2
- package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.routes.js +22 -8
- package/dist/backend/backend/src/controllers/payment/payment.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.types.d.ts +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.types.js +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.types.js.map +1 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts +2 -2
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts +19 -0
- package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/scheduler.controller.js +51 -0
- package/dist/backend/backend/src/controllers/system/scheduler.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 +13 -5
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/template/template.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/template/template.controller.js +2 -2
- package/dist/backend/backend/src/controllers/template/template.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +31 -30
- 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 +4 -12
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/log-rotation.routes.d.ts +8 -0
- package/dist/backend/backend/src/routes/modules/log-rotation.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/routes/modules/log-rotation.routes.js +62 -0
- package/dist/backend/backend/src/routes/modules/log-rotation.routes.js.map +1 -0
- package/dist/backend/backend/src/routes/modules/scheduler.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/scheduler.routes.js +2 -0
- package/dist/backend/backend/src/routes/modules/scheduler.routes.js.map +1 -1
- package/dist/backend/backend/src/scripts/run-log-rotation.d.ts +3 -0
- package/dist/backend/backend/src/scripts/run-log-rotation.d.ts.map +1 -0
- package/dist/backend/backend/src/scripts/run-log-rotation.js +31 -0
- package/dist/backend/backend/src/scripts/run-log-rotation.js.map +1 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +10 -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 +85 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts +150 -0
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js +307 -0
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +105 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +199 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts +68 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js +131 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts +29 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +229 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +127 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +242 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts +95 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.js +130 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/in-process-log-buffer.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +14 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js +14 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +57 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +93 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts +13 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +91 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +29 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +519 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +159 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js +63 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -0
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +56 -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 +273 -215
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-service.factory.js +8 -8
- package/dist/backend/backend/src/services/agent/runtime-service.factory.js.map +1 -1
- package/dist/backend/backend/src/services/chat/chat.service.d.ts +7 -1
- package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat/chat.service.js +14 -5
- package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/admin-seed.service.d.ts +18 -0
- package/dist/backend/backend/src/services/cloud/admin-seed.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/admin-seed.service.js +50 -0
- package/dist/backend/backend/src/services/cloud/admin-seed.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-features.d.ts +19 -0
- package/dist/backend/backend/src/services/cloud/cloud-features.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-features.js +23 -0
- package/dist/backend/backend/src/services/cloud/cloud-features.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.d.ts +3 -3
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.js +10 -6
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mongodb.service.d.ts +45 -0
- package/dist/backend/backend/src/services/cloud/mongodb.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/mongodb.service.js +76 -0
- package/dist/backend/backend/src/services/cloud/mongodb.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-server.service.d.ts +0 -2
- package/dist/backend/backend/src/services/cloud/relay-server.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/relay-server.service.js +7 -36
- package/dist/backend/backend/src/services/cloud/relay-server.service.js.map +1 -1
- package/dist/backend/backend/src/services/continuation/continuation.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/continuation/continuation.service.js +5 -10
- package/dist/backend/backend/src/services/continuation/continuation.service.js.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +10 -2
- 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 +47 -12
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
- package/dist/backend/backend/src/services/mcp-server.js +1 -1
- package/dist/backend/backend/src/services/mcp-server.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/message-queue.service.js +1 -0
- package/dist/backend/backend/src/services/messaging/message-queue.service.js.map +1 -1
- 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 +22 -4
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +6 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
- package/dist/backend/backend/src/services/payment/stripe.service.d.ts +4 -43
- package/dist/backend/backend/src/services/payment/stripe.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/payment/stripe.service.js +56 -180
- package/dist/backend/backend/src/services/payment/stripe.service.js.map +1 -1
- package/dist/backend/backend/src/services/session/index.d.ts +2 -0
- package/dist/backend/backend/src/services/session/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/index.js +2 -0
- package/dist/backend/backend/src/services/session/index.js.map +1 -1
- package/dist/backend/backend/src/services/session/log-rotation.service.d.ts +163 -0
- package/dist/backend/backend/src/services/session/log-rotation.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/session/log-rotation.service.js +362 -0
- package/dist/backend/backend/src/services/session/log-rotation.service.js.map +1 -0
- package/dist/backend/backend/src/services/settings/settings.service.js +1 -1
- package/dist/backend/backend/src/services/settings/settings.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +11 -0
- 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 +83 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/template/template.service.d.ts +9 -44
- package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/template/template.service.js +7 -80
- package/dist/backend/backend/src/services/template/template.service.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +35 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js +133 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/chat.types.d.ts +1 -1
- package/dist/backend/backend/src/types/chat.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/chat.types.js +21 -17
- package/dist/backend/backend/src/types/chat.types.js.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.d.ts +31 -0
- package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.js +50 -0
- package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +1 -1
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/messaging.types.d.ts +4 -0
- package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
- package/dist/backend/backend/src/types/settings.types.d.ts +1 -1
- package/dist/backend/backend/src/types/settings.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/settings.types.js +4 -4
- package/dist/backend/backend/src/types/settings.types.js.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.d.ts +2 -2
- package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.js +1 -1
- package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +4 -4
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.js +9 -6
- package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
- package/dist/backend/config/constants.d.ts +4 -2
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +4 -2
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +53 -13
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +54 -16
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/mcp-server.js +1 -1
- package/dist/cli/backend/src/services/mcp-server.js.map +1 -1
- package/dist/cli/backend/src/types/chat.types.d.ts +1 -1
- package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/chat.types.js +21 -17
- package/dist/cli/backend/src/types/chat.types.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +1 -1
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/settings.types.d.ts +1 -1
- package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/settings.types.js +4 -4
- package/dist/cli/backend/src/types/settings.types.js.map +1 -1
- package/dist/cli/config/constants.d.ts +4 -2
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +4 -2
- package/dist/cli/config/constants.js.map +1 -1
- package/frontend/dist/assets/index-3558d1a2.js +4919 -0
- package/frontend/dist/assets/index-4c4dcc31.css +33 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +15 -9
- package/frontend/dist/assets/index-510ab719.css +0 -33
- package/frontend/dist/assets/index-935cd846.js +0 -4961
|
@@ -185,6 +185,10 @@ export class RuntimeExitMonitorService {
|
|
|
185
185
|
/**
|
|
186
186
|
* Stop monitoring a PTY session.
|
|
187
187
|
*
|
|
188
|
+
* Also prunes the restartHistory entry for this session if it has no
|
|
189
|
+
* recent timestamps within the cooldown window, preventing slow memory
|
|
190
|
+
* leak for terminated sessions.
|
|
191
|
+
*
|
|
188
192
|
* @param sessionName - PTY session name
|
|
189
193
|
*/
|
|
190
194
|
stopMonitoring(sessionName) {
|
|
@@ -200,6 +204,21 @@ export class RuntimeExitMonitorService {
|
|
|
200
204
|
}
|
|
201
205
|
monitored.unsubscribe();
|
|
202
206
|
this.sessions.delete(sessionName);
|
|
207
|
+
// Fix 3: Clean up restartHistory for terminated sessions to prevent
|
|
208
|
+
// unbounded Map growth. Keep the entry only if it has recent timestamps
|
|
209
|
+
// within the cooldown window (they may still be needed if the session
|
|
210
|
+
// is restarted soon). Delete the entry entirely otherwise.
|
|
211
|
+
const timestamps = this.restartHistory.get(sessionName);
|
|
212
|
+
if (timestamps) {
|
|
213
|
+
const windowStart = Date.now() - AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS;
|
|
214
|
+
const recent = timestamps.filter(ts => ts > windowStart);
|
|
215
|
+
if (recent.length === 0) {
|
|
216
|
+
this.restartHistory.delete(sessionName);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this.restartHistory.set(sessionName, recent);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
203
222
|
this.logger.debug('Stopped runtime exit monitoring', { sessionName });
|
|
204
223
|
}
|
|
205
224
|
/**
|
|
@@ -252,6 +271,10 @@ export class RuntimeExitMonitorService {
|
|
|
252
271
|
/**
|
|
253
272
|
* Confirm exit by checking for a shell prompt, then react.
|
|
254
273
|
*
|
|
274
|
+
* Runtime-specific failure checks are gated by runtimeType so that
|
|
275
|
+
* patterns for one runtime cannot accidentally match another (e.g. a
|
|
276
|
+
* Codex exit matching Claude or Gemini patterns).
|
|
277
|
+
*
|
|
255
278
|
* For Gemini CLI failure patterns (API errors, quota exhaustion, etc.),
|
|
256
279
|
* the system retries with exponential backoff before declaring the agent
|
|
257
280
|
* dead. Gemini CLI often recovers automatically from transient API errors
|
|
@@ -272,58 +295,11 @@ export class RuntimeExitMonitorService {
|
|
|
272
295
|
// Verify shell prompt is visible (avoids false positives)
|
|
273
296
|
const shellPromptConfirmed = this.verifyExitWithShellPrompt(sessionName, helper);
|
|
274
297
|
if (!shellPromptConfirmed) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
// as an actionable runtime failure even if shell prompt isn't visible.
|
|
278
|
-
const isCodexInterrupted = monitored.runtimeType === RUNTIME_TYPES.CODEX_CLI
|
|
279
|
-
&& /Conversation interrupted/i.test(monitored.buffer);
|
|
280
|
-
if (isCodexInterrupted) {
|
|
281
|
-
this.logger.warn('Codex interruption detected, proceeding with recovery flow', {
|
|
282
|
-
sessionName,
|
|
283
|
-
});
|
|
284
|
-
// fall through to exit/restart handling below
|
|
285
|
-
}
|
|
286
|
-
// Claude Code: detect fatal API errors that make the CLI permanently
|
|
287
|
-
// non-functional (e.g. thinking block corruption). These are unrecoverable
|
|
288
|
-
// — no retry will help, immediate restart is required.
|
|
289
|
-
const isClaudeFatal = monitored.runtimeType === RUNTIME_TYPES.CLAUDE_CODE
|
|
290
|
-
&& CLAUDE_FATAL_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
|
|
291
|
-
if (isClaudeFatal) {
|
|
292
|
-
const detectedPattern = CLAUDE_FATAL_PATTERNS.find((p) => p.test(monitored.buffer))?.source;
|
|
293
|
-
this.logger.warn('Claude Code fatal error detected, forcing immediate recovery', {
|
|
294
|
-
sessionName,
|
|
295
|
-
detectedPattern,
|
|
296
|
-
});
|
|
297
|
-
// fall through to exit/restart handling below (no retry)
|
|
298
|
-
}
|
|
299
|
-
// For Gemini CLI: detect either retryable failure patterns or forced
|
|
300
|
-
// restart/update markers that require immediate recovery handling.
|
|
301
|
-
const isGeminiFailure = monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI
|
|
302
|
-
&& GEMINI_FAILURE_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
|
|
303
|
-
const isGeminiForceRestart = monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI
|
|
304
|
-
&& GEMINI_FORCE_RESTART_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
|
|
305
|
-
if (!isGeminiFailure && !isGeminiForceRestart && !isCodexInterrupted && !isClaudeFatal) {
|
|
298
|
+
const runtimeSpecificMatch = await this.checkRuntimeSpecificFailure(sessionName, monitored, helper);
|
|
299
|
+
if (!runtimeSpecificMatch) {
|
|
306
300
|
this.logger.debug('Exit pattern matched but shell prompt not confirmed, ignoring', { sessionName });
|
|
307
301
|
return;
|
|
308
302
|
}
|
|
309
|
-
if (isGeminiFailure || isGeminiForceRestart) {
|
|
310
|
-
// Some Gemini failures are transient; others (auto-update/restart)
|
|
311
|
-
// should trigger immediate recovery and task re-delivery.
|
|
312
|
-
if (isGeminiForceRestart) {
|
|
313
|
-
this.logger.warn('Gemini auto-update interruption detected, forcing recovery flow', {
|
|
314
|
-
sessionName,
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
// Retry with exponential backoff before declaring exit.
|
|
319
|
-
// Gemini CLI can recover from transient API errors automatically.
|
|
320
|
-
const retryResult = await this.handleGeminiFailureWithRetry(sessionName, monitored, helper);
|
|
321
|
-
if (retryResult === 'recovered' || retryResult === 'deferred') {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
// retryResult === 'exhausted' — fall through to exit flow
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
303
|
}
|
|
328
304
|
// Mark as detected to prevent double-processing
|
|
329
305
|
monitored.exitDetected = true;
|
|
@@ -333,199 +309,281 @@ export class RuntimeExitMonitorService {
|
|
|
333
309
|
role: monitored.role,
|
|
334
310
|
});
|
|
335
311
|
// Fire the exit-detected callback (used to cancel pending registrations)
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
this.onExitDetectedCallback(sessionName);
|
|
339
|
-
}
|
|
340
|
-
catch (error) {
|
|
341
|
-
this.logger.warn('onExitDetected callback error', {
|
|
342
|
-
sessionName,
|
|
343
|
-
error: error instanceof Error ? error.message : String(error),
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
// Check for in-progress tasks — restart agent if any exist (non-orchestrator only)
|
|
312
|
+
this.fireExitDetectedCallback(sessionName);
|
|
313
|
+
// Try agent restart if it has in-progress tasks (non-orchestrator only)
|
|
348
314
|
if (monitored.role !== ORCHESTRATOR_ROLE && this.agentRegistrationService && this.taskTrackingService) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (activeTasks.length > 0) {
|
|
353
|
-
// Check cooldown before attempting restart to prevent infinite
|
|
354
|
-
// restart loops (e.g. during network outages where agents keep crashing)
|
|
355
|
-
if (!this.isAgentRestartAllowed(sessionName)) {
|
|
356
|
-
this.logger.warn('Agent restart cooldown active, skipping restart', {
|
|
357
|
-
sessionName,
|
|
358
|
-
activeTaskCount: activeTasks.length,
|
|
359
|
-
maxRestartsPerWindow: AGENT_HEARTBEAT_MONITOR_CONSTANTS.MAX_RESTARTS_PER_WINDOW,
|
|
360
|
-
cooldownWindowMs: AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS,
|
|
361
|
-
});
|
|
362
|
-
this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited_cooldown', activeTasks, false);
|
|
363
|
-
// Fall through to normal inactive flow
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
this.logger.info('Runtime exit with in-progress tasks, attempting restart', {
|
|
367
|
-
sessionName,
|
|
368
|
-
activeTaskCount: activeTasks.length,
|
|
369
|
-
});
|
|
370
|
-
try {
|
|
371
|
-
await this.restartAgentWithTasks(sessionName, monitored, activeTasks);
|
|
372
|
-
this.recordAgentRestart(sessionName);
|
|
373
|
-
// Notify orchestrator that agent was restarted (#129)
|
|
374
|
-
this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, true);
|
|
375
|
-
// Cleanup this subscription (restart succeeded, skip inactive flow)
|
|
376
|
-
this.stopMonitoring(sessionName);
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
catch (restartError) {
|
|
380
|
-
this.logger.warn('Agent restart after runtime exit failed, falling back to inactive', {
|
|
381
|
-
sessionName,
|
|
382
|
-
error: restartError instanceof Error ? restartError.message : String(restartError),
|
|
383
|
-
});
|
|
384
|
-
// Record the attempt even on failure to prevent rapid retry loops
|
|
385
|
-
this.recordAgentRestart(sessionName);
|
|
386
|
-
// Notify orchestrator that restart failed — needs manual intervention (#129)
|
|
387
|
-
this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, false);
|
|
388
|
-
// Fall through to normal inactive flow
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
catch (error) {
|
|
394
|
-
this.logger.warn('Failed to check in-progress tasks after runtime exit', {
|
|
395
|
-
sessionName,
|
|
396
|
-
error: error instanceof Error ? error.message : String(error),
|
|
397
|
-
});
|
|
398
|
-
// Fall through to normal inactive flow
|
|
399
|
-
}
|
|
315
|
+
const restarted = await this.tryAgentRestartWithTasks(sessionName, monitored);
|
|
316
|
+
if (restarted)
|
|
317
|
+
return;
|
|
400
318
|
}
|
|
401
|
-
// Orchestrator-specific restart
|
|
319
|
+
// Orchestrator-specific restart
|
|
402
320
|
if (sessionName === ORCHESTRATOR_SESSION_NAME) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
321
|
+
const restarted = await this.tryOrchestratorRestart(sessionName, monitored);
|
|
322
|
+
if (restarted)
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
// Normal inactive flow: update status, capture memory, broadcast
|
|
326
|
+
await this.transitionToInactive(sessionName, monitored);
|
|
327
|
+
// Cleanup this subscription
|
|
328
|
+
this.stopMonitoring(sessionName);
|
|
329
|
+
}
|
|
330
|
+
finally {
|
|
331
|
+
monitored.confirmationInFlight = false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Check for runtime-specific failure patterns when shell prompt is not confirmed.
|
|
336
|
+
*
|
|
337
|
+
* Gated by runtimeType so patterns for one runtime cannot accidentally
|
|
338
|
+
* match another. Returns true if a runtime-specific failure was detected,
|
|
339
|
+
* or 'deferred' handling occurred (Gemini retry).
|
|
340
|
+
*
|
|
341
|
+
* @param sessionName - PTY session name
|
|
342
|
+
* @param monitored - Monitored session state
|
|
343
|
+
* @param helper - Session command helper
|
|
344
|
+
* @returns True if a runtime-specific failure was confirmed
|
|
345
|
+
*/
|
|
346
|
+
async checkRuntimeSpecificFailure(sessionName, monitored, helper) {
|
|
347
|
+
if (monitored.runtimeType === RUNTIME_TYPES.CODEX_CLI) {
|
|
348
|
+
const isCodexInterrupted = /Conversation interrupted/i.test(monitored.buffer);
|
|
349
|
+
if (isCodexInterrupted) {
|
|
350
|
+
this.logger.warn('Codex interruption detected, proceeding with recovery flow', { sessionName });
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else if (monitored.runtimeType === RUNTIME_TYPES.CLAUDE_CODE) {
|
|
355
|
+
const isClaudeFatal = CLAUDE_FATAL_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
|
|
356
|
+
if (isClaudeFatal) {
|
|
357
|
+
const detectedPattern = CLAUDE_FATAL_PATTERNS.find((p) => p.test(monitored.buffer))?.source;
|
|
358
|
+
this.logger.warn('Claude Code fatal error detected, forcing immediate recovery', {
|
|
359
|
+
sessionName,
|
|
360
|
+
detectedPattern,
|
|
361
|
+
});
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else if (monitored.runtimeType === RUNTIME_TYPES.GEMINI_CLI) {
|
|
366
|
+
const isGeminiFailure = GEMINI_FAILURE_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
|
|
367
|
+
const isGeminiForceRestart = GEMINI_FORCE_RESTART_PATTERNS.some((pattern) => pattern.test(monitored.buffer));
|
|
368
|
+
if (isGeminiFailure || isGeminiForceRestart) {
|
|
369
|
+
if (isGeminiForceRestart) {
|
|
370
|
+
this.logger.warn('Gemini auto-update interruption detected, forcing recovery flow', { sessionName });
|
|
425
371
|
}
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
this.logger.info('Orchestrator restarted after runtime exit', { sessionName });
|
|
431
|
-
// Broadcast restarted status as STARTED (not ACTIVE).
|
|
432
|
-
// The agent becomes ACTIVE only after the registration prompt
|
|
433
|
-
// is fully processed and the MCP registration call completes.
|
|
434
|
-
// Broadcasting ACTIVE prematurely causes the queue processor
|
|
435
|
-
// to deliver messages during postInitialize.
|
|
436
|
-
try {
|
|
437
|
-
const terminalGateway = getTerminalGateway();
|
|
438
|
-
if (terminalGateway) {
|
|
439
|
-
terminalGateway.broadcastOrchestratorStatus({
|
|
440
|
-
sessionName,
|
|
441
|
-
agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.STARTED,
|
|
442
|
-
reason: 'runtime_exit_restart',
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
catch {
|
|
447
|
-
// Best-effort broadcast
|
|
448
|
-
}
|
|
449
|
-
this.stopMonitoring(sessionName);
|
|
450
|
-
return;
|
|
372
|
+
else {
|
|
373
|
+
const retryResult = await this.handleGeminiFailureWithRetry(sessionName, monitored, helper);
|
|
374
|
+
if (retryResult === 'recovered' || retryResult === 'deferred') {
|
|
375
|
+
return false; // Not a confirmed exit — caller should return early
|
|
451
376
|
}
|
|
452
|
-
this.logger.warn('Orchestrator restart after runtime exit failed or not allowed, falling back to inactive', {
|
|
453
|
-
sessionName,
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
catch (error) {
|
|
457
|
-
this.logger.warn('Orchestrator restart attempt threw error, falling back to inactive', {
|
|
458
|
-
sessionName,
|
|
459
|
-
error: error instanceof Error ? error.message : String(error),
|
|
460
|
-
});
|
|
461
377
|
}
|
|
462
|
-
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Fire the onExitDetected callback safely.
|
|
385
|
+
*
|
|
386
|
+
* @param sessionName - PTY session name
|
|
387
|
+
*/
|
|
388
|
+
fireExitDetectedCallback(sessionName) {
|
|
389
|
+
if (!this.onExitDetectedCallback)
|
|
390
|
+
return;
|
|
391
|
+
try {
|
|
392
|
+
this.onExitDetectedCallback(sessionName);
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
this.logger.warn('onExitDetected callback error', {
|
|
396
|
+
sessionName,
|
|
397
|
+
error: error instanceof Error ? error.message : String(error),
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Try to restart an agent that has in-progress tasks.
|
|
403
|
+
*
|
|
404
|
+
* @param sessionName - PTY session name
|
|
405
|
+
* @param monitored - Monitored session state
|
|
406
|
+
* @returns True if the agent was successfully restarted (caller should return)
|
|
407
|
+
*/
|
|
408
|
+
async tryAgentRestartWithTasks(sessionName, monitored) {
|
|
409
|
+
try {
|
|
410
|
+
const tasks = await this.taskTrackingService.getTasksForTeamMember(monitored.memberId || '');
|
|
411
|
+
const activeTasks = tasks.filter(t => t.status === 'assigned' || t.status === 'active' || t.status === 'pending_assignment');
|
|
412
|
+
if (activeTasks.length === 0)
|
|
413
|
+
return false;
|
|
414
|
+
if (!this.isAgentRestartAllowed(sessionName)) {
|
|
415
|
+
this.logger.warn('Agent restart cooldown active, skipping restart', {
|
|
416
|
+
sessionName,
|
|
417
|
+
activeTaskCount: activeTasks.length,
|
|
418
|
+
maxRestartsPerWindow: AGENT_HEARTBEAT_MONITOR_CONSTANTS.MAX_RESTARTS_PER_WINDOW,
|
|
419
|
+
cooldownWindowMs: AGENT_HEARTBEAT_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS,
|
|
420
|
+
});
|
|
421
|
+
this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited_cooldown', activeTasks, false);
|
|
422
|
+
return false;
|
|
463
423
|
}
|
|
464
|
-
|
|
424
|
+
this.logger.info('Runtime exit with in-progress tasks, attempting restart', {
|
|
425
|
+
sessionName,
|
|
426
|
+
activeTaskCount: activeTasks.length,
|
|
427
|
+
});
|
|
465
428
|
try {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
this.
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
429
|
+
await this.restartAgentWithTasks(sessionName, monitored, activeTasks);
|
|
430
|
+
this.recordAgentRestart(sessionName);
|
|
431
|
+
this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, true);
|
|
432
|
+
this.stopMonitoring(sessionName);
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
catch (restartError) {
|
|
436
|
+
this.logger.warn('Agent restart after runtime exit failed, falling back to inactive', {
|
|
437
|
+
sessionName,
|
|
438
|
+
error: restartError instanceof Error ? restartError.message : String(restartError),
|
|
439
|
+
});
|
|
440
|
+
this.recordAgentRestart(sessionName);
|
|
441
|
+
this.notifyOrchestratorOfFailure(sessionName, 'runtime_exited', activeTasks, false);
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
this.logger.warn('Failed to check in-progress tasks after runtime exit', {
|
|
447
|
+
sessionName,
|
|
448
|
+
error: error instanceof Error ? error.message : String(error),
|
|
449
|
+
});
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Try to restart the orchestrator after runtime exit.
|
|
455
|
+
*
|
|
456
|
+
* Sets status to inactive before restart to prevent queue processor
|
|
457
|
+
* from delivering messages during postInitialize, captures session
|
|
458
|
+
* memory, and broadcasts restart status.
|
|
459
|
+
*
|
|
460
|
+
* @param sessionName - PTY session name (should be ORCHESTRATOR_SESSION_NAME)
|
|
461
|
+
* @param monitored - Monitored session state
|
|
462
|
+
* @returns True if orchestrator was successfully restarted (caller should return)
|
|
463
|
+
*/
|
|
464
|
+
async tryOrchestratorRestart(sessionName, monitored) {
|
|
465
|
+
// Set status to inactive BEFORE restart so the queue processor
|
|
466
|
+
// doesn't deliver messages during postInitialize.
|
|
467
|
+
try {
|
|
468
|
+
const storageService = StorageService.getInstance();
|
|
469
|
+
await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
// Best-effort — continue with restart
|
|
473
|
+
}
|
|
474
|
+
// Capture session memory before restart
|
|
475
|
+
try {
|
|
476
|
+
const sessionMemoryService = SessionMemoryService.getInstance();
|
|
477
|
+
await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
|
|
478
|
+
}
|
|
479
|
+
catch (error) {
|
|
480
|
+
this.logger.warn('Failed to capture session memory before orchestrator restart', {
|
|
481
|
+
sessionName,
|
|
482
|
+
error: error instanceof Error ? error.message : String(error),
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
486
|
+
const restartService = OrchestratorRestartService.getInstance();
|
|
487
|
+
const success = await restartService.attemptRestart();
|
|
488
|
+
if (success) {
|
|
489
|
+
this.logger.info('Orchestrator restarted after runtime exit', { sessionName });
|
|
490
|
+
// Broadcast STARTED (not ACTIVE) — agent becomes ACTIVE only
|
|
491
|
+
// after registration prompt is processed and MCP call completes.
|
|
492
|
+
try {
|
|
493
|
+
const terminalGateway = getTerminalGateway();
|
|
494
|
+
if (terminalGateway) {
|
|
495
|
+
terminalGateway.broadcastOrchestratorStatus({
|
|
476
496
|
sessionName,
|
|
477
|
-
|
|
497
|
+
agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.STARTED,
|
|
498
|
+
reason: 'runtime_exit_restart',
|
|
478
499
|
});
|
|
479
500
|
}
|
|
480
501
|
}
|
|
502
|
+
catch {
|
|
503
|
+
// Best-effort broadcast
|
|
504
|
+
}
|
|
505
|
+
this.stopMonitoring(sessionName);
|
|
506
|
+
return true;
|
|
481
507
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
508
|
+
this.logger.warn('Orchestrator restart after runtime exit failed or not allowed, falling back to inactive', {
|
|
509
|
+
sessionName,
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
this.logger.warn('Orchestrator restart attempt threw error, falling back to inactive', {
|
|
514
|
+
sessionName,
|
|
515
|
+
error: error instanceof Error ? error.message : String(error),
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Transition agent to inactive state: update storage, capture memory,
|
|
522
|
+
* publish events, and broadcast WebSocket status.
|
|
523
|
+
*
|
|
524
|
+
* @param sessionName - PTY session name
|
|
525
|
+
* @param monitored - Monitored session state
|
|
526
|
+
*/
|
|
527
|
+
async transitionToInactive(sessionName, monitored) {
|
|
528
|
+
// Update agent status to inactive
|
|
529
|
+
try {
|
|
530
|
+
const storageService = StorageService.getInstance();
|
|
531
|
+
await storageService.updateAgentStatus(sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE);
|
|
532
|
+
this.logger.info('Agent status updated to inactive after runtime exit', { sessionName });
|
|
533
|
+
// Publish agent:inactive event to EventBus so orchestrator is notified
|
|
534
|
+
if (this.eventBusService) {
|
|
490
535
|
try {
|
|
491
|
-
|
|
492
|
-
await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
|
|
536
|
+
await this.publishInactiveEvent(sessionName, monitored, storageService);
|
|
493
537
|
}
|
|
494
|
-
catch (
|
|
495
|
-
this.logger.warn('Failed to
|
|
538
|
+
catch (eventError) {
|
|
539
|
+
this.logger.warn('Failed to publish agent:inactive event to EventBus', {
|
|
496
540
|
sessionName,
|
|
497
|
-
error:
|
|
541
|
+
error: eventError instanceof Error ? eventError.message : String(eventError),
|
|
498
542
|
});
|
|
499
543
|
}
|
|
500
544
|
}
|
|
501
|
-
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
this.logger.warn('Failed to update agent status after runtime exit', {
|
|
548
|
+
sessionName,
|
|
549
|
+
error: error instanceof Error ? error.message : String(error),
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
// Capture session memory (skip for orchestrator — already captured above)
|
|
553
|
+
if (sessionName !== ORCHESTRATOR_SESSION_NAME) {
|
|
502
554
|
try {
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
const statusPayload = {
|
|
506
|
-
sessionName,
|
|
507
|
-
agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE,
|
|
508
|
-
reason: 'runtime_exited',
|
|
509
|
-
};
|
|
510
|
-
if (sessionName === ORCHESTRATOR_SESSION_NAME) {
|
|
511
|
-
terminalGateway.broadcastOrchestratorStatus(statusPayload);
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
514
|
-
terminalGateway.broadcastTeamMemberStatus(statusPayload);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
555
|
+
const sessionMemoryService = SessionMemoryService.getInstance();
|
|
556
|
+
await sessionMemoryService.onSessionEnd(sessionName, monitored.role, process.cwd());
|
|
517
557
|
}
|
|
518
558
|
catch (error) {
|
|
519
|
-
this.logger.warn('Failed to
|
|
559
|
+
this.logger.warn('Failed to capture session memory after runtime exit', {
|
|
520
560
|
sessionName,
|
|
521
561
|
error: error instanceof Error ? error.message : String(error),
|
|
522
562
|
});
|
|
523
563
|
}
|
|
524
|
-
// Cleanup this subscription
|
|
525
|
-
this.stopMonitoring(sessionName);
|
|
526
564
|
}
|
|
527
|
-
|
|
528
|
-
|
|
565
|
+
// Broadcast WebSocket event
|
|
566
|
+
try {
|
|
567
|
+
const terminalGateway = getTerminalGateway();
|
|
568
|
+
if (terminalGateway) {
|
|
569
|
+
const statusPayload = {
|
|
570
|
+
sessionName,
|
|
571
|
+
agentStatus: CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE,
|
|
572
|
+
reason: 'runtime_exited',
|
|
573
|
+
};
|
|
574
|
+
if (sessionName === ORCHESTRATOR_SESSION_NAME) {
|
|
575
|
+
terminalGateway.broadcastOrchestratorStatus(statusPayload);
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
terminalGateway.broadcastTeamMemberStatus(statusPayload);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
catch (error) {
|
|
583
|
+
this.logger.warn('Failed to broadcast runtime exit event', {
|
|
584
|
+
sessionName,
|
|
585
|
+
error: error instanceof Error ? error.message : String(error),
|
|
586
|
+
});
|
|
529
587
|
}
|
|
530
588
|
}
|
|
531
589
|
/**
|