crewly 1.2.3 → 1.2.4
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/README.md +1 -1
- package/config/constants.ts +44 -1
- package/config/index.ts +4 -0
- package/config/roles/orchestrator/prompt.md +30 -2
- package/config/roles/team-leader/prompt.md +169 -0
- package/config/roles/team-leader/role.json +13 -0
- package/config/roles/team-leader/tl-addon.md +142 -0
- package/config/runtime_scripts/runtime-config.json +7 -0
- package/config/skills/_common/lib.sh +37 -0
- package/config/skills/agent/computer-use/execute.sh +228 -0
- package/config/skills/agent/computer-use/instructions.md +103 -0
- package/config/skills/agent/computer-use/lib/accessibility.sh +292 -0
- package/config/skills/agent/computer-use/lib/applescript.sh +117 -0
- package/config/skills/agent/computer-use/lib/discover.sh +122 -0
- package/config/skills/agent/computer-use/lib/playwright.sh +153 -0
- package/config/skills/agent/computer-use/lib/screenshot.sh +61 -0
- package/config/skills/agent/computer-use/skill.json +29 -0
- package/config/skills/agent/core/accept-task/execute.sh +7 -1
- package/config/skills/agent/core/complete-task/execute.sh +38 -1
- package/config/skills/agent/core/report-status/execute.sh +51 -2
- package/config/skills/agent/desktop-app-control/execute.sh +561 -0
- package/config/skills/agent/desktop-app-control/instructions.md +102 -0
- package/config/skills/agent/desktop-app-control/skill.json +33 -0
- package/config/skills/orchestrator/broadcast-to-org/execute.sh +88 -0
- package/config/skills/orchestrator/broadcast-to-org/instructions.md +51 -0
- package/config/skills/orchestrator/broadcast-to-org/skill.json +20 -0
- package/config/skills/orchestrator/delegate-task/execute.sh +75 -10
- package/config/skills/orchestrator/delegate-task/instructions.md +11 -1
- package/config/skills/orchestrator/handle-agent-failure/execute.sh +45 -0
- package/config/skills/orchestrator/handle-agent-failure/instructions.md +29 -0
- package/config/skills/orchestrator/handle-agent-failure/skill.json +20 -0
- package/config/skills/orchestrator/restart-crewly/instructions.md +9 -2
- package/config/skills/team-leader/_common/lib.sh +4 -0
- package/config/skills/team-leader/aggregate-results/execute.sh +168 -0
- package/config/skills/team-leader/aggregate-results/instructions.md +89 -0
- package/config/skills/team-leader/aggregate-results/skill.json +20 -0
- package/config/skills/team-leader/decompose-goal/execute.sh +86 -0
- package/config/skills/team-leader/decompose-goal/instructions.md +84 -0
- package/config/skills/team-leader/decompose-goal/skill.json +20 -0
- package/config/skills/team-leader/delegate-task/execute.sh +142 -0
- package/config/skills/team-leader/delegate-task/instructions.md +55 -0
- package/config/skills/team-leader/delegate-task/skill.json +20 -0
- package/config/skills/team-leader/handle-failure/execute.sh +119 -0
- package/config/skills/team-leader/handle-failure/instructions.md +93 -0
- package/config/skills/team-leader/handle-failure/skill.json +20 -0
- package/config/skills/team-leader/schedule-check/execute.sh +65 -0
- package/config/skills/team-leader/schedule-check/execute.test.sh +247 -0
- package/config/skills/team-leader/schedule-check/instructions.md +49 -0
- package/config/skills/team-leader/schedule-check/skill.json +20 -0
- package/config/skills/team-leader/start-agent/execute.sh +39 -0
- package/config/skills/team-leader/start-agent/instructions.md +48 -0
- package/config/skills/team-leader/start-agent/skill.json +20 -0
- package/config/skills/team-leader/stop-agent/execute.sh +39 -0
- package/config/skills/team-leader/stop-agent/instructions.md +49 -0
- package/config/skills/team-leader/stop-agent/skill.json +20 -0
- package/config/skills/team-leader/verify-output/execute.sh +296 -0
- package/config/skills/team-leader/verify-output/instructions.md +122 -0
- package/config/skills/team-leader/verify-output/skill.json +20 -0
- package/config/templates/core-team/demo-script.md +41 -0
- package/config/templates/core-team/goals.md +20 -0
- package/config/templates/core-team/team.json +22 -0
- package/config/templates/dev-fullstack/template.json +115 -0
- package/config/templates/education-smb/README.md +27 -0
- package/config/templates/education-smb/goals.md +16 -0
- package/config/templates/education-smb/knowledge/docs/content-standards.md +24 -0
- package/config/templates/education-smb/knowledge/docs/education-industry-context.md +13 -0
- package/config/templates/education-smb/knowledge/index.json +24 -0
- package/config/templates/education-smb/learned-patterns.json +16 -0
- package/config/templates/education-smb/quality-gates.yaml +66 -0
- package/config/templates/education-smb/roles/analytics-specialist.md +6 -0
- package/config/templates/education-smb/roles/content-creator.md +6 -0
- package/config/templates/education-smb/roles/curriculum-designer.md +6 -0
- package/config/templates/education-smb/roles/engagement-manager.md +6 -0
- package/config/templates/education-smb/team.json +40 -0
- package/config/templates/education-smb/template.json +26 -0
- package/config/templates/education-smb/workflows/course-content-generation.yaml +44 -0
- package/config/templates/education-smb/workflows/reporting.yaml +31 -0
- package/config/templates/education-smb/workflows/student-communication.yaml +44 -0
- package/config/templates/education-smb/workflows.yaml +40 -0
- package/config/templates/insurance-smb/README.md +28 -0
- package/config/templates/insurance-smb/goals.md +21 -0
- package/config/templates/insurance-smb/knowledge/docs/compliance-checklist.md +28 -0
- package/config/templates/insurance-smb/knowledge/docs/insurance-industry-context.md +23 -0
- package/config/templates/insurance-smb/knowledge/index.json +24 -0
- package/config/templates/insurance-smb/learned-patterns.json +16 -0
- package/config/templates/insurance-smb/quality-gates.yaml +54 -0
- package/config/templates/insurance-smb/roles/claims-processor.md +6 -0
- package/config/templates/insurance-smb/roles/client-manager.md +6 -0
- package/config/templates/insurance-smb/roles/compliance-officer.md +6 -0
- package/config/templates/insurance-smb/roles/marketing-specialist.md +6 -0
- package/config/templates/insurance-smb/roles/policy-analyst.md +6 -0
- package/config/templates/insurance-smb/team.json +48 -0
- package/config/templates/insurance-smb/template.json +26 -0
- package/config/templates/insurance-smb/workflows/claims-processing.yaml +48 -0
- package/config/templates/insurance-smb/workflows.yaml +43 -0
- package/config/templates/research-analysis/template.json +88 -0
- package/config/templates/social-media-ops/template.json +85 -0
- package/config/templates/video-production/template.json +123 -0
- package/dist/backend/backend/src/constants.d.ts +303 -15
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +296 -15
- package/dist/backend/backend/src/constants.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 +69 -48
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/auth/auth.controller.d.ts +81 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.controller.js +234 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.d.ts +25 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.js +38 -0
- package/dist/backend/backend/src/controllers/cloud/auth/auth.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.controller.d.ts +69 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.controller.js +165 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.routes.d.ts +23 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.routes.js +32 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-auth.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts +52 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +122 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts +21 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +32 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.controller.d.ts +42 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.controller.js +138 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.routes.d.ts +23 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.routes.js +34 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.types.d.ts +43 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.types.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.types.js +9 -0
- package/dist/backend/backend/src/controllers/cloud/files/cloud-file.types.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/index.d.ts +7 -0
- package/dist/backend/backend/src/controllers/cloud/files/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/files/index.js +7 -0
- package/dist/backend/backend/src/controllers/cloud/files/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.controller.d.ts +47 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.controller.js +131 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.routes.d.ts +23 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.routes.js +30 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.types.d.ts +81 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.types.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.types.js +85 -0
- package/dist/backend/backend/src/controllers/cloud/h5/h5-entry.types.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/index.d.ts +7 -0
- package/dist/backend/backend/src/controllers/cloud/h5/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/h5/index.js +7 -0
- package/dist/backend/backend/src/controllers/cloud/h5/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/index.d.ts +14 -0
- package/dist/backend/backend/src/controllers/cloud/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/index.js +14 -0
- package/dist/backend/backend/src/controllers/cloud/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/index.d.ts +7 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/index.js +7 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.controller.d.ts +45 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.controller.js +155 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.routes.d.ts +25 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.routes.js +32 -0
- package/dist/backend/backend/src/controllers/cloud/magic-moment/magic-moment.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts +101 -0
- package/dist/backend/backend/src/controllers/cloud/relay.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/relay.controller.js +343 -0
- package/dist/backend/backend/src/controllers/cloud/relay.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/relay.routes.d.ts +29 -0
- package/dist/backend/backend/src/controllers/cloud/relay.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/relay.routes.js +44 -0
- package/dist/backend/backend/src/controllers/cloud/relay.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.controller.d.ts +49 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.controller.js +152 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.routes.d.ts +24 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.routes.js +34 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.types.d.ts +90 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.types.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.types.js +48 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/cloud-task.types.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/index.d.ts +7 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/index.js +7 -0
- package/dist/backend/backend/src/controllers/cloud/tasks/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/marketplace/index.d.ts +2 -0
- package/dist/backend/backend/src/controllers/marketplace/index.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/index.js +3 -0
- package/dist/backend/backend/src/controllers/marketplace/index.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.d.ts +12 -12
- package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js +1 -18
- package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js +3 -0
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.controller.d.ts +111 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.controller.js +220 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts +33 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js +50 -0
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +4 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.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 +18 -2
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/index.d.ts +7 -0
- package/dist/backend/backend/src/controllers/payment/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/payment/index.js +7 -0
- package/dist/backend/backend/src/controllers/payment/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/payment/payment.controller.d.ts +57 -0
- package/dist/backend/backend/src/controllers/payment/payment.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/payment/payment.controller.js +136 -0
- package/dist/backend/backend/src/controllers/payment/payment.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts +27 -0
- package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/payment/payment.routes.js +38 -0
- package/dist/backend/backend/src/controllers/payment/payment.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/payment/payment.types.d.ts +109 -0
- package/dist/backend/backend/src/controllers/payment/payment.types.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/payment/payment.types.js +54 -0
- package/dist/backend/backend/src/controllers/payment/payment.types.js.map +1 -0
- package/dist/backend/backend/src/controllers/request-types.d.ts +34 -5
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/session/session.controller.d.ts +14 -0
- package/dist/backend/backend/src/controllers/session/session.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/session/session.controller.js +48 -0
- package/dist/backend/backend/src/controllers/session/session.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/session/session.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/session/session.routes.js +3 -1
- package/dist/backend/backend/src/controllers/session/session.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/scheduler.controller.js +4 -3
- package/dist/backend/backend/src/controllers/system/scheduler.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.js +13 -15
- package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/assignments.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/assignments.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +40 -4
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +259 -13
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/template/index.d.ts +8 -0
- package/dist/backend/backend/src/controllers/template/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/template/index.js +8 -0
- package/dist/backend/backend/src/controllers/template/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/template/template.controller.d.ts +63 -0
- package/dist/backend/backend/src/controllers/template/template.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/template/template.controller.js +112 -0
- package/dist/backend/backend/src/controllers/template/template.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/template/template.routes.d.ts +24 -0
- package/dist/backend/backend/src/controllers/template/template.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/template/template.routes.js +33 -0
- package/dist/backend/backend/src/controllers/template/template.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +105 -13
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/middleware/agent-heartbeat.middleware.js +3 -3
- package/dist/backend/backend/src/middleware/agent-heartbeat.middleware.js.map +1 -1
- package/dist/backend/backend/src/models/Team.d.ts +5 -0
- package/dist/backend/backend/src/models/Team.d.ts.map +1 -1
- package/dist/backend/backend/src/models/Team.js +24 -0
- package/dist/backend/backend/src/models/Team.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 +21 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +1 -6
- 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 +211 -287
- 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 +7 -1
- 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 +11 -2
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.d.ts +1 -0
- 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 +30 -43
- package/dist/backend/backend/src/services/agent/gemini-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +216 -0
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +496 -0
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/openhands-runtime.service.d.ts +70 -0
- package/dist/backend/backend/src/services/agent/openhands-runtime.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/openhands-runtime.service.js +131 -0
- package/dist/backend/backend/src/services/agent/openhands-runtime.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.d.ts +21 -1
- package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.js +32 -1
- package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +77 -3
- 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 +281 -30
- 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.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-service.factory.js +9 -0
- package/dist/backend/backend/src/services/agent/runtime-service.factory.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +49 -2
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js +124 -2
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat/chat.service.d.ts +10 -2
- package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat/chat.service.js +49 -8
- package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/auth/auth.service.d.ts +174 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.service.js +402 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.types.d.ts +110 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.types.js +54 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.types.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.utils.d.ts +36 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.utils.js +31 -0
- package/dist/backend/backend/src/services/cloud/auth/auth.utils.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/jwt-auth.middleware.d.ts +47 -0
- package/dist/backend/backend/src/services/cloud/auth/jwt-auth.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/jwt-auth.middleware.js +116 -0
- package/dist/backend/backend/src/services/cloud/auth/jwt-auth.middleware.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/supabase-auth.middleware.d.ts +61 -0
- package/dist/backend/backend/src/services/cloud/auth/supabase-auth.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/auth/supabase-auth.middleware.js +203 -0
- package/dist/backend/backend/src/services/cloud/auth/supabase-auth.middleware.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.middleware.d.ts +46 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.middleware.js +95 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.middleware.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.service.d.ts +136 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.service.js +204 -0
- package/dist/backend/backend/src/services/cloud/cloud-auth.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +179 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js +237 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-file.service.d.ts +97 -0
- package/dist/backend/backend/src/services/cloud/cloud-file.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-file.service.js +184 -0
- package/dist/backend/backend/src/services/cloud/cloud-file.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-image-analysis.service.d.ts +114 -0
- package/dist/backend/backend/src/services/cloud/cloud-image-analysis.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-image-analysis.service.js +196 -0
- package/dist/backend/backend/src/services/cloud/cloud-image-analysis.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.d.ts +118 -0
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.js +322 -0
- package/dist/backend/backend/src/services/cloud/cloud-task-processor.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-task.service.d.ts +115 -0
- package/dist/backend/backend/src/services/cloud/cloud-task.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-task.service.js +265 -0
- package/dist/backend/backend/src/services/cloud/cloud-task.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-client.service.d.ts +175 -0
- package/dist/backend/backend/src/services/cloud/relay-client.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-client.service.js +392 -0
- package/dist/backend/backend/src/services/cloud/relay-client.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-crypto.service.d.ts +87 -0
- package/dist/backend/backend/src/services/cloud/relay-crypto.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-crypto.service.js +140 -0
- package/dist/backend/backend/src/services/cloud/relay-crypto.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-server.service.d.ts +183 -0
- package/dist/backend/backend/src/services/cloud/relay-server.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay-server.service.js +523 -0
- package/dist/backend/backend/src/services/cloud/relay-server.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay.types.d.ts +170 -0
- package/dist/backend/backend/src/services/cloud/relay.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/relay.types.js +69 -0
- package/dist/backend/backend/src/services/cloud/relay.types.js.map +1 -0
- package/dist/backend/backend/src/services/continuation/patterns/idle-patterns.d.ts +9 -1
- package/dist/backend/backend/src/services/continuation/patterns/idle-patterns.d.ts.map +1 -1
- package/dist/backend/backend/src/services/continuation/patterns/idle-patterns.js +18 -4
- package/dist/backend/backend/src/services/continuation/patterns/idle-patterns.js.map +1 -1
- package/dist/backend/backend/src/services/core/env.config.d.ts +147 -0
- package/dist/backend/backend/src/services/core/env.config.d.ts.map +1 -0
- package/dist/backend/backend/src/services/core/env.config.js +226 -0
- package/dist/backend/backend/src/services/core/env.config.js.map +1 -0
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +5 -0
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +20 -0
- 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 +35 -0
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
- package/dist/backend/backend/src/services/hierarchy/hierarchy-escalation.service.d.ts +160 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-escalation.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-escalation.service.js +261 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-escalation.service.js.map +1 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-reporting.service.d.ts +161 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-reporting.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-reporting.service.js +276 -0
- package/dist/backend/backend/src/services/hierarchy/hierarchy-reporting.service.js.map +1 -0
- package/dist/backend/backend/src/services/marketplace/index.d.ts +1 -0
- package/dist/backend/backend/src/services/marketplace/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/marketplace/index.js +2 -0
- package/dist/backend/backend/src/services/marketplace/index.js.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace.service.js +2 -2
- package/dist/backend/backend/src/services/marketplace/template-marketplace.service.d.ts +149 -0
- package/dist/backend/backend/src/services/marketplace/template-marketplace.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/marketplace/template-marketplace.service.js +500 -0
- package/dist/backend/backend/src/services/marketplace/template-marketplace.service.js.map +1 -0
- 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/adapters/google-chat-messenger.adapter.d.ts +90 -0
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.js +233 -0
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +1 -1
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +3 -3
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +29 -5
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/payment/magic-moment.service.d.ts +69 -0
- package/dist/backend/backend/src/services/payment/magic-moment.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/payment/magic-moment.service.js +158 -0
- package/dist/backend/backend/src/services/payment/magic-moment.service.js.map +1 -0
- package/dist/backend/backend/src/services/payment/magic-moment.types.d.ts +95 -0
- package/dist/backend/backend/src/services/payment/magic-moment.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/payment/magic-moment.types.js +91 -0
- package/dist/backend/backend/src/services/payment/magic-moment.types.js.map +1 -0
- package/dist/backend/backend/src/services/payment/stripe.service.d.ts +122 -0
- package/dist/backend/backend/src/services/payment/stripe.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/payment/stripe.service.js +403 -0
- package/dist/backend/backend/src/services/payment/stripe.service.js.map +1 -0
- package/dist/backend/backend/src/services/plugin/index.d.ts +9 -0
- package/dist/backend/backend/src/services/plugin/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/plugin/index.js +8 -0
- package/dist/backend/backend/src/services/plugin/index.js.map +1 -0
- package/dist/backend/backend/src/services/plugin/plugin.service.d.ts +102 -0
- package/dist/backend/backend/src/services/plugin/plugin.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/plugin/plugin.service.js +179 -0
- package/dist/backend/backend/src/services/plugin/plugin.service.js.map +1 -0
- package/dist/backend/backend/src/services/plugin/plugin.types.d.ts +88 -0
- package/dist/backend/backend/src/services/plugin/plugin.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/plugin/plugin.types.js +17 -0
- package/dist/backend/backend/src/services/plugin/plugin.types.js.map +1 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +17 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.js +63 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
- package/dist/backend/backend/src/services/session/session-command-helper.d.ts +14 -0
- package/dist/backend/backend/src/services/session/session-command-helper.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/session-command-helper.js +54 -0
- package/dist/backend/backend/src/services/session/session-command-helper.js.map +1 -1
- package/dist/backend/backend/src/services/settings/settings.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/settings/settings.service.js +1 -0
- 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.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +15 -5
- 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 +153 -0
- package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/template/template.service.js +372 -0
- package/dist/backend/backend/src/services/template/template.service.js.map +1 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +51 -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 +118 -2
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/chat.types.d.ts +39 -1
- package/dist/backend/backend/src/types/chat.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/chat.types.js +45 -2
- package/dist/backend/backend/src/types/chat.types.js.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.d.ts +14 -2
- package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.js +15 -0
- package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
- package/dist/backend/backend/src/types/hierarchy-message.types.d.ts +101 -0
- package/dist/backend/backend/src/types/hierarchy-message.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/hierarchy-message.types.js +15 -0
- package/dist/backend/backend/src/types/hierarchy-message.types.js.map +1 -0
- package/dist/backend/backend/src/types/index.d.ts +54 -4
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/marketplace.types.d.ts +99 -0
- package/dist/backend/backend/src/types/marketplace.types.d.ts.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 -0
- package/dist/backend/backend/src/types/settings.types.js.map +1 -1
- package/dist/backend/backend/src/types/task-tracking.types.d.ts +79 -1
- package/dist/backend/backend/src/types/task-tracking.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/task-tracking.types.js.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.d.ts +166 -0
- package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/team-template.types.js +139 -0
- package/dist/backend/backend/src/types/team-template.types.js.map +1 -0
- package/dist/backend/backend/src/utils/async-handler.d.ts +20 -0
- package/dist/backend/backend/src/utils/async-handler.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/async-handler.js +29 -0
- package/dist/backend/backend/src/utils/async-handler.js.map +1 -0
- package/dist/backend/backend/src/utils/defaultPrompts.d.ts +4 -4
- package/dist/backend/backend/src/utils/defaultPrompts.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/defaultPrompts.js +16 -0
- package/dist/backend/backend/src/utils/defaultPrompts.js.map +1 -1
- package/dist/backend/backend/src/utils/gemini-trusted-folders.d.ts +43 -0
- package/dist/backend/backend/src/utils/gemini-trusted-folders.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/gemini-trusted-folders.js +94 -0
- package/dist/backend/backend/src/utils/gemini-trusted-folders.js.map +1 -0
- package/dist/backend/backend/src/utils/message-serializer.d.ts +74 -0
- package/dist/backend/backend/src/utils/message-serializer.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/message-serializer.js +380 -0
- package/dist/backend/backend/src/utils/message-serializer.js.map +1 -0
- package/dist/backend/backend/src/utils/terminal-string-ops.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/terminal-string-ops.js +20 -11
- package/dist/backend/backend/src/utils/terminal-string-ops.js.map +1 -1
- package/dist/backend/config/constants.d.ts +40 -1
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +41 -1
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/backend/config/index.d.ts +2 -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 +303 -15
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +296 -15
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/models/Team.d.ts +5 -0
- package/dist/cli/backend/src/models/Team.d.ts.map +1 -1
- package/dist/cli/backend/src/models/Team.js +24 -0
- package/dist/cli/backend/src/models/Team.js.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.js +5 -0
- package/dist/cli/backend/src/services/core/storage.service.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 +39 -1
- package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/chat.types.js +45 -2
- package/dist/cli/backend/src/types/chat.types.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +54 -4
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/types/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 -0
- package/dist/cli/backend/src/types/settings.types.js.map +1 -1
- package/dist/cli/backend/src/utils/gemini-trusted-folders.d.ts +43 -0
- package/dist/cli/backend/src/utils/gemini-trusted-folders.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/gemini-trusted-folders.js +94 -0
- package/dist/cli/backend/src/utils/gemini-trusted-folders.js.map +1 -0
- package/dist/cli/backend/src/utils/terminal-string-ops.d.ts.map +1 -1
- package/dist/cli/backend/src/utils/terminal-string-ops.js +20 -11
- package/dist/cli/backend/src/utils/terminal-string-ops.js.map +1 -1
- package/dist/cli/cli/src/commands/onboard.d.ts +2 -1
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +21 -8
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/dist/cli/cli/src/commands/start.d.ts +1 -0
- package/dist/cli/cli/src/commands/start.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/start.js +71 -23
- package/dist/cli/cli/src/commands/start.js.map +1 -1
- package/dist/cli/cli/src/constants.d.ts +1 -1
- package/dist/cli/cli/src/constants.d.ts.map +1 -1
- package/dist/cli/cli/src/constants.js +1 -1
- package/dist/cli/cli/src/constants.js.map +1 -1
- package/dist/cli/cli/src/index.js +1 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/cli/src/utils/project-scaffold.d.ts +109 -0
- package/dist/cli/cli/src/utils/project-scaffold.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/project-scaffold.js +346 -0
- package/dist/cli/cli/src/utils/project-scaffold.js.map +1 -0
- package/dist/cli/cli/src/utils/templates.d.ts +7 -2
- package/dist/cli/cli/src/utils/templates.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/templates.js +76 -7
- package/dist/cli/cli/src/utils/templates.js.map +1 -1
- package/dist/cli/config/constants.d.ts +40 -1
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +41 -1
- package/dist/cli/config/constants.js.map +1 -1
- package/dist/cli/config/index.d.ts +2 -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-510ab719.css +33 -0
- package/frontend/dist/assets/index-935cd846.js +4961 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +9 -4
- package/frontend/dist/assets/index-a23214ae.js +0 -4919
- package/frontend/dist/assets/index-c407fe13.css +0 -33
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relay Server Service
|
|
3
|
+
*
|
|
4
|
+
* WebSocket server that accepts connections from Crewly instances,
|
|
5
|
+
* assigns session IDs, pairs nodes by pairing code, and relays
|
|
6
|
+
* encrypted messages between paired instances.
|
|
7
|
+
*
|
|
8
|
+
* The server never inspects or decrypts message payloads (E2EE).
|
|
9
|
+
* It only reads the wire protocol envelope to route messages.
|
|
10
|
+
*
|
|
11
|
+
* @module services/cloud/relay-server.service
|
|
12
|
+
*/
|
|
13
|
+
import type { Server as HttpServer } from 'http';
|
|
14
|
+
import { type RelaySession } from './relay.types.js';
|
|
15
|
+
/**
|
|
16
|
+
* RelayServerService singleton.
|
|
17
|
+
*
|
|
18
|
+
* Manages the WebSocket server lifecycle, client connections, pairing,
|
|
19
|
+
* and message forwarding between paired Crewly instances.
|
|
20
|
+
*/
|
|
21
|
+
export declare class RelayServerService {
|
|
22
|
+
private static instance;
|
|
23
|
+
private readonly logger;
|
|
24
|
+
/** WebSocket server instance */
|
|
25
|
+
private wss;
|
|
26
|
+
/** Map of session ID → connected client */
|
|
27
|
+
private clients;
|
|
28
|
+
/** Map of pairing code → array of session IDs waiting to pair */
|
|
29
|
+
private pairingQueue;
|
|
30
|
+
/** Whether the server is running */
|
|
31
|
+
private running;
|
|
32
|
+
/** Cleanup function for the HTTP server upgrade listener (when using noServer mode) */
|
|
33
|
+
private removeUpgradeListener;
|
|
34
|
+
private constructor();
|
|
35
|
+
/**
|
|
36
|
+
* Get the singleton instance.
|
|
37
|
+
*
|
|
38
|
+
* @returns RelayServerService instance
|
|
39
|
+
*/
|
|
40
|
+
static getInstance(): RelayServerService;
|
|
41
|
+
/**
|
|
42
|
+
* Reset the singleton (for testing).
|
|
43
|
+
*/
|
|
44
|
+
static resetInstance(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Start the relay WebSocket server.
|
|
47
|
+
*
|
|
48
|
+
* Can attach to an existing HTTP server or listen on a standalone port.
|
|
49
|
+
*
|
|
50
|
+
* @param options - Server options: either an httpServer or a port number
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const relay = RelayServerService.getInstance();
|
|
55
|
+
* relay.start({ port: 8787 });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
start(options: {
|
|
59
|
+
httpServer?: HttpServer;
|
|
60
|
+
port?: number;
|
|
61
|
+
path?: string;
|
|
62
|
+
}): void;
|
|
63
|
+
/**
|
|
64
|
+
* Stop the relay server and close all connections.
|
|
65
|
+
*
|
|
66
|
+
* @returns Promise that resolves when the server is fully closed
|
|
67
|
+
*/
|
|
68
|
+
stop(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Check whether the relay server is currently running.
|
|
71
|
+
*
|
|
72
|
+
* @returns true if running
|
|
73
|
+
*/
|
|
74
|
+
isRunning(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Get the number of currently connected clients.
|
|
77
|
+
*
|
|
78
|
+
* @returns Client count
|
|
79
|
+
*/
|
|
80
|
+
getClientCount(): number;
|
|
81
|
+
/**
|
|
82
|
+
* Get a snapshot of all active sessions.
|
|
83
|
+
*
|
|
84
|
+
* @returns Array of relay session metadata
|
|
85
|
+
*/
|
|
86
|
+
getSessions(): RelaySession[];
|
|
87
|
+
/**
|
|
88
|
+
* Handle a new WebSocket connection.
|
|
89
|
+
*
|
|
90
|
+
* Sets up message, close, and error handlers. The client must send
|
|
91
|
+
* a `register` message within the handshake timeout or be disconnected.
|
|
92
|
+
*
|
|
93
|
+
* @param ws - Incoming WebSocket connection
|
|
94
|
+
*/
|
|
95
|
+
private handleConnection;
|
|
96
|
+
/**
|
|
97
|
+
* Handle a register message from a client.
|
|
98
|
+
*
|
|
99
|
+
* Assigns a session ID, stores the client, and attempts pairing
|
|
100
|
+
* if another client with the same pairing code is waiting.
|
|
101
|
+
*
|
|
102
|
+
* @param ws - Client WebSocket
|
|
103
|
+
* @param msg - Registration message
|
|
104
|
+
*/
|
|
105
|
+
private handleRegister;
|
|
106
|
+
/**
|
|
107
|
+
* Attempt to pair a newly registered client with an existing one.
|
|
108
|
+
*
|
|
109
|
+
* Two clients are paired when they share the same pairing code and
|
|
110
|
+
* have complementary roles (orchestrator + agent).
|
|
111
|
+
*
|
|
112
|
+
* @param sessionId - Session ID of the newly registered client
|
|
113
|
+
* @param pairingCode - Pairing code to match
|
|
114
|
+
*/
|
|
115
|
+
private attemptPairing;
|
|
116
|
+
/**
|
|
117
|
+
* Complete pairing between two sessions.
|
|
118
|
+
*
|
|
119
|
+
* Updates both sessions to 'paired' state and sends paired messages
|
|
120
|
+
* to both clients.
|
|
121
|
+
*
|
|
122
|
+
* @param idA - First session ID
|
|
123
|
+
* @param idB - Second session ID
|
|
124
|
+
*/
|
|
125
|
+
private completePairing;
|
|
126
|
+
/**
|
|
127
|
+
* Forward a relay message from one peer to its paired counterpart.
|
|
128
|
+
*
|
|
129
|
+
* The payload is forwarded unchanged — the server never decrypts it.
|
|
130
|
+
*
|
|
131
|
+
* @param senderSessionId - Session ID of the sending client
|
|
132
|
+
* @param msg - Relay data message with encrypted payload
|
|
133
|
+
*/
|
|
134
|
+
private handleRelay;
|
|
135
|
+
/**
|
|
136
|
+
* Handle a heartbeat from a client by resetting its timeout timer.
|
|
137
|
+
*
|
|
138
|
+
* @param sessionId - Session ID of the heartbeating client
|
|
139
|
+
*/
|
|
140
|
+
private handleHeartbeat;
|
|
141
|
+
/**
|
|
142
|
+
* Handle a client disconnection.
|
|
143
|
+
*
|
|
144
|
+
* Cleans up the session, removes from pairing queue, and notifies
|
|
145
|
+
* the paired peer if applicable.
|
|
146
|
+
*
|
|
147
|
+
* @param sessionId - Session ID of the disconnected client
|
|
148
|
+
*/
|
|
149
|
+
private handleDisconnect;
|
|
150
|
+
/**
|
|
151
|
+
* Find the session ID associated with a WebSocket connection.
|
|
152
|
+
*
|
|
153
|
+
* @param ws - WebSocket to look up
|
|
154
|
+
* @returns Session ID or undefined
|
|
155
|
+
*/
|
|
156
|
+
private findSessionIdByWs;
|
|
157
|
+
/**
|
|
158
|
+
* Start a heartbeat timeout timer for a session.
|
|
159
|
+
*
|
|
160
|
+
* If no heartbeat is received within the timeout window, the client
|
|
161
|
+
* is disconnected.
|
|
162
|
+
*
|
|
163
|
+
* @param sessionId - Session ID to monitor
|
|
164
|
+
* @returns Timer handle
|
|
165
|
+
*/
|
|
166
|
+
private startHeartbeatTimer;
|
|
167
|
+
/**
|
|
168
|
+
* Send a typed relay message to a WebSocket.
|
|
169
|
+
*
|
|
170
|
+
* @param ws - Target WebSocket
|
|
171
|
+
* @param message - Relay message to send
|
|
172
|
+
*/
|
|
173
|
+
private send;
|
|
174
|
+
/**
|
|
175
|
+
* Send an error message to a WebSocket.
|
|
176
|
+
*
|
|
177
|
+
* @param ws - Target WebSocket (or null if unavailable)
|
|
178
|
+
* @param code - Machine-readable error code
|
|
179
|
+
* @param message - Human-readable error description
|
|
180
|
+
*/
|
|
181
|
+
private sendError;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=relay-server.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-server.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/relay-server.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAmB,MAAM,MAAM,CAAC;AAIlE,OAAO,EAEL,KAAK,YAAY,EAUlB,MAAM,kBAAkB,CAAC;AAgC1B;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,gCAAgC;IAChC,OAAO,CAAC,GAAG,CAAgC;IAC3C,2CAA2C;IAC3C,OAAO,CAAC,OAAO,CAAmD;IAClE,iEAAiE;IACjE,OAAO,CAAC,YAAY,CAA4C;IAChE,oCAAoC;IACpC,OAAO,CAAC,OAAO,CAAS;IACxB,uFAAuF;IACvF,OAAO,CAAC,qBAAqB,CAA6B;IAE1D,OAAO;IAIP;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,kBAAkB;IAOxC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAQ5B;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,OAAO,EAAE;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAsD/E;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;OAIG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;OAIG;IACH,WAAW,IAAI,YAAY,EAAE;IAc7B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IA0ExB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAgCtB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IA+BtB;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAiCvB;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;IAkBnB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IA6CxB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;;OAKG;IACH,OAAO,CAAC,IAAI;IAMZ;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;CAKlB"}
|
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relay Server Service
|
|
3
|
+
*
|
|
4
|
+
* WebSocket server that accepts connections from Crewly instances,
|
|
5
|
+
* assigns session IDs, pairs nodes by pairing code, and relays
|
|
6
|
+
* encrypted messages between paired instances.
|
|
7
|
+
*
|
|
8
|
+
* The server never inspects or decrypts message payloads (E2EE).
|
|
9
|
+
* It only reads the wire protocol envelope to route messages.
|
|
10
|
+
*
|
|
11
|
+
* @module services/cloud/relay-server.service
|
|
12
|
+
*/
|
|
13
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
14
|
+
import { randomUUID } from 'crypto';
|
|
15
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
16
|
+
import { CLOUD_CONSTANTS } from '../../constants.js';
|
|
17
|
+
import { isRelayMessage, } from './relay.types.js';
|
|
18
|
+
const RELAY = CLOUD_CONSTANTS.RELAY;
|
|
19
|
+
/** Named WebSocket close codes used by the relay server. */
|
|
20
|
+
const WS_CLOSE = {
|
|
21
|
+
/** Normal server shutdown */
|
|
22
|
+
SERVER_SHUTDOWN: 1001,
|
|
23
|
+
/** Client failed to register within the handshake window */
|
|
24
|
+
HANDSHAKE_TIMEOUT: 4001,
|
|
25
|
+
/** Client missed heartbeat deadline */
|
|
26
|
+
HEARTBEAT_TIMEOUT: 4002,
|
|
27
|
+
};
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Service
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* RelayServerService singleton.
|
|
33
|
+
*
|
|
34
|
+
* Manages the WebSocket server lifecycle, client connections, pairing,
|
|
35
|
+
* and message forwarding between paired Crewly instances.
|
|
36
|
+
*/
|
|
37
|
+
export class RelayServerService {
|
|
38
|
+
static instance = null;
|
|
39
|
+
logger;
|
|
40
|
+
/** WebSocket server instance */
|
|
41
|
+
wss = null;
|
|
42
|
+
/** Map of session ID → connected client */
|
|
43
|
+
clients = new Map();
|
|
44
|
+
/** Map of pairing code → array of session IDs waiting to pair */
|
|
45
|
+
pairingQueue = new Map();
|
|
46
|
+
/** Whether the server is running */
|
|
47
|
+
running = false;
|
|
48
|
+
/** Cleanup function for the HTTP server upgrade listener (when using noServer mode) */
|
|
49
|
+
removeUpgradeListener = null;
|
|
50
|
+
constructor() {
|
|
51
|
+
this.logger = LoggerService.getInstance().createComponentLogger('RelayServerService');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the singleton instance.
|
|
55
|
+
*
|
|
56
|
+
* @returns RelayServerService instance
|
|
57
|
+
*/
|
|
58
|
+
static getInstance() {
|
|
59
|
+
if (!RelayServerService.instance) {
|
|
60
|
+
RelayServerService.instance = new RelayServerService();
|
|
61
|
+
}
|
|
62
|
+
return RelayServerService.instance;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Reset the singleton (for testing).
|
|
66
|
+
*/
|
|
67
|
+
static resetInstance() {
|
|
68
|
+
RelayServerService.instance = null;
|
|
69
|
+
}
|
|
70
|
+
// -------------------------------------------------------------------------
|
|
71
|
+
// Public API
|
|
72
|
+
// -------------------------------------------------------------------------
|
|
73
|
+
/**
|
|
74
|
+
* Start the relay WebSocket server.
|
|
75
|
+
*
|
|
76
|
+
* Can attach to an existing HTTP server or listen on a standalone port.
|
|
77
|
+
*
|
|
78
|
+
* @param options - Server options: either an httpServer or a port number
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const relay = RelayServerService.getInstance();
|
|
83
|
+
* relay.start({ port: 8787 });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
start(options) {
|
|
87
|
+
if (this.running) {
|
|
88
|
+
this.logger.warn('Relay server already running');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const relayPath = options.path ?? '/relay';
|
|
92
|
+
if (options.httpServer) {
|
|
93
|
+
// Use noServer mode to avoid conflicting with Socket.IO's upgrade handler.
|
|
94
|
+
// The ws library's default { server } mode registers an upgrade listener
|
|
95
|
+
// that calls handleUpgrade for ALL paths, which breaks Socket.IO's
|
|
96
|
+
// WebSocket transport on the same HTTP server.
|
|
97
|
+
this.wss = new WebSocketServer({
|
|
98
|
+
noServer: true,
|
|
99
|
+
maxPayload: RELAY.MAX_PAYLOAD_BYTES,
|
|
100
|
+
});
|
|
101
|
+
const onUpgrade = (req, socket, head) => {
|
|
102
|
+
const url = req.url ?? '';
|
|
103
|
+
const pathname = url.indexOf('?') !== -1 ? url.slice(0, url.indexOf('?')) : url;
|
|
104
|
+
if (pathname === relayPath) {
|
|
105
|
+
this.wss.handleUpgrade(req, socket, head, (ws) => {
|
|
106
|
+
this.wss.emit('connection', ws, req);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Non-matching paths are left for other handlers (e.g. Socket.IO)
|
|
110
|
+
};
|
|
111
|
+
options.httpServer.on('upgrade', onUpgrade);
|
|
112
|
+
this.removeUpgradeListener = () => {
|
|
113
|
+
options.httpServer.removeListener('upgrade', onUpgrade);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.wss = new WebSocketServer({
|
|
118
|
+
port: options.port ?? RELAY.DEFAULT_PORT,
|
|
119
|
+
path: relayPath,
|
|
120
|
+
maxPayload: RELAY.MAX_PAYLOAD_BYTES,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
this.running = true;
|
|
124
|
+
this.wss.on('connection', (ws) => {
|
|
125
|
+
this.handleConnection(ws);
|
|
126
|
+
});
|
|
127
|
+
this.logger.info('Relay server started', {
|
|
128
|
+
path: relayPath,
|
|
129
|
+
port: options.port ?? (options.httpServer ? 'attached' : RELAY.DEFAULT_PORT),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Stop the relay server and close all connections.
|
|
134
|
+
*
|
|
135
|
+
* @returns Promise that resolves when the server is fully closed
|
|
136
|
+
*/
|
|
137
|
+
async stop() {
|
|
138
|
+
if (!this.running || !this.wss) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this.running = false;
|
|
142
|
+
// Remove HTTP server upgrade listener if using noServer mode
|
|
143
|
+
if (this.removeUpgradeListener) {
|
|
144
|
+
this.removeUpgradeListener();
|
|
145
|
+
this.removeUpgradeListener = null;
|
|
146
|
+
}
|
|
147
|
+
// Clear all heartbeat timers
|
|
148
|
+
for (const client of this.clients.values()) {
|
|
149
|
+
if (client.heartbeatTimer) {
|
|
150
|
+
clearTimeout(client.heartbeatTimer);
|
|
151
|
+
}
|
|
152
|
+
client.ws.close(WS_CLOSE.SERVER_SHUTDOWN, 'Server shutting down');
|
|
153
|
+
}
|
|
154
|
+
this.clients.clear();
|
|
155
|
+
this.pairingQueue.clear();
|
|
156
|
+
return new Promise((resolve) => {
|
|
157
|
+
this.wss.close(() => {
|
|
158
|
+
this.wss = null;
|
|
159
|
+
this.logger.info('Relay server stopped');
|
|
160
|
+
resolve();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Check whether the relay server is currently running.
|
|
166
|
+
*
|
|
167
|
+
* @returns true if running
|
|
168
|
+
*/
|
|
169
|
+
isRunning() {
|
|
170
|
+
return this.running;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get the number of currently connected clients.
|
|
174
|
+
*
|
|
175
|
+
* @returns Client count
|
|
176
|
+
*/
|
|
177
|
+
getClientCount() {
|
|
178
|
+
return this.clients.size;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get a snapshot of all active sessions.
|
|
182
|
+
*
|
|
183
|
+
* @returns Array of relay session metadata
|
|
184
|
+
*/
|
|
185
|
+
getSessions() {
|
|
186
|
+
const sessions = [];
|
|
187
|
+
for (const client of this.clients.values()) {
|
|
188
|
+
if (client.session) {
|
|
189
|
+
sessions.push({ ...client.session });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return sessions;
|
|
193
|
+
}
|
|
194
|
+
// -------------------------------------------------------------------------
|
|
195
|
+
// Connection handling
|
|
196
|
+
// -------------------------------------------------------------------------
|
|
197
|
+
/**
|
|
198
|
+
* Handle a new WebSocket connection.
|
|
199
|
+
*
|
|
200
|
+
* Sets up message, close, and error handlers. The client must send
|
|
201
|
+
* a `register` message within the handshake timeout or be disconnected.
|
|
202
|
+
*
|
|
203
|
+
* @param ws - Incoming WebSocket connection
|
|
204
|
+
*/
|
|
205
|
+
handleConnection(ws) {
|
|
206
|
+
const tempId = `pending-${randomUUID()}`;
|
|
207
|
+
this.logger.debug('New WebSocket connection', { tempId });
|
|
208
|
+
// Handshake timeout: client must register within the window
|
|
209
|
+
const handshakeTimer = setTimeout(() => {
|
|
210
|
+
this.sendError(ws, 'HANDSHAKE_TIMEOUT', 'Registration timeout — send a register message');
|
|
211
|
+
ws.close(WS_CLOSE.HANDSHAKE_TIMEOUT, 'Handshake timeout');
|
|
212
|
+
}, RELAY.HANDSHAKE_TIMEOUT_MS);
|
|
213
|
+
ws.on('message', (data) => {
|
|
214
|
+
const raw = typeof data === 'string' ? data : data.toString('utf8');
|
|
215
|
+
let parsed;
|
|
216
|
+
try {
|
|
217
|
+
parsed = JSON.parse(raw);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
this.sendError(ws, 'INVALID_JSON', 'Message is not valid JSON');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (!isRelayMessage(parsed)) {
|
|
224
|
+
this.sendError(ws, 'INVALID_MESSAGE', 'Unknown or malformed relay message');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const msg = parsed;
|
|
228
|
+
if (msg.type === 'register') {
|
|
229
|
+
clearTimeout(handshakeTimer);
|
|
230
|
+
this.handleRegister(ws, msg);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// All other message types require a registered session
|
|
234
|
+
const sessionId = this.findSessionIdByWs(ws);
|
|
235
|
+
if (!sessionId) {
|
|
236
|
+
this.sendError(ws, 'NOT_REGISTERED', 'Send a register message first');
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
switch (msg.type) {
|
|
240
|
+
case 'relay':
|
|
241
|
+
this.handleRelay(sessionId, msg);
|
|
242
|
+
break;
|
|
243
|
+
case 'heartbeat':
|
|
244
|
+
this.handleHeartbeat(sessionId);
|
|
245
|
+
break;
|
|
246
|
+
default:
|
|
247
|
+
this.sendError(ws, 'UNEXPECTED_TYPE', `Unexpected message type: ${msg.type}`);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
ws.on('close', () => {
|
|
251
|
+
clearTimeout(handshakeTimer);
|
|
252
|
+
const sessionId = this.findSessionIdByWs(ws);
|
|
253
|
+
if (sessionId) {
|
|
254
|
+
this.handleDisconnect(sessionId);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
ws.on('error', (err) => {
|
|
258
|
+
this.logger.error('WebSocket error', { error: err.message });
|
|
259
|
+
const sessionId = this.findSessionIdByWs(ws);
|
|
260
|
+
if (sessionId) {
|
|
261
|
+
this.handleDisconnect(sessionId);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
// -------------------------------------------------------------------------
|
|
266
|
+
// Message handlers
|
|
267
|
+
// -------------------------------------------------------------------------
|
|
268
|
+
/**
|
|
269
|
+
* Handle a register message from a client.
|
|
270
|
+
*
|
|
271
|
+
* Assigns a session ID, stores the client, and attempts pairing
|
|
272
|
+
* if another client with the same pairing code is waiting.
|
|
273
|
+
*
|
|
274
|
+
* @param ws - Client WebSocket
|
|
275
|
+
* @param msg - Registration message
|
|
276
|
+
*/
|
|
277
|
+
handleRegister(ws, msg) {
|
|
278
|
+
const sessionId = randomUUID();
|
|
279
|
+
const now = new Date().toISOString();
|
|
280
|
+
const session = {
|
|
281
|
+
sessionId,
|
|
282
|
+
role: msg.role,
|
|
283
|
+
pairingCode: msg.pairingCode,
|
|
284
|
+
state: 'waiting',
|
|
285
|
+
pairedWith: null,
|
|
286
|
+
registeredAt: now,
|
|
287
|
+
lastHeartbeatAt: now,
|
|
288
|
+
};
|
|
289
|
+
const client = {
|
|
290
|
+
ws,
|
|
291
|
+
session,
|
|
292
|
+
heartbeatTimer: this.startHeartbeatTimer(sessionId),
|
|
293
|
+
};
|
|
294
|
+
this.clients.set(sessionId, client);
|
|
295
|
+
// Send registration confirmation
|
|
296
|
+
const registered = { type: 'registered', sessionId };
|
|
297
|
+
this.send(ws, registered);
|
|
298
|
+
this.logger.info('Client registered', { sessionId, role: msg.role, pairingCode: msg.pairingCode });
|
|
299
|
+
// Attempt pairing
|
|
300
|
+
this.attemptPairing(sessionId, msg.pairingCode);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Attempt to pair a newly registered client with an existing one.
|
|
304
|
+
*
|
|
305
|
+
* Two clients are paired when they share the same pairing code and
|
|
306
|
+
* have complementary roles (orchestrator + agent).
|
|
307
|
+
*
|
|
308
|
+
* @param sessionId - Session ID of the newly registered client
|
|
309
|
+
* @param pairingCode - Pairing code to match
|
|
310
|
+
*/
|
|
311
|
+
attemptPairing(sessionId, pairingCode) {
|
|
312
|
+
const queue = this.pairingQueue.get(pairingCode) ?? [];
|
|
313
|
+
// Look for a compatible peer in the queue
|
|
314
|
+
const newClient = this.clients.get(sessionId);
|
|
315
|
+
if (!newClient?.session)
|
|
316
|
+
return;
|
|
317
|
+
const peerIndex = queue.findIndex((peerId) => {
|
|
318
|
+
const peer = this.clients.get(peerId);
|
|
319
|
+
if (!peer?.session)
|
|
320
|
+
return false;
|
|
321
|
+
// Pair orchestrator with agent (different roles)
|
|
322
|
+
return peer.session.role !== newClient.session.role && peer.session.state === 'waiting';
|
|
323
|
+
});
|
|
324
|
+
if (peerIndex >= 0) {
|
|
325
|
+
const peerId = queue[peerIndex];
|
|
326
|
+
queue.splice(peerIndex, 1);
|
|
327
|
+
if (queue.length === 0) {
|
|
328
|
+
this.pairingQueue.delete(pairingCode);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
this.pairingQueue.set(pairingCode, queue);
|
|
332
|
+
}
|
|
333
|
+
this.completePairing(sessionId, peerId);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
// No peer yet — add to queue
|
|
337
|
+
queue.push(sessionId);
|
|
338
|
+
this.pairingQueue.set(pairingCode, queue);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Complete pairing between two sessions.
|
|
343
|
+
*
|
|
344
|
+
* Updates both sessions to 'paired' state and sends paired messages
|
|
345
|
+
* to both clients.
|
|
346
|
+
*
|
|
347
|
+
* @param idA - First session ID
|
|
348
|
+
* @param idB - Second session ID
|
|
349
|
+
*/
|
|
350
|
+
completePairing(idA, idB) {
|
|
351
|
+
const clientA = this.clients.get(idA);
|
|
352
|
+
const clientB = this.clients.get(idB);
|
|
353
|
+
if (!clientA?.session || !clientB?.session)
|
|
354
|
+
return;
|
|
355
|
+
clientA.session.state = 'paired';
|
|
356
|
+
clientA.session.pairedWith = idB;
|
|
357
|
+
clientB.session.state = 'paired';
|
|
358
|
+
clientB.session.pairedWith = idA;
|
|
359
|
+
const pairedA = {
|
|
360
|
+
type: 'paired',
|
|
361
|
+
peerSessionId: idB,
|
|
362
|
+
peerRole: clientB.session.role,
|
|
363
|
+
};
|
|
364
|
+
const pairedB = {
|
|
365
|
+
type: 'paired',
|
|
366
|
+
peerSessionId: idA,
|
|
367
|
+
peerRole: clientA.session.role,
|
|
368
|
+
};
|
|
369
|
+
this.send(clientA.ws, pairedA);
|
|
370
|
+
this.send(clientB.ws, pairedB);
|
|
371
|
+
this.logger.info('Clients paired', {
|
|
372
|
+
sessionA: idA,
|
|
373
|
+
roleA: clientA.session.role,
|
|
374
|
+
sessionB: idB,
|
|
375
|
+
roleB: clientB.session.role,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Forward a relay message from one peer to its paired counterpart.
|
|
380
|
+
*
|
|
381
|
+
* The payload is forwarded unchanged — the server never decrypts it.
|
|
382
|
+
*
|
|
383
|
+
* @param senderSessionId - Session ID of the sending client
|
|
384
|
+
* @param msg - Relay data message with encrypted payload
|
|
385
|
+
*/
|
|
386
|
+
handleRelay(senderSessionId, msg) {
|
|
387
|
+
const sender = this.clients.get(senderSessionId);
|
|
388
|
+
if (!sender?.session?.pairedWith) {
|
|
389
|
+
this.sendError(sender?.ws ?? null, 'NOT_PAIRED', 'Cannot relay — not paired with a peer');
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const peer = this.clients.get(sender.session.pairedWith);
|
|
393
|
+
if (!peer) {
|
|
394
|
+
this.sendError(sender.ws, 'PEER_UNAVAILABLE', 'Paired peer is no longer connected');
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
// Forward the encrypted payload as-is
|
|
398
|
+
const forwarded = { type: 'relay', payload: msg.payload };
|
|
399
|
+
this.send(peer.ws, forwarded);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Handle a heartbeat from a client by resetting its timeout timer.
|
|
403
|
+
*
|
|
404
|
+
* @param sessionId - Session ID of the heartbeating client
|
|
405
|
+
*/
|
|
406
|
+
handleHeartbeat(sessionId) {
|
|
407
|
+
const client = this.clients.get(sessionId);
|
|
408
|
+
if (!client?.session)
|
|
409
|
+
return;
|
|
410
|
+
client.session.lastHeartbeatAt = new Date().toISOString();
|
|
411
|
+
// Reset heartbeat timer
|
|
412
|
+
if (client.heartbeatTimer) {
|
|
413
|
+
clearTimeout(client.heartbeatTimer);
|
|
414
|
+
}
|
|
415
|
+
client.heartbeatTimer = this.startHeartbeatTimer(sessionId);
|
|
416
|
+
const ack = { type: 'heartbeat_ack' };
|
|
417
|
+
this.send(client.ws, ack);
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Handle a client disconnection.
|
|
421
|
+
*
|
|
422
|
+
* Cleans up the session, removes from pairing queue, and notifies
|
|
423
|
+
* the paired peer if applicable.
|
|
424
|
+
*
|
|
425
|
+
* @param sessionId - Session ID of the disconnected client
|
|
426
|
+
*/
|
|
427
|
+
handleDisconnect(sessionId) {
|
|
428
|
+
const client = this.clients.get(sessionId);
|
|
429
|
+
if (!client)
|
|
430
|
+
return;
|
|
431
|
+
if (client.heartbeatTimer) {
|
|
432
|
+
clearTimeout(client.heartbeatTimer);
|
|
433
|
+
}
|
|
434
|
+
// Notify peer of disconnection
|
|
435
|
+
if (client.session?.pairedWith) {
|
|
436
|
+
const peer = this.clients.get(client.session.pairedWith);
|
|
437
|
+
if (peer?.session) {
|
|
438
|
+
peer.session.state = 'waiting';
|
|
439
|
+
peer.session.pairedWith = null;
|
|
440
|
+
const disconnected = {
|
|
441
|
+
type: 'peer_disconnected',
|
|
442
|
+
peerSessionId: sessionId,
|
|
443
|
+
};
|
|
444
|
+
this.send(peer.ws, disconnected);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// Remove from pairing queue
|
|
448
|
+
if (client.session) {
|
|
449
|
+
const queue = this.pairingQueue.get(client.session.pairingCode);
|
|
450
|
+
if (queue) {
|
|
451
|
+
const idx = queue.indexOf(sessionId);
|
|
452
|
+
if (idx >= 0) {
|
|
453
|
+
queue.splice(idx, 1);
|
|
454
|
+
if (queue.length === 0) {
|
|
455
|
+
this.pairingQueue.delete(client.session.pairingCode);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
this.clients.delete(sessionId);
|
|
461
|
+
this.logger.info('Client disconnected', { sessionId });
|
|
462
|
+
}
|
|
463
|
+
// -------------------------------------------------------------------------
|
|
464
|
+
// Helpers
|
|
465
|
+
// -------------------------------------------------------------------------
|
|
466
|
+
/**
|
|
467
|
+
* Find the session ID associated with a WebSocket connection.
|
|
468
|
+
*
|
|
469
|
+
* @param ws - WebSocket to look up
|
|
470
|
+
* @returns Session ID or undefined
|
|
471
|
+
*/
|
|
472
|
+
findSessionIdByWs(ws) {
|
|
473
|
+
for (const [sessionId, client] of this.clients.entries()) {
|
|
474
|
+
if (client.ws === ws)
|
|
475
|
+
return sessionId;
|
|
476
|
+
}
|
|
477
|
+
return undefined;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Start a heartbeat timeout timer for a session.
|
|
481
|
+
*
|
|
482
|
+
* If no heartbeat is received within the timeout window, the client
|
|
483
|
+
* is disconnected.
|
|
484
|
+
*
|
|
485
|
+
* @param sessionId - Session ID to monitor
|
|
486
|
+
* @returns Timer handle
|
|
487
|
+
*/
|
|
488
|
+
startHeartbeatTimer(sessionId) {
|
|
489
|
+
return setTimeout(() => {
|
|
490
|
+
this.logger.warn('Heartbeat timeout', { sessionId });
|
|
491
|
+
const client = this.clients.get(sessionId);
|
|
492
|
+
if (client) {
|
|
493
|
+
client.ws.close(WS_CLOSE.HEARTBEAT_TIMEOUT, 'Heartbeat timeout');
|
|
494
|
+
this.handleDisconnect(sessionId);
|
|
495
|
+
}
|
|
496
|
+
}, RELAY.HEARTBEAT_TIMEOUT_MS);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Send a typed relay message to a WebSocket.
|
|
500
|
+
*
|
|
501
|
+
* @param ws - Target WebSocket
|
|
502
|
+
* @param message - Relay message to send
|
|
503
|
+
*/
|
|
504
|
+
send(ws, message) {
|
|
505
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
506
|
+
ws.send(JSON.stringify(message));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Send an error message to a WebSocket.
|
|
511
|
+
*
|
|
512
|
+
* @param ws - Target WebSocket (or null if unavailable)
|
|
513
|
+
* @param code - Machine-readable error code
|
|
514
|
+
* @param message - Human-readable error description
|
|
515
|
+
*/
|
|
516
|
+
sendError(ws, code, message) {
|
|
517
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
518
|
+
return;
|
|
519
|
+
const errorMsg = { type: 'error', code, message };
|
|
520
|
+
ws.send(JSON.stringify(errorMsg));
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
//# sourceMappingURL=relay-server.service.js.map
|