crewly 1.3.31 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/constants.ts +18 -3
- package/config/hooks/install-hooks.sh +88 -0
- package/config/hooks/pre-commit +104 -0
- package/config/orchestrator_tasks/prompts/orchestrator-prompt.md +17 -24
- package/config/roles/auditor/role.json +13 -0
- package/config/roles/orchestrator/prompt.md +25 -0
- package/config/roles/product-manager/prompt.md +18 -1
- package/config/roles/researcher/prompt.md +110 -0
- package/config/roles/team-leader/prompt.md +31 -8
- package/config/roles/team-leader/tl-addon.md +40 -9
- package/config/roles/ux-designer/prompt.md +111 -0
- package/config/skills/_common/lib.sh +33 -0
- package/config/skills/agent/browse-stealth/{instructions.md → SKILL.md} +40 -0
- package/config/skills/agent/chrome-attach/SKILL.md +84 -0
- package/config/skills/agent/chrome-attach/execute.sh +279 -0
- package/config/skills/agent/competitor-content-tracker/{instructions.md → SKILL.md} +34 -0
- package/config/skills/agent/computer-use/{instructions.md → SKILL.md} +43 -0
- package/config/skills/agent/content-calendar/{instructions.md → SKILL.md} +32 -0
- package/config/skills/agent/content-repurposer/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/content-writer/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/core/accept-task/{instructions.md → SKILL.md} +37 -0
- package/config/skills/agent/core/block-task/{instructions.md → SKILL.md} +37 -0
- package/config/skills/agent/core/check-quality-gates/{instructions.md → SKILL.md} +40 -0
- package/config/skills/agent/core/complete-task/{instructions.md → SKILL.md} +37 -0
- package/config/skills/agent/core/complete-task/execute.sh +15 -0
- package/config/skills/agent/core/generate-pdf/{instructions.md → SKILL.md} +42 -0
- package/config/skills/agent/core/get-my-context/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/core/get-sops/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/core/get-team-norms/execute.sh +106 -0
- package/config/skills/agent/core/get-team-status/SKILL.md +55 -0
- package/config/skills/agent/core/handoff-task/execute.sh +150 -0
- package/config/skills/agent/core/heartbeat/{instructions.md → SKILL.md} +27 -0
- package/config/skills/agent/core/marketplace-search/{instructions.md → SKILL.md} +41 -0
- package/config/skills/agent/core/query-knowledge/{instructions.md → SKILL.md} +40 -0
- package/config/skills/agent/core/read-task/SKILL.md +56 -0
- package/config/skills/agent/core/recall/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/core/record-learning/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/core/register-self/SKILL.md +54 -0
- package/config/skills/agent/core/remember/{instructions.md → SKILL.md} +37 -0
- package/config/skills/agent/core/remember/execute.sh +6 -0
- package/config/skills/agent/core/reply-chat/{instructions.md → SKILL.md} +37 -0
- package/config/skills/agent/core/report-progress/{instructions.md → SKILL.md} +38 -0
- package/config/skills/agent/core/report-status/{instructions.md → SKILL.md} +39 -0
- package/config/skills/agent/core/send-chat-response/{instructions.md → SKILL.md} +37 -0
- package/config/skills/agent/core/send-message/SKILL.md +58 -0
- package/config/skills/agent/core/update-team-norm/execute.sh +115 -0
- package/config/skills/agent/desktop-app-control/{instructions.md → SKILL.md} +42 -0
- package/config/skills/agent/trend-monitor/{instructions.md → SKILL.md} +34 -0
- package/config/skills/agent/vnc-browser/{instructions.md → SKILL.md} +38 -0
- package/config/skills/auditor/score-task/SKILL.md +28 -0
- package/config/skills/auditor/score-task/execute.sh +21 -0
- package/config/skills/examples/enterprise-skill-example.json +22 -0
- package/config/skills/examples/premium-skill-example.json +22 -0
- package/config/skills/orchestrator/assign-task/SKILL.md +41 -0
- package/config/skills/orchestrator/assign-team-to-project/{instructions.md → SKILL.md} +25 -0
- package/config/skills/orchestrator/broadcast/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/broadcast-to-org/{instructions.md → SKILL.md} +25 -0
- package/config/skills/orchestrator/cancel-all-schedules/{instructions.md → SKILL.md} +5 -0
- package/config/skills/orchestrator/cancel-schedule/SKILL.md +43 -0
- package/config/skills/orchestrator/complete-task/SKILL.md +41 -0
- package/config/skills/orchestrator/create-project/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/create-team/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/delegate-task/{instructions.md → SKILL.md} +27 -0
- package/config/skills/orchestrator/delegate-task/execute.sh +31 -2
- package/config/skills/orchestrator/get-agent-logs/{instructions.md → SKILL.md} +25 -0
- package/config/skills/orchestrator/get-agent-status/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/get-project-overview/SKILL.md +41 -0
- package/config/skills/orchestrator/get-tasks/SKILL.md +41 -0
- package/config/skills/orchestrator/get-team-status/SKILL.md +43 -0
- package/config/skills/orchestrator/handle-agent-failure/{instructions.md → SKILL.md} +27 -0
- package/config/skills/orchestrator/heartbeat/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/list-schedules/{instructions.md → SKILL.md} +5 -0
- package/config/skills/orchestrator/list-subscriptions/SKILL.md +41 -0
- package/config/skills/orchestrator/query-knowledge/{instructions.md → SKILL.md} +28 -0
- package/config/skills/orchestrator/read-session-logs/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/read-system-logs/{instructions.md → SKILL.md} +25 -0
- package/config/skills/orchestrator/recall/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/record-failure/{instructions.md → SKILL.md} +27 -0
- package/config/skills/orchestrator/record-learning/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/record-success/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/register-self/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/remember/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/reply-chat/{instructions.md → SKILL.md} +25 -0
- package/config/skills/orchestrator/reply-chat/execute.sh +0 -13
- package/config/skills/orchestrator/reply-gchat/{instructions.md → SKILL.md} +25 -0
- package/config/skills/orchestrator/reply-gchat/execute.sh +0 -18
- package/config/skills/orchestrator/reply-slack/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/reply-slack/execute.sh +18 -31
- package/config/skills/orchestrator/report-bug/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/restart-crewly/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/resume-session/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/schedule-check/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/send-key/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/send-message/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/send-pdf-to-slack/{instructions.md → SKILL.md} +27 -0
- package/config/skills/orchestrator/set-goal/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/start-agent/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/start-team/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/stop-agent/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/stop-team/SKILL.md +43 -0
- package/config/skills/orchestrator/subscribe-event/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/terminate-agent/{instructions.md → SKILL.md} +24 -0
- package/config/skills/orchestrator/unsubscribe-event/SKILL.md +42 -0
- package/config/skills/orchestrator/update-focus/{instructions.md → SKILL.md} +26 -0
- package/config/skills/orchestrator/update-team/{instructions.md → SKILL.md} +24 -0
- package/config/skills/team-leader/aggregate-results/{instructions.md → SKILL.md} +26 -0
- package/config/skills/team-leader/decompose-goal/{instructions.md → SKILL.md} +26 -0
- package/config/skills/team-leader/delegate-task/{instructions.md → SKILL.md} +26 -0
- package/config/skills/team-leader/delegate-task/execute.sh +14 -6
- package/config/skills/team-leader/delegate-task/execute.test.sh +401 -0
- package/config/skills/team-leader/handle-failure/{instructions.md → SKILL.md} +27 -0
- package/config/skills/team-leader/schedule-check/{instructions.md → SKILL.md} +26 -0
- package/config/skills/team-leader/start-agent/{instructions.md → SKILL.md} +26 -0
- package/config/skills/team-leader/stop-agent/{instructions.md → SKILL.md} +26 -0
- package/config/skills/team-leader/verify-output/{instructions.md → SKILL.md} +27 -0
- package/config/templates/agent-agents-md.md +35 -0
- package/config/templates/agent-gemini-md.md +35 -0
- package/config/templates/code-review-team/team-config.json +7 -0
- package/config/templates/content-generation-team/norms/brand-guidelines.md +64 -0
- package/config/templates/content-generation-team/norms/content-review.md +66 -0
- package/config/templates/content-generation-team/norms/publish-checklist.md +58 -0
- package/config/templates/content-generation-team/team-config.json +8 -0
- package/config/templates/dev-fullstack/norms/code-commit-sop.md +40 -0
- package/config/templates/dev-fullstack/norms/quality-gates.md +35 -0
- package/config/templates/dev-fullstack/template.json +17 -1
- package/config/templates/education-smb/template.json +10 -1
- package/config/templates/insurance-smb/template.json +10 -1
- package/config/templates/research-analysis/norms/research-methodology.md +36 -0
- package/config/templates/research-analysis/norms/source-citation.md +33 -0
- package/config/templates/research-analysis/template.json +17 -1
- package/config/templates/security-audit-team.json +67 -0
- package/config/templates/social-media-ops/norms/engagement-rules.md +35 -0
- package/config/templates/social-media-ops/norms/posting-schedule.md +43 -0
- package/config/templates/social-media-ops/template.json +17 -1
- package/config/templates/video-production/template.json +10 -1
- package/dist/backend/backend/src/constants.d.ts +80 -11
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +85 -11
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/approvals/approvals.controller.d.ts +99 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.controller.js +183 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.routes.d.ts +15 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.routes.js +27 -0
- package/dist/backend/backend/src/controllers/approvals/approvals.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts +70 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.js +368 -0
- package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts +24 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +195 -3
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts +9 -4
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +19 -5
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/index.d.ts +1 -0
- package/dist/backend/backend/src/controllers/cloud/index.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/index.js +1 -0
- package/dist/backend/backend/src/controllers/cloud/index.js.map +1 -1
- package/dist/backend/backend/src/controllers/index.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/index.js +2 -0
- package/dist/backend/backend/src/controllers/index.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts +3 -3
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js +9 -9
- package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/memory/memory.controller.js +6 -6
- package/dist/backend/backend/src/controllers/memory/memory.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts +0 -7
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +2 -135
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +14 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +96 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.js +8 -1
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.controller.js +2 -2
- package/dist/backend/backend/src/controllers/payment/payment.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts +3 -3
- package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.routes.js +4 -14
- package/dist/backend/backend/src/controllers/payment/payment.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.types.d.ts +15 -94
- package/dist/backend/backend/src/controllers/payment/payment.types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/payment/payment.types.js +11 -35
- package/dist/backend/backend/src/controllers/payment/payment.types.js.map +1 -1
- package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.d.ts +49 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.js +138 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.d.ts +20 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.js +30 -0
- package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.d.ts +12 -0
- package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.js +107 -0
- package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts +20 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +11 -5
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +46 -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 +598 -326
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts +12 -0
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +105 -36
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +2 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/template/template.controller.d.ts +11 -0
- package/dist/backend/backend/src/controllers/template/template.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/template/template.controller.js +59 -0
- package/dist/backend/backend/src/controllers/template/template.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/template/template.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/template/template.routes.js +2 -1
- package/dist/backend/backend/src/controllers/template/template.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/workspace/workspace.controller.d.ts +39 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.controller.js +120 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.routes.d.ts +18 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.routes.js +27 -0
- package/dist/backend/backend/src/controllers/workspace/workspace.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +108 -15
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts +20 -0
- package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/middleware/require-auth.middleware.js +21 -0
- package/dist/backend/backend/src/middleware/require-auth.middleware.js.map +1 -0
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +18 -5
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/quality-gate.routes.d.ts +2 -1
- package/dist/backend/backend/src/routes/modules/quality-gate.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/quality-gate.routes.js +4 -2
- package/dist/backend/backend/src/routes/modules/quality-gate.routes.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 +8 -0
- package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/terminal.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/terminal.routes.js +4 -0
- package/dist/backend/backend/src/routes/modules/terminal.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.d.ts +149 -0
- package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.js +200 -0
- package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts +13 -0
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js +65 -6
- package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +36 -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 +174 -52
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts +66 -20
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js +261 -60
- package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +19 -0
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js +80 -0
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts +11 -0
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +49 -1
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +74 -3
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +248 -18
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.d.ts +161 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.js +237 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts +74 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js +140 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +50 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +16 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +45 -5
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +3 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js +3 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts +135 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js +185 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +10 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +22 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts +143 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js +264 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +2 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +55 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +660 -45
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +75 -3
- package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js +49 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +17 -2
- package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +37 -0
- 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 +170 -3
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/chrome-discovery.service.d.ts +108 -0
- package/dist/backend/backend/src/services/browser/chrome-discovery.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/browser/chrome-discovery.service.js +251 -0
- package/dist/backend/backend/src/services/browser/chrome-discovery.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +12 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js +19 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.d.ts +191 -0
- package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.js +415 -0
- package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/device-identity.service.d.ts +89 -0
- package/dist/backend/backend/src/services/cloud/device-identity.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/device-identity.service.js +148 -0
- package/dist/backend/backend/src/services/cloud/device-identity.service.js.map +1 -0
- package/dist/backend/backend/src/services/core/tracing.service.d.ts +127 -0
- package/dist/backend/backend/src/services/core/tracing.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/core/tracing.service.js +238 -0
- package/dist/backend/backend/src/services/core/tracing.service.js.map +1 -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 +11 -3
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
- package/dist/backend/backend/src/services/index.d.ts +1 -0
- package/dist/backend/backend/src/services/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/index.js +1 -0
- package/dist/backend/backend/src/services/index.js.map +1 -1
- package/dist/backend/backend/src/services/knowledge/embedding-provider.d.ts +78 -0
- package/dist/backend/backend/src/services/knowledge/embedding-provider.d.ts.map +1 -0
- package/dist/backend/backend/src/services/knowledge/embedding-provider.js +164 -0
- package/dist/backend/backend/src/services/knowledge/embedding-provider.js.map +1 -0
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +39 -13
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +114 -17
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
- package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts +170 -23
- package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/knowledge/vector-store.service.js +565 -73
- package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +8 -11
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace.service.js +1 -0
- package/dist/backend/backend/src/services/marketplace/marketplace.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/context-flush.service.d.ts +73 -0
- package/dist/backend/backend/src/services/memory/context-flush.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/memory/context-flush.service.js +131 -0
- package/dist/backend/backend/src/services/memory/context-flush.service.js.map +1 -0
- package/dist/backend/backend/src/services/memory/learning-accumulation.service.d.ts +23 -2
- package/dist/backend/backend/src/services/memory/learning-accumulation.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/learning-accumulation.service.js +78 -16
- package/dist/backend/backend/src/services/memory/learning-accumulation.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/memory.service.d.ts +38 -0
- package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/memory.service.js +121 -2
- package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.d.ts +29 -207
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.js +97 -683
- package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/google-chat-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/google-chat-initializer.js +13 -12
- package/dist/backend/backend/src/services/messaging/google-chat-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +2 -0
- 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.d.ts +6 -23
- 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 +48 -184
- 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 +51 -5
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/index.d.ts +1 -1
- package/dist/backend/backend/src/services/orchestrator/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/index.js +1 -1
- package/dist/backend/backend/src/services/orchestrator/index.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts +65 -0
- 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 +165 -2
- package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +8 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +23 -0
- package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
- package/dist/backend/backend/src/services/payment/stripe.service.d.ts +95 -43
- package/dist/backend/backend/src/services/payment/stripe.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/payment/stripe.service.js +229 -190
- package/dist/backend/backend/src/services/payment/stripe.service.js.map +1 -1
- package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts +181 -0
- package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/pr-review/pr-review.service.js +336 -0
- package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +23 -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 +88 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
- package/dist/backend/backend/src/services/session/index.d.ts +2 -0
- package/dist/backend/backend/src/services/session/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/index.js +2 -0
- package/dist/backend/backend/src/services/session/index.js.map +1 -1
- package/dist/backend/backend/src/services/session/session-handoff.service.d.ts +260 -0
- package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/session/session-handoff.service.js +565 -0
- package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -0
- package/dist/backend/backend/src/services/skill/index.d.ts +1 -0
- package/dist/backend/backend/src/services/skill/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/index.js +1 -0
- package/dist/backend/backend/src/services/skill/index.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts +25 -6
- package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-catalog.service.js +78 -20
- package/dist/backend/backend/src/services/skill/skill-catalog.service.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-tier.service.d.ts +116 -0
- package/dist/backend/backend/src/services/skill/skill-tier.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/skill/skill-tier.service.js +155 -0
- package/dist/backend/backend/src/services/skill/skill-tier.service.js.map +1 -0
- package/dist/backend/backend/src/services/skill/skill.service.d.ts +35 -7
- package/dist/backend/backend/src/services/skill/skill.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill.service.js +128 -35
- package/dist/backend/backend/src/services/skill/skill.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +50 -47
- 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 +267 -202
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +28 -2
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +69 -3
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/template/template.service.d.ts +19 -1
- package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/template/template.service.js +110 -3
- package/dist/backend/backend/src/services/template/template.service.js.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts +11 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +57 -3
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +6 -0
- package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +52 -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 +319 -6
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/chat.types.d.ts +2 -2
- package/dist/backend/backend/src/types/chat.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/chat.types.js +18 -22
- package/dist/backend/backend/src/types/chat.types.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +37 -0
- 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 +1 -1
- package/dist/backend/backend/src/types/marketplace.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/scheduler.types.d.ts +4 -0
- package/dist/backend/backend/src/types/scheduler.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/scheduler.types.js.map +1 -1
- package/dist/backend/backend/src/types/skill.types.d.ts +4 -0
- package/dist/backend/backend/src/types/skill.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/skill.types.js.map +1 -1
- package/dist/backend/backend/src/types/task-tracking.types.d.ts +6 -0
- 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 +2 -0
- package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
- package/dist/backend/backend/src/utils/skill-md-parser.d.ts +38 -0
- package/dist/backend/backend/src/utils/skill-md-parser.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/skill-md-parser.js +47 -0
- package/dist/backend/backend/src/utils/skill-md-parser.js.map +1 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +0 -154
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.js +0 -515
- package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
- package/dist/backend/config/constants.d.ts +18 -3
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +18 -3
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +80 -11
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +85 -11
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/knowledge/embedding-provider.d.ts +78 -0
- package/dist/cli/backend/src/services/knowledge/embedding-provider.d.ts.map +1 -0
- package/dist/cli/backend/src/services/knowledge/embedding-provider.js +164 -0
- package/dist/cli/backend/src/services/knowledge/embedding-provider.js.map +1 -0
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +39 -13
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +114 -17
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
- package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts +170 -23
- package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/knowledge/vector-store.service.js +565 -73
- package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
- package/dist/cli/backend/src/services/memory/memory.service.d.ts +38 -0
- package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/memory/memory.service.js +121 -2
- package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
- package/dist/cli/backend/src/types/chat.types.d.ts +2 -2
- package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/chat.types.js +18 -22
- package/dist/cli/backend/src/types/chat.types.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +37 -0
- 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/scheduler.types.d.ts +4 -0
- package/dist/cli/backend/src/types/scheduler.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/scheduler.types.js.map +1 -1
- package/dist/cli/backend/src/types/skill.types.d.ts +4 -0
- package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/skill.types.js.map +1 -1
- package/dist/cli/cli/src/commands/onboard.d.ts +19 -2
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +58 -15
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/dist/cli/cli/src/commands/pair.d.ts +46 -0
- package/dist/cli/cli/src/commands/pair.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/pair.js +258 -0
- package/dist/cli/cli/src/commands/pair.js.map +1 -0
- package/dist/cli/cli/src/commands/service.d.ts +86 -0
- package/dist/cli/cli/src/commands/service.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/service.js +687 -0
- package/dist/cli/cli/src/commands/service.js.map +1 -0
- package/dist/cli/cli/src/index.js +17 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/config/constants.d.ts +18 -3
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +18 -3
- package/dist/cli/config/constants.js.map +1 -1
- package/frontend/dist/assets/index-1d23cce8.js +4919 -0
- package/frontend/dist/assets/index-60a9e4ea.css +33 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +22 -10
- package/config/skills/agent/browse-stealth/skill.json +0 -20
- package/config/skills/agent/competitor-content-tracker/skill.json +0 -22
- package/config/skills/agent/computer-use/skill.json +0 -29
- package/config/skills/agent/content-calendar/skill.json +0 -22
- package/config/skills/agent/content-repurposer/skill.json +0 -22
- package/config/skills/agent/content-writer/skill.json +0 -22
- package/config/skills/agent/core/accept-task/skill.json +0 -20
- package/config/skills/agent/core/block-task/skill.json +0 -20
- package/config/skills/agent/core/check-quality-gates/skill.json +0 -20
- package/config/skills/agent/core/complete-task/skill.json +0 -20
- package/config/skills/agent/core/generate-pdf/skill.json +0 -20
- package/config/skills/agent/core/get-my-context/skill.json +0 -20
- package/config/skills/agent/core/get-sops/skill.json +0 -20
- package/config/skills/agent/core/get-team-status/instructions.md +0 -17
- package/config/skills/agent/core/get-team-status/skill.json +0 -20
- package/config/skills/agent/core/heartbeat/skill.json +0 -20
- package/config/skills/agent/core/marketplace-search/skill.json +0 -20
- package/config/skills/agent/core/query-knowledge/skill.json +0 -20
- package/config/skills/agent/core/read-task/instructions.md +0 -19
- package/config/skills/agent/core/read-task/skill.json +0 -20
- package/config/skills/agent/core/recall/skill.json +0 -20
- package/config/skills/agent/core/record-learning/skill.json +0 -20
- package/config/skills/agent/core/register-self/instructions.md +0 -18
- package/config/skills/agent/core/register-self/skill.json +0 -20
- package/config/skills/agent/core/remember/skill.json +0 -20
- package/config/skills/agent/core/reply-chat/skill.json +0 -20
- package/config/skills/agent/core/report-progress/skill.json +0 -20
- package/config/skills/agent/core/report-status/skill.json +0 -20
- package/config/skills/agent/core/send-chat-response/skill.json +0 -20
- package/config/skills/agent/core/send-message/instructions.md +0 -20
- package/config/skills/agent/core/send-message/skill.json +0 -20
- package/config/skills/agent/desktop-app-control/skill.json +0 -33
- package/config/skills/agent/trend-monitor/skill.json +0 -22
- package/config/skills/agent/vnc-browser/skill.json +0 -20
- package/config/skills/orchestrator/assign-task/instructions.md +0 -17
- package/config/skills/orchestrator/assign-task/skill.json +0 -20
- package/config/skills/orchestrator/assign-team-to-project/skill.json +0 -20
- package/config/skills/orchestrator/broadcast/skill.json +0 -20
- package/config/skills/orchestrator/broadcast-to-org/skill.json +0 -20
- package/config/skills/orchestrator/cancel-all-schedules/skill.json +0 -17
- package/config/skills/orchestrator/cancel-schedule/instructions.md +0 -19
- package/config/skills/orchestrator/cancel-schedule/skill.json +0 -20
- package/config/skills/orchestrator/complete-task/instructions.md +0 -17
- package/config/skills/orchestrator/complete-task/skill.json +0 -20
- package/config/skills/orchestrator/create-project/skill.json +0 -20
- package/config/skills/orchestrator/create-team/skill.json +0 -20
- package/config/skills/orchestrator/delegate-task/skill.json +0 -20
- package/config/skills/orchestrator/get-agent-logs/skill.json +0 -20
- package/config/skills/orchestrator/get-agent-status/skill.json +0 -20
- package/config/skills/orchestrator/get-project-overview/instructions.md +0 -17
- package/config/skills/orchestrator/get-project-overview/skill.json +0 -20
- package/config/skills/orchestrator/get-tasks/instructions.md +0 -17
- package/config/skills/orchestrator/get-tasks/skill.json +0 -20
- package/config/skills/orchestrator/get-team-status/instructions.md +0 -17
- package/config/skills/orchestrator/get-team-status/skill.json +0 -20
- package/config/skills/orchestrator/handle-agent-failure/skill.json +0 -20
- package/config/skills/orchestrator/heartbeat/skill.json +0 -20
- package/config/skills/orchestrator/list-schedules/skill.json +0 -12
- package/config/skills/orchestrator/list-subscriptions/instructions.md +0 -17
- package/config/skills/orchestrator/list-subscriptions/skill.json +0 -20
- package/config/skills/orchestrator/query-knowledge/skill.json +0 -20
- package/config/skills/orchestrator/read-session-logs/skill.json +0 -20
- package/config/skills/orchestrator/read-system-logs/skill.json +0 -20
- package/config/skills/orchestrator/recall/skill.json +0 -20
- package/config/skills/orchestrator/record-failure/skill.json +0 -20
- package/config/skills/orchestrator/record-learning/skill.json +0 -20
- package/config/skills/orchestrator/record-success/skill.json +0 -20
- package/config/skills/orchestrator/register-self/skill.json +0 -20
- package/config/skills/orchestrator/remember/skill.json +0 -20
- package/config/skills/orchestrator/reply-chat/skill.json +0 -20
- package/config/skills/orchestrator/reply-gchat/skill.json +0 -20
- package/config/skills/orchestrator/reply-slack/skill.json +0 -20
- package/config/skills/orchestrator/report-bug/skill.json +0 -20
- package/config/skills/orchestrator/restart-crewly/skill.json +0 -20
- package/config/skills/orchestrator/resume-session/skill.json +0 -20
- package/config/skills/orchestrator/schedule-check/skill.json +0 -20
- package/config/skills/orchestrator/send-key/skill.json +0 -20
- package/config/skills/orchestrator/send-message/skill.json +0 -20
- package/config/skills/orchestrator/send-pdf-to-slack/skill.json +0 -20
- package/config/skills/orchestrator/set-goal/skill.json +0 -20
- package/config/skills/orchestrator/start-agent/skill.json +0 -20
- package/config/skills/orchestrator/start-team/skill.json +0 -20
- package/config/skills/orchestrator/stop-agent/skill.json +0 -20
- package/config/skills/orchestrator/stop-team/instructions.md +0 -19
- package/config/skills/orchestrator/stop-team/skill.json +0 -20
- package/config/skills/orchestrator/subscribe-event/skill.json +0 -20
- package/config/skills/orchestrator/terminate-agent/skill.json +0 -20
- package/config/skills/orchestrator/unsubscribe-event/instructions.md +0 -19
- package/config/skills/orchestrator/unsubscribe-event/skill.json +0 -20
- package/config/skills/orchestrator/update-focus/skill.json +0 -20
- package/config/skills/orchestrator/update-team/skill.json +0 -20
- package/config/skills/team-leader/aggregate-results/skill.json +0 -20
- package/config/skills/team-leader/decompose-goal/skill.json +0 -20
- package/config/skills/team-leader/delegate-task/skill.json +0 -20
- package/config/skills/team-leader/handle-failure/skill.json +0 -20
- package/config/skills/team-leader/schedule-check/skill.json +0 -20
- package/config/skills/team-leader/start-agent/skill.json +0 -20
- package/config/skills/team-leader/stop-agent/skill.json +0 -20
- package/config/skills/team-leader/verify-output/skill.json +0 -20
- package/frontend/dist/assets/index-0e5673b0.css +0 -33
- package/frontend/dist/assets/index-e6d7db4a.js +0 -5213
|
@@ -8,8 +8,107 @@
|
|
|
8
8
|
* @module services/agent/crewly-agent/tool-registry
|
|
9
9
|
*/
|
|
10
10
|
import { promises as fsPromises } from 'fs';
|
|
11
|
+
import { execSync, spawnSync } from 'child_process';
|
|
11
12
|
import { homedir } from 'os';
|
|
12
13
|
import { z } from 'zod';
|
|
14
|
+
/** TTL for delegation idle event subscriptions (minutes) */
|
|
15
|
+
const DELEGATION_SUBSCRIPTION_TTL_MINUTES = 120;
|
|
16
|
+
/** Maximum characters for git diff output */
|
|
17
|
+
const GIT_DIFF_MAX_CHARS = 5000;
|
|
18
|
+
/**
|
|
19
|
+
* Commands that could kill/signal the parent Crewly server process or
|
|
20
|
+
* cause irreversible system damage. Checked against the raw command
|
|
21
|
+
* string (case-insensitive, word-boundary match via regex).
|
|
22
|
+
*/
|
|
23
|
+
const BLOCKED_COMMAND_PATTERNS = [
|
|
24
|
+
/\bkill\b/i,
|
|
25
|
+
/\bkillall\b/i,
|
|
26
|
+
/\bpkill\b/i,
|
|
27
|
+
/\bshutdown\b/i,
|
|
28
|
+
/\breboot\b/i,
|
|
29
|
+
/\brm\s+-[^\s]*r[^\s]*\s+\/(?!\S)/i, // rm -rf / (root wipe)
|
|
30
|
+
/\bmkfs\b/i,
|
|
31
|
+
/\bdd\s+.*of=\/dev\//i, // dd of=/dev/...
|
|
32
|
+
/\blaunchctl\b/i,
|
|
33
|
+
/\bsystemctl\b/i,
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Bash commands that require explicit approval before execution.
|
|
37
|
+
* These are dangerous but not catastrophic — they modify remote state,
|
|
38
|
+
* delete files, or interact with container/network infrastructure.
|
|
39
|
+
*
|
|
40
|
+
* Matched against the raw command string (case-insensitive, word-boundary).
|
|
41
|
+
*/
|
|
42
|
+
export const APPROVAL_REQUIRED_BASH_PATTERNS = [
|
|
43
|
+
{ pattern: /\bgit\s+push\b/i, label: 'git push (modifies remote repository)' },
|
|
44
|
+
{ pattern: /\bgit\s+push\s+.*--force\b/i, label: 'git push --force (destructive remote rewrite)' },
|
|
45
|
+
{ pattern: /\brm\s+/i, label: 'rm (file deletion)' },
|
|
46
|
+
{ pattern: /\bdocker\s+(rm|rmi|stop|kill|exec|run|build|push|pull)\b/i, label: 'docker operation (container/image management)' },
|
|
47
|
+
{ pattern: /\bcurl\b/i, label: 'curl (network request)' },
|
|
48
|
+
{ pattern: /\bwget\b/i, label: 'wget (network download)' },
|
|
49
|
+
{ pattern: /\bnpm\s+publish\b/i, label: 'npm publish (package registry push)' },
|
|
50
|
+
{ pattern: /\bgit\s+reset\s+--hard\b/i, label: 'git reset --hard (destructive history rewrite)' },
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Validate a shell command against the blocklist.
|
|
54
|
+
*
|
|
55
|
+
* @param command - Raw shell command string
|
|
56
|
+
* @returns Error message if blocked, or null if allowed
|
|
57
|
+
*/
|
|
58
|
+
export function validateBashCommand(command) {
|
|
59
|
+
for (const pattern of BLOCKED_COMMAND_PATTERNS) {
|
|
60
|
+
if (pattern.test(command)) {
|
|
61
|
+
return `Command blocked by security policy: matches forbidden pattern ${pattern}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if a bash command matches any approval-required pattern.
|
|
68
|
+
*
|
|
69
|
+
* @param command - Raw shell command string
|
|
70
|
+
* @returns Matching label if approval is required, or null if safe to proceed
|
|
71
|
+
*/
|
|
72
|
+
export function checkBashApprovalRequired(command) {
|
|
73
|
+
for (const { pattern, label } of APPROVAL_REQUIRED_BASH_PATTERNS) {
|
|
74
|
+
if (pattern.test(command)) {
|
|
75
|
+
return label;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Execute a shell command in an isolated process group so that signals
|
|
82
|
+
* (SIGTERM, SIGINT) from the child cannot propagate to the Crewly server.
|
|
83
|
+
*
|
|
84
|
+
* Uses spawnSync with setsid (macOS/Linux) to create a new session,
|
|
85
|
+
* preventing the child's process group signals from reaching the parent.
|
|
86
|
+
*
|
|
87
|
+
* @param cmd - Shell command to run
|
|
88
|
+
* @param workDir - Working directory
|
|
89
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
90
|
+
* @returns Object with stdout, stderr, exitCode
|
|
91
|
+
*/
|
|
92
|
+
function execIsolated(cmd, workDir, timeoutMs) {
|
|
93
|
+
const result = spawnSync('/bin/sh', ['-c', cmd], {
|
|
94
|
+
cwd: workDir,
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
timeout: timeoutMs,
|
|
97
|
+
maxBuffer: 1024 * 1024,
|
|
98
|
+
env: { ...process.env, FORCE_COLOR: '0' },
|
|
99
|
+
// Run in a new process group — signals sent to the child group
|
|
100
|
+
// will NOT propagate to the Crewly server's process group.
|
|
101
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
102
|
+
});
|
|
103
|
+
// If the process was killed by a signal (e.g. timeout → SIGTERM),
|
|
104
|
+
// reflect it in the exit code.
|
|
105
|
+
const exitCode = result.status ?? (result.signal ? 128 : 1);
|
|
106
|
+
return {
|
|
107
|
+
stdout: result.stdout ?? '',
|
|
108
|
+
stderr: result.stderr ?? '',
|
|
109
|
+
exitCode,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
13
112
|
/**
|
|
14
113
|
* Expand ~ and $HOME in a file path to the user's home directory.
|
|
15
114
|
*
|
|
@@ -26,6 +125,72 @@ function expandPath(filePath) {
|
|
|
26
125
|
}
|
|
27
126
|
return filePath;
|
|
28
127
|
}
|
|
128
|
+
/** File extensions recognized as images for multimodal read_file support */
|
|
129
|
+
const IMAGE_EXTENSIONS = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg']);
|
|
130
|
+
/** MIME type mapping for image extensions */
|
|
131
|
+
const IMAGE_MIME_TYPES = {
|
|
132
|
+
png: 'image/png',
|
|
133
|
+
jpg: 'image/jpeg',
|
|
134
|
+
jpeg: 'image/jpeg',
|
|
135
|
+
gif: 'image/gif',
|
|
136
|
+
webp: 'image/webp',
|
|
137
|
+
svg: 'image/svg+xml',
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Strip [NOTIFY]...[/NOTIFY] markers from text.
|
|
141
|
+
*
|
|
142
|
+
* The crewly-agent model sometimes wraps tool arguments in NOTIFY markers
|
|
143
|
+
* intended for the terminal gateway routing layer. When this leaks into
|
|
144
|
+
* reply_slack or other outward-facing tools, the raw markers appear in
|
|
145
|
+
* the Slack message. This function extracts the body content (after the
|
|
146
|
+
* --- separator if present) or the full block content.
|
|
147
|
+
*
|
|
148
|
+
* @param text - Text that may contain NOTIFY markers
|
|
149
|
+
* @returns Clean text with markers stripped and body content extracted
|
|
150
|
+
*/
|
|
151
|
+
export function stripNotifyMarkers(text) {
|
|
152
|
+
// Replace each [NOTIFY]...[/NOTIFY] block with its body content
|
|
153
|
+
const cleaned = text.replace(/\[NOTIFY\]([\s\S]*?)\[\/NOTIFY\]/gi, (_match, inner) => {
|
|
154
|
+
const trimmed = inner.trim();
|
|
155
|
+
// If there's a --- separator, extract only the body after it
|
|
156
|
+
const separatorIdx = trimmed.indexOf('---');
|
|
157
|
+
if (separatorIdx !== -1) {
|
|
158
|
+
return trimmed.slice(separatorIdx + 3).trim();
|
|
159
|
+
}
|
|
160
|
+
// No separator — return the full inner content
|
|
161
|
+
return trimmed;
|
|
162
|
+
});
|
|
163
|
+
return cleaned.trim();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Convert GitHub-flavored Markdown to Slack mrkdwn format (#181).
|
|
167
|
+
*
|
|
168
|
+
* Transformations applied (in order):
|
|
169
|
+
* 1. Escape &, <, > to HTML entities (Slack requirement)
|
|
170
|
+
* 2. Convert fenced code blocks (```lang\n...\n```) to Slack code blocks
|
|
171
|
+
* 3. Convert **bold** to *bold* (Slack uses single asterisks)
|
|
172
|
+
* 4. Convert [text](url) links to <url|text> (Slack link format)
|
|
173
|
+
*
|
|
174
|
+
* @param text - Markdown-formatted text
|
|
175
|
+
* @returns Text formatted for Slack mrkdwn
|
|
176
|
+
*/
|
|
177
|
+
export function convertMarkdownToSlackMrkdwn(text) {
|
|
178
|
+
// 1. Escape special Slack characters (must happen first, before adding <> for links)
|
|
179
|
+
let result = text
|
|
180
|
+
.replace(/&/g, '&')
|
|
181
|
+
.replace(/</g, '<')
|
|
182
|
+
.replace(/>/g, '>');
|
|
183
|
+
// 2. Convert fenced code blocks: ```lang\n...\n``` → ```\n...\n```
|
|
184
|
+
// Slack doesn't support language hints in code blocks, so strip them
|
|
185
|
+
result = result.replace(/```\w*\n/g, '```\n');
|
|
186
|
+
// 3. Convert **bold** to *bold* (Slack bold is single asterisk)
|
|
187
|
+
// Must not touch single * (already italic in both formats)
|
|
188
|
+
result = result.replace(/\*\*(.+?)\*\*/g, '*$1*');
|
|
189
|
+
// 4. Convert [text](url) links to <url|text>
|
|
190
|
+
// The url may contain escaped > from step 1, but real URLs won't have those
|
|
191
|
+
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<$2|$1>');
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
29
194
|
/**
|
|
30
195
|
* Sensitivity classification for each tool.
|
|
31
196
|
* Used by the audit trail to classify tool invocations.
|
|
@@ -42,7 +207,9 @@ export const TOOL_SENSITIVITY = {
|
|
|
42
207
|
recall_memory: 'safe',
|
|
43
208
|
subscribe_event: 'safe',
|
|
44
209
|
get_audit_log: 'safe',
|
|
210
|
+
get_scheduled_checks: 'safe',
|
|
45
211
|
compact_memory: 'safe',
|
|
212
|
+
get_context_budget: 'safe',
|
|
46
213
|
// Sensitive: modify state, communicate externally
|
|
47
214
|
delegate_task: 'sensitive',
|
|
48
215
|
send_message: 'sensitive',
|
|
@@ -60,6 +227,14 @@ export const TOOL_SENSITIVITY = {
|
|
|
60
227
|
handle_agent_failure: 'destructive',
|
|
61
228
|
edit_file: 'destructive',
|
|
62
229
|
write_file: 'destructive',
|
|
230
|
+
// Git tools (#176)
|
|
231
|
+
git_status: 'safe',
|
|
232
|
+
git_diff: 'safe',
|
|
233
|
+
git_commit: 'sensitive',
|
|
234
|
+
// Shell execution (#176)
|
|
235
|
+
bash_exec: 'destructive',
|
|
236
|
+
// Task handoff (F12)
|
|
237
|
+
handoff_task: 'sensitive',
|
|
63
238
|
};
|
|
64
239
|
/**
|
|
65
240
|
* Wrap a tool's execute function with audit logging.
|
|
@@ -107,10 +282,17 @@ function wrapWithAudit(toolName, executeFn, callbacks) {
|
|
|
107
282
|
};
|
|
108
283
|
if (callbacks?.onAuditLog)
|
|
109
284
|
callbacks.onAuditLog(entry);
|
|
285
|
+
// Enqueue for approval if not hard-blocked
|
|
286
|
+
let approvalId;
|
|
287
|
+
if (!approvalResult.blocked && callbacks?.onEnqueueApproval) {
|
|
288
|
+
const enqueued = callbacks.onEnqueueApproval(toolName, sensitivity, sanitizedArgs);
|
|
289
|
+
approvalId = enqueued.approvalId;
|
|
290
|
+
}
|
|
110
291
|
return {
|
|
111
292
|
success: false,
|
|
112
293
|
blocked: approvalResult.blocked ?? false,
|
|
113
294
|
requiresApproval: !approvalResult.blocked,
|
|
295
|
+
approvalId,
|
|
114
296
|
error: approvalResult.reason || 'Tool execution denied by security policy',
|
|
115
297
|
};
|
|
116
298
|
}
|
|
@@ -166,8 +348,8 @@ function sanitizeArgs(args) {
|
|
|
166
348
|
if (sensitiveKeys.some(sk => key.toLowerCase().includes(sk))) {
|
|
167
349
|
result[key] = '[REDACTED]';
|
|
168
350
|
}
|
|
169
|
-
else if (typeof value === 'string' && value.length >
|
|
170
|
-
result[key] = value.substring(0,
|
|
351
|
+
else if (typeof value === 'string' && value.length > 2000) {
|
|
352
|
+
result[key] = value.substring(0, 2000) + '...[truncated]';
|
|
171
353
|
}
|
|
172
354
|
else {
|
|
173
355
|
result[key] = value;
|
|
@@ -188,11 +370,17 @@ function sanitizeArgs(args) {
|
|
|
188
370
|
* @param callbacks - Optional callbacks for compaction and audit logging
|
|
189
371
|
* @returns Object of named tools ready to pass to generateText
|
|
190
372
|
*/
|
|
191
|
-
export function createTools(client, sessionName, projectPath, callbacks) {
|
|
373
|
+
export function createTools(client, sessionName, projectPath, callbacks, conversationId, slackContext, mcpTools) {
|
|
374
|
+
// Slack rate-limiting state: throttle messages within a 3-second window
|
|
375
|
+
let lastSlackSendMs = 0;
|
|
376
|
+
const SLACK_THROTTLE_MS = 3000;
|
|
377
|
+
// Slack dedup: ring buffer of recent messages to prevent duplicate sends
|
|
378
|
+
const recentSlackMessages = [];
|
|
379
|
+
const SLACK_DEDUP_WINDOW = 10;
|
|
192
380
|
const rawTools = {
|
|
193
381
|
// ===== Core Orchestration Tools =====
|
|
194
382
|
delegate_task: {
|
|
195
|
-
description: 'Delegate a task to a worker agent. Sends the task message and creates a task tracking file.',
|
|
383
|
+
description: 'Delegate a task to a worker agent. Sends the task message and creates a task tracking file. Enforces TL hierarchy — if target has a parent TL, routes through TL instead.',
|
|
196
384
|
inputSchema: z.object({
|
|
197
385
|
to: z.string().describe('Target agent session name'),
|
|
198
386
|
task: z.string().describe('Task description and instructions'),
|
|
@@ -201,6 +389,42 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
201
389
|
projectPath: z.string().optional().describe('Project path for task tracking'),
|
|
202
390
|
}),
|
|
203
391
|
execute: async ({ to, task, priority, context, projectPath }) => {
|
|
392
|
+
// #164: TL hierarchy validation — enforce that the caller has delegation authority
|
|
393
|
+
const teamsResult = await client.get('/teams').catch(() => null);
|
|
394
|
+
if (teamsResult?.success && Array.isArray(teamsResult.data)) {
|
|
395
|
+
for (const team of teamsResult.data) {
|
|
396
|
+
const targetMember = team.members?.find(m => m.sessionName === to);
|
|
397
|
+
const callerMember = team.members?.find(m => m.sessionName === sessionName);
|
|
398
|
+
if (targetMember?.parentMemberId) {
|
|
399
|
+
const tlMember = team.members?.find(m => m.id === targetMember.parentMemberId);
|
|
400
|
+
// If the caller is NOT the TL, redirect through TL
|
|
401
|
+
if (tlMember && tlMember.sessionName !== sessionName) {
|
|
402
|
+
return {
|
|
403
|
+
success: false,
|
|
404
|
+
error: `Hierarchy violation: ${to} reports to TL ${tlMember.sessionName} (${tlMember.id}). You must delegate through the TL, not directly. Use send_message to ask ${tlMember.sessionName} to delegate this task to ${to}.`,
|
|
405
|
+
redirectTo: tlMember.sessionName,
|
|
406
|
+
hint: 'Use send_message to the TL with the task details, and ask them to delegate to the worker.',
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// Verify caller has canDelegate permission when delegating to a subordinate
|
|
411
|
+
if (callerMember && targetMember && callerMember.canDelegate === false) {
|
|
412
|
+
return {
|
|
413
|
+
success: false,
|
|
414
|
+
error: `You (${sessionName}) do not have delegation permission (canDelegate: false). Ask your TL to delegate this task.`,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
// Task stacking prevention — check if target already has in-progress tasks
|
|
418
|
+
if (targetMember && targetMember.workingStatus === 'in_progress') {
|
|
419
|
+
return {
|
|
420
|
+
success: false,
|
|
421
|
+
error: `Agent ${to} is already working on a task (workingStatus: in_progress). Wait for current task to complete before delegating a new one.`,
|
|
422
|
+
agentStatus: targetMember.agentStatus,
|
|
423
|
+
workingStatus: targetMember.workingStatus,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
204
428
|
const taskMessage = buildTaskMessage(to, task, priority, context, projectPath);
|
|
205
429
|
// Deliver the task message
|
|
206
430
|
const deliverResult = await client.post(`/terminal/${to}/deliver`, {
|
|
@@ -232,15 +456,20 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
232
456
|
taskId = createResult.data.taskId;
|
|
233
457
|
}
|
|
234
458
|
}
|
|
235
|
-
// Subscribe to idle event for monitoring
|
|
236
|
-
await client.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
459
|
+
// Subscribe to idle event for monitoring (with dedup check)
|
|
460
|
+
const existingSubs = await client.get(`/events/subscriptions?subscriberSession=${encodeURIComponent(sessionName)}`).catch(() => null);
|
|
461
|
+
const alreadySubscribed = existingSubs?.success && Array.isArray(existingSubs.data) &&
|
|
462
|
+
existingSubs.data.some(sub => sub.eventType === 'agent:idle' && sub.filter?.sessionName === to);
|
|
463
|
+
if (!alreadySubscribed) {
|
|
464
|
+
await client.post('/events/subscribe', {
|
|
465
|
+
eventType: 'agent:idle',
|
|
466
|
+
filter: { sessionName: to },
|
|
467
|
+
subscriberSession: sessionName,
|
|
468
|
+
oneShot: true,
|
|
469
|
+
ttlMinutes: DELEGATION_SUBSCRIPTION_TTL_MINUTES,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
return { success: true, delegatedTo: to, taskId, conversationId: conversationId || undefined };
|
|
244
473
|
},
|
|
245
474
|
},
|
|
246
475
|
send_message: {
|
|
@@ -306,17 +535,53 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
306
535
|
},
|
|
307
536
|
},
|
|
308
537
|
reply_slack: {
|
|
309
|
-
description: 'Send a reply to a Slack channel or thread.',
|
|
538
|
+
description: 'Send a reply to a Slack channel or thread. If channelId is omitted, uses the current Slack thread context. Messages sent within 3 seconds are batched to avoid spam.',
|
|
310
539
|
inputSchema: z.object({
|
|
311
|
-
channelId: z.string().describe('Slack channel ID'),
|
|
540
|
+
channelId: z.string().optional().describe('Slack channel ID (auto-filled from current thread context if omitted)'),
|
|
312
541
|
text: z.string().describe('Message text'),
|
|
313
|
-
threadTs: z.string().optional().describe('Thread timestamp for replies'),
|
|
542
|
+
threadTs: z.string().optional().describe('Thread timestamp for replies (auto-filled from current thread context if omitted)'),
|
|
314
543
|
}),
|
|
315
544
|
execute: async ({ channelId, text, threadTs }) => {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
545
|
+
let cleanText = stripNotifyMarkers(text);
|
|
546
|
+
// #181: Convert markdown to Slack mrkdwn format
|
|
547
|
+
cleanText = convertMarkdownToSlackMrkdwn(cleanText);
|
|
548
|
+
// Auto-prefix with agent display name so Slack messages are attributable
|
|
549
|
+
// Session format: "crewly-{team}-{name}-{uuid}" → extract {name}
|
|
550
|
+
// Fallback: "crewly-orc" → "orc"
|
|
551
|
+
if (sessionName && !cleanText.startsWith('[')) {
|
|
552
|
+
const parts = sessionName.split('-');
|
|
553
|
+
// For "crewly-product-sam-217bfbbf": parts[2] = "sam"
|
|
554
|
+
// For "crewly-orc": parts[1] = "orc"
|
|
555
|
+
const namePart = parts.length >= 3 ? parts[2] : parts[parts.length - 1];
|
|
556
|
+
const capitalized = namePart.charAt(0).toUpperCase() + namePart.slice(1);
|
|
557
|
+
cleanText = `[${capitalized}] ${cleanText}`;
|
|
558
|
+
}
|
|
559
|
+
const resolvedChannelId = channelId || slackContext?.channelId;
|
|
560
|
+
const resolvedThreadTs = threadTs || slackContext?.threadTs;
|
|
561
|
+
if (!resolvedChannelId) {
|
|
562
|
+
return { success: false, error: 'No channelId provided and no Slack thread context available. Use reply_slack with an explicit channelId.' };
|
|
563
|
+
}
|
|
564
|
+
// Dedup: skip if this exact message was recently sent
|
|
565
|
+
if (recentSlackMessages.includes(cleanText)) {
|
|
566
|
+
return { success: true, sent: false, deduplicated: true, reason: 'Message already sent recently' };
|
|
567
|
+
}
|
|
568
|
+
// Issue 3: Rate-limit Slack messages — throttle within a 3s window
|
|
569
|
+
const now = Date.now();
|
|
570
|
+
if (now - lastSlackSendMs < SLACK_THROTTLE_MS) {
|
|
571
|
+
return { success: true, sent: false, throttled: true, retryAfterMs: SLACK_THROTTLE_MS - (now - lastSlackSendMs) };
|
|
572
|
+
}
|
|
573
|
+
const body = { channelId: resolvedChannelId, text: cleanText };
|
|
574
|
+
if (resolvedThreadTs)
|
|
575
|
+
body.threadTs = resolvedThreadTs;
|
|
319
576
|
const result = await client.post('/slack/send', body);
|
|
577
|
+
if (result.success) {
|
|
578
|
+
lastSlackSendMs = Date.now();
|
|
579
|
+
// Track for dedup
|
|
580
|
+
recentSlackMessages.push(cleanText);
|
|
581
|
+
if (recentSlackMessages.length > SLACK_DEDUP_WINDOW) {
|
|
582
|
+
recentSlackMessages.shift();
|
|
583
|
+
}
|
|
584
|
+
}
|
|
320
585
|
return result.success
|
|
321
586
|
? { success: true, sent: true }
|
|
322
587
|
: { success: false, error: result.error };
|
|
@@ -324,16 +589,27 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
324
589
|
},
|
|
325
590
|
// ===== Scheduling Tools =====
|
|
326
591
|
schedule_check: {
|
|
327
|
-
description: 'Schedule a future check-in reminder.',
|
|
592
|
+
description: 'Schedule a future check-in reminder. Include taskId to auto-cancel when the linked task completes. Deduplicates: skips if a similar check already exists for the same target.',
|
|
328
593
|
inputSchema: z.object({
|
|
329
594
|
minutes: z.number().describe('Minutes from now'),
|
|
330
595
|
message: z.string().describe('Reminder message'),
|
|
331
596
|
target: z.string().optional().describe('Target session (defaults to self)'),
|
|
332
597
|
recurring: z.boolean().default(false),
|
|
333
598
|
maxOccurrences: z.number().optional(),
|
|
599
|
+
taskId: z.string().optional().describe('Link to a task ID — recurring check auto-cancels when this task completes'),
|
|
334
600
|
}),
|
|
335
|
-
execute: async ({ minutes, message, target, recurring, maxOccurrences }) => {
|
|
601
|
+
execute: async ({ minutes, message, target, recurring, maxOccurrences, taskId }) => {
|
|
336
602
|
const targetSession = target || sessionName;
|
|
603
|
+
// Issue 2: Dedup check — list existing scheduled checks for this target
|
|
604
|
+
const existingResult = await client.get(`/schedule?session=${encodeURIComponent(targetSession)}`).catch(() => null);
|
|
605
|
+
if (existingResult?.success && Array.isArray(existingResult.data)) {
|
|
606
|
+
const msgPrefix = message.slice(0, 50); // Match on message prefix
|
|
607
|
+
const isDuplicate = existingResult.data.some(check => check.targetSession === targetSession &&
|
|
608
|
+
(check.message?.startsWith(msgPrefix) || (taskId && check.taskId === taskId)));
|
|
609
|
+
if (isDuplicate) {
|
|
610
|
+
return { success: true, status: 'already_scheduled', targetSession, message };
|
|
611
|
+
}
|
|
612
|
+
}
|
|
337
613
|
const body = {
|
|
338
614
|
targetSession,
|
|
339
615
|
minutes,
|
|
@@ -345,6 +621,8 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
345
621
|
}
|
|
346
622
|
if (maxOccurrences)
|
|
347
623
|
body.maxOccurrences = maxOccurrences;
|
|
624
|
+
if (taskId)
|
|
625
|
+
body.taskId = taskId;
|
|
348
626
|
const result = await client.post('/schedule', body);
|
|
349
627
|
return result.success ? result.data : { error: result.error };
|
|
350
628
|
},
|
|
@@ -359,14 +637,43 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
359
637
|
return result.success ? { success: true } : { error: result.error };
|
|
360
638
|
},
|
|
361
639
|
},
|
|
640
|
+
get_scheduled_checks: {
|
|
641
|
+
description: 'List all active scheduled checks. Use to identify stale or completed checks that should be cancelled.',
|
|
642
|
+
inputSchema: z.object({
|
|
643
|
+
session: z.string().optional().describe('Filter by target session name'),
|
|
644
|
+
}),
|
|
645
|
+
execute: async ({ session }) => {
|
|
646
|
+
const endpoint = session
|
|
647
|
+
? `/schedule?session=${encodeURIComponent(session)}`
|
|
648
|
+
: '/schedule';
|
|
649
|
+
const result = await client.get(endpoint);
|
|
650
|
+
return result.success ? result.data : { error: result.error };
|
|
651
|
+
},
|
|
652
|
+
},
|
|
362
653
|
// ===== Agent Lifecycle Tools =====
|
|
363
654
|
start_agent: {
|
|
364
|
-
description: 'Start a specific agent within a team.',
|
|
655
|
+
description: 'Start a specific agent within a team. Safely skips if the agent is already active.',
|
|
365
656
|
inputSchema: z.object({
|
|
366
657
|
teamId: z.string().describe('Team UUID'),
|
|
367
658
|
memberId: z.string().describe('Member UUID'),
|
|
368
659
|
}),
|
|
369
660
|
execute: async ({ teamId, memberId }) => {
|
|
661
|
+
// Pre-check: if the agent is already active, return immediately to avoid
|
|
662
|
+
// timeout and session interruption from redundant start calls
|
|
663
|
+
const teamResult = await client.get(`/teams/${teamId}`).catch(() => null);
|
|
664
|
+
if (teamResult?.success && teamResult.data) {
|
|
665
|
+
const team = teamResult.data;
|
|
666
|
+
const member = team.members?.find(m => m.id === memberId);
|
|
667
|
+
if (member && member.agentStatus === 'active' && member.sessionName) {
|
|
668
|
+
return {
|
|
669
|
+
success: true,
|
|
670
|
+
memberName: member.name,
|
|
671
|
+
memberId: member.id,
|
|
672
|
+
sessionName: member.sessionName,
|
|
673
|
+
status: 'already_active',
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
370
677
|
const result = await client.post(`/teams/${teamId}/members/${memberId}/start`, {});
|
|
371
678
|
return result.success ? result.data : { error: result.error };
|
|
372
679
|
},
|
|
@@ -384,13 +691,24 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
384
691
|
},
|
|
385
692
|
// ===== Event Tools =====
|
|
386
693
|
subscribe_event: {
|
|
387
|
-
description: 'Subscribe to agent lifecycle events (e.g., agent:idle, agent:busy).',
|
|
694
|
+
description: 'Subscribe to agent lifecycle events (e.g., agent:idle, agent:busy). Deduplicates: skips if an identical subscription already exists.',
|
|
388
695
|
inputSchema: z.object({
|
|
389
696
|
eventType: z.string().describe('Event type (e.g., "agent:idle")'),
|
|
390
697
|
filter: z.record(z.string()).optional().describe('Event filter criteria'),
|
|
391
698
|
oneShot: z.boolean().default(true),
|
|
392
699
|
}),
|
|
393
700
|
execute: async ({ eventType, filter, oneShot }) => {
|
|
701
|
+
// Issue 2: Dedup check — list existing subscriptions and skip if duplicate
|
|
702
|
+
const existingResult = await client.get(`/events/subscriptions?subscriberSession=${encodeURIComponent(sessionName)}`).catch(() => null);
|
|
703
|
+
if (existingResult?.success && Array.isArray(existingResult.data)) {
|
|
704
|
+
const filterStr = JSON.stringify(filter || {});
|
|
705
|
+
const isDuplicate = existingResult.data.some(sub => sub.eventType === eventType &&
|
|
706
|
+
sub.subscriberSession === sessionName &&
|
|
707
|
+
JSON.stringify(sub.filter || {}) === filterStr);
|
|
708
|
+
if (isDuplicate) {
|
|
709
|
+
return { success: true, status: 'already_subscribed', eventType, filter };
|
|
710
|
+
}
|
|
711
|
+
}
|
|
394
712
|
const result = await client.post('/events/subscribe', {
|
|
395
713
|
eventType,
|
|
396
714
|
filter: filter || {},
|
|
@@ -480,7 +798,7 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
480
798
|
},
|
|
481
799
|
},
|
|
482
800
|
complete_task: {
|
|
483
|
-
description: 'Mark a task as complete.',
|
|
801
|
+
description: 'Mark a task as complete. Also cancels any scheduled checks targeting the completing agent session.',
|
|
484
802
|
inputSchema: z.object({
|
|
485
803
|
absoluteTaskPath: z.string().describe('Absolute path to the task file'),
|
|
486
804
|
sessionName: z.string().describe('Agent session that completed it'),
|
|
@@ -492,7 +810,27 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
492
810
|
sessionName: agent,
|
|
493
811
|
summary,
|
|
494
812
|
});
|
|
495
|
-
|
|
813
|
+
// Auto-cancel scheduled checks targeting the completing agent
|
|
814
|
+
// to prevent stale recurring checks from firing after task completion
|
|
815
|
+
let cancelledChecks = 0;
|
|
816
|
+
try {
|
|
817
|
+
const checksResult = await client.get(`/schedule?session=${encodeURIComponent(agent)}`);
|
|
818
|
+
if (checksResult.success && Array.isArray(checksResult.data)) {
|
|
819
|
+
for (const check of checksResult.data) {
|
|
820
|
+
if (check.isRecurring) {
|
|
821
|
+
await client.delete(`/schedule/${check.id}`);
|
|
822
|
+
cancelledChecks++;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
catch {
|
|
828
|
+
// Non-fatal: task completion succeeded even if check cleanup fails
|
|
829
|
+
}
|
|
830
|
+
if (result.success) {
|
|
831
|
+
return { ...result.data, cancelledChecks };
|
|
832
|
+
}
|
|
833
|
+
return { error: result.error };
|
|
496
834
|
},
|
|
497
835
|
},
|
|
498
836
|
broadcast: {
|
|
@@ -605,15 +943,30 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
605
943
|
},
|
|
606
944
|
},
|
|
607
945
|
read_file: {
|
|
608
|
-
description: 'Read the contents of a file. Returns
|
|
946
|
+
description: 'Read the contents of a file. Returns text content with line numbers, or base64-encoded image data for image files (png/jpg/gif/webp/svg). Image files are returned as multimodal content parts for AI SDK.',
|
|
609
947
|
inputSchema: z.object({
|
|
610
948
|
file_path: z.string().describe('Absolute path to the file to read'),
|
|
611
|
-
offset: z.number().optional().describe('Line number to start reading from (1-based)'),
|
|
612
|
-
limit: z.number().optional().describe('Maximum number of lines to read'),
|
|
949
|
+
offset: z.number().optional().describe('Line number to start reading from (1-based, text files only)'),
|
|
950
|
+
limit: z.number().optional().describe('Maximum number of lines to read (text files only)'),
|
|
613
951
|
}),
|
|
614
952
|
execute: async ({ file_path, offset, limit }) => {
|
|
615
953
|
const fp = expandPath(file_path);
|
|
616
954
|
try {
|
|
955
|
+
// Check if this is an image file
|
|
956
|
+
const ext = fp.split('.').pop()?.toLowerCase() || '';
|
|
957
|
+
if (IMAGE_EXTENSIONS.has(ext)) {
|
|
958
|
+
const buffer = await fsPromises.readFile(fp);
|
|
959
|
+
const base64 = buffer.toString('base64');
|
|
960
|
+
const mimeType = IMAGE_MIME_TYPES[ext] || 'application/octet-stream';
|
|
961
|
+
return {
|
|
962
|
+
success: true,
|
|
963
|
+
type: 'image',
|
|
964
|
+
mimeType,
|
|
965
|
+
data: base64,
|
|
966
|
+
file: fp,
|
|
967
|
+
sizeBytes: buffer.length,
|
|
968
|
+
};
|
|
969
|
+
}
|
|
617
970
|
const content = await fsPromises.readFile(fp, 'utf8');
|
|
618
971
|
const lines = content.split('\n');
|
|
619
972
|
if (offset || limit) {
|
|
@@ -686,20 +1039,39 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
686
1039
|
},
|
|
687
1040
|
},
|
|
688
1041
|
report_status: {
|
|
689
|
-
description: 'Report task status to the orchestrator.',
|
|
1042
|
+
description: 'Report task status to the orchestrator. sessionName and role are auto-injected from the current session context.',
|
|
690
1043
|
inputSchema: z.object({
|
|
691
1044
|
status: z.enum(['in_progress', 'done', 'blocked', 'error']).describe('Current status'),
|
|
692
1045
|
summary: z.string().describe('Brief status summary'),
|
|
693
1046
|
}),
|
|
694
1047
|
execute: async ({ status, summary }) => {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
1048
|
+
// Build status message matching the bash report-status format
|
|
1049
|
+
const statusUpper = status.toUpperCase();
|
|
1050
|
+
const message = `[${statusUpper}] Agent ${sessionName}: ${summary}`;
|
|
1051
|
+
// Send to orchestrator via chat API (matches bash skill behavior)
|
|
1052
|
+
const chatBody = {
|
|
1053
|
+
content: message,
|
|
1054
|
+
senderName: sessionName,
|
|
1055
|
+
senderType: 'agent',
|
|
699
1056
|
};
|
|
700
|
-
if (
|
|
701
|
-
|
|
702
|
-
|
|
1057
|
+
if (conversationId) {
|
|
1058
|
+
chatBody.conversationId = conversationId;
|
|
1059
|
+
}
|
|
1060
|
+
const result = await client.post('/chat/agent-response', chatBody);
|
|
1061
|
+
// Auto-complete tracked tasks when status is done
|
|
1062
|
+
if (status === 'done') {
|
|
1063
|
+
await client.post('/task-management/complete-by-session', { sessionName }).catch(() => { });
|
|
1064
|
+
}
|
|
1065
|
+
// Auto-persist key findings as project knowledge when done (#127)
|
|
1066
|
+
if (status === 'done' && summary && projectPath) {
|
|
1067
|
+
await client.post('/memory/remember', {
|
|
1068
|
+
agentId: sessionName,
|
|
1069
|
+
content: `Task completed by ${sessionName}: ${summary}`,
|
|
1070
|
+
category: 'pattern',
|
|
1071
|
+
scope: 'project',
|
|
1072
|
+
projectPath,
|
|
1073
|
+
}).catch(() => { });
|
|
1074
|
+
}
|
|
703
1075
|
return result.success ? result.data : { error: result.error };
|
|
704
1076
|
},
|
|
705
1077
|
},
|
|
@@ -719,6 +1091,18 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
719
1091
|
};
|
|
720
1092
|
},
|
|
721
1093
|
},
|
|
1094
|
+
get_context_budget: {
|
|
1095
|
+
description: 'Check current context window token budget usage. Returns total tokens used, context window size, usage percentage, and warning level (normal/warning/critical). Use proactively to decide when to compact or wrap up work.',
|
|
1096
|
+
inputSchema: z.object({}),
|
|
1097
|
+
sensitivity: 'safe',
|
|
1098
|
+
execute: async () => {
|
|
1099
|
+
if (!callbacks?.onGetContextBudget) {
|
|
1100
|
+
return { success: false, error: 'Context budget tracking not available — no runner callback configured' };
|
|
1101
|
+
}
|
|
1102
|
+
const budget = callbacks.onGetContextBudget();
|
|
1103
|
+
return { success: true, ...budget };
|
|
1104
|
+
},
|
|
1105
|
+
},
|
|
722
1106
|
// ===== Security Audit Tool =====
|
|
723
1107
|
get_audit_log: {
|
|
724
1108
|
description: 'Retrieve the security audit trail of recent tool invocations. Shows tool name, sensitivity classification, success/failure, duration, and sanitized arguments. Use for security review, debugging, or compliance.',
|
|
@@ -729,16 +1113,237 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
729
1113
|
}),
|
|
730
1114
|
sensitivity: 'safe',
|
|
731
1115
|
execute: async ({ limit, sensitivity: filterSensitivity, toolName: filterTool }) => {
|
|
732
|
-
|
|
733
|
-
|
|
1116
|
+
if (!callbacks?.onGetAuditLog) {
|
|
1117
|
+
return {
|
|
1118
|
+
success: false,
|
|
1119
|
+
error: 'Audit log not available — no runner callback configured',
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
const filters = {
|
|
1123
|
+
limit: limit || 50,
|
|
1124
|
+
sensitivity: filterSensitivity,
|
|
1125
|
+
toolName: filterTool,
|
|
1126
|
+
};
|
|
1127
|
+
const entries = callbacks.onGetAuditLog(filters);
|
|
734
1128
|
return {
|
|
735
1129
|
success: true,
|
|
736
|
-
|
|
1130
|
+
totalEntries: entries.length,
|
|
737
1131
|
filters: {
|
|
738
|
-
limit: limit
|
|
739
|
-
sensitivity:
|
|
740
|
-
toolName:
|
|
1132
|
+
limit: filters.limit,
|
|
1133
|
+
sensitivity: filters.sensitivity || 'all',
|
|
1134
|
+
toolName: filters.toolName || 'all',
|
|
741
1135
|
},
|
|
1136
|
+
entries,
|
|
1137
|
+
};
|
|
1138
|
+
},
|
|
1139
|
+
},
|
|
1140
|
+
// ===================================================================
|
|
1141
|
+
// Shell Execution (#176)
|
|
1142
|
+
// ===================================================================
|
|
1143
|
+
bash_exec: {
|
|
1144
|
+
description: 'Execute a shell command and return stdout/stderr. Commands run with a timeout (default 30s, max 120s). Use for build, test, lint, and system operations. Some commands (kill, reboot, rm -rf /, etc.) are blocked by security policy.',
|
|
1145
|
+
inputSchema: z.object({
|
|
1146
|
+
command: z.string().describe('Shell command to execute'),
|
|
1147
|
+
cwd: z.string().optional().describe('Working directory (defaults to project path)'),
|
|
1148
|
+
timeout: z.number().optional().describe('Timeout in milliseconds (default: 30000, max: 120000)'),
|
|
1149
|
+
}),
|
|
1150
|
+
sensitivity: 'destructive',
|
|
1151
|
+
execute: async ({ command, cwd, timeout }) => {
|
|
1152
|
+
const cmd = command;
|
|
1153
|
+
// Check command against blocklist before execution
|
|
1154
|
+
const blockReason = validateBashCommand(cmd);
|
|
1155
|
+
if (blockReason) {
|
|
1156
|
+
return {
|
|
1157
|
+
success: false,
|
|
1158
|
+
exitCode: 126,
|
|
1159
|
+
stdout: '',
|
|
1160
|
+
stderr: blockReason,
|
|
1161
|
+
error: blockReason,
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
// Check if command requires explicit approval (git push, rm, docker, network, etc.)
|
|
1165
|
+
const approvalLabel = checkBashApprovalRequired(cmd);
|
|
1166
|
+
if (approvalLabel && callbacks?.onEnqueueApproval) {
|
|
1167
|
+
const sanitizedArgs = sanitizeArgs({ command: cmd, cwd, timeout });
|
|
1168
|
+
const enqueued = callbacks.onEnqueueApproval('bash_exec', 'destructive', sanitizedArgs);
|
|
1169
|
+
return {
|
|
1170
|
+
success: false,
|
|
1171
|
+
requiresApproval: true,
|
|
1172
|
+
approvalId: enqueued.approvalId,
|
|
1173
|
+
reason: `Command requires approval: ${approvalLabel}`,
|
|
1174
|
+
error: `Approval required for: ${approvalLabel}. Approval ID: ${enqueued.approvalId}`,
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
const workDir = expandPath(cwd || projectPath || process.cwd());
|
|
1178
|
+
const timeoutMs = Math.min(timeout || 30000, 120000);
|
|
1179
|
+
// Run in isolated process group to prevent signal propagation
|
|
1180
|
+
const result = execIsolated(cmd, workDir, timeoutMs);
|
|
1181
|
+
if (result.exitCode === 0) {
|
|
1182
|
+
const truncated = result.stdout.length > 10000;
|
|
1183
|
+
return {
|
|
1184
|
+
success: true,
|
|
1185
|
+
exitCode: 0,
|
|
1186
|
+
stdout: truncated ? result.stdout.slice(-10000) + '\n...(truncated)' : result.stdout,
|
|
1187
|
+
truncated,
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
return {
|
|
1191
|
+
success: false,
|
|
1192
|
+
exitCode: result.exitCode,
|
|
1193
|
+
stdout: (result.stdout || '').slice(-5000),
|
|
1194
|
+
stderr: (result.stderr || '').slice(-5000),
|
|
1195
|
+
error: result.stderr ? result.stderr.slice(0, 500) : `Process exited with code ${result.exitCode}`,
|
|
1196
|
+
};
|
|
1197
|
+
},
|
|
1198
|
+
},
|
|
1199
|
+
// ===================================================================
|
|
1200
|
+
// Git Tools (#176)
|
|
1201
|
+
// ===================================================================
|
|
1202
|
+
git_status: {
|
|
1203
|
+
description: 'Get the git status of a project directory. Returns current branch, staged files, unstaged changes, and untracked files.',
|
|
1204
|
+
inputSchema: z.object({
|
|
1205
|
+
projectPath: z.string().describe('Absolute path to the git repository'),
|
|
1206
|
+
}),
|
|
1207
|
+
execute: async ({ projectPath }) => {
|
|
1208
|
+
const cwd = expandPath(projectPath);
|
|
1209
|
+
try {
|
|
1210
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd, encoding: 'utf8' }).trim();
|
|
1211
|
+
const statusOutput = execSync('git status --porcelain', { cwd, encoding: 'utf8' });
|
|
1212
|
+
const staged = [];
|
|
1213
|
+
const unstaged = [];
|
|
1214
|
+
const untracked = [];
|
|
1215
|
+
for (const line of statusOutput.split('\n')) {
|
|
1216
|
+
if (!line.trim())
|
|
1217
|
+
continue;
|
|
1218
|
+
const x = line[0]; // index status
|
|
1219
|
+
const y = line[1]; // working tree status
|
|
1220
|
+
const file = line.slice(3);
|
|
1221
|
+
if (x === '?' && y === '?') {
|
|
1222
|
+
untracked.push(file);
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
if (x !== ' ' && x !== '?')
|
|
1226
|
+
staged.push(file);
|
|
1227
|
+
if (y !== ' ' && y !== '?')
|
|
1228
|
+
unstaged.push(file);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return { success: true, branch, staged, unstaged, untracked };
|
|
1232
|
+
}
|
|
1233
|
+
catch (error) {
|
|
1234
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1235
|
+
}
|
|
1236
|
+
},
|
|
1237
|
+
},
|
|
1238
|
+
git_diff: {
|
|
1239
|
+
description: 'Get the git diff output for a project directory. Shows unstaged changes by default, or staged changes when staged=true. Output truncated to 5000 characters.',
|
|
1240
|
+
inputSchema: z.object({
|
|
1241
|
+
projectPath: z.string().describe('Absolute path to the git repository'),
|
|
1242
|
+
staged: z.boolean().default(false).describe('Show staged (cached) changes instead of unstaged'),
|
|
1243
|
+
}),
|
|
1244
|
+
execute: async ({ projectPath, staged }) => {
|
|
1245
|
+
const cwd = expandPath(projectPath);
|
|
1246
|
+
try {
|
|
1247
|
+
const cmd = staged ? 'git diff --cached' : 'git diff';
|
|
1248
|
+
const diff = execSync(cmd, { cwd, encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 });
|
|
1249
|
+
const truncated = diff.length > GIT_DIFF_MAX_CHARS;
|
|
1250
|
+
const output = truncated ? diff.slice(0, GIT_DIFF_MAX_CHARS) + '\n... (truncated)' : diff;
|
|
1251
|
+
return { success: true, diff: output, truncated, totalLength: diff.length };
|
|
1252
|
+
}
|
|
1253
|
+
catch (error) {
|
|
1254
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1255
|
+
}
|
|
1256
|
+
},
|
|
1257
|
+
},
|
|
1258
|
+
git_commit: {
|
|
1259
|
+
description: 'Stage files and create a git commit. If files are provided, stages only those files. Otherwise stages all changes (git add -A). Returns the new commit hash.',
|
|
1260
|
+
inputSchema: z.object({
|
|
1261
|
+
projectPath: z.string().describe('Absolute path to the git repository'),
|
|
1262
|
+
message: z.string().describe('Commit message'),
|
|
1263
|
+
files: z.array(z.string()).optional().describe('Specific files to stage (omit for git add -A)'),
|
|
1264
|
+
}),
|
|
1265
|
+
sensitivity: 'sensitive',
|
|
1266
|
+
execute: async ({ projectPath, message, files }) => {
|
|
1267
|
+
const cwd = expandPath(projectPath);
|
|
1268
|
+
try {
|
|
1269
|
+
// Stage files
|
|
1270
|
+
if (files && files.length > 0) {
|
|
1271
|
+
for (const file of files) {
|
|
1272
|
+
execSync(`git add -- ${JSON.stringify(file)}`, { cwd, encoding: 'utf8' });
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
else {
|
|
1276
|
+
execSync('git add -A', { cwd, encoding: 'utf8' });
|
|
1277
|
+
}
|
|
1278
|
+
// Commit
|
|
1279
|
+
execSync(`git commit -m ${JSON.stringify(message)}`, { cwd, encoding: 'utf8' });
|
|
1280
|
+
// Get the commit hash
|
|
1281
|
+
const hash = execSync('git rev-parse HEAD', { cwd, encoding: 'utf8' }).trim();
|
|
1282
|
+
return { success: true, commitHash: hash, message: message };
|
|
1283
|
+
}
|
|
1284
|
+
catch (error) {
|
|
1285
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1286
|
+
}
|
|
1287
|
+
},
|
|
1288
|
+
},
|
|
1289
|
+
// ===================================================================
|
|
1290
|
+
// Task Handoff (F12)
|
|
1291
|
+
// ===================================================================
|
|
1292
|
+
handoff_task: {
|
|
1293
|
+
description: 'Hand off an in-progress task to another agent with full context (progress, findings, blockers). Unlike delegate_task which assigns NEW work, handoff transfers ONGOING work so the receiving agent can continue where you left off.',
|
|
1294
|
+
inputSchema: z.object({
|
|
1295
|
+
to: z.string().describe('Target agent session name to hand off to'),
|
|
1296
|
+
reason: z.string().describe('Why you are handing off (blocked, expertise needed, etc.)'),
|
|
1297
|
+
progress: z.string().optional().describe('Current progress summary (what is done so far)'),
|
|
1298
|
+
findings: z.string().optional().describe('Key findings and decisions made'),
|
|
1299
|
+
blockers: z.string().optional().describe('Current blockers or notes for the receiving agent'),
|
|
1300
|
+
taskPath: z.string().optional().describe('Path to the task markdown file'),
|
|
1301
|
+
}),
|
|
1302
|
+
sensitivity: 'sensitive',
|
|
1303
|
+
execute: async ({ to, reason, progress, findings, blockers, taskPath }) => {
|
|
1304
|
+
const target = to;
|
|
1305
|
+
const handoffReason = reason;
|
|
1306
|
+
// Build handoff context message
|
|
1307
|
+
let message = `[TASK HANDOFF] from ${sessionName}\n\n## Reason\n${handoffReason}\n`;
|
|
1308
|
+
if (progress)
|
|
1309
|
+
message += `\n## Progress\n${progress}\n`;
|
|
1310
|
+
if (findings)
|
|
1311
|
+
message += `\n## Key Findings\n${findings}\n`;
|
|
1312
|
+
if (blockers)
|
|
1313
|
+
message += `\n## Blockers / Notes\n${blockers}\n`;
|
|
1314
|
+
if (taskPath)
|
|
1315
|
+
message += `\n## Task File\n${taskPath}\n`;
|
|
1316
|
+
if (projectPath) {
|
|
1317
|
+
message += `\n---\nWhen done, report back using: bash config/skills/agent/core/report-status/execute.sh '{"sessionName":"${target}","status":"done","summary":"<brief summary>","projectPath":"${projectPath}"}'`;
|
|
1318
|
+
}
|
|
1319
|
+
// Deliver to target agent
|
|
1320
|
+
const deliverResult = await client.post(`/terminal/${target}/deliver`, {
|
|
1321
|
+
message,
|
|
1322
|
+
waitForReady: true,
|
|
1323
|
+
waitTimeout: 15000,
|
|
1324
|
+
}).catch(async () => {
|
|
1325
|
+
// Retry with force
|
|
1326
|
+
return client.post(`/terminal/${target}/deliver`, { message, force: true });
|
|
1327
|
+
});
|
|
1328
|
+
// Record handoff via task management
|
|
1329
|
+
const handoffRecord = await client.post('/task-management/handoff', {
|
|
1330
|
+
from: sessionName,
|
|
1331
|
+
to: target,
|
|
1332
|
+
taskPath: taskPath || '',
|
|
1333
|
+
reason: handoffReason,
|
|
1334
|
+
progress: progress || '',
|
|
1335
|
+
projectPath: projectPath || '',
|
|
1336
|
+
}).catch(() => ({ success: false, error: 'handoff tracking not available' }));
|
|
1337
|
+
return {
|
|
1338
|
+
success: deliverResult?.success ?? false,
|
|
1339
|
+
handoff: {
|
|
1340
|
+
from: sessionName,
|
|
1341
|
+
to: target,
|
|
1342
|
+
reason: handoffReason,
|
|
1343
|
+
timestamp: new Date().toISOString(),
|
|
1344
|
+
},
|
|
1345
|
+
delivery: deliverResult?.success ? 'delivered' : (deliverResult?.error || 'failed'),
|
|
1346
|
+
tracking: handoffRecord?.success ? 'tracked' : 'not tracked',
|
|
742
1347
|
};
|
|
743
1348
|
},
|
|
744
1349
|
},
|
|
@@ -752,6 +1357,15 @@ export function createTools(client, sessionName, projectPath, callbacks) {
|
|
|
752
1357
|
execute: wrapWithAudit(name, tool.execute, callbacks),
|
|
753
1358
|
};
|
|
754
1359
|
}
|
|
1360
|
+
// Merge MCP-sourced tools with audit wrapping
|
|
1361
|
+
if (mcpTools) {
|
|
1362
|
+
for (const [name, tool] of Object.entries(mcpTools)) {
|
|
1363
|
+
tools[name] = {
|
|
1364
|
+
...tool,
|
|
1365
|
+
execute: wrapWithAudit(name, tool.execute, callbacks),
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
755
1369
|
return tools;
|
|
756
1370
|
}
|
|
757
1371
|
/**
|
|
@@ -782,11 +1396,12 @@ export function getToolNames() {
|
|
|
782
1396
|
return [
|
|
783
1397
|
'delegate_task', 'send_message', 'get_agent_status', 'get_team_status',
|
|
784
1398
|
'get_agent_logs', 'reply_slack', 'schedule_check', 'cancel_schedule',
|
|
785
|
-
'
|
|
786
|
-
'remember', 'heartbeat', 'get_tasks', 'complete_task',
|
|
787
|
-
'handle_agent_failure', 'edit_file', 'read_file', 'write_file',
|
|
1399
|
+
'get_scheduled_checks', 'start_agent', 'stop_agent', 'subscribe_event',
|
|
1400
|
+
'recall_memory', 'remember', 'heartbeat', 'get_tasks', 'complete_task',
|
|
1401
|
+
'broadcast', 'handle_agent_failure', 'edit_file', 'read_file', 'write_file',
|
|
788
1402
|
'register_self', 'get_project_overview', 'report_status',
|
|
789
1403
|
'compact_memory', 'get_audit_log',
|
|
1404
|
+
'git_status', 'git_diff', 'git_commit',
|
|
790
1405
|
];
|
|
791
1406
|
}
|
|
792
1407
|
//# sourceMappingURL=tool-registry.js.map
|