crewly 1.0.7 → 1.0.8
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 +50 -3
- package/config/roles/architect/prompt.md +11 -0
- package/config/roles/backend-developer/prompt.md +11 -0
- package/config/roles/designer/prompt.md +11 -0
- package/config/roles/developer/prompt.md +18 -4
- package/config/roles/frontend-developer/prompt.md +11 -0
- package/config/roles/fullstack-dev/prompt.md +11 -0
- package/config/roles/generalist/prompt.md +11 -0
- package/config/roles/orchestrator/prompt.md +27 -0
- package/config/roles/product-manager/prompt.md +18 -4
- package/config/roles/qa/prompt.md +11 -0
- package/config/roles/qa-engineer/prompt.md +11 -0
- package/config/roles/sales/prompt.md +11 -0
- package/config/roles/support/prompt.md +11 -0
- package/config/roles/tpm/prompt.md +11 -0
- package/config/skills/orchestrator/complete-task/execute.sh +1 -0
- package/config/templates/agent-claude-md.md +16 -0
- package/config/templates/research-team.json +22 -0
- package/config/templates/startup-team.json +22 -0
- package/config/templates/web-dev-team.json +22 -0
- package/dist/backend/backend/src/constants.d.ts +61 -1
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +65 -7
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +7 -0
- 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 +174 -4
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +34 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/task-management.routes.js +2 -0
- package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +8 -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 +75 -17
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts +222 -0
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +621 -0
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -0
- package/dist/backend/backend/src/services/index.d.ts +3 -0
- package/dist/backend/backend/src/services/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/index.js +5 -0
- package/dist/backend/backend/src/services/index.js.map +1 -1
- package/dist/backend/backend/src/services/mcp-client.d.ts +233 -0
- package/dist/backend/backend/src/services/mcp-client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/mcp-client.js +297 -0
- package/dist/backend/backend/src/services/mcp-client.js.map +1 -0
- package/dist/backend/backend/src/services/mcp-server.d.ts +167 -0
- package/dist/backend/backend/src/services/mcp-server.d.ts.map +1 -0
- package/dist/backend/backend/src/services/mcp-server.js +586 -0
- package/dist/backend/backend/src/services/mcp-server.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts +2 -0
- 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 +6 -1
- 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 +10 -0
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +94 -38
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/quality/index.d.ts +1 -0
- package/dist/backend/backend/src/services/quality/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/quality/index.js +1 -0
- package/dist/backend/backend/src/services/quality/index.js.map +1 -1
- package/dist/backend/backend/src/services/quality/task-output-validator.service.d.ts +84 -0
- package/dist/backend/backend/src/services/quality/task-output-validator.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/quality/task-output-validator.service.js +163 -0
- package/dist/backend/backend/src/services/quality/task-output-validator.service.js.map +1 -0
- package/dist/backend/backend/src/services/runtime-adapter.d.ts +234 -0
- package/dist/backend/backend/src/services/runtime-adapter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/runtime-adapter.js +180 -0
- package/dist/backend/backend/src/services/runtime-adapter.js.map +1 -0
- package/dist/backend/backend/src/types/event-bus.types.d.ts +2 -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 +2 -0
- package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +1 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js +2 -0
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/messaging.types.d.ts +9 -6
- package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/messaging.types.js +10 -3
- package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
- package/dist/backend/backend/src/types/task-output.types.d.ts +78 -0
- package/dist/backend/backend/src/types/task-output.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/task-output.types.js +27 -0
- package/dist/backend/backend/src/types/task-output.types.js.map +1 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +13 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.js +12 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +751 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -0
- package/dist/cli/backend/src/constants.js +550 -0
- package/dist/cli/backend/src/constants.js.map +1 -0
- package/dist/cli/backend/src/models/Project.d.ts +18 -0
- package/dist/cli/backend/src/models/Project.d.ts.map +1 -0
- package/dist/cli/backend/src/models/Project.js +70 -0
- package/dist/cli/backend/src/models/Project.js.map +1 -0
- package/dist/cli/backend/src/models/ScheduledMessage.d.ts +27 -0
- package/dist/cli/backend/src/models/ScheduledMessage.d.ts.map +1 -0
- package/dist/cli/backend/src/models/ScheduledMessage.js +50 -0
- package/dist/cli/backend/src/models/ScheduledMessage.js.map +1 -0
- package/dist/cli/backend/src/models/Team.d.ts +20 -0
- package/dist/cli/backend/src/models/Team.d.ts.map +1 -0
- package/dist/cli/backend/src/models/Team.js +120 -0
- package/dist/cli/backend/src/models/Team.js.map +1 -0
- package/dist/cli/backend/src/models/Ticket.d.ts +24 -0
- package/dist/cli/backend/src/models/Ticket.d.ts.map +1 -0
- package/dist/cli/backend/src/models/Ticket.js +102 -0
- package/dist/cli/backend/src/models/Ticket.js.map +1 -0
- package/dist/cli/backend/src/models/index.d.ts +5 -0
- package/dist/cli/backend/src/models/index.d.ts.map +1 -0
- package/dist/cli/backend/src/models/index.js +5 -0
- package/dist/cli/backend/src/models/index.js.map +1 -0
- package/dist/cli/backend/src/services/core/config.service.d.ts +91 -0
- package/dist/cli/backend/src/services/core/config.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/core/config.service.js +246 -0
- package/dist/cli/backend/src/services/core/config.service.js.map +1 -0
- package/dist/cli/backend/src/services/core/logger.service.d.ts +70 -0
- package/dist/cli/backend/src/services/core/logger.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/core/logger.service.js +350 -0
- package/dist/cli/backend/src/services/core/logger.service.js.map +1 -0
- package/dist/cli/backend/src/services/core/storage.service.d.ts +269 -0
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/core/storage.service.js +1406 -0
- package/dist/cli/backend/src/services/core/storage.service.js.map +1 -0
- package/dist/cli/backend/src/services/core/teams-backup.service.d.ts +92 -0
- package/dist/cli/backend/src/services/core/teams-backup.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/core/teams-backup.service.js +120 -0
- package/dist/cli/backend/src/services/core/teams-backup.service.js.map +1 -0
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +125 -0
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +247 -0
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -0
- package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts +153 -0
- package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/knowledge/knowledge.service.js +409 -0
- package/dist/cli/backend/src/services/knowledge/knowledge.service.js.map +1 -0
- package/dist/cli/backend/src/services/mcp-server.d.ts +167 -0
- package/dist/cli/backend/src/services/mcp-server.d.ts.map +1 -0
- package/dist/cli/backend/src/services/mcp-server.js +586 -0
- package/dist/cli/backend/src/services/mcp-server.js.map +1 -0
- package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts +259 -0
- package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/memory/agent-memory.service.js +539 -0
- package/dist/cli/backend/src/services/memory/agent-memory.service.js.map +1 -0
- package/dist/cli/backend/src/services/memory/memory.service.d.ts +306 -0
- package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/memory/memory.service.js +517 -0
- package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -0
- package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +252 -0
- package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/memory/project-memory.service.js +600 -0
- package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -0
- package/dist/cli/backend/src/types/auto-assign.types.d.ts +271 -0
- package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/auto-assign.types.js +136 -0
- package/dist/cli/backend/src/types/auto-assign.types.js.map +1 -0
- package/dist/cli/backend/src/types/budget.types.d.ts +217 -0
- package/dist/cli/backend/src/types/budget.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/budget.types.js +82 -0
- package/dist/cli/backend/src/types/budget.types.js.map +1 -0
- package/dist/cli/backend/src/types/chat.types.d.ts +550 -0
- package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/chat.types.js +743 -0
- package/dist/cli/backend/src/types/chat.types.js.map +1 -0
- package/dist/cli/backend/src/types/continuation.types.d.ts +237 -0
- package/dist/cli/backend/src/types/continuation.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/continuation.types.js +10 -0
- package/dist/cli/backend/src/types/continuation.types.js.map +1 -0
- package/dist/cli/backend/src/types/index.d.ts +164 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -0
- package/dist/cli/backend/src/types/index.js +25 -0
- package/dist/cli/backend/src/types/index.js.map +1 -0
- package/dist/cli/backend/src/types/knowledge.types.d.ts +195 -0
- package/dist/cli/backend/src/types/knowledge.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/knowledge.types.js +38 -0
- package/dist/cli/backend/src/types/knowledge.types.js.map +1 -0
- package/dist/cli/backend/src/types/memory.types.d.ts +587 -0
- package/dist/cli/backend/src/types/memory.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/memory.types.js +47 -0
- package/dist/cli/backend/src/types/memory.types.js.map +1 -0
- package/dist/cli/backend/src/types/quality-gate.types.d.ts +171 -0
- package/dist/cli/backend/src/types/quality-gate.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/quality-gate.types.js +42 -0
- package/dist/cli/backend/src/types/quality-gate.types.js.map +1 -0
- package/dist/cli/backend/src/types/role.types.d.ts +260 -0
- package/dist/cli/backend/src/types/role.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/role.types.js +238 -0
- package/dist/cli/backend/src/types/role.types.js.map +1 -0
- package/dist/cli/backend/src/types/scheduler.types.d.ts +254 -0
- package/dist/cli/backend/src/types/scheduler.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/scheduler.types.js +32 -0
- package/dist/cli/backend/src/types/scheduler.types.js.map +1 -0
- package/dist/cli/backend/src/types/settings.types.d.ts +178 -0
- package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/settings.types.js +206 -0
- package/dist/cli/backend/src/types/settings.types.js.map +1 -0
- package/dist/cli/backend/src/types/skill.types.d.ts +515 -0
- package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/skill.types.js +481 -0
- package/dist/cli/backend/src/types/skill.types.js.map +1 -0
- package/dist/cli/backend/src/types/sop.types.d.ts +224 -0
- package/dist/cli/backend/src/types/sop.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/sop.types.js +85 -0
- package/dist/cli/backend/src/types/sop.types.js.map +1 -0
- package/dist/cli/backend/src/types/task-output.types.d.ts +78 -0
- package/dist/cli/backend/src/types/task-output.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/task-output.types.js +27 -0
- package/dist/cli/backend/src/types/task-output.types.js.map +1 -0
- package/dist/cli/backend/src/utils/file-io.utils.d.ts +102 -0
- package/dist/cli/backend/src/utils/file-io.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/file-io.utils.js +214 -0
- package/dist/cli/backend/src/utils/file-io.utils.js.map +1 -0
- package/dist/cli/backend/src/utils/terminal-output.utils.d.ts +54 -0
- package/dist/cli/backend/src/utils/terminal-output.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/terminal-output.utils.js +97 -0
- package/dist/cli/backend/src/utils/terminal-output.utils.js.map +1 -0
- package/dist/cli/cli/src/commands/mcp-server.d.ts +38 -0
- package/dist/cli/cli/src/commands/mcp-server.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/mcp-server.js +49 -0
- package/dist/cli/cli/src/commands/mcp-server.js.map +1 -0
- package/dist/cli/cli/src/commands/onboard.d.ts +61 -7
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +192 -19
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/dist/cli/cli/src/commands/publish.d.ts +27 -0
- package/dist/cli/cli/src/commands/publish.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/publish.js +69 -0
- package/dist/cli/cli/src/commands/publish.js.map +1 -0
- package/dist/cli/cli/src/index.js +14 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/cli/src/utils/archive-creator.d.ts +82 -0
- package/dist/cli/cli/src/utils/archive-creator.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/archive-creator.js +105 -0
- package/dist/cli/cli/src/utils/archive-creator.js.map +1 -0
- package/dist/cli/cli/src/utils/package-validator.d.ts +62 -0
- package/dist/cli/cli/src/utils/package-validator.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/package-validator.js +122 -0
- package/dist/cli/cli/src/utils/package-validator.js.map +1 -0
- package/dist/cli/cli/src/utils/templates.d.ts +71 -0
- package/dist/cli/cli/src/utils/templates.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/templates.js +91 -0
- package/dist/cli/cli/src/utils/templates.js.map +1 -0
- package/frontend/dist/assets/{index-523c7fce.js → index-68d1eb5a.js} +71 -71
- package/frontend/dist/assets/{index-4c050f52.css → index-c5043a83.css} +1 -1
- package/frontend/dist/assets/nunito-cyrillic-400-normal-e44e669f.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-400-normal-ff8e8bdd.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-500-normal-2159679b.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-500-normal-61a3b80e.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-600-normal-ac046097.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-600-normal-e61eb97b.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-700-normal-8fcefcc9.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-700-normal-b9684104.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-800-normal-40253beb.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-800-normal-d80292de.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-400-normal-20d73ae7.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-400-normal-d48c37c9.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-500-normal-16197abd.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-500-normal-9dcfe9b5.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-600-normal-d53e9851.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-600-normal-e3d0201f.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-700-normal-5936f6ac.woff2 +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-700-normal-c8c02775.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-800-normal-217b8f51.woff +0 -0
- package/frontend/dist/assets/nunito-cyrillic-ext-800-normal-796cf7bd.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-400-normal-a5906e15.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-400-normal-b51e7635.woff +0 -0
- package/frontend/dist/assets/nunito-latin-500-normal-23ae3083.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-500-normal-be14dbc6.woff +0 -0
- package/frontend/dist/assets/nunito-latin-600-normal-06a9c8b3.woff +0 -0
- package/frontend/dist/assets/nunito-latin-600-normal-45f437de.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-700-normal-ce9107dc.woff +0 -0
- package/frontend/dist/assets/nunito-latin-700-normal-fa89300b.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-800-normal-0ca02785.woff +0 -0
- package/frontend/dist/assets/nunito-latin-800-normal-2363d3ed.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-ext-400-normal-67250a41.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-ext-400-normal-d7e2415e.woff +0 -0
- package/frontend/dist/assets/nunito-latin-ext-500-normal-06f35d1c.woff +0 -0
- package/frontend/dist/assets/nunito-latin-ext-500-normal-343e7adc.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-ext-600-normal-5a8efd17.woff +0 -0
- package/frontend/dist/assets/nunito-latin-ext-600-normal-a7ba5f4f.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-ext-700-normal-0a4e4a02.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-ext-700-normal-0c607961.woff +0 -0
- package/frontend/dist/assets/nunito-latin-ext-800-normal-39f54b55.woff2 +0 -0
- package/frontend/dist/assets/nunito-latin-ext-800-normal-466d0211.woff +0 -0
- package/frontend/dist/assets/nunito-vietnamese-400-normal-2a755616.woff2 +0 -0
- package/frontend/dist/assets/nunito-vietnamese-400-normal-9c01ea9f.woff +0 -0
- package/frontend/dist/assets/nunito-vietnamese-500-normal-452e5e08.woff +0 -0
- package/frontend/dist/assets/nunito-vietnamese-500-normal-dc98d965.woff2 +0 -0
- package/frontend/dist/assets/nunito-vietnamese-600-normal-2ffbb85f.woff +0 -0
- package/frontend/dist/assets/nunito-vietnamese-600-normal-cf95b95d.woff2 +0 -0
- package/frontend/dist/assets/nunito-vietnamese-700-normal-0e29c28c.woff2 +0 -0
- package/frontend/dist/assets/nunito-vietnamese-700-normal-7793b75e.woff +0 -0
- package/frontend/dist/assets/nunito-vietnamese-800-normal-5baf507e.woff +0 -0
- package/frontend/dist/assets/nunito-vietnamese-800-normal-fac6740e.woff2 +0 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +15 -5
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Atomic File I/O Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides safe, atomic file operations for all JSON persistence in Crewly.
|
|
5
|
+
* Uses temp-file + fsync + rename to prevent corruption on crash,
|
|
6
|
+
* and in-process locks to serialize concurrent writes to the same file.
|
|
7
|
+
*
|
|
8
|
+
* @module utils/file-io.utils
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from 'fs/promises';
|
|
11
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
12
|
+
// Module-level lock maps (singleton per process — no class needed)
|
|
13
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
14
|
+
const fileLocks = new Map();
|
|
15
|
+
const operationLocks = new Map();
|
|
16
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
17
|
+
// Directory helpers
|
|
18
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Ensures a directory exists, creating it recursively if necessary.
|
|
21
|
+
*
|
|
22
|
+
* @param dirPath - Absolute path to the directory
|
|
23
|
+
*/
|
|
24
|
+
export async function ensureDir(dirPath) {
|
|
25
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
28
|
+
// Locking
|
|
29
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Acquire and hold a lock from the given map for the duration of the operation.
|
|
32
|
+
*
|
|
33
|
+
* Uses promise-chaining so each caller queues behind the previous one.
|
|
34
|
+
* This avoids the race condition where multiple awaiters of the same
|
|
35
|
+
* promise all wake up and proceed past a `while` check simultaneously.
|
|
36
|
+
*/
|
|
37
|
+
async function withLock(lockMap, lockKey, operation) {
|
|
38
|
+
// Chain behind whatever is currently queued (or resolve immediately)
|
|
39
|
+
const prevLock = lockMap.get(lockKey) ?? Promise.resolve();
|
|
40
|
+
let releaseLock;
|
|
41
|
+
const myLock = new Promise((resolve) => { releaseLock = resolve; });
|
|
42
|
+
lockMap.set(lockKey, myLock);
|
|
43
|
+
// Wait for the previous holder to finish
|
|
44
|
+
await prevLock;
|
|
45
|
+
try {
|
|
46
|
+
return await operation();
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
releaseLock();
|
|
50
|
+
// Only clean up if we're still the tail of the chain
|
|
51
|
+
if (lockMap.get(lockKey) === myLock) {
|
|
52
|
+
lockMap.delete(lockKey);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Serialize concurrent writes to the same file.
|
|
58
|
+
*
|
|
59
|
+
* @param lockKey - Unique key for the lock (typically the file path)
|
|
60
|
+
* @param operation - Async operation to run while holding the lock
|
|
61
|
+
* @returns The result of the operation
|
|
62
|
+
*/
|
|
63
|
+
export async function withFileLock(lockKey, operation) {
|
|
64
|
+
return withLock(fileLocks, lockKey, operation);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Serialize read-modify-write cycles on a logical resource.
|
|
68
|
+
*
|
|
69
|
+
* Uses a separate lock map from {@link withFileLock} so that callers
|
|
70
|
+
* can hold an operation lock across a read + write without deadlocking
|
|
71
|
+
* on the inner file lock.
|
|
72
|
+
*
|
|
73
|
+
* @param lockKey - Unique key for the lock
|
|
74
|
+
* @param operation - Async operation to run while holding the lock
|
|
75
|
+
* @returns The result of the operation
|
|
76
|
+
*/
|
|
77
|
+
export async function withOperationLock(lockKey, operation) {
|
|
78
|
+
return withLock(operationLocks, lockKey, operation);
|
|
79
|
+
}
|
|
80
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
81
|
+
// Atomic write
|
|
82
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Write a string to a file atomically (temp file → fsync → rename).
|
|
85
|
+
*
|
|
86
|
+
* Acquires a per-path file lock so concurrent callers targeting the
|
|
87
|
+
* same path are serialized.
|
|
88
|
+
*
|
|
89
|
+
* **Precondition:** The parent directory must already exist. This function
|
|
90
|
+
* does not create intermediate directories — use {@link ensureDir} first
|
|
91
|
+
* if the directory may not exist.
|
|
92
|
+
*
|
|
93
|
+
* @param filePath - Destination file path
|
|
94
|
+
* @param content - String content to write
|
|
95
|
+
*/
|
|
96
|
+
export async function atomicWriteFile(filePath, content) {
|
|
97
|
+
await withFileLock(filePath, async () => {
|
|
98
|
+
const tempPath = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).substring(2)}`;
|
|
99
|
+
try {
|
|
100
|
+
await fs.writeFile(tempPath, content, 'utf8');
|
|
101
|
+
// Ensure data hits the disk before the atomic rename
|
|
102
|
+
const handle = await fs.open(tempPath, 'r+');
|
|
103
|
+
await handle.sync();
|
|
104
|
+
await handle.close();
|
|
105
|
+
await fs.rename(tempPath, filePath);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// Clean up temp file on failure
|
|
109
|
+
try {
|
|
110
|
+
await fs.unlink(tempPath);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Ignore cleanup errors
|
|
114
|
+
}
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Serialize a JavaScript value to JSON and write it atomically.
|
|
121
|
+
*
|
|
122
|
+
* @param filePath - Destination file path
|
|
123
|
+
* @param data - Value to serialize (via `JSON.stringify`)
|
|
124
|
+
*/
|
|
125
|
+
export async function atomicWriteJson(filePath, data) {
|
|
126
|
+
await atomicWriteFile(filePath, JSON.stringify(data, null, 2));
|
|
127
|
+
}
|
|
128
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
129
|
+
// Safe read
|
|
130
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
131
|
+
/**
|
|
132
|
+
* Read and parse a JSON file safely.
|
|
133
|
+
*
|
|
134
|
+
* - On `ENOENT` → returns `defaultValue` silently.
|
|
135
|
+
* - On parse error → backs up the corrupt file as `<path>.corrupt.<ts>`
|
|
136
|
+
* and returns `defaultValue`.
|
|
137
|
+
*
|
|
138
|
+
* @param filePath - Path to the JSON file
|
|
139
|
+
* @param defaultValue - Value to return when the file is missing or corrupt
|
|
140
|
+
* @param logger - Optional logger for warnings on corruption
|
|
141
|
+
* @returns Parsed value or `defaultValue`
|
|
142
|
+
*/
|
|
143
|
+
export async function safeReadJson(filePath, defaultValue, logger) {
|
|
144
|
+
let raw;
|
|
145
|
+
try {
|
|
146
|
+
raw = await fs.readFile(filePath, 'utf-8');
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
// File does not exist — totally normal, return default
|
|
150
|
+
if (error.code === 'ENOENT') {
|
|
151
|
+
return defaultValue;
|
|
152
|
+
}
|
|
153
|
+
throw error; // Permission errors etc. should bubble
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
return JSON.parse(raw);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Corrupt JSON — back up the file so we can debug later
|
|
160
|
+
const backupPath = `${filePath}.corrupt.${Date.now()}`;
|
|
161
|
+
try {
|
|
162
|
+
await fs.copyFile(filePath, backupPath);
|
|
163
|
+
logger?.warn('Backed up corrupt JSON file', { filePath, backupPath });
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
logger?.warn('Failed to back up corrupt JSON file', { filePath });
|
|
167
|
+
}
|
|
168
|
+
return defaultValue;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
172
|
+
// Read-modify-write helper
|
|
173
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
174
|
+
/**
|
|
175
|
+
* Locked read → mutate → atomic write cycle.
|
|
176
|
+
*
|
|
177
|
+
* This is the most common persistence pattern: load a JSON file,
|
|
178
|
+
* apply a mutation, and write it back atomically — all while holding
|
|
179
|
+
* an operation lock to prevent concurrent read-modify-write races.
|
|
180
|
+
*
|
|
181
|
+
* **Important:** If the mutator returns `undefined` (void), the mutated
|
|
182
|
+
* `data` object is written back. If it returns any other value — including
|
|
183
|
+
* falsy values like `null`, `0`, or `false` — that value is written instead.
|
|
184
|
+
* Beware of methods like `Array.push()` which return a number: an accidental
|
|
185
|
+
* `return records.push(item)` will write the array length to the file.
|
|
186
|
+
*
|
|
187
|
+
* @param filePath - Path to the JSON file
|
|
188
|
+
* @param defaultValue - Value to use if the file is missing or corrupt
|
|
189
|
+
* @param mutator - Function that receives the current data and mutates it in place (or returns new data)
|
|
190
|
+
* @param logger - Optional logger
|
|
191
|
+
* @returns The value returned by `mutator` (or void)
|
|
192
|
+
*/
|
|
193
|
+
export async function modifyJsonFile(filePath, defaultValue, mutator, logger) {
|
|
194
|
+
return withOperationLock(filePath, async () => {
|
|
195
|
+
const data = await safeReadJson(filePath, defaultValue, logger);
|
|
196
|
+
const result = await mutator(data);
|
|
197
|
+
// If mutator returns undefined (void), write the mutated data in place;
|
|
198
|
+
// otherwise write the returned value (including null, 0, false, etc.)
|
|
199
|
+
const toWrite = result === undefined ? data : result;
|
|
200
|
+
await atomicWriteJson(filePath, toWrite);
|
|
201
|
+
return result;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
205
|
+
// Test helper
|
|
206
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
207
|
+
/**
|
|
208
|
+
* Reset all lock maps. **Test-only** — never call in production.
|
|
209
|
+
*/
|
|
210
|
+
export function _clearAllLocks() {
|
|
211
|
+
fileLocks.clear();
|
|
212
|
+
operationLocks.clear();
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=file-io.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-io.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/file-io.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal output utilities for processing PTY output.
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for stripping ANSI escape codes and deduplicating
|
|
5
|
+
* chat responses from orchestrator terminal output.
|
|
6
|
+
*
|
|
7
|
+
* @module terminal-output-utils
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Strip ANSI escape codes from PTY output for reliable pattern matching.
|
|
11
|
+
*
|
|
12
|
+
* Handles color codes, cursor movements, OSC sequences, and other control
|
|
13
|
+
* characters. Cursor forward movements are replaced with spaces to preserve
|
|
14
|
+
* word boundaries in rendered output.
|
|
15
|
+
*
|
|
16
|
+
* @param content - Raw PTY output containing ANSI codes
|
|
17
|
+
* @returns Clean text with ANSI codes removed
|
|
18
|
+
*/
|
|
19
|
+
export declare function stripAnsiCodes(content: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Generate a hash key for a chat response to detect duplicates.
|
|
22
|
+
*
|
|
23
|
+
* Normalizes whitespace and truncates to create a consistent key
|
|
24
|
+
* for the same logical response content.
|
|
25
|
+
*
|
|
26
|
+
* @param conversationId - The conversation this response belongs to
|
|
27
|
+
* @param content - The response content to hash
|
|
28
|
+
* @returns A string key for deduplication
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateResponseHash(conversationId: string, content: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Manages a set of recent response hashes for deduplication.
|
|
33
|
+
* Uses a circular eviction strategy to bound memory usage.
|
|
34
|
+
*/
|
|
35
|
+
export declare class ResponseDeduplicator {
|
|
36
|
+
private recentHashes;
|
|
37
|
+
private readonly maxSize;
|
|
38
|
+
/**
|
|
39
|
+
* @param maxSize - Maximum number of hashes to track before evicting oldest
|
|
40
|
+
*/
|
|
41
|
+
constructor(maxSize?: number);
|
|
42
|
+
/**
|
|
43
|
+
* Check if a response is a duplicate and track it if not.
|
|
44
|
+
*
|
|
45
|
+
* @param hash - The response hash to check
|
|
46
|
+
* @returns true if the response is a duplicate, false if it's new
|
|
47
|
+
*/
|
|
48
|
+
isDuplicate(hash: string): boolean;
|
|
49
|
+
/** Clear all tracked hashes */
|
|
50
|
+
clear(): void;
|
|
51
|
+
/** Current number of tracked hashes */
|
|
52
|
+
get size(): number;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=terminal-output.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-output.utils.d.ts","sourceRoot":"","sources":["../../../../../backend/src/utils/terminal-output.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsBtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpF;AAED;;;GAGG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;OAEG;gBACS,OAAO,GAAE,MAAW;IAIhC;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAclC,+BAA+B;IAC/B,KAAK,IAAI,IAAI;IAIb,uCAAuC;IACvC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal output utilities for processing PTY output.
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for stripping ANSI escape codes and deduplicating
|
|
5
|
+
* chat responses from orchestrator terminal output.
|
|
6
|
+
*
|
|
7
|
+
* @module terminal-output-utils
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Strip ANSI escape codes from PTY output for reliable pattern matching.
|
|
11
|
+
*
|
|
12
|
+
* Handles color codes, cursor movements, OSC sequences, and other control
|
|
13
|
+
* characters. Cursor forward movements are replaced with spaces to preserve
|
|
14
|
+
* word boundaries in rendered output.
|
|
15
|
+
*
|
|
16
|
+
* @param content - Raw PTY output containing ANSI codes
|
|
17
|
+
* @returns Clean text with ANSI codes removed
|
|
18
|
+
*/
|
|
19
|
+
export function stripAnsiCodes(content) {
|
|
20
|
+
return content
|
|
21
|
+
// Replace cursor forward movements with a space (\d* is safe here because \x1b prefix
|
|
22
|
+
// prevents false matches with text like [CHAT_RESPONSE]; orphaned CSI below uses \d+)
|
|
23
|
+
.replace(/\x1b\[\d*C/g, ' ')
|
|
24
|
+
// Remove other CSI sequences (colors, cursor positioning, etc.)
|
|
25
|
+
.replace(/\x1b\[[0-9;]*[A-Za-zH]/g, '')
|
|
26
|
+
// Remove OSC sequences (title changes, hyperlinks, etc.)
|
|
27
|
+
.replace(/\x1b\][^\x07]*\x07/g, '')
|
|
28
|
+
// Remove other escape sequences
|
|
29
|
+
.replace(/\x1b[^[\]].?/g, '')
|
|
30
|
+
// Clean orphaned CSI fragments from PTY buffer boundary splits.
|
|
31
|
+
// When ESC char lands in one chunk and the CSI params in the next,
|
|
32
|
+
// artifacts like "[1C", "[22m", or "[38;2;249;226;175m" appear mid-word.
|
|
33
|
+
// Note: \d+ (one or more digits) required to avoid matching [C in [CHAT_RESPONSE]
|
|
34
|
+
.replace(/\[\d+C/g, ' ')
|
|
35
|
+
.replace(/\[\d+(?:;\d+)*[A-BJKHfm]/g, '')
|
|
36
|
+
// Replace carriage returns with newline (CR/LF normalization)
|
|
37
|
+
.replace(/\r\n/g, '\n')
|
|
38
|
+
.replace(/\r/g, '\n')
|
|
39
|
+
// Remove remaining control characters but keep tabs and newlines
|
|
40
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Generate a hash key for a chat response to detect duplicates.
|
|
44
|
+
*
|
|
45
|
+
* Normalizes whitespace and truncates to create a consistent key
|
|
46
|
+
* for the same logical response content.
|
|
47
|
+
*
|
|
48
|
+
* @param conversationId - The conversation this response belongs to
|
|
49
|
+
* @param content - The response content to hash
|
|
50
|
+
* @returns A string key for deduplication
|
|
51
|
+
*/
|
|
52
|
+
export function generateResponseHash(conversationId, content) {
|
|
53
|
+
const normalized = content.replace(/\s+/g, ' ').trim();
|
|
54
|
+
return `${conversationId}:${normalized.substring(0, 200)}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Manages a set of recent response hashes for deduplication.
|
|
58
|
+
* Uses a circular eviction strategy to bound memory usage.
|
|
59
|
+
*/
|
|
60
|
+
export class ResponseDeduplicator {
|
|
61
|
+
recentHashes = new Set();
|
|
62
|
+
maxSize;
|
|
63
|
+
/**
|
|
64
|
+
* @param maxSize - Maximum number of hashes to track before evicting oldest
|
|
65
|
+
*/
|
|
66
|
+
constructor(maxSize = 20) {
|
|
67
|
+
this.maxSize = maxSize;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if a response is a duplicate and track it if not.
|
|
71
|
+
*
|
|
72
|
+
* @param hash - The response hash to check
|
|
73
|
+
* @returns true if the response is a duplicate, false if it's new
|
|
74
|
+
*/
|
|
75
|
+
isDuplicate(hash) {
|
|
76
|
+
if (this.recentHashes.has(hash)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
this.recentHashes.add(hash);
|
|
80
|
+
if (this.recentHashes.size > this.maxSize) {
|
|
81
|
+
const first = this.recentHashes.values().next().value;
|
|
82
|
+
if (first !== undefined) {
|
|
83
|
+
this.recentHashes.delete(first);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
/** Clear all tracked hashes */
|
|
89
|
+
clear() {
|
|
90
|
+
this.recentHashes.clear();
|
|
91
|
+
}
|
|
92
|
+
/** Current number of tracked hashes */
|
|
93
|
+
get size() {
|
|
94
|
+
return this.recentHashes.size;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=terminal-output.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-output.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/terminal-output.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC7C,OAAO,OAAO;QACb,sFAAsF;QACtF,sFAAsF;SACrF,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;QAC5B,gEAAgE;SAC/D,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC;QACvC,yDAAyD;SACxD,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC;QACnC,gCAAgC;SAC/B,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;QAC7B,gEAAgE;QAChE,mEAAmE;QACnE,yEAAyE;QACzE,kFAAkF;SACjF,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC;QACzC,8DAA8D;SAC7D,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;SACtB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;QACrB,iEAAiE;SAChE,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,cAAsB,EAAE,OAAe;IAC3E,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACvD,OAAO,GAAG,cAAc,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IACxB,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACxB,OAAO,CAAS;IAEjC;;OAEG;IACH,YAAY,UAAkB,EAAE;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,IAAY;QACvB,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,KAAK;QACJ,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,uCAAuC;IACvC,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;IAC/B,CAAC;CACD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command: crewly mcp-server
|
|
3
|
+
*
|
|
4
|
+
* Starts the Crewly MCP Server on stdio transport so that external AI tools
|
|
5
|
+
* (Claude Code, Cursor, Windsurf, etc.) can manage Crewly teams via MCP.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* crewly mcp-server
|
|
9
|
+
*
|
|
10
|
+
* Claude Code configuration example:
|
|
11
|
+
* Add to ~/.claude.json or project .mcp.json:
|
|
12
|
+
* {
|
|
13
|
+
* "mcpServers": {
|
|
14
|
+
* "crewly": {
|
|
15
|
+
* "command": "npx",
|
|
16
|
+
* "args": ["crewly", "mcp-server"]
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* @module commands/mcp-server
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Start the Crewly MCP Server on stdio transport.
|
|
25
|
+
*
|
|
26
|
+
* The server exposes Crewly capabilities as MCP tools:
|
|
27
|
+
* - crewly_get_teams: List all teams
|
|
28
|
+
* - crewly_create_team: Create a new team
|
|
29
|
+
* - crewly_assign_task: Assign task to an agent
|
|
30
|
+
* - crewly_get_status: Get team/agent status
|
|
31
|
+
* - crewly_recall_memory: Search team memory
|
|
32
|
+
* - crewly_send_message: Send message to orchestrator
|
|
33
|
+
*
|
|
34
|
+
* Runs on stdio (stdin/stdout) for MCP protocol communication.
|
|
35
|
+
* The process stays alive until the client disconnects.
|
|
36
|
+
*/
|
|
37
|
+
export declare function mcpServerCommand(): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../../../../cli/src/commands/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAatD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command: crewly mcp-server
|
|
3
|
+
*
|
|
4
|
+
* Starts the Crewly MCP Server on stdio transport so that external AI tools
|
|
5
|
+
* (Claude Code, Cursor, Windsurf, etc.) can manage Crewly teams via MCP.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* crewly mcp-server
|
|
9
|
+
*
|
|
10
|
+
* Claude Code configuration example:
|
|
11
|
+
* Add to ~/.claude.json or project .mcp.json:
|
|
12
|
+
* {
|
|
13
|
+
* "mcpServers": {
|
|
14
|
+
* "crewly": {
|
|
15
|
+
* "command": "npx",
|
|
16
|
+
* "args": ["crewly", "mcp-server"]
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* @module commands/mcp-server
|
|
22
|
+
*/
|
|
23
|
+
import { CrewlyMcpServer } from '../../../backend/src/services/mcp-server.js';
|
|
24
|
+
/**
|
|
25
|
+
* Start the Crewly MCP Server on stdio transport.
|
|
26
|
+
*
|
|
27
|
+
* The server exposes Crewly capabilities as MCP tools:
|
|
28
|
+
* - crewly_get_teams: List all teams
|
|
29
|
+
* - crewly_create_team: Create a new team
|
|
30
|
+
* - crewly_assign_task: Assign task to an agent
|
|
31
|
+
* - crewly_get_status: Get team/agent status
|
|
32
|
+
* - crewly_recall_memory: Search team memory
|
|
33
|
+
* - crewly_send_message: Send message to orchestrator
|
|
34
|
+
*
|
|
35
|
+
* Runs on stdio (stdin/stdout) for MCP protocol communication.
|
|
36
|
+
* The process stays alive until the client disconnects.
|
|
37
|
+
*/
|
|
38
|
+
export async function mcpServerCommand() {
|
|
39
|
+
const server = new CrewlyMcpServer();
|
|
40
|
+
// Handle graceful shutdown
|
|
41
|
+
const shutdown = async () => {
|
|
42
|
+
await server.stop();
|
|
43
|
+
process.exit(0);
|
|
44
|
+
};
|
|
45
|
+
process.on('SIGINT', shutdown);
|
|
46
|
+
process.on('SIGTERM', shutdown);
|
|
47
|
+
await server.start();
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../../../../cli/src/commands/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IAErC,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -8,11 +8,22 @@
|
|
|
8
8
|
* Used directly via `crewly onboard`, by the curl install script, and
|
|
9
9
|
* by the Electron desktop app.
|
|
10
10
|
*
|
|
11
|
+
* Supports non-interactive mode via `--yes` flag and direct template
|
|
12
|
+
* selection via `--template <id>`.
|
|
13
|
+
*
|
|
11
14
|
* @module cli/commands/onboard
|
|
12
15
|
*/
|
|
13
16
|
import { type Interface as ReadlineInterface } from 'readline';
|
|
17
|
+
import { type TeamTemplate } from '../utils/templates.js';
|
|
14
18
|
/** Provider choice returned by the selection step */
|
|
15
19
|
export type ProviderChoice = 'claude' | 'gemini' | 'both' | 'skip';
|
|
20
|
+
/** Options passed from Commander.js for the onboard command */
|
|
21
|
+
export interface OnboardOptions {
|
|
22
|
+
/** Skip all interactive prompts and use defaults */
|
|
23
|
+
yes?: boolean;
|
|
24
|
+
/** Select a team template by ID (e.g. "web-dev-team") */
|
|
25
|
+
template?: string;
|
|
26
|
+
}
|
|
16
27
|
/**
|
|
17
28
|
* Prints the Crewly ASCII art banner to stdout.
|
|
18
29
|
*/
|
|
@@ -59,12 +70,14 @@ export declare function installTool(displayName: string, npmPackage: string): bo
|
|
|
59
70
|
* Checks for and optionally installs the tools needed for the selected provider.
|
|
60
71
|
*
|
|
61
72
|
* For each required tool, checks if it's on the PATH. If missing, asks the user
|
|
62
|
-
* whether to install it via npm.
|
|
73
|
+
* whether to install it via npm. In non-interactive (--yes) mode, automatically
|
|
74
|
+
* installs missing tools.
|
|
63
75
|
*
|
|
64
76
|
* @param rl - Readline interface
|
|
65
77
|
* @param provider - The chosen provider
|
|
78
|
+
* @param autoYes - When true, skip prompts and install missing tools automatically
|
|
66
79
|
*/
|
|
67
|
-
export declare function ensureTools(rl: ReadlineInterface, provider: ProviderChoice): Promise<void>;
|
|
80
|
+
export declare function ensureTools(rl: ReadlineInterface, provider: ProviderChoice, autoYes?: boolean): Promise<void>;
|
|
68
81
|
/**
|
|
69
82
|
* Checks for and installs agent skills from the marketplace.
|
|
70
83
|
*
|
|
@@ -72,18 +85,59 @@ export declare function ensureTools(rl: ReadlineInterface, provider: ProviderCho
|
|
|
72
85
|
* and installs all skills with progress feedback.
|
|
73
86
|
*/
|
|
74
87
|
export declare function ensureSkills(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Asks the user to pick a pre-built team template.
|
|
90
|
+
*
|
|
91
|
+
* Displays available templates with descriptions. The user can pick one
|
|
92
|
+
* or skip to configure their team later through the dashboard.
|
|
93
|
+
*
|
|
94
|
+
* @param rl - Readline interface
|
|
95
|
+
* @returns The selected template, or null if skipped
|
|
96
|
+
*/
|
|
97
|
+
export declare function selectTemplate(rl: ReadlineInterface): Promise<TeamTemplate | null>;
|
|
98
|
+
/**
|
|
99
|
+
* Scaffolds the .crewly/ directory in the current working directory.
|
|
100
|
+
*
|
|
101
|
+
* Creates the minimum directory structure needed for `crewly start` to work:
|
|
102
|
+
* - .crewly/
|
|
103
|
+
* - .crewly/docs/
|
|
104
|
+
* - .crewly/memory/
|
|
105
|
+
* - .crewly/tasks/
|
|
106
|
+
* - .crewly/teams/
|
|
107
|
+
*
|
|
108
|
+
* If the directory already exists, reports it and moves on.
|
|
109
|
+
*
|
|
110
|
+
* @param projectDir - The project root directory (defaults to process.cwd())
|
|
111
|
+
* @returns True if the directory was created or already existed
|
|
112
|
+
*/
|
|
113
|
+
export declare function scaffoldCrewlyDirectory(projectDir?: string): boolean;
|
|
75
114
|
/**
|
|
76
115
|
* Prints the setup-complete summary with next-step instructions.
|
|
116
|
+
*
|
|
117
|
+
* If a team template was selected, includes instructions on how to
|
|
118
|
+
* create the team from the dashboard.
|
|
119
|
+
*
|
|
120
|
+
* @param selectedTemplate - The template chosen during onboarding, or null
|
|
121
|
+
* @param projectDir - The project directory path for next-steps output
|
|
77
122
|
*/
|
|
78
|
-
export declare function printSummary(): void;
|
|
123
|
+
export declare function printSummary(selectedTemplate?: TeamTemplate | null, projectDir?: string): void;
|
|
79
124
|
/**
|
|
80
|
-
* Runs the
|
|
125
|
+
* Runs the onboarding wizard.
|
|
81
126
|
*
|
|
82
|
-
*
|
|
127
|
+
* In interactive mode (default), walks the user through 5 steps:
|
|
83
128
|
* 1. Choose an AI provider (Claude Code, Gemini CLI, both, or skip)
|
|
84
129
|
* 2. Detect / install the chosen tool(s)
|
|
85
130
|
* 3. Install agent skills from the marketplace
|
|
86
|
-
* 4.
|
|
131
|
+
* 4. Pick a team template (or skip)
|
|
132
|
+
* 5. Print a success summary
|
|
133
|
+
*
|
|
134
|
+
* In non-interactive mode (--yes), uses defaults:
|
|
135
|
+
* - Provider: claude
|
|
136
|
+
* - Auto-install missing tools
|
|
137
|
+
* - First available template (or --template flag)
|
|
138
|
+
* - Scaffold .crewly/ directory
|
|
139
|
+
*
|
|
140
|
+
* @param options - Command options from Commander.js
|
|
87
141
|
*/
|
|
88
|
-
export declare function onboardCommand(): Promise<void>;
|
|
142
|
+
export declare function onboardCommand(options?: OnboardOptions): Promise<void>;
|
|
89
143
|
//# sourceMappingURL=onboard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../../../../cli/src/commands/onboard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../../../../cli/src/commands/onboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAmB,KAAK,SAAS,IAAI,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAShF,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,qDAAqD;AACrD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnE,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAUlC;AAID;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAK3D;AAmBD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAwBnF;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAO3D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,SAAc,GAAG,MAAM,GAAG,IAAI,CAYxF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAc5E;AAwBD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BjH;AAID;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BlD;AAID;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAoCxF;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,GAAE,MAAsB,GAAG,OAAO,CA2BnF;AAID;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,GAAE,YAAY,GAAG,IAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAoBpG;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFhF"}
|