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.
Files changed (665) hide show
  1. package/config/constants.ts +18 -3
  2. package/config/hooks/install-hooks.sh +88 -0
  3. package/config/hooks/pre-commit +104 -0
  4. package/config/orchestrator_tasks/prompts/orchestrator-prompt.md +17 -24
  5. package/config/roles/auditor/role.json +13 -0
  6. package/config/roles/orchestrator/prompt.md +25 -0
  7. package/config/roles/product-manager/prompt.md +18 -1
  8. package/config/roles/researcher/prompt.md +110 -0
  9. package/config/roles/team-leader/prompt.md +31 -8
  10. package/config/roles/team-leader/tl-addon.md +40 -9
  11. package/config/roles/ux-designer/prompt.md +111 -0
  12. package/config/skills/_common/lib.sh +33 -0
  13. package/config/skills/agent/browse-stealth/{instructions.md → SKILL.md} +40 -0
  14. package/config/skills/agent/chrome-attach/SKILL.md +84 -0
  15. package/config/skills/agent/chrome-attach/execute.sh +279 -0
  16. package/config/skills/agent/competitor-content-tracker/{instructions.md → SKILL.md} +34 -0
  17. package/config/skills/agent/computer-use/{instructions.md → SKILL.md} +43 -0
  18. package/config/skills/agent/content-calendar/{instructions.md → SKILL.md} +32 -0
  19. package/config/skills/agent/content-repurposer/{instructions.md → SKILL.md} +38 -0
  20. package/config/skills/agent/content-writer/{instructions.md → SKILL.md} +38 -0
  21. package/config/skills/agent/core/accept-task/{instructions.md → SKILL.md} +37 -0
  22. package/config/skills/agent/core/block-task/{instructions.md → SKILL.md} +37 -0
  23. package/config/skills/agent/core/check-quality-gates/{instructions.md → SKILL.md} +40 -0
  24. package/config/skills/agent/core/complete-task/{instructions.md → SKILL.md} +37 -0
  25. package/config/skills/agent/core/complete-task/execute.sh +15 -0
  26. package/config/skills/agent/core/generate-pdf/{instructions.md → SKILL.md} +42 -0
  27. package/config/skills/agent/core/get-my-context/{instructions.md → SKILL.md} +38 -0
  28. package/config/skills/agent/core/get-sops/{instructions.md → SKILL.md} +38 -0
  29. package/config/skills/agent/core/get-team-norms/execute.sh +106 -0
  30. package/config/skills/agent/core/get-team-status/SKILL.md +55 -0
  31. package/config/skills/agent/core/handoff-task/execute.sh +150 -0
  32. package/config/skills/agent/core/heartbeat/{instructions.md → SKILL.md} +27 -0
  33. package/config/skills/agent/core/marketplace-search/{instructions.md → SKILL.md} +41 -0
  34. package/config/skills/agent/core/query-knowledge/{instructions.md → SKILL.md} +40 -0
  35. package/config/skills/agent/core/read-task/SKILL.md +56 -0
  36. package/config/skills/agent/core/recall/{instructions.md → SKILL.md} +38 -0
  37. package/config/skills/agent/core/record-learning/{instructions.md → SKILL.md} +38 -0
  38. package/config/skills/agent/core/register-self/SKILL.md +54 -0
  39. package/config/skills/agent/core/remember/{instructions.md → SKILL.md} +37 -0
  40. package/config/skills/agent/core/remember/execute.sh +6 -0
  41. package/config/skills/agent/core/reply-chat/{instructions.md → SKILL.md} +37 -0
  42. package/config/skills/agent/core/report-progress/{instructions.md → SKILL.md} +38 -0
  43. package/config/skills/agent/core/report-status/{instructions.md → SKILL.md} +39 -0
  44. package/config/skills/agent/core/send-chat-response/{instructions.md → SKILL.md} +37 -0
  45. package/config/skills/agent/core/send-message/SKILL.md +58 -0
  46. package/config/skills/agent/core/update-team-norm/execute.sh +115 -0
  47. package/config/skills/agent/desktop-app-control/{instructions.md → SKILL.md} +42 -0
  48. package/config/skills/agent/trend-monitor/{instructions.md → SKILL.md} +34 -0
  49. package/config/skills/agent/vnc-browser/{instructions.md → SKILL.md} +38 -0
  50. package/config/skills/auditor/score-task/SKILL.md +28 -0
  51. package/config/skills/auditor/score-task/execute.sh +21 -0
  52. package/config/skills/examples/enterprise-skill-example.json +22 -0
  53. package/config/skills/examples/premium-skill-example.json +22 -0
  54. package/config/skills/orchestrator/assign-task/SKILL.md +41 -0
  55. package/config/skills/orchestrator/assign-team-to-project/{instructions.md → SKILL.md} +25 -0
  56. package/config/skills/orchestrator/broadcast/{instructions.md → SKILL.md} +24 -0
  57. package/config/skills/orchestrator/broadcast-to-org/{instructions.md → SKILL.md} +25 -0
  58. package/config/skills/orchestrator/cancel-all-schedules/{instructions.md → SKILL.md} +5 -0
  59. package/config/skills/orchestrator/cancel-schedule/SKILL.md +43 -0
  60. package/config/skills/orchestrator/complete-task/SKILL.md +41 -0
  61. package/config/skills/orchestrator/create-project/{instructions.md → SKILL.md} +24 -0
  62. package/config/skills/orchestrator/create-team/{instructions.md → SKILL.md} +24 -0
  63. package/config/skills/orchestrator/delegate-task/{instructions.md → SKILL.md} +27 -0
  64. package/config/skills/orchestrator/delegate-task/execute.sh +31 -2
  65. package/config/skills/orchestrator/get-agent-logs/{instructions.md → SKILL.md} +25 -0
  66. package/config/skills/orchestrator/get-agent-status/{instructions.md → SKILL.md} +24 -0
  67. package/config/skills/orchestrator/get-project-overview/SKILL.md +41 -0
  68. package/config/skills/orchestrator/get-tasks/SKILL.md +41 -0
  69. package/config/skills/orchestrator/get-team-status/SKILL.md +43 -0
  70. package/config/skills/orchestrator/handle-agent-failure/{instructions.md → SKILL.md} +27 -0
  71. package/config/skills/orchestrator/heartbeat/{instructions.md → SKILL.md} +24 -0
  72. package/config/skills/orchestrator/list-schedules/{instructions.md → SKILL.md} +5 -0
  73. package/config/skills/orchestrator/list-subscriptions/SKILL.md +41 -0
  74. package/config/skills/orchestrator/query-knowledge/{instructions.md → SKILL.md} +28 -0
  75. package/config/skills/orchestrator/read-session-logs/{instructions.md → SKILL.md} +26 -0
  76. package/config/skills/orchestrator/read-system-logs/{instructions.md → SKILL.md} +25 -0
  77. package/config/skills/orchestrator/recall/{instructions.md → SKILL.md} +24 -0
  78. package/config/skills/orchestrator/record-failure/{instructions.md → SKILL.md} +27 -0
  79. package/config/skills/orchestrator/record-learning/{instructions.md → SKILL.md} +24 -0
  80. package/config/skills/orchestrator/record-success/{instructions.md → SKILL.md} +26 -0
  81. package/config/skills/orchestrator/register-self/{instructions.md → SKILL.md} +24 -0
  82. package/config/skills/orchestrator/remember/{instructions.md → SKILL.md} +24 -0
  83. package/config/skills/orchestrator/reply-chat/{instructions.md → SKILL.md} +25 -0
  84. package/config/skills/orchestrator/reply-chat/execute.sh +0 -13
  85. package/config/skills/orchestrator/reply-gchat/{instructions.md → SKILL.md} +25 -0
  86. package/config/skills/orchestrator/reply-gchat/execute.sh +0 -18
  87. package/config/skills/orchestrator/reply-slack/{instructions.md → SKILL.md} +24 -0
  88. package/config/skills/orchestrator/reply-slack/execute.sh +18 -31
  89. package/config/skills/orchestrator/report-bug/{instructions.md → SKILL.md} +26 -0
  90. package/config/skills/orchestrator/restart-crewly/{instructions.md → SKILL.md} +26 -0
  91. package/config/skills/orchestrator/resume-session/{instructions.md → SKILL.md} +24 -0
  92. package/config/skills/orchestrator/schedule-check/{instructions.md → SKILL.md} +24 -0
  93. package/config/skills/orchestrator/send-key/{instructions.md → SKILL.md} +26 -0
  94. package/config/skills/orchestrator/send-message/{instructions.md → SKILL.md} +24 -0
  95. package/config/skills/orchestrator/send-pdf-to-slack/{instructions.md → SKILL.md} +27 -0
  96. package/config/skills/orchestrator/set-goal/{instructions.md → SKILL.md} +26 -0
  97. package/config/skills/orchestrator/start-agent/{instructions.md → SKILL.md} +24 -0
  98. package/config/skills/orchestrator/start-team/{instructions.md → SKILL.md} +24 -0
  99. package/config/skills/orchestrator/stop-agent/{instructions.md → SKILL.md} +24 -0
  100. package/config/skills/orchestrator/stop-team/SKILL.md +43 -0
  101. package/config/skills/orchestrator/subscribe-event/{instructions.md → SKILL.md} +24 -0
  102. package/config/skills/orchestrator/terminate-agent/{instructions.md → SKILL.md} +24 -0
  103. package/config/skills/orchestrator/unsubscribe-event/SKILL.md +42 -0
  104. package/config/skills/orchestrator/update-focus/{instructions.md → SKILL.md} +26 -0
  105. package/config/skills/orchestrator/update-team/{instructions.md → SKILL.md} +24 -0
  106. package/config/skills/team-leader/aggregate-results/{instructions.md → SKILL.md} +26 -0
  107. package/config/skills/team-leader/decompose-goal/{instructions.md → SKILL.md} +26 -0
  108. package/config/skills/team-leader/delegate-task/{instructions.md → SKILL.md} +26 -0
  109. package/config/skills/team-leader/delegate-task/execute.sh +14 -6
  110. package/config/skills/team-leader/delegate-task/execute.test.sh +401 -0
  111. package/config/skills/team-leader/handle-failure/{instructions.md → SKILL.md} +27 -0
  112. package/config/skills/team-leader/schedule-check/{instructions.md → SKILL.md} +26 -0
  113. package/config/skills/team-leader/start-agent/{instructions.md → SKILL.md} +26 -0
  114. package/config/skills/team-leader/stop-agent/{instructions.md → SKILL.md} +26 -0
  115. package/config/skills/team-leader/verify-output/{instructions.md → SKILL.md} +27 -0
  116. package/config/templates/agent-agents-md.md +35 -0
  117. package/config/templates/agent-gemini-md.md +35 -0
  118. package/config/templates/code-review-team/team-config.json +7 -0
  119. package/config/templates/content-generation-team/norms/brand-guidelines.md +64 -0
  120. package/config/templates/content-generation-team/norms/content-review.md +66 -0
  121. package/config/templates/content-generation-team/norms/publish-checklist.md +58 -0
  122. package/config/templates/content-generation-team/team-config.json +8 -0
  123. package/config/templates/dev-fullstack/norms/code-commit-sop.md +40 -0
  124. package/config/templates/dev-fullstack/norms/quality-gates.md +35 -0
  125. package/config/templates/dev-fullstack/template.json +17 -1
  126. package/config/templates/education-smb/template.json +10 -1
  127. package/config/templates/insurance-smb/template.json +10 -1
  128. package/config/templates/research-analysis/norms/research-methodology.md +36 -0
  129. package/config/templates/research-analysis/norms/source-citation.md +33 -0
  130. package/config/templates/research-analysis/template.json +17 -1
  131. package/config/templates/security-audit-team.json +67 -0
  132. package/config/templates/social-media-ops/norms/engagement-rules.md +35 -0
  133. package/config/templates/social-media-ops/norms/posting-schedule.md +43 -0
  134. package/config/templates/social-media-ops/template.json +17 -1
  135. package/config/templates/video-production/template.json +10 -1
  136. package/dist/backend/backend/src/constants.d.ts +80 -11
  137. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  138. package/dist/backend/backend/src/constants.js +85 -11
  139. package/dist/backend/backend/src/constants.js.map +1 -1
  140. package/dist/backend/backend/src/controllers/approvals/approvals.controller.d.ts +99 -0
  141. package/dist/backend/backend/src/controllers/approvals/approvals.controller.d.ts.map +1 -0
  142. package/dist/backend/backend/src/controllers/approvals/approvals.controller.js +183 -0
  143. package/dist/backend/backend/src/controllers/approvals/approvals.controller.js.map +1 -0
  144. package/dist/backend/backend/src/controllers/approvals/approvals.routes.d.ts +15 -0
  145. package/dist/backend/backend/src/controllers/approvals/approvals.routes.d.ts.map +1 -0
  146. package/dist/backend/backend/src/controllers/approvals/approvals.routes.js +27 -0
  147. package/dist/backend/backend/src/controllers/approvals/approvals.routes.js.map +1 -0
  148. package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts +70 -0
  149. package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts.map +1 -0
  150. package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.js +368 -0
  151. package/dist/backend/backend/src/controllers/cloud/cloud-google-auth.controller.js.map +1 -0
  152. package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts +24 -0
  153. package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
  154. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +195 -3
  155. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
  156. package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts +9 -4
  157. package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
  158. package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +19 -5
  159. package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
  160. package/dist/backend/backend/src/controllers/cloud/index.d.ts +1 -0
  161. package/dist/backend/backend/src/controllers/cloud/index.d.ts.map +1 -1
  162. package/dist/backend/backend/src/controllers/cloud/index.js +1 -0
  163. package/dist/backend/backend/src/controllers/cloud/index.js.map +1 -1
  164. package/dist/backend/backend/src/controllers/index.d.ts.map +1 -1
  165. package/dist/backend/backend/src/controllers/index.js +2 -0
  166. package/dist/backend/backend/src/controllers/index.js.map +1 -1
  167. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js +1 -1
  168. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js.map +1 -1
  169. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.d.ts +3 -3
  170. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js +9 -9
  171. package/dist/backend/backend/src/controllers/marketplace/template-marketplace.routes.js.map +1 -1
  172. package/dist/backend/backend/src/controllers/memory/memory.controller.js +6 -6
  173. package/dist/backend/backend/src/controllers/memory/memory.controller.js.map +1 -1
  174. package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts +0 -7
  175. package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
  176. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +2 -135
  177. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
  178. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +14 -0
  179. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  180. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +96 -1
  181. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  182. package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts.map +1 -1
  183. package/dist/backend/backend/src/controllers/oauth/oauth.routes.js +8 -1
  184. package/dist/backend/backend/src/controllers/oauth/oauth.routes.js.map +1 -1
  185. package/dist/backend/backend/src/controllers/payment/payment.controller.js +2 -2
  186. package/dist/backend/backend/src/controllers/payment/payment.controller.js.map +1 -1
  187. package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts +3 -3
  188. package/dist/backend/backend/src/controllers/payment/payment.routes.d.ts.map +1 -1
  189. package/dist/backend/backend/src/controllers/payment/payment.routes.js +4 -14
  190. package/dist/backend/backend/src/controllers/payment/payment.routes.js.map +1 -1
  191. package/dist/backend/backend/src/controllers/payment/payment.types.d.ts +15 -94
  192. package/dist/backend/backend/src/controllers/payment/payment.types.d.ts.map +1 -1
  193. package/dist/backend/backend/src/controllers/payment/payment.types.js +11 -35
  194. package/dist/backend/backend/src/controllers/payment/payment.types.js.map +1 -1
  195. package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.d.ts +49 -0
  196. package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.d.ts.map +1 -0
  197. package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.js +138 -0
  198. package/dist/backend/backend/src/controllers/pr-review/pr-review.controller.js.map +1 -0
  199. package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.d.ts +20 -0
  200. package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.d.ts.map +1 -0
  201. package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.js +30 -0
  202. package/dist/backend/backend/src/controllers/pr-review/pr-review.routes.js.map +1 -0
  203. package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.d.ts +12 -0
  204. package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.d.ts.map +1 -1
  205. package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.js +107 -0
  206. package/dist/backend/backend/src/controllers/quality-gate/quality-gate.controller.js.map +1 -1
  207. package/dist/backend/backend/src/controllers/request-types.d.ts +20 -1
  208. package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
  209. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  210. package/dist/backend/backend/src/controllers/slack/slack.controller.js +11 -5
  211. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  212. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +46 -0
  213. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
  214. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +598 -326
  215. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
  216. package/dist/backend/backend/src/controllers/team/team.controller.d.ts +12 -0
  217. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  218. package/dist/backend/backend/src/controllers/team/team.controller.js +105 -36
  219. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  220. package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
  221. package/dist/backend/backend/src/controllers/team/team.routes.js +2 -1
  222. package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
  223. package/dist/backend/backend/src/controllers/template/template.controller.d.ts +11 -0
  224. package/dist/backend/backend/src/controllers/template/template.controller.d.ts.map +1 -1
  225. package/dist/backend/backend/src/controllers/template/template.controller.js +59 -0
  226. package/dist/backend/backend/src/controllers/template/template.controller.js.map +1 -1
  227. package/dist/backend/backend/src/controllers/template/template.routes.d.ts.map +1 -1
  228. package/dist/backend/backend/src/controllers/template/template.routes.js +2 -1
  229. package/dist/backend/backend/src/controllers/template/template.routes.js.map +1 -1
  230. package/dist/backend/backend/src/controllers/workspace/workspace.controller.d.ts +39 -0
  231. package/dist/backend/backend/src/controllers/workspace/workspace.controller.d.ts.map +1 -0
  232. package/dist/backend/backend/src/controllers/workspace/workspace.controller.js +120 -0
  233. package/dist/backend/backend/src/controllers/workspace/workspace.controller.js.map +1 -0
  234. package/dist/backend/backend/src/controllers/workspace/workspace.routes.d.ts +18 -0
  235. package/dist/backend/backend/src/controllers/workspace/workspace.routes.d.ts.map +1 -0
  236. package/dist/backend/backend/src/controllers/workspace/workspace.routes.js +27 -0
  237. package/dist/backend/backend/src/controllers/workspace/workspace.routes.js.map +1 -0
  238. package/dist/backend/backend/src/index.d.ts.map +1 -1
  239. package/dist/backend/backend/src/index.js +108 -15
  240. package/dist/backend/backend/src/index.js.map +1 -1
  241. package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts +20 -0
  242. package/dist/backend/backend/src/middleware/require-auth.middleware.d.ts.map +1 -0
  243. package/dist/backend/backend/src/middleware/require-auth.middleware.js +21 -0
  244. package/dist/backend/backend/src/middleware/require-auth.middleware.js.map +1 -0
  245. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  246. package/dist/backend/backend/src/routes/api.routes.js +18 -5
  247. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  248. package/dist/backend/backend/src/routes/modules/quality-gate.routes.d.ts +2 -1
  249. package/dist/backend/backend/src/routes/modules/quality-gate.routes.d.ts.map +1 -1
  250. package/dist/backend/backend/src/routes/modules/quality-gate.routes.js +4 -2
  251. package/dist/backend/backend/src/routes/modules/quality-gate.routes.js.map +1 -1
  252. package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
  253. package/dist/backend/backend/src/routes/modules/task-management.routes.js +8 -0
  254. package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
  255. package/dist/backend/backend/src/routes/modules/terminal.routes.d.ts.map +1 -1
  256. package/dist/backend/backend/src/routes/modules/terminal.routes.js +4 -0
  257. package/dist/backend/backend/src/routes/modules/terminal.routes.js.map +1 -1
  258. package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.d.ts +149 -0
  259. package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.d.ts.map +1 -0
  260. package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.js +200 -0
  261. package/dist/backend/backend/src/services/agent/adaptive-heartbeat.service.js.map +1 -0
  262. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts +13 -0
  263. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts.map +1 -1
  264. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js +65 -6
  265. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js.map +1 -1
  266. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +36 -0
  267. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  268. package/dist/backend/backend/src/services/agent/agent-registration.service.js +174 -52
  269. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  270. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts +66 -20
  271. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -1
  272. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js +261 -60
  273. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js.map +1 -1
  274. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +19 -0
  275. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
  276. package/dist/backend/backend/src/services/agent/claude-runtime.service.js +80 -0
  277. package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
  278. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts +11 -0
  279. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -1
  280. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +49 -1
  281. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -1
  282. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +74 -3
  283. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -1
  284. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +248 -18
  285. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -1
  286. package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.d.ts +161 -0
  287. package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.d.ts.map +1 -0
  288. package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.js +237 -0
  289. package/dist/backend/backend/src/services/agent/crewly-agent/approval-queue.service.js.map +1 -0
  290. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts +74 -0
  291. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts.map +1 -0
  292. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js +140 -0
  293. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js.map +1 -0
  294. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -1
  295. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +50 -2
  296. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -1
  297. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +16 -1
  298. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -1
  299. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +45 -5
  300. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -1
  301. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +3 -1
  302. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +1 -1
  303. package/dist/backend/backend/src/services/agent/crewly-agent/index.js +3 -1
  304. package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +1 -1
  305. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts +135 -0
  306. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts.map +1 -0
  307. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js +185 -0
  308. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js.map +1 -0
  309. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +10 -2
  310. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  311. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +22 -2
  312. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  313. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts +143 -0
  314. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts.map +1 -0
  315. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js +264 -0
  316. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js.map +1 -0
  317. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +2 -2
  318. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +55 -1
  319. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -1
  320. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +660 -45
  321. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -1
  322. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +75 -3
  323. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  324. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +49 -2
  325. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  326. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  327. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +17 -2
  328. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  329. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +37 -0
  330. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  331. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +170 -3
  332. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  333. package/dist/backend/backend/src/services/browser/chrome-discovery.service.d.ts +108 -0
  334. package/dist/backend/backend/src/services/browser/chrome-discovery.service.d.ts.map +1 -0
  335. package/dist/backend/backend/src/services/browser/chrome-discovery.service.js +251 -0
  336. package/dist/backend/backend/src/services/browser/chrome-discovery.service.js.map +1 -0
  337. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +12 -0
  338. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  339. package/dist/backend/backend/src/services/cloud/cloud-client.service.js +19 -0
  340. package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  341. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.d.ts +191 -0
  342. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.d.ts.map +1 -0
  343. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.js +415 -0
  344. package/dist/backend/backend/src/services/cloud/device-auto-discovery.service.js.map +1 -0
  345. package/dist/backend/backend/src/services/cloud/device-identity.service.d.ts +89 -0
  346. package/dist/backend/backend/src/services/cloud/device-identity.service.d.ts.map +1 -0
  347. package/dist/backend/backend/src/services/cloud/device-identity.service.js +148 -0
  348. package/dist/backend/backend/src/services/cloud/device-identity.service.js.map +1 -0
  349. package/dist/backend/backend/src/services/core/tracing.service.d.ts +127 -0
  350. package/dist/backend/backend/src/services/core/tracing.service.d.ts.map +1 -0
  351. package/dist/backend/backend/src/services/core/tracing.service.js +238 -0
  352. package/dist/backend/backend/src/services/core/tracing.service.js.map +1 -0
  353. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  354. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +11 -3
  355. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  356. package/dist/backend/backend/src/services/index.d.ts +1 -0
  357. package/dist/backend/backend/src/services/index.d.ts.map +1 -1
  358. package/dist/backend/backend/src/services/index.js +1 -0
  359. package/dist/backend/backend/src/services/index.js.map +1 -1
  360. package/dist/backend/backend/src/services/knowledge/embedding-provider.d.ts +78 -0
  361. package/dist/backend/backend/src/services/knowledge/embedding-provider.d.ts.map +1 -0
  362. package/dist/backend/backend/src/services/knowledge/embedding-provider.js +164 -0
  363. package/dist/backend/backend/src/services/knowledge/embedding-provider.js.map +1 -0
  364. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +39 -13
  365. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  366. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +114 -17
  367. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  368. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts +170 -23
  369. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  370. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +565 -73
  371. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  372. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
  373. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +8 -11
  374. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
  375. package/dist/backend/backend/src/services/marketplace/marketplace.service.d.ts.map +1 -1
  376. package/dist/backend/backend/src/services/marketplace/marketplace.service.js +1 -0
  377. package/dist/backend/backend/src/services/marketplace/marketplace.service.js.map +1 -1
  378. package/dist/backend/backend/src/services/memory/context-flush.service.d.ts +73 -0
  379. package/dist/backend/backend/src/services/memory/context-flush.service.d.ts.map +1 -0
  380. package/dist/backend/backend/src/services/memory/context-flush.service.js +131 -0
  381. package/dist/backend/backend/src/services/memory/context-flush.service.js.map +1 -0
  382. package/dist/backend/backend/src/services/memory/learning-accumulation.service.d.ts +23 -2
  383. package/dist/backend/backend/src/services/memory/learning-accumulation.service.d.ts.map +1 -1
  384. package/dist/backend/backend/src/services/memory/learning-accumulation.service.js +78 -16
  385. package/dist/backend/backend/src/services/memory/learning-accumulation.service.js.map +1 -1
  386. package/dist/backend/backend/src/services/memory/memory.service.d.ts +38 -0
  387. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  388. package/dist/backend/backend/src/services/memory/memory.service.js +121 -2
  389. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  390. package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.d.ts +29 -207
  391. package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.d.ts.map +1 -1
  392. package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.js +97 -683
  393. package/dist/backend/backend/src/services/messaging/adapters/google-chat-messenger.adapter.js.map +1 -1
  394. package/dist/backend/backend/src/services/messaging/google-chat-initializer.d.ts.map +1 -1
  395. package/dist/backend/backend/src/services/messaging/google-chat-initializer.js +13 -12
  396. package/dist/backend/backend/src/services/messaging/google-chat-initializer.js.map +1 -1
  397. package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +2 -0
  398. package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts.map +1 -1
  399. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +6 -23
  400. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  401. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +48 -184
  402. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  403. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  404. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +51 -5
  405. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  406. package/dist/backend/backend/src/services/orchestrator/index.d.ts +1 -1
  407. package/dist/backend/backend/src/services/orchestrator/index.d.ts.map +1 -1
  408. package/dist/backend/backend/src/services/orchestrator/index.js +1 -1
  409. package/dist/backend/backend/src/services/orchestrator/index.js.map +1 -1
  410. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts +65 -0
  411. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
  412. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +165 -2
  413. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
  414. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +8 -0
  415. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  416. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +23 -0
  417. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  418. package/dist/backend/backend/src/services/payment/stripe.service.d.ts +95 -43
  419. package/dist/backend/backend/src/services/payment/stripe.service.d.ts.map +1 -1
  420. package/dist/backend/backend/src/services/payment/stripe.service.js +229 -190
  421. package/dist/backend/backend/src/services/payment/stripe.service.js.map +1 -1
  422. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts +181 -0
  423. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -0
  424. package/dist/backend/backend/src/services/pr-review/pr-review.service.js +336 -0
  425. package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -0
  426. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +23 -0
  427. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
  428. package/dist/backend/backend/src/services/project/task-tracking.service.js +88 -0
  429. package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
  430. package/dist/backend/backend/src/services/session/index.d.ts +2 -0
  431. package/dist/backend/backend/src/services/session/index.d.ts.map +1 -1
  432. package/dist/backend/backend/src/services/session/index.js +2 -0
  433. package/dist/backend/backend/src/services/session/index.js.map +1 -1
  434. package/dist/backend/backend/src/services/session/session-handoff.service.d.ts +260 -0
  435. package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -0
  436. package/dist/backend/backend/src/services/session/session-handoff.service.js +565 -0
  437. package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -0
  438. package/dist/backend/backend/src/services/skill/index.d.ts +1 -0
  439. package/dist/backend/backend/src/services/skill/index.d.ts.map +1 -1
  440. package/dist/backend/backend/src/services/skill/index.js +1 -0
  441. package/dist/backend/backend/src/services/skill/index.js.map +1 -1
  442. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts +25 -6
  443. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -1
  444. package/dist/backend/backend/src/services/skill/skill-catalog.service.js +78 -20
  445. package/dist/backend/backend/src/services/skill/skill-catalog.service.js.map +1 -1
  446. package/dist/backend/backend/src/services/skill/skill-tier.service.d.ts +116 -0
  447. package/dist/backend/backend/src/services/skill/skill-tier.service.d.ts.map +1 -0
  448. package/dist/backend/backend/src/services/skill/skill-tier.service.js +155 -0
  449. package/dist/backend/backend/src/services/skill/skill-tier.service.js.map +1 -0
  450. package/dist/backend/backend/src/services/skill/skill.service.d.ts +35 -7
  451. package/dist/backend/backend/src/services/skill/skill.service.d.ts.map +1 -1
  452. package/dist/backend/backend/src/services/skill/skill.service.js +128 -35
  453. package/dist/backend/backend/src/services/skill/skill.service.js.map +1 -1
  454. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +50 -47
  455. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  456. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +267 -202
  457. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  458. package/dist/backend/backend/src/services/slack/slack.service.d.ts +28 -2
  459. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  460. package/dist/backend/backend/src/services/slack/slack.service.js +69 -3
  461. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  462. package/dist/backend/backend/src/services/template/template.service.d.ts +19 -1
  463. package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -1
  464. package/dist/backend/backend/src/services/template/template.service.js +110 -3
  465. package/dist/backend/backend/src/services/template/template.service.js.map +1 -1
  466. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts +11 -0
  467. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -1
  468. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +57 -3
  469. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -1
  470. package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
  471. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +6 -0
  472. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
  473. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +52 -0
  474. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  475. package/dist/backend/backend/src/services/workflow/scheduler.service.js +319 -6
  476. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  477. package/dist/backend/backend/src/types/chat.types.d.ts +2 -2
  478. package/dist/backend/backend/src/types/chat.types.d.ts.map +1 -1
  479. package/dist/backend/backend/src/types/chat.types.js +18 -22
  480. package/dist/backend/backend/src/types/chat.types.js.map +1 -1
  481. package/dist/backend/backend/src/types/index.d.ts +37 -0
  482. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  483. package/dist/backend/backend/src/types/index.js.map +1 -1
  484. package/dist/backend/backend/src/types/marketplace.types.d.ts +1 -1
  485. package/dist/backend/backend/src/types/marketplace.types.d.ts.map +1 -1
  486. package/dist/backend/backend/src/types/scheduler.types.d.ts +4 -0
  487. package/dist/backend/backend/src/types/scheduler.types.d.ts.map +1 -1
  488. package/dist/backend/backend/src/types/scheduler.types.js.map +1 -1
  489. package/dist/backend/backend/src/types/skill.types.d.ts +4 -0
  490. package/dist/backend/backend/src/types/skill.types.d.ts.map +1 -1
  491. package/dist/backend/backend/src/types/skill.types.js.map +1 -1
  492. package/dist/backend/backend/src/types/task-tracking.types.d.ts +6 -0
  493. package/dist/backend/backend/src/types/task-tracking.types.d.ts.map +1 -1
  494. package/dist/backend/backend/src/types/task-tracking.types.js.map +1 -1
  495. package/dist/backend/backend/src/types/team-template.types.d.ts +2 -0
  496. package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
  497. package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
  498. package/dist/backend/backend/src/utils/skill-md-parser.d.ts +38 -0
  499. package/dist/backend/backend/src/utils/skill-md-parser.d.ts.map +1 -0
  500. package/dist/backend/backend/src/utils/skill-md-parser.js +47 -0
  501. package/dist/backend/backend/src/utils/skill-md-parser.js.map +1 -0
  502. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +0 -154
  503. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  504. package/dist/backend/backend/src/websocket/terminal.gateway.js +0 -515
  505. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  506. package/dist/backend/config/constants.d.ts +18 -3
  507. package/dist/backend/config/constants.d.ts.map +1 -1
  508. package/dist/backend/config/constants.js +18 -3
  509. package/dist/backend/config/constants.js.map +1 -1
  510. package/dist/cli/backend/src/constants.d.ts +80 -11
  511. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  512. package/dist/cli/backend/src/constants.js +85 -11
  513. package/dist/cli/backend/src/constants.js.map +1 -1
  514. package/dist/cli/backend/src/services/knowledge/embedding-provider.d.ts +78 -0
  515. package/dist/cli/backend/src/services/knowledge/embedding-provider.d.ts.map +1 -0
  516. package/dist/cli/backend/src/services/knowledge/embedding-provider.js +164 -0
  517. package/dist/cli/backend/src/services/knowledge/embedding-provider.js.map +1 -0
  518. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +39 -13
  519. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  520. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +114 -17
  521. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  522. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts +170 -23
  523. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  524. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +565 -73
  525. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  526. package/dist/cli/backend/src/services/memory/memory.service.d.ts +38 -0
  527. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  528. package/dist/cli/backend/src/services/memory/memory.service.js +121 -2
  529. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  530. package/dist/cli/backend/src/types/chat.types.d.ts +2 -2
  531. package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -1
  532. package/dist/cli/backend/src/types/chat.types.js +18 -22
  533. package/dist/cli/backend/src/types/chat.types.js.map +1 -1
  534. package/dist/cli/backend/src/types/index.d.ts +37 -0
  535. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  536. package/dist/cli/backend/src/types/index.js.map +1 -1
  537. package/dist/cli/backend/src/types/scheduler.types.d.ts +4 -0
  538. package/dist/cli/backend/src/types/scheduler.types.d.ts.map +1 -1
  539. package/dist/cli/backend/src/types/scheduler.types.js.map +1 -1
  540. package/dist/cli/backend/src/types/skill.types.d.ts +4 -0
  541. package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -1
  542. package/dist/cli/backend/src/types/skill.types.js.map +1 -1
  543. package/dist/cli/cli/src/commands/onboard.d.ts +19 -2
  544. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  545. package/dist/cli/cli/src/commands/onboard.js +58 -15
  546. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  547. package/dist/cli/cli/src/commands/pair.d.ts +46 -0
  548. package/dist/cli/cli/src/commands/pair.d.ts.map +1 -0
  549. package/dist/cli/cli/src/commands/pair.js +258 -0
  550. package/dist/cli/cli/src/commands/pair.js.map +1 -0
  551. package/dist/cli/cli/src/commands/service.d.ts +86 -0
  552. package/dist/cli/cli/src/commands/service.d.ts.map +1 -0
  553. package/dist/cli/cli/src/commands/service.js +687 -0
  554. package/dist/cli/cli/src/commands/service.js.map +1 -0
  555. package/dist/cli/cli/src/index.js +17 -0
  556. package/dist/cli/cli/src/index.js.map +1 -1
  557. package/dist/cli/config/constants.d.ts +18 -3
  558. package/dist/cli/config/constants.d.ts.map +1 -1
  559. package/dist/cli/config/constants.js +18 -3
  560. package/dist/cli/config/constants.js.map +1 -1
  561. package/frontend/dist/assets/index-1d23cce8.js +4919 -0
  562. package/frontend/dist/assets/index-60a9e4ea.css +33 -0
  563. package/frontend/dist/index.html +2 -2
  564. package/package.json +22 -10
  565. package/config/skills/agent/browse-stealth/skill.json +0 -20
  566. package/config/skills/agent/competitor-content-tracker/skill.json +0 -22
  567. package/config/skills/agent/computer-use/skill.json +0 -29
  568. package/config/skills/agent/content-calendar/skill.json +0 -22
  569. package/config/skills/agent/content-repurposer/skill.json +0 -22
  570. package/config/skills/agent/content-writer/skill.json +0 -22
  571. package/config/skills/agent/core/accept-task/skill.json +0 -20
  572. package/config/skills/agent/core/block-task/skill.json +0 -20
  573. package/config/skills/agent/core/check-quality-gates/skill.json +0 -20
  574. package/config/skills/agent/core/complete-task/skill.json +0 -20
  575. package/config/skills/agent/core/generate-pdf/skill.json +0 -20
  576. package/config/skills/agent/core/get-my-context/skill.json +0 -20
  577. package/config/skills/agent/core/get-sops/skill.json +0 -20
  578. package/config/skills/agent/core/get-team-status/instructions.md +0 -17
  579. package/config/skills/agent/core/get-team-status/skill.json +0 -20
  580. package/config/skills/agent/core/heartbeat/skill.json +0 -20
  581. package/config/skills/agent/core/marketplace-search/skill.json +0 -20
  582. package/config/skills/agent/core/query-knowledge/skill.json +0 -20
  583. package/config/skills/agent/core/read-task/instructions.md +0 -19
  584. package/config/skills/agent/core/read-task/skill.json +0 -20
  585. package/config/skills/agent/core/recall/skill.json +0 -20
  586. package/config/skills/agent/core/record-learning/skill.json +0 -20
  587. package/config/skills/agent/core/register-self/instructions.md +0 -18
  588. package/config/skills/agent/core/register-self/skill.json +0 -20
  589. package/config/skills/agent/core/remember/skill.json +0 -20
  590. package/config/skills/agent/core/reply-chat/skill.json +0 -20
  591. package/config/skills/agent/core/report-progress/skill.json +0 -20
  592. package/config/skills/agent/core/report-status/skill.json +0 -20
  593. package/config/skills/agent/core/send-chat-response/skill.json +0 -20
  594. package/config/skills/agent/core/send-message/instructions.md +0 -20
  595. package/config/skills/agent/core/send-message/skill.json +0 -20
  596. package/config/skills/agent/desktop-app-control/skill.json +0 -33
  597. package/config/skills/agent/trend-monitor/skill.json +0 -22
  598. package/config/skills/agent/vnc-browser/skill.json +0 -20
  599. package/config/skills/orchestrator/assign-task/instructions.md +0 -17
  600. package/config/skills/orchestrator/assign-task/skill.json +0 -20
  601. package/config/skills/orchestrator/assign-team-to-project/skill.json +0 -20
  602. package/config/skills/orchestrator/broadcast/skill.json +0 -20
  603. package/config/skills/orchestrator/broadcast-to-org/skill.json +0 -20
  604. package/config/skills/orchestrator/cancel-all-schedules/skill.json +0 -17
  605. package/config/skills/orchestrator/cancel-schedule/instructions.md +0 -19
  606. package/config/skills/orchestrator/cancel-schedule/skill.json +0 -20
  607. package/config/skills/orchestrator/complete-task/instructions.md +0 -17
  608. package/config/skills/orchestrator/complete-task/skill.json +0 -20
  609. package/config/skills/orchestrator/create-project/skill.json +0 -20
  610. package/config/skills/orchestrator/create-team/skill.json +0 -20
  611. package/config/skills/orchestrator/delegate-task/skill.json +0 -20
  612. package/config/skills/orchestrator/get-agent-logs/skill.json +0 -20
  613. package/config/skills/orchestrator/get-agent-status/skill.json +0 -20
  614. package/config/skills/orchestrator/get-project-overview/instructions.md +0 -17
  615. package/config/skills/orchestrator/get-project-overview/skill.json +0 -20
  616. package/config/skills/orchestrator/get-tasks/instructions.md +0 -17
  617. package/config/skills/orchestrator/get-tasks/skill.json +0 -20
  618. package/config/skills/orchestrator/get-team-status/instructions.md +0 -17
  619. package/config/skills/orchestrator/get-team-status/skill.json +0 -20
  620. package/config/skills/orchestrator/handle-agent-failure/skill.json +0 -20
  621. package/config/skills/orchestrator/heartbeat/skill.json +0 -20
  622. package/config/skills/orchestrator/list-schedules/skill.json +0 -12
  623. package/config/skills/orchestrator/list-subscriptions/instructions.md +0 -17
  624. package/config/skills/orchestrator/list-subscriptions/skill.json +0 -20
  625. package/config/skills/orchestrator/query-knowledge/skill.json +0 -20
  626. package/config/skills/orchestrator/read-session-logs/skill.json +0 -20
  627. package/config/skills/orchestrator/read-system-logs/skill.json +0 -20
  628. package/config/skills/orchestrator/recall/skill.json +0 -20
  629. package/config/skills/orchestrator/record-failure/skill.json +0 -20
  630. package/config/skills/orchestrator/record-learning/skill.json +0 -20
  631. package/config/skills/orchestrator/record-success/skill.json +0 -20
  632. package/config/skills/orchestrator/register-self/skill.json +0 -20
  633. package/config/skills/orchestrator/remember/skill.json +0 -20
  634. package/config/skills/orchestrator/reply-chat/skill.json +0 -20
  635. package/config/skills/orchestrator/reply-gchat/skill.json +0 -20
  636. package/config/skills/orchestrator/reply-slack/skill.json +0 -20
  637. package/config/skills/orchestrator/report-bug/skill.json +0 -20
  638. package/config/skills/orchestrator/restart-crewly/skill.json +0 -20
  639. package/config/skills/orchestrator/resume-session/skill.json +0 -20
  640. package/config/skills/orchestrator/schedule-check/skill.json +0 -20
  641. package/config/skills/orchestrator/send-key/skill.json +0 -20
  642. package/config/skills/orchestrator/send-message/skill.json +0 -20
  643. package/config/skills/orchestrator/send-pdf-to-slack/skill.json +0 -20
  644. package/config/skills/orchestrator/set-goal/skill.json +0 -20
  645. package/config/skills/orchestrator/start-agent/skill.json +0 -20
  646. package/config/skills/orchestrator/start-team/skill.json +0 -20
  647. package/config/skills/orchestrator/stop-agent/skill.json +0 -20
  648. package/config/skills/orchestrator/stop-team/instructions.md +0 -19
  649. package/config/skills/orchestrator/stop-team/skill.json +0 -20
  650. package/config/skills/orchestrator/subscribe-event/skill.json +0 -20
  651. package/config/skills/orchestrator/terminate-agent/skill.json +0 -20
  652. package/config/skills/orchestrator/unsubscribe-event/instructions.md +0 -19
  653. package/config/skills/orchestrator/unsubscribe-event/skill.json +0 -20
  654. package/config/skills/orchestrator/update-focus/skill.json +0 -20
  655. package/config/skills/orchestrator/update-team/skill.json +0 -20
  656. package/config/skills/team-leader/aggregate-results/skill.json +0 -20
  657. package/config/skills/team-leader/decompose-goal/skill.json +0 -20
  658. package/config/skills/team-leader/delegate-task/skill.json +0 -20
  659. package/config/skills/team-leader/handle-failure/skill.json +0 -20
  660. package/config/skills/team-leader/schedule-check/skill.json +0 -20
  661. package/config/skills/team-leader/start-agent/skill.json +0 -20
  662. package/config/skills/team-leader/stop-agent/skill.json +0 -20
  663. package/config/skills/team-leader/verify-output/skill.json +0 -20
  664. package/frontend/dist/assets/index-0e5673b0.css +0 -33
  665. package/frontend/dist/assets/index-e6d7db4a.js +0 -5213
@@ -6,6 +6,8 @@ import { updateAgentHeartbeat } from '../../services/agent/agent-heartbeat.servi
6
6
  import { CREWLY_CONSTANTS } from '../../constants.js';
7
7
  import { LoggerService } from '../../services/core/logger.service.js';
8
8
  import { TaskOutputValidatorService } from '../../services/quality/task-output-validator.service.js';
9
+ import { TracingService } from '../../services/core/tracing.service.js';
10
+ import { TRACING_CONSTANTS } from '../../constants.js';
9
11
  import { TASK_OUTPUT_CONSTANTS } from '../../types/task-output.types.js';
10
12
  const logger = LoggerService.getInstance().createComponentLogger('TaskManagementController');
11
13
  /** Module-level reference to EventBusService for auto-cleanup on task completion */
@@ -67,85 +69,92 @@ export function getEventBusServiceForTaskCleanup() {
67
69
  * @param res - Response with success status, created task path, and status
68
70
  */
69
71
  export async function createTask(req, res) {
70
- try {
71
- const { projectPath, task, priority = 'medium', sessionName, milestone = 'delegated', outputSchema, } = req.body;
72
- if (!projectPath) {
73
- res.status(400).json({ success: false, error: 'projectPath is required' });
74
- return;
72
+ return TracingService.getInstance().withSpan(TRACING_CONSTANTS.SPANS.TASK_CREATE, {
73
+ attributes: {
74
+ 'task.priority': req.body.priority || 'medium',
75
+ 'task.milestone': req.body.milestone || 'delegated',
75
76
  }
76
- if (!task) {
77
- res.status(400).json({ success: false, error: 'task is required' });
78
- return;
79
- }
80
- // Determine initial status folder based on whether an assignee is provided
81
- const statusFolder = sessionName ? 'in_progress' : 'open';
82
- const tasksDir = join(projectPath, '.crewly', 'tasks', milestone, statusFolder);
83
- // Ensure directory exists
84
- await ensureDirectoryExists(tasksDir);
85
- // Generate sanitized filename from task description
86
- const sanitizedName = task
87
- .toLowerCase()
88
- .replace(/[^a-z0-9]+/g, '_')
89
- .replace(/^_|_$/g, '')
90
- .substring(0, 80);
91
- const timestamp = Date.now();
92
- const fileName = `${sanitizedName}_${timestamp}.md`;
93
- const taskPath = join(tasksDir, fileName);
94
- // Build task markdown content
95
- let taskContent = `# ${task}\n\n## Task Information\n- **Priority**: ${priority}\n- **Milestone**: ${milestone}\n- **Created at**: ${new Date().toISOString()}\n- **Status**: ${statusFolder === 'in_progress' ? 'In Progress' : 'Open'}\n`;
96
- if (sessionName) {
97
- taskContent += `\n## Assignment Information\n- **Assigned to**: ${sessionName}\n- **Assigned at**: ${new Date().toISOString()}\n- **Status**: In Progress\n`;
98
- }
99
- taskContent += `\n## Task Description\n\n${task}\n`;
100
- // Embed output schema if provided
101
- if (outputSchema && typeof outputSchema === 'object') {
102
- const validator = TaskOutputValidatorService.getInstance();
103
- taskContent += validator.generateSchemaMarkdown(outputSchema);
104
- }
105
- await writeFile(taskPath, taskContent, 'utf-8');
106
- // If assigned, track via TaskTrackingService
107
- let trackedTaskId;
108
- if (sessionName) {
109
- try {
110
- const projects = await this.storageService.getProjects();
111
- const project = projects.find(p => projectPath.startsWith(p.path));
112
- if (project) {
113
- const teams = await this.storageService.getTeams();
114
- let teamId = '';
115
- let memberId = '';
116
- for (const team of teams) {
117
- const member = team.members.find(m => m.sessionName === sessionName);
118
- if (member) {
119
- teamId = team.id;
120
- memberId = member.id;
121
- break;
77
+ }, async (span) => {
78
+ try {
79
+ const { projectPath, task, priority = 'medium', sessionName, milestone = 'delegated', outputSchema, } = req.body;
80
+ if (!projectPath) {
81
+ res.status(400).json({ success: false, error: 'projectPath is required' });
82
+ return;
83
+ }
84
+ if (!task) {
85
+ res.status(400).json({ success: false, error: 'task is required' });
86
+ return;
87
+ }
88
+ // Determine initial status folder based on whether an assignee is provided
89
+ const statusFolder = sessionName ? 'in_progress' : 'open';
90
+ const tasksDir = join(projectPath, '.crewly', 'tasks', milestone, statusFolder);
91
+ // Ensure directory exists
92
+ await ensureDirectoryExists(tasksDir);
93
+ // Generate sanitized filename from task description
94
+ const sanitizedName = task
95
+ .toLowerCase()
96
+ .replace(/[^a-z0-9]+/g, '_')
97
+ .replace(/^_|_$/g, '')
98
+ .substring(0, 80);
99
+ const timestamp = Date.now();
100
+ const fileName = `${sanitizedName}_${timestamp}.md`;
101
+ const taskPath = join(tasksDir, fileName);
102
+ // Build task markdown content
103
+ let taskContent = `# ${task}\n\n## Task Information\n- **Priority**: ${priority}\n- **Milestone**: ${milestone}\n- **Created at**: ${new Date().toISOString()}\n- **Status**: ${statusFolder === 'in_progress' ? 'In Progress' : 'Open'}\n`;
104
+ if (sessionName) {
105
+ taskContent += `\n## Assignment Information\n- **Assigned to**: ${sessionName}\n- **Assigned at**: ${new Date().toISOString()}\n- **Status**: In Progress\n`;
106
+ }
107
+ taskContent += `\n## Task Description\n\n${task}\n`;
108
+ // Embed output schema if provided
109
+ if (outputSchema && typeof outputSchema === 'object') {
110
+ const validator = TaskOutputValidatorService.getInstance();
111
+ taskContent += validator.generateSchemaMarkdown(outputSchema);
112
+ }
113
+ await writeFile(taskPath, taskContent, 'utf-8');
114
+ // If assigned, track via TaskTrackingService
115
+ let trackedTaskId;
116
+ if (sessionName) {
117
+ try {
118
+ const projects = await this.storageService.getProjects();
119
+ const project = projects.find(p => projectPath.startsWith(p.path));
120
+ if (project) {
121
+ const teams = await this.storageService.getTeams();
122
+ let teamId = '';
123
+ let memberId = '';
124
+ for (const team of teams) {
125
+ const member = team.members.find(m => m.sessionName === sessionName);
126
+ if (member) {
127
+ teamId = team.id;
128
+ memberId = member.id;
129
+ break;
130
+ }
131
+ }
132
+ if (teamId) {
133
+ const trackedTask = await this.taskTrackingService.assignTask(project.id, teamId, taskPath, task, 'delegated', memberId, sessionName);
134
+ trackedTaskId = trackedTask?.id;
122
135
  }
123
- }
124
- if (teamId) {
125
- const trackedTask = await this.taskTrackingService.assignTask(project.id, teamId, taskPath, task, 'delegated', memberId, sessionName);
126
- trackedTaskId = trackedTask?.id;
127
136
  }
128
137
  }
138
+ catch (trackingError) {
139
+ logger.warn('Failed to track task assignment', { error: trackingError instanceof Error ? trackingError.message : String(trackingError) });
140
+ // Non-fatal - the file was still created
141
+ }
129
142
  }
130
- catch (trackingError) {
131
- logger.warn('Failed to track task assignment', { error: trackingError instanceof Error ? trackingError.message : String(trackingError) });
132
- // Non-fatal - the file was still created
133
- }
143
+ res.json({
144
+ success: true,
145
+ message: `Task file created: ${fileName}`,
146
+ taskPath,
147
+ fileName,
148
+ status: statusFolder,
149
+ milestone,
150
+ taskId: trackedTaskId,
151
+ });
134
152
  }
135
- res.json({
136
- success: true,
137
- message: `Task file created: ${fileName}`,
138
- taskPath,
139
- fileName,
140
- status: statusFolder,
141
- milestone,
142
- taskId: trackedTaskId,
143
- });
144
- }
145
- catch (error) {
146
- logger.error('Error creating task', { error: error instanceof Error ? error.message : String(error) });
147
- res.status(500).json({ success: false, error: 'Failed to create task' });
148
- }
153
+ catch (error) {
154
+ logger.error('Error creating task', { error: error instanceof Error ? error.message : String(error) });
155
+ res.status(500).json({ success: false, error: 'Failed to create task' });
156
+ }
157
+ });
149
158
  }
150
159
  /**
151
160
  * Assigns a task to a team member by moving it from open/ to in_progress/ folder
@@ -154,106 +163,113 @@ export async function createTask(req, res) {
154
163
  * @param res - Response with success status and task information
155
164
  */
156
165
  export async function assignTask(req, res) {
157
- try {
158
- const { taskPath, sessionName } = req.body;
159
- // Update agent heartbeat (proof of life)
160
- try {
161
- await updateAgentHeartbeat(sessionName, undefined, CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE);
162
- }
163
- catch (error) {
164
- logger.warn('Failed to update agent heartbeat', { error: error instanceof Error ? error.message : String(error) });
165
- // Continue execution - heartbeat failures shouldn't break task assignment
166
- }
167
- if (!taskPath) {
168
- res.status(400).json({ success: false, error: 'taskPath is required' });
169
- return;
170
- }
171
- if (!sessionName) {
172
- res.status(400).json({ success: false, error: 'sessionName is required' });
173
- return;
166
+ return TracingService.getInstance().withSpan(TRACING_CONSTANTS.SPANS.TASK_ASSIGN, {
167
+ attributes: {
168
+ 'task.path': req.body.taskPath || 'unknown',
169
+ 'agent.session': req.body.sessionName || 'unknown',
174
170
  }
175
- // Verify source task file exists
176
- if (!existsSync(taskPath)) {
177
- res.status(200).json({
178
- success: false,
179
- error: 'Task file does not exist at the specified path',
180
- details: `No task file found at: ${taskPath}. Make sure the task file exists in the open/ folder.`,
181
- taskPath,
182
- suggestion: 'Verify the task file path is correct and the file exists'
183
- });
184
- return;
185
- }
186
- // Ensure task is in open/ folder
187
- if (!taskPath.includes('/open/')) {
188
- res.status(200).json({
189
- success: false,
190
- error: 'Task is not in the correct folder for assignment',
191
- details: `Task must be in open/ folder to be assigned. Current path: ${taskPath}`,
192
- taskPath,
193
- expectedFolder: 'open',
194
- currentFolder: taskPath.includes('/in_progress/') ? 'in_progress' : taskPath.includes('/done/') ? 'done' : taskPath.includes('/blocked/') ? 'blocked' : 'unknown'
195
- });
196
- return;
197
- }
198
- // Parse task information
199
- const taskContent = await readFile(taskPath, 'utf-8');
200
- const taskInfo = parseTaskInfo(taskContent, basename(taskPath));
201
- // Extract project and team information from task path
202
- const pathMatch = taskPath.match(/\/([^/]+)\/\.crewly/);
203
- if (!pathMatch) {
204
- res.status(400).json({ success: false, error: 'Cannot determine project from task path' });
205
- return;
206
- }
207
- const projectPath = taskPath.substring(0, taskPath.indexOf('.crewly'));
208
- // Find project by path
209
- const projects = await this.storageService.getProjects();
210
- const project = projects.find(p => resolve(p.path) === resolve(projectPath));
211
- if (!project) {
212
- res.status(404).json({ success: false, error: 'Project not found' });
213
- return;
214
- }
215
- // Find team and member by sessionName
216
- const teams = await this.storageService.getTeams();
217
- let teamId = '';
218
- let memberId = '';
219
- for (const team of teams) {
220
- const member = team.members.find(m => m.sessionName === sessionName);
221
- if (member) {
222
- teamId = team.id;
223
- memberId = member.id;
224
- break;
171
+ }, async (span) => {
172
+ try {
173
+ const { taskPath, sessionName } = req.body;
174
+ // Update agent heartbeat (proof of life)
175
+ try {
176
+ await updateAgentHeartbeat(sessionName, undefined, CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE);
225
177
  }
178
+ catch (error) {
179
+ logger.warn('Failed to update agent heartbeat', { error: error instanceof Error ? error.message : String(error) });
180
+ // Continue execution - heartbeat failures shouldn't break task assignment
181
+ }
182
+ if (!taskPath) {
183
+ res.status(400).json({ success: false, error: 'taskPath is required' });
184
+ return;
185
+ }
186
+ if (!sessionName) {
187
+ res.status(400).json({ success: false, error: 'sessionName is required' });
188
+ return;
189
+ }
190
+ // Verify source task file exists
191
+ if (!existsSync(taskPath)) {
192
+ res.status(200).json({
193
+ success: false,
194
+ error: 'Task file does not exist at the specified path',
195
+ details: `No task file found at: ${taskPath}. Make sure the task file exists in the open/ folder.`,
196
+ taskPath,
197
+ suggestion: 'Verify the task file path is correct and the file exists'
198
+ });
199
+ return;
200
+ }
201
+ // Ensure task is in open/ folder
202
+ if (!taskPath.includes('/open/')) {
203
+ res.status(200).json({
204
+ success: false,
205
+ error: 'Task is not in the correct folder for assignment',
206
+ details: `Task must be in open/ folder to be assigned. Current path: ${taskPath}`,
207
+ taskPath,
208
+ expectedFolder: 'open',
209
+ currentFolder: taskPath.includes('/in_progress/') ? 'in_progress' : taskPath.includes('/done/') ? 'done' : taskPath.includes('/blocked/') ? 'blocked' : 'unknown'
210
+ });
211
+ return;
212
+ }
213
+ // Parse task information
214
+ const taskContent = await readFile(taskPath, 'utf-8');
215
+ const taskInfo = parseTaskInfo(taskContent, basename(taskPath));
216
+ // Extract project and team information from task path
217
+ const pathMatch = taskPath.match(/\/([^/]+)\/\.crewly/);
218
+ if (!pathMatch) {
219
+ res.status(400).json({ success: false, error: 'Cannot determine project from task path' });
220
+ return;
221
+ }
222
+ const projectPath = taskPath.substring(0, taskPath.indexOf('.crewly'));
223
+ // Find project by path
224
+ const projects = await this.storageService.getProjects();
225
+ const project = projects.find(p => resolve(p.path) === resolve(projectPath));
226
+ if (!project) {
227
+ res.status(404).json({ success: false, error: 'Project not found' });
228
+ return;
229
+ }
230
+ // Find team and member by sessionName
231
+ const teams = await this.storageService.getTeams();
232
+ let teamId = '';
233
+ let memberId = '';
234
+ for (const team of teams) {
235
+ const member = team.members.find(m => m.sessionName === sessionName);
236
+ if (member) {
237
+ teamId = team.id;
238
+ memberId = member.id;
239
+ break;
240
+ }
241
+ }
242
+ if (!teamId) {
243
+ res.status(404).json({ success: false, error: 'Team member not found for sessionName' });
244
+ return;
245
+ }
246
+ // Create target path in in_progress/ folder
247
+ const fileName = basename(taskPath);
248
+ const targetPath = taskPath.replace('/open/', '/in_progress/');
249
+ const targetDir = dirname(targetPath);
250
+ // Ensure in_progress directory exists
251
+ await ensureDirectoryExists(targetDir);
252
+ // Read, update, and move task file
253
+ const updatedContent = addTaskAssignmentInfo(taskContent, memberId, sessionName);
254
+ await writeFile(targetPath, updatedContent, 'utf-8');
255
+ await unlinkFile(taskPath);
256
+ // Add to task tracking
257
+ await this.taskTrackingService.assignTask(project.id, teamId, targetPath, taskInfo.title || taskInfo.fileName, taskInfo.targetRole || 'unknown', memberId, sessionName);
258
+ res.json({
259
+ success: true,
260
+ message: `Task ${fileName} assigned to member ${sessionName}`,
261
+ originalPath: taskPath,
262
+ newPath: targetPath,
263
+ memberId,
264
+ sessionName,
265
+ status: 'in_progress',
266
+ });
226
267
  }
227
- if (!teamId) {
228
- res.status(404).json({ success: false, error: 'Team member not found for sessionName' });
229
- return;
268
+ catch (error) {
269
+ logger.error('Error assigning task', { error: error instanceof Error ? error.message : String(error) });
270
+ res.status(500).json({ success: false, error: 'Failed to assign task' });
230
271
  }
231
- // Create target path in in_progress/ folder
232
- const fileName = basename(taskPath);
233
- const targetPath = taskPath.replace('/open/', '/in_progress/');
234
- const targetDir = dirname(targetPath);
235
- // Ensure in_progress directory exists
236
- await ensureDirectoryExists(targetDir);
237
- // Read, update, and move task file
238
- const updatedContent = addTaskAssignmentInfo(taskContent, memberId, sessionName);
239
- await writeFile(targetPath, updatedContent, 'utf-8');
240
- await unlinkFile(taskPath);
241
- // Add to task tracking
242
- await this.taskTrackingService.assignTask(project.id, teamId, targetPath, taskInfo.title || taskInfo.fileName, taskInfo.targetRole || 'unknown', memberId, sessionName);
243
- res.json({
244
- success: true,
245
- message: `Task ${fileName} assigned to member ${sessionName}`,
246
- originalPath: taskPath,
247
- newPath: targetPath,
248
- memberId,
249
- sessionName,
250
- status: 'in_progress',
251
- });
252
- }
253
- catch (error) {
254
- logger.error('Error assigning task', { error: error instanceof Error ? error.message : String(error) });
255
- res.status(500).json({ success: false, error: 'Failed to assign task' });
256
- }
272
+ });
257
273
  }
258
274
  /**
259
275
  * Completes a task by moving it from in_progress/ to done/ folder
@@ -262,203 +278,222 @@ export async function assignTask(req, res) {
262
278
  * @param res - Response with success status and completion information
263
279
  */
264
280
  export async function completeTask(req, res) {
265
- try {
266
- const { taskPath, sessionName, output } = req.body;
267
- // Update agent heartbeat (proof of life)
268
- try {
269
- await updateAgentHeartbeat(sessionName, undefined, CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE);
270
- }
271
- catch (error) {
272
- logger.warn('Failed to update agent heartbeat', { error: error instanceof Error ? error.message : String(error) });
273
- // Continue execution - heartbeat failures shouldn't break task completion
281
+ return TracingService.getInstance().withSpan(TRACING_CONSTANTS.SPANS.TASK_COMPLETE, {
282
+ attributes: {
283
+ 'task.path': req.body.taskPath || 'unknown',
284
+ 'agent.session': req.body.sessionName || 'unknown',
274
285
  }
275
- if (!taskPath) {
276
- res.status(400).json({ success: false, error: 'taskPath is required' });
277
- return;
278
- }
279
- // Verify source task file exists
280
- if (!existsSync(taskPath)) {
281
- res.status(200).json({
282
- success: false,
283
- error: 'Task file does not exist at the specified path',
284
- details: `No task file found at: ${taskPath}. Make sure the task has been properly assigned and is in the in_progress folder.`,
285
- taskPath,
286
- suggestion: 'Check if the task file exists and use accept_task first to move it from open/ to in_progress/'
287
- });
288
- return;
289
- }
290
- // Ensure task is in in_progress/ folder
291
- if (!taskPath.includes('/in_progress/')) {
292
- res.status(200).json({
293
- success: false,
294
- error: 'Task is not in the correct folder for completion',
295
- details: `Task must be in in_progress/ folder to be completed. Current path: ${taskPath}. Use accept_task first to move the task from open/ to in_progress/.`,
296
- taskPath,
297
- expectedFolder: 'in_progress',
298
- currentFolder: taskPath.includes('/open/') ? 'open' : taskPath.includes('/done/') ? 'done' : taskPath.includes('/blocked/') ? 'blocked' : 'unknown',
299
- action: 'Use accept_task tool first to assign the task'
300
- });
301
- return;
302
- }
303
- // Read task content to check for output schema
304
- const taskContent = await readFile(taskPath, 'utf-8');
305
- const validator = TaskOutputValidatorService.getInstance();
306
- const schema = validator.extractSchemaFromMarkdown(taskContent);
307
- // If task has an output schema, validate the output
308
- if (schema) {
309
- if (!output || typeof output !== 'object') {
286
+ }, async (span) => {
287
+ try {
288
+ const { taskPath, sessionName, output, qualityScore } = req.body;
289
+ // Update agent heartbeat (proof of life)
290
+ try {
291
+ await updateAgentHeartbeat(sessionName, undefined, CREWLY_CONSTANTS.AGENT_STATUSES.ACTIVE);
292
+ }
293
+ catch (error) {
294
+ logger.warn('Failed to update agent heartbeat', { error: error instanceof Error ? error.message : String(error) });
295
+ // Continue execution - heartbeat failures shouldn't break task completion
296
+ }
297
+ if (!taskPath) {
298
+ res.status(400).json({ success: false, error: 'taskPath is required' });
299
+ return;
300
+ }
301
+ // Verify source task file exists
302
+ if (!existsSync(taskPath)) {
310
303
  res.status(200).json({
311
304
  success: false,
312
- error: 'Task requires structured output but none was provided',
313
- details: 'This task has an output schema. Provide an "output" object matching the schema.',
305
+ error: 'Task file does not exist at the specified path',
306
+ details: `No task file found at: ${taskPath}. Make sure the task has been properly assigned and is in the in_progress folder.`,
314
307
  taskPath,
308
+ suggestion: 'Check if the task file exists and use accept_task first to move it from open/ to in_progress/'
315
309
  });
316
310
  return;
317
311
  }
318
- // Check output size
319
- const sizeCheck = validator.validateOutputSize(output);
320
- if (!sizeCheck.valid) {
312
+ // Ensure task is in in_progress/ folder
313
+ if (!taskPath.includes('/in_progress/')) {
321
314
  res.status(200).json({
322
315
  success: false,
323
- error: 'Output size exceeds maximum',
324
- details: sizeCheck.error,
316
+ error: 'Task is not in the correct folder for completion',
317
+ details: `Task must be in in_progress/ folder to be completed. Current path: ${taskPath}. Use accept_task first to move the task from open/ to in_progress/.`,
325
318
  taskPath,
319
+ expectedFolder: 'in_progress',
320
+ currentFolder: taskPath.includes('/open/') ? 'open' : taskPath.includes('/done/') ? 'done' : taskPath.includes('/blocked/') ? 'blocked' : 'unknown',
321
+ action: 'Use accept_task tool first to assign the task'
326
322
  });
327
323
  return;
328
324
  }
329
- // Validate output against schema
330
- const validationResult = validator.validate(output, schema);
331
- if (!validationResult.valid) {
332
- // Check retry info
333
- const existingRetryInfo = validator.extractRetryInfoFromMarkdown(taskContent);
334
- const retryCount = existingRetryInfo ? existingRetryInfo.retryCount + 1 : 1;
335
- const maxRetries = TASK_OUTPUT_CONSTANTS.MAX_RETRIES;
336
- if (retryCount > maxRetries) {
337
- // Max retries exceeded - move to blocked
338
- const blockedPath = taskPath.replace('/in_progress/', '/blocked/');
339
- const blockedDir = dirname(blockedPath);
340
- await ensureDirectoryExists(blockedDir);
341
- const failureInfo = `\n\n${TASK_OUTPUT_CONSTANTS.SECTION_HEADERS.VALIDATION_FAILURE}\n- **Status**: Blocked (max validation retries exceeded)\n- **Retry count**: ${retryCount}/${maxRetries}\n- **Errors**: ${validationResult.errors.join('; ')}\n- **Blocked at**: ${new Date().toISOString()}\n`;
342
- const blockedContent = taskContent + failureInfo;
343
- await writeFile(blockedPath, blockedContent, 'utf-8');
344
- await unlinkFile(taskPath);
325
+ // Read task content to check for output schema
326
+ const taskContent = await readFile(taskPath, 'utf-8');
327
+ const validator = TaskOutputValidatorService.getInstance();
328
+ const schema = validator.extractSchemaFromMarkdown(taskContent);
329
+ // If task has an output schema, validate the output
330
+ if (schema) {
331
+ if (!output || typeof output !== 'object') {
332
+ res.status(200).json({
333
+ success: false,
334
+ error: 'Task requires structured output but none was provided',
335
+ details: 'This task has an output schema. Provide an "output" object matching the schema.',
336
+ taskPath,
337
+ });
338
+ return;
339
+ }
340
+ // Check output size
341
+ const sizeCheck = validator.validateOutputSize(output);
342
+ if (!sizeCheck.valid) {
343
+ res.status(200).json({
344
+ success: false,
345
+ error: 'Output size exceeds maximum',
346
+ details: sizeCheck.error,
347
+ taskPath,
348
+ });
349
+ return;
350
+ }
351
+ // Validate output against schema
352
+ const validationResult = validator.validate(output, schema);
353
+ if (!validationResult.valid) {
354
+ // Check retry info
355
+ const existingRetryInfo = validator.extractRetryInfoFromMarkdown(taskContent);
356
+ const retryCount = existingRetryInfo ? existingRetryInfo.retryCount + 1 : 1;
357
+ const maxRetries = TASK_OUTPUT_CONSTANTS.MAX_RETRIES;
358
+ if (retryCount > maxRetries) {
359
+ // Max retries exceeded - move to blocked
360
+ const blockedPath = taskPath.replace('/in_progress/', '/blocked/');
361
+ const blockedDir = dirname(blockedPath);
362
+ await ensureDirectoryExists(blockedDir);
363
+ const failureInfo = `\n\n${TASK_OUTPUT_CONSTANTS.SECTION_HEADERS.VALIDATION_FAILURE}\n- **Status**: Blocked (max validation retries exceeded)\n- **Retry count**: ${retryCount}/${maxRetries}\n- **Errors**: ${validationResult.errors.join('; ')}\n- **Blocked at**: ${new Date().toISOString()}\n`;
364
+ const blockedContent = taskContent + failureInfo;
365
+ await writeFile(blockedPath, blockedContent, 'utf-8');
366
+ await unlinkFile(taskPath);
367
+ res.status(200).json({
368
+ success: false,
369
+ validationFailed: true,
370
+ maxRetriesExceeded: true,
371
+ errors: validationResult.errors,
372
+ retryCount,
373
+ maxRetries,
374
+ message: `Task moved to blocked/ after ${maxRetries} failed validation attempts`,
375
+ taskPath: blockedPath,
376
+ });
377
+ return;
378
+ }
379
+ // Retries remaining - update retry info in task file
380
+ const retryInfo = {
381
+ retryCount,
382
+ maxRetries,
383
+ lastErrors: validationResult.errors,
384
+ lastAttemptAt: new Date().toISOString(),
385
+ };
386
+ // Remove existing retry info section if present, then append new one
387
+ const retryHeader = TASK_OUTPUT_CONSTANTS.SECTION_HEADERS.RETRY_INFO;
388
+ let updatedTaskContent = taskContent;
389
+ const retryHeaderIdx = updatedTaskContent.indexOf(retryHeader);
390
+ if (retryHeaderIdx !== -1) {
391
+ // Find the end of the retry section (next ## header or end of file)
392
+ const afterRetry = updatedTaskContent.substring(retryHeaderIdx + retryHeader.length);
393
+ const nextSectionMatch = afterRetry.match(/\n## /);
394
+ if (nextSectionMatch && nextSectionMatch.index !== undefined) {
395
+ updatedTaskContent = updatedTaskContent.substring(0, retryHeaderIdx) +
396
+ updatedTaskContent.substring(retryHeaderIdx + retryHeader.length + nextSectionMatch.index);
397
+ }
398
+ else {
399
+ updatedTaskContent = updatedTaskContent.substring(0, retryHeaderIdx);
400
+ }
401
+ }
402
+ updatedTaskContent += validator.generateRetryMarkdown(retryInfo);
403
+ await writeFile(taskPath, updatedTaskContent, 'utf-8');
345
404
  res.status(200).json({
346
405
  success: false,
347
406
  validationFailed: true,
348
- maxRetriesExceeded: true,
349
407
  errors: validationResult.errors,
350
408
  retryCount,
351
409
  maxRetries,
352
- message: `Task moved to blocked/ after ${maxRetries} failed validation attempts`,
353
- taskPath: blockedPath,
410
+ message: `Output validation failed. ${maxRetries - retryCount} retries remaining.`,
411
+ taskPath,
354
412
  });
355
413
  return;
356
414
  }
357
- // Retries remaining - update retry info in task file
358
- const retryInfo = {
359
- retryCount,
360
- maxRetries,
361
- lastErrors: validationResult.errors,
362
- lastAttemptAt: new Date().toISOString(),
415
+ // Validation passed - store output file alongside the done task
416
+ const doneTargetPath = taskPath.replace('/in_progress/', '/done/');
417
+ const outputFilePath = doneTargetPath.replace(/\.md$/, TASK_OUTPUT_CONSTANTS.OUTPUT_FILE_EXTENSION);
418
+ const doneDir = dirname(doneTargetPath);
419
+ await ensureDirectoryExists(doneDir);
420
+ const outputData = {
421
+ output,
422
+ producedAt: new Date().toISOString(),
423
+ sessionName: sessionName || 'unknown',
363
424
  };
364
- // Remove existing retry info section if present, then append new one
365
- const retryHeader = TASK_OUTPUT_CONSTANTS.SECTION_HEADERS.RETRY_INFO;
366
- let updatedTaskContent = taskContent;
367
- const retryHeaderIdx = updatedTaskContent.indexOf(retryHeader);
368
- if (retryHeaderIdx !== -1) {
369
- // Find the end of the retry section (next ## header or end of file)
370
- const afterRetry = updatedTaskContent.substring(retryHeaderIdx + retryHeader.length);
371
- const nextSectionMatch = afterRetry.match(/\n## /);
372
- if (nextSectionMatch && nextSectionMatch.index !== undefined) {
373
- updatedTaskContent = updatedTaskContent.substring(0, retryHeaderIdx) +
374
- updatedTaskContent.substring(retryHeaderIdx + retryHeader.length + nextSectionMatch.index);
375
- }
376
- else {
377
- updatedTaskContent = updatedTaskContent.substring(0, retryHeaderIdx);
425
+ await writeFile(outputFilePath, JSON.stringify(outputData, null, 2), 'utf-8');
426
+ // Move task to done
427
+ const updatedContent = addTaskCompletionInfo(taskContent);
428
+ await writeFile(doneTargetPath, updatedContent, 'utf-8');
429
+ await unlinkFile(taskPath);
430
+ // Remove from task tracking and clean up monitoring
431
+ const allTasksWithSchema = await this.taskTrackingService.getAllInProgressTasks();
432
+ const taskToRemoveWithSchema = allTasksWithSchema.find(t => t.taskFilePath === taskPath);
433
+ let cleanupResultSchema = { cancelledSchedules: 0, unsubscribedEvents: 0 };
434
+ if (taskToRemoveWithSchema) {
435
+ // #174: Store quality score on task before completing
436
+ if (typeof qualityScore === 'number' && qualityScore >= 0 && qualityScore <= 100) {
437
+ taskToRemoveWithSchema.qualityScore = qualityScore;
438
+ taskToRemoveWithSchema.scoredAt = new Date().toISOString();
439
+ taskToRemoveWithSchema.scoredBy = sessionName;
378
440
  }
441
+ publishTaskCompletedEvent(taskToRemoveWithSchema, sessionName);
442
+ cleanupResultSchema = await cleanupTaskMonitoring(this, taskToRemoveWithSchema);
443
+ await this.taskTrackingService.removeTask(taskToRemoveWithSchema.id);
379
444
  }
380
- updatedTaskContent += validator.generateRetryMarkdown(retryInfo);
381
- await writeFile(taskPath, updatedTaskContent, 'utf-8');
382
- res.status(200).json({
383
- success: false,
384
- validationFailed: true,
385
- errors: validationResult.errors,
386
- retryCount,
387
- maxRetries,
388
- message: `Output validation failed. ${maxRetries - retryCount} retries remaining.`,
389
- taskPath,
445
+ res.json({
446
+ success: true,
447
+ message: `Task ${basename(taskPath)} marked as completed with validated output`,
448
+ originalPath: taskPath,
449
+ newPath: doneTargetPath,
450
+ outputPath: outputFilePath,
451
+ status: 'done',
452
+ completedAt: new Date().toISOString(),
453
+ monitoringCleanup: cleanupResultSchema,
390
454
  });
391
455
  return;
392
456
  }
393
- // Validation passed - store output file alongside the done task
394
- const doneTargetPath = taskPath.replace('/in_progress/', '/done/');
395
- const outputFilePath = doneTargetPath.replace(/\.md$/, TASK_OUTPUT_CONSTANTS.OUTPUT_FILE_EXTENSION);
396
- const doneDir = dirname(doneTargetPath);
397
- await ensureDirectoryExists(doneDir);
398
- const outputData = {
399
- output,
400
- producedAt: new Date().toISOString(),
401
- sessionName: sessionName || 'unknown',
402
- };
403
- await writeFile(outputFilePath, JSON.stringify(outputData, null, 2), 'utf-8');
404
- // Move task to done
457
+ // No schema - original behavior (backward compatible)
458
+ const fileName = basename(taskPath);
459
+ const targetPath = taskPath.replace('/in_progress/', '/done/');
460
+ const targetDir = dirname(targetPath);
461
+ // Ensure done directory exists
462
+ await ensureDirectoryExists(targetDir);
463
+ // Read, update, and move task file
405
464
  const updatedContent = addTaskCompletionInfo(taskContent);
406
- await writeFile(doneTargetPath, updatedContent, 'utf-8');
465
+ await writeFile(targetPath, updatedContent, 'utf-8');
407
466
  await unlinkFile(taskPath);
408
467
  // Remove from task tracking and clean up monitoring
409
- const allTasksWithSchema = await this.taskTrackingService.getAllInProgressTasks();
410
- const taskToRemoveWithSchema = allTasksWithSchema.find(t => t.taskFilePath === taskPath);
411
- let cleanupResultSchema = { cancelledSchedules: 0, unsubscribedEvents: 0 };
412
- if (taskToRemoveWithSchema) {
413
- publishTaskCompletedEvent(taskToRemoveWithSchema, sessionName);
414
- cleanupResultSchema = await cleanupTaskMonitoring(this, taskToRemoveWithSchema);
415
- await this.taskTrackingService.removeTask(taskToRemoveWithSchema.id);
468
+ const allTasks = await this.taskTrackingService.getAllInProgressTasks();
469
+ const taskToRemove = allTasks.find(t => t.taskFilePath === taskPath);
470
+ let cleanupResult = { cancelledSchedules: 0, unsubscribedEvents: 0 };
471
+ if (taskToRemove) {
472
+ // #174: Store quality score on task before completing
473
+ if (typeof qualityScore === 'number' && qualityScore >= 0 && qualityScore <= 100) {
474
+ taskToRemove.qualityScore = qualityScore;
475
+ taskToRemove.scoredAt = new Date().toISOString();
476
+ taskToRemove.scoredBy = sessionName;
477
+ }
478
+ publishTaskCompletedEvent(taskToRemove, sessionName);
479
+ cleanupResult = await cleanupTaskMonitoring(this, taskToRemove);
480
+ await this.taskTrackingService.removeTask(taskToRemove.id);
416
481
  }
417
482
  res.json({
418
483
  success: true,
419
- message: `Task ${basename(taskPath)} marked as completed with validated output`,
484
+ message: `Task ${fileName} marked as completed`,
420
485
  originalPath: taskPath,
421
- newPath: doneTargetPath,
422
- outputPath: outputFilePath,
486
+ newPath: targetPath,
423
487
  status: 'done',
424
488
  completedAt: new Date().toISOString(),
425
- monitoringCleanup: cleanupResultSchema,
489
+ monitoringCleanup: cleanupResult,
426
490
  });
427
- return;
428
491
  }
429
- // No schema - original behavior (backward compatible)
430
- const fileName = basename(taskPath);
431
- const targetPath = taskPath.replace('/in_progress/', '/done/');
432
- const targetDir = dirname(targetPath);
433
- // Ensure done directory exists
434
- await ensureDirectoryExists(targetDir);
435
- // Read, update, and move task file
436
- const updatedContent = addTaskCompletionInfo(taskContent);
437
- await writeFile(targetPath, updatedContent, 'utf-8');
438
- await unlinkFile(taskPath);
439
- // Remove from task tracking and clean up monitoring
440
- const allTasks = await this.taskTrackingService.getAllInProgressTasks();
441
- const taskToRemove = allTasks.find(t => t.taskFilePath === taskPath);
442
- let cleanupResult = { cancelledSchedules: 0, unsubscribedEvents: 0 };
443
- if (taskToRemove) {
444
- publishTaskCompletedEvent(taskToRemove, sessionName);
445
- cleanupResult = await cleanupTaskMonitoring(this, taskToRemove);
446
- await this.taskTrackingService.removeTask(taskToRemove.id);
492
+ catch (error) {
493
+ logger.error('Error completing task', { error: error instanceof Error ? error.message : String(error) });
494
+ res.status(500).json({ success: false, error: 'Failed to complete task' });
447
495
  }
448
- res.json({
449
- success: true,
450
- message: `Task ${fileName} marked as completed`,
451
- originalPath: taskPath,
452
- newPath: targetPath,
453
- status: 'done',
454
- completedAt: new Date().toISOString(),
455
- monitoringCleanup: cleanupResult,
456
- });
457
- }
458
- catch (error) {
459
- logger.error('Error completing task', { error: error instanceof Error ? error.message : String(error) });
460
- res.status(500).json({ success: false, error: 'Failed to complete task' });
461
- }
496
+ });
462
497
  }
463
498
  /**
464
499
  * Blocks a task by moving it from in_progress/ to blocked/ folder
@@ -1456,4 +1491,241 @@ export async function completeTasksBySession(req, res) {
1456
1491
  res.status(500).json({ success: false, error: 'Failed to complete tasks by session' });
1457
1492
  }
1458
1493
  }
1494
+ /**
1495
+ * GET /task-management/tasks
1496
+ *
1497
+ * List task files for a project, optionally filtered by status.
1498
+ * Returns task filenames and paths grouped by milestone.
1499
+ *
1500
+ * @param req - Request with query: { projectPath, status? }
1501
+ * @param res - Response with { success, tasks }
1502
+ */
1503
+ /**
1504
+ * Detect and optionally clean up orphan tasks — tasks stuck in progress
1505
+ * assigned to agents that no longer exist or have been inactive too long.
1506
+ *
1507
+ * POST /api/task-management/cleanup
1508
+ * Body:
1509
+ * - action: 'detect' (default, dry run) | 'cancel' | 'reopen'
1510
+ * - staleThresholdHours: number (default 24)
1511
+ * - taskIds: string[] (optional, specific tasks to clean; if omitted, cleans all detected orphans)
1512
+ *
1513
+ * @param req - Request with cleanup parameters
1514
+ * @param res - Response with orphan detection/cleanup report
1515
+ * @see https://github.com/stevehuang0115/crewly/issues/168
1516
+ */
1517
+ export async function cleanupOrphanTasks(req, res) {
1518
+ try {
1519
+ const { action = 'detect', staleThresholdHours = 24, taskIds, } = req.body;
1520
+ const staleThresholdMs = staleThresholdHours * 60 * 60 * 1000;
1521
+ const getTeamStatus = async () => {
1522
+ return await this.storageService.getTeams();
1523
+ };
1524
+ // Step 1: Detect orphan tasks
1525
+ const orphans = await this.taskTrackingService.detectOrphanTasks(getTeamStatus, staleThresholdMs);
1526
+ if (action === 'detect') {
1527
+ res.json({
1528
+ success: true,
1529
+ message: `Found ${orphans.length} orphan task(s)`,
1530
+ data: {
1531
+ orphanCount: orphans.length,
1532
+ orphans: orphans.map(t => ({
1533
+ id: t.id,
1534
+ taskName: t.taskName,
1535
+ assignedSessionName: t.assignedSessionName,
1536
+ assignedTeamMemberId: t.assignedTeamMemberId,
1537
+ status: t.status,
1538
+ assignedAt: t.assignedAt,
1539
+ staleSinceHours: Math.round(t.staleSinceMs / (60 * 60 * 1000) * 10) / 10,
1540
+ taskFilePath: t.taskFilePath,
1541
+ })),
1542
+ },
1543
+ });
1544
+ return;
1545
+ }
1546
+ // Step 2: Clean up
1547
+ const idsToClean = taskIds || orphans.map(t => t.id);
1548
+ if (idsToClean.length === 0) {
1549
+ res.json({ success: true, message: 'No orphan tasks to clean up', data: { cleaned: 0 } });
1550
+ return;
1551
+ }
1552
+ const cleanupAction = action === 'reopen' ? 'reopen' : 'cancel';
1553
+ const report = await this.taskTrackingService.cleanupOrphanTasks(idsToClean, cleanupAction);
1554
+ logger.info('Orphan task cleanup completed', {
1555
+ action: cleanupAction,
1556
+ cleaned: report.cleaned,
1557
+ errors: report.errors.length,
1558
+ });
1559
+ res.json({
1560
+ success: true,
1561
+ message: `Cleaned ${report.cleaned} orphan task(s) (action: ${cleanupAction})`,
1562
+ data: {
1563
+ cleaned: report.cleaned,
1564
+ errors: report.errors,
1565
+ totalOrphansDetected: orphans.length,
1566
+ },
1567
+ });
1568
+ }
1569
+ catch (error) {
1570
+ logger.error('Orphan task cleanup failed', { error: error instanceof Error ? error.message : String(error) });
1571
+ res.status(500).json({
1572
+ success: false,
1573
+ error: 'Failed to clean up orphan tasks',
1574
+ details: error instanceof Error ? error.message : String(error),
1575
+ });
1576
+ }
1577
+ }
1578
+ export async function listTasks(req, res) {
1579
+ try {
1580
+ const projectPath = req.query.projectPath;
1581
+ const statusFilter = req.query.status;
1582
+ if (!projectPath) {
1583
+ res.status(400).json({ success: false, error: 'projectPath query parameter is required' });
1584
+ return;
1585
+ }
1586
+ // Validate status filter against known values to prevent path traversal
1587
+ const VALID_STATUSES = ['open', 'in_progress', 'blocked', 'done'];
1588
+ if (statusFilter && !VALID_STATUSES.includes(statusFilter)) {
1589
+ res.status(400).json({ success: false, error: `status must be one of: ${VALID_STATUSES.join(', ')}` });
1590
+ return;
1591
+ }
1592
+ // Resolve and validate project path to prevent directory traversal
1593
+ const resolvedPath = resolve(projectPath);
1594
+ const tasksBasePath = join(resolvedPath, '.crewly', 'tasks');
1595
+ if (!existsSync(tasksBasePath)) {
1596
+ res.json({ success: true, tasks: [] });
1597
+ return;
1598
+ }
1599
+ const tasks = [];
1600
+ const milestones = await readdir(tasksBasePath);
1601
+ for (const milestone of milestones) {
1602
+ const milestonePath = join(tasksBasePath, milestone);
1603
+ const milestoneStat = await stat(milestonePath).catch(() => null);
1604
+ if (!milestoneStat?.isDirectory())
1605
+ continue;
1606
+ const statusDirs = statusFilter ? [statusFilter] : [...VALID_STATUSES];
1607
+ for (const status of statusDirs) {
1608
+ const statusPath = join(milestonePath, status);
1609
+ if (!existsSync(statusPath))
1610
+ continue;
1611
+ const files = await readdir(statusPath);
1612
+ for (const file of files) {
1613
+ if (file.endsWith('.md')) {
1614
+ tasks.push({
1615
+ name: file.replace('.md', ''),
1616
+ path: join(statusPath, file),
1617
+ milestone,
1618
+ status,
1619
+ });
1620
+ }
1621
+ }
1622
+ }
1623
+ }
1624
+ res.json({ success: true, tasks });
1625
+ }
1626
+ catch (error) {
1627
+ logger.error('Error listing tasks', { error: error instanceof Error ? error.message : String(error) });
1628
+ res.status(500).json({ success: false, error: 'Failed to list tasks' });
1629
+ }
1630
+ }
1631
+ /**
1632
+ * Score a completed task's quality (#174).
1633
+ * Called by the auditor's score-task skill after task:completed events.
1634
+ * Updates the task's qualityScore in the tracking data.
1635
+ *
1636
+ * @param req - Request containing taskId, qualityScore, and optional scoredBy
1637
+ * @param res - Response with success status
1638
+ */
1639
+ export async function scoreTask(req, res) {
1640
+ try {
1641
+ const { taskId, qualityScore, scoredBy } = req.body;
1642
+ if (!taskId) {
1643
+ res.status(400).json({ success: false, error: 'taskId is required' });
1644
+ return;
1645
+ }
1646
+ if (typeof qualityScore !== 'number' || qualityScore < 0 || qualityScore > 100) {
1647
+ res.status(400).json({ success: false, error: 'qualityScore must be a number between 0 and 100' });
1648
+ return;
1649
+ }
1650
+ // Load task data directly for in-place update
1651
+ const taskData = await this.taskTrackingService.loadTaskData();
1652
+ const task = taskData.tasks.find(t => t.id === taskId);
1653
+ if (task) {
1654
+ // Task still in tracking — update in place and persist
1655
+ task.qualityScore = qualityScore;
1656
+ task.scoredAt = new Date().toISOString();
1657
+ task.scoredBy = scoredBy || 'auditor';
1658
+ await this.taskTrackingService.saveTaskData(taskData);
1659
+ logger.info('Task scored', { taskId, qualityScore, scoredBy: scoredBy || 'auditor' });
1660
+ res.json({ success: true, message: 'Task scored successfully', taskId, qualityScore });
1661
+ }
1662
+ else {
1663
+ // Task already removed from tracking — score acknowledged
1664
+ logger.warn('Task not found in tracking (may already be completed)', { taskId });
1665
+ res.json({ success: true, message: 'Score acknowledged but task already completed', taskId, qualityScore });
1666
+ }
1667
+ }
1668
+ catch (error) {
1669
+ logger.error('Error scoring task', { error: error instanceof Error ? error.message : String(error) });
1670
+ res.status(500).json({ success: false, error: 'Failed to score task' });
1671
+ }
1672
+ }
1673
+ /**
1674
+ * Record a task handoff from one agent to another (F12).
1675
+ *
1676
+ * POST /api/task-management/handoff
1677
+ * Body: { from, to, taskPath?, reason, progress?, projectPath? }
1678
+ *
1679
+ * Updates the task tracking data to reflect the handoff and logs the event.
1680
+ *
1681
+ * @param req - Request with handoff parameters
1682
+ * @param res - Response with handoff record
1683
+ */
1684
+ export async function recordHandoff(req, res) {
1685
+ try {
1686
+ const { from, to, taskPath, reason, progress, projectPath } = req.body;
1687
+ if (!from || !to || !reason) {
1688
+ res.status(400).json({ success: false, error: 'from, to, and reason are required' });
1689
+ return;
1690
+ }
1691
+ // Find the task being handed off (by assignedSessionName)
1692
+ const tasks = await this.taskTrackingService.getTasksBySessionName(from);
1693
+ const activeTask = tasks.find(t => t.status === 'assigned' || t.status === 'active' || t.status === 'working');
1694
+ if (activeTask) {
1695
+ // Update task assignment to new agent
1696
+ const data = await this.taskTrackingService.loadTaskData();
1697
+ const task = data.tasks.find(t => t.id === activeTask.id);
1698
+ if (task) {
1699
+ task.assignedSessionName = to;
1700
+ task.status = 'assigned';
1701
+ task.statusHistory = task.statusHistory || [];
1702
+ task.statusHistory.push({
1703
+ timestamp: new Date().toISOString(),
1704
+ fromStatus: activeTask.status,
1705
+ toStatus: 'assigned',
1706
+ message: `Handed off from ${from} to ${to}: ${reason}`,
1707
+ reportedBy: from,
1708
+ });
1709
+ await this.taskTrackingService.saveTaskData(data);
1710
+ }
1711
+ }
1712
+ logger.info('Task handoff recorded', { from, to, reason, taskId: activeTask?.id });
1713
+ res.json({
1714
+ success: true,
1715
+ handoff: {
1716
+ from,
1717
+ to,
1718
+ reason,
1719
+ taskId: activeTask?.id || null,
1720
+ taskPath: taskPath || null,
1721
+ progress: progress || null,
1722
+ timestamp: new Date().toISOString(),
1723
+ },
1724
+ });
1725
+ }
1726
+ catch (error) {
1727
+ logger.error('Error recording handoff', { error: error instanceof Error ? error.message : String(error) });
1728
+ res.status(500).json({ success: false, error: 'Failed to record handoff' });
1729
+ }
1730
+ }
1459
1731
  //# sourceMappingURL=task-management.controller.js.map