crewly 1.6.1 → 1.6.3

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 (367) hide show
  1. package/config/roles/orchestrator/prompt.md +16 -0
  2. package/config/skills/agent/core/get-my-active-work/SKILL.md +101 -0
  3. package/config/skills/agent/core/get-my-active-work/execute.sh +122 -0
  4. package/config/skills/agent/core/record-learning/SKILL.md +29 -0
  5. package/config/skills/agent/core/reply-channel/SKILL.md +41 -0
  6. package/config/skills/agent/core/reply-channel/execute.sh +165 -0
  7. package/config/skills/agent/core/reply-channel/execute.test.sh +148 -0
  8. package/config/skills/agent/remote-browser/execute.sh +296 -14
  9. package/config/skills/agent/remote-browser/execute.test.sh +482 -0
  10. package/config/skills/orchestrator/send-message/SKILL.md +30 -7
  11. package/config/skills/orchestrator/team-health-scan/SKILL.md +98 -0
  12. package/config/skills/orchestrator/team-health-scan/execute.sh +44 -0
  13. package/config/skills/registry.json +62 -1
  14. package/config/slack-app-manifest.json +2 -1
  15. package/config/sops/developer/git-workflow.md +38 -3
  16. package/dist/backend/backend/src/constants.d.ts +69 -1
  17. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  18. package/dist/backend/backend/src/constants.js +69 -2
  19. package/dist/backend/backend/src/constants.js.map +1 -1
  20. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts +53 -0
  21. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -0
  22. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +92 -0
  23. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -0
  24. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
  25. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +18 -1
  26. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
  27. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +68 -0
  28. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  29. package/dist/backend/backend/src/controllers/browser/browser.controller.js +233 -5
  30. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  31. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  32. package/dist/backend/backend/src/controllers/browser/browser.routes.js +10 -1
  33. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  34. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  35. package/dist/backend/backend/src/controllers/chat/chat.controller.js +8 -3
  36. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  37. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +132 -0
  38. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -0
  39. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +401 -0
  40. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -0
  41. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +29 -0
  42. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -0
  43. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +39 -0
  44. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -0
  45. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts +8 -0
  46. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts.map +1 -0
  47. package/dist/backend/backend/src/controllers/chat-v2/index.js +8 -0
  48. package/dist/backend/backend/src/controllers/chat-v2/index.js.map +1 -0
  49. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +13 -13
  50. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
  51. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +74 -234
  52. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
  53. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
  54. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +76 -15
  55. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js.map +1 -1
  56. package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
  57. package/dist/backend/backend/src/controllers/request/request.controller.js +4 -6
  58. package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
  59. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts +43 -0
  60. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
  61. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +200 -72
  62. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
  63. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  64. package/dist/backend/backend/src/controllers/team/team.controller.js +49 -0
  65. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  66. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts +59 -0
  67. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts.map +1 -0
  68. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js +127 -0
  69. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js.map +1 -0
  70. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts +13 -0
  71. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts.map +1 -0
  72. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js +20 -0
  73. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js.map +1 -0
  74. package/dist/backend/backend/src/index.d.ts +9 -0
  75. package/dist/backend/backend/src/index.d.ts.map +1 -1
  76. package/dist/backend/backend/src/index.js +233 -0
  77. package/dist/backend/backend/src/index.js.map +1 -1
  78. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  79. package/dist/backend/backend/src/routes/api.routes.js +40 -6
  80. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  81. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +498 -0
  82. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  83. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +759 -0
  84. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  85. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +25 -0
  86. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/agent/agent-registration.service.js +221 -58
  88. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +9 -2
  90. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +35 -2
  92. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  93. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +8 -2
  94. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +1 -0
  96. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  97. package/dist/backend/backend/src/services/agent/tmux-command.service.d.ts.map +1 -1
  98. package/dist/backend/backend/src/services/agent/tmux-command.service.js +2 -1
  99. package/dist/backend/backend/src/services/agent/tmux-command.service.js.map +1 -1
  100. package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
  102. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +148 -3
  104. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +241 -2
  106. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  107. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -1
  108. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +13 -0
  109. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -1
  110. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
  111. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +26 -1
  112. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
  113. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  114. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  115. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  116. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  117. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +161 -0
  118. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +382 -2
  120. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  121. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +105 -0
  122. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  123. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +232 -13
  124. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  125. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +178 -0
  126. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
  127. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +254 -0
  128. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
  129. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
  130. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
  131. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
  132. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
  133. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts +25 -0
  134. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts.map +1 -0
  135. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js +23 -0
  136. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js.map +1 -0
  137. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +254 -0
  138. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +467 -0
  140. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  141. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  142. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  143. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  144. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  145. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts +43 -0
  146. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts.map +1 -0
  147. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js +54 -0
  148. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js.map +1 -0
  149. package/dist/backend/backend/src/services/chat-v2/config.d.ts +100 -0
  150. package/dist/backend/backend/src/services/chat-v2/config.d.ts.map +1 -0
  151. package/dist/backend/backend/src/services/chat-v2/config.js +174 -0
  152. package/dist/backend/backend/src/services/chat-v2/config.js.map +1 -0
  153. package/dist/backend/backend/src/services/chat-v2/index.d.ts +11 -0
  154. package/dist/backend/backend/src/services/chat-v2/index.d.ts.map +1 -0
  155. package/dist/backend/backend/src/services/chat-v2/index.js +12 -0
  156. package/dist/backend/backend/src/services/chat-v2/index.js.map +1 -0
  157. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +114 -0
  158. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  159. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +194 -0
  160. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  161. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +100 -0
  162. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  163. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +351 -0
  164. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  165. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +132 -0
  166. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  167. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +281 -0
  168. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  169. package/dist/backend/backend/src/services/chat-v2/types.d.ts +295 -0
  170. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -0
  171. package/dist/backend/backend/src/services/chat-v2/types.js +61 -0
  172. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -0
  173. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +113 -0
  174. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +1 -0
  175. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +179 -0
  176. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +1 -0
  177. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +131 -0
  178. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +1 -0
  179. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +227 -0
  180. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +1 -0
  181. package/dist/backend/backend/src/services/core/config.service.js +3 -3
  182. package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
  183. package/dist/backend/backend/src/services/core/storage.service.d.ts +22 -0
  184. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  185. package/dist/backend/backend/src/services/core/storage.service.js +57 -0
  186. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  187. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +69 -1
  188. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  189. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +118 -0
  190. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  191. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +275 -0
  192. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -0
  193. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +736 -0
  194. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -0
  195. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  196. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -2
  197. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  198. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  199. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  200. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  201. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  202. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
  203. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
  204. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js +304 -0
  205. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
  206. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  207. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +24 -4
  208. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  209. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +174 -0
  210. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -0
  211. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +375 -0
  212. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -0
  213. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +97 -0
  214. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +1 -0
  215. package/dist/backend/backend/src/services/memory/learning-format.validator.js +209 -0
  216. package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +1 -0
  217. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
  218. package/dist/backend/backend/src/services/memory/vector-store.service.js +19 -4
  219. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
  220. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts +16 -5
  221. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts.map +1 -1
  222. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js +32 -5
  223. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js.map +1 -1
  224. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +157 -0
  225. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -0
  226. package/dist/backend/backend/src/services/onboarding/onboarding.service.js +229 -0
  227. package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -0
  228. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +141 -0
  229. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -0
  230. package/dist/backend/backend/src/services/onboarding/onboarding.types.js +18 -0
  231. package/dist/backend/backend/src/services/onboarding/onboarding.types.js.map +1 -0
  232. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -1
  233. package/dist/backend/backend/src/services/pr-review/pr-review.service.js +1 -1
  234. package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -1
  235. package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +17 -1
  237. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
  238. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +39 -1
  239. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +158 -26
  241. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  242. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +248 -6
  243. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  244. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +531 -51
  245. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  246. package/dist/backend/backend/src/services/team-health/index.d.ts +16 -0
  247. package/dist/backend/backend/src/services/team-health/index.d.ts.map +1 -0
  248. package/dist/backend/backend/src/services/team-health/index.js +16 -0
  249. package/dist/backend/backend/src/services/team-health/index.js.map +1 -0
  250. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts +52 -0
  251. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -0
  252. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +161 -0
  253. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -0
  254. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts +53 -0
  255. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts.map +1 -0
  256. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js +88 -0
  257. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js.map +1 -0
  258. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts +44 -0
  259. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts.map +1 -0
  260. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js +83 -0
  261. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js.map +1 -0
  262. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts +92 -0
  263. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts.map +1 -0
  264. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js +328 -0
  265. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js.map +1 -0
  266. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts +41 -0
  267. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts.map +1 -0
  268. package/dist/backend/backend/src/services/team-health/team-health-config.js +213 -0
  269. package/dist/backend/backend/src/services/team-health/team-health-config.js.map +1 -0
  270. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts +46 -0
  271. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts.map +1 -0
  272. package/dist/backend/backend/src/services/team-health/team-health-detector.js +347 -0
  273. package/dist/backend/backend/src/services/team-health/team-health-detector.js.map +1 -0
  274. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts +154 -0
  275. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts.map +1 -0
  276. package/dist/backend/backend/src/services/team-health/team-health-types.js +94 -0
  277. package/dist/backend/backend/src/services/team-health/team-health-types.js.map +1 -0
  278. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts +111 -0
  279. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts.map +1 -0
  280. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js +226 -0
  281. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js.map +1 -0
  282. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +148 -0
  283. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -0
  284. package/dist/backend/backend/src/services/v3/mission-reminder.service.js +545 -0
  285. package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -0
  286. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +499 -0
  287. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  288. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +1105 -0
  289. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  290. package/dist/backend/backend/src/services/v3/request.service.d.ts +22 -0
  291. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  292. package/dist/backend/backend/src/services/v3/request.service.js +71 -0
  293. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  294. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +1 -0
  295. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  296. package/dist/backend/backend/src/services/v3/v3-data.service.js +22 -6
  297. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  298. package/dist/backend/backend/src/types/event-bus.types.d.ts +19 -1
  299. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  300. package/dist/backend/backend/src/types/event-bus.types.js +43 -0
  301. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  302. package/dist/backend/backend/src/types/index.d.ts +22 -1
  303. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  304. package/dist/backend/backend/src/types/index.js.map +1 -1
  305. package/dist/backend/backend/src/types/review-reason.types.d.ts +63 -0
  306. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -0
  307. package/dist/backend/backend/src/types/review-reason.types.js +50 -0
  308. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -0
  309. package/dist/backend/backend/src/types/slack.types.d.ts +4 -1
  310. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  311. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  312. package/dist/backend/backend/src/types/v2/mission.types.d.ts +18 -0
  313. package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
  314. package/dist/backend/backend/src/types/v2/mission.types.js +1 -0
  315. package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
  316. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  317. package/dist/backend/backend/src/types/v2/work-item.types.js +25 -1
  318. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  319. package/dist/backend/backend/src/utils/team.utils.d.ts +38 -0
  320. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -0
  321. package/dist/backend/backend/src/utils/team.utils.js +45 -0
  322. package/dist/backend/backend/src/utils/team.utils.js.map +1 -0
  323. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +195 -0
  324. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -0
  325. package/dist/backend/backend/src/websocket/chat-v2.gateway.js +401 -0
  326. package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -0
  327. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +37 -2
  328. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  329. package/dist/backend/backend/src/websocket/terminal.gateway.js +106 -5
  330. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  331. package/dist/cli/backend/src/constants.d.ts +69 -1
  332. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  333. package/dist/cli/backend/src/constants.js +69 -2
  334. package/dist/cli/backend/src/constants.js.map +1 -1
  335. package/dist/cli/backend/src/services/core/config.service.js +3 -3
  336. package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
  337. package/dist/cli/backend/src/services/core/storage.service.d.ts +22 -0
  338. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  339. package/dist/cli/backend/src/services/core/storage.service.js +57 -0
  340. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  341. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  342. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -2
  343. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  344. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  345. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  346. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  347. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  348. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  349. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +24 -4
  350. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  351. package/dist/cli/backend/src/types/index.d.ts +22 -1
  352. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  353. package/dist/cli/backend/src/types/index.js.map +1 -1
  354. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  355. package/dist/cli/backend/src/types/v2/work-item.types.js +25 -1
  356. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  357. package/frontend/dist/assets/{index-70356616.js → index-7a4e7df5.js} +328 -326
  358. package/frontend/dist/assets/index-b7e59b2b.css +33 -0
  359. package/frontend/dist/index.html +2 -2
  360. package/package.json +2 -1
  361. package/config/skills/orchestrator/recall/SKILL.md +0 -47
  362. package/config/skills/orchestrator/recall/execute.sh +0 -13
  363. package/config/skills/orchestrator/record-learning/SKILL.md +0 -47
  364. package/config/skills/orchestrator/record-learning/execute.sh +0 -13
  365. package/config/skills/orchestrator/remember/SKILL.md +0 -55
  366. package/config/skills/orchestrator/remember/execute.sh +0 -15
  367. package/frontend/dist/assets/index-6aaa0630.css +0 -33
@@ -734,6 +734,22 @@ bash {{ORCHESTRATOR_SKILLS_PATH}}/reply-slack/execute.sh '{"channelId":"C0123","
734
734
 
735
735
  **You are the project manager. The user should not have to ask "what happened?" — you should tell them before they need to ask.**
736
736
 
737
+ ## V3 Intelligent Decomposition Pipeline (MANDATORY)
738
+
739
+ To ensure tasks are specific and context-aware (avoiding generic "Plan/Execute/Review" blocks), you MUST follow this decomposition pipeline for every user goal or complex request:
740
+
741
+ 1. **Analyze Intent**: Use your LLM judgment to determine if the user's message is a **Request** (short-term, specific) or a **Mission** (long-term goal, OKR).
742
+ 2. **Create Entity**:
743
+ - For Missions: Call `create-mission`.
744
+ - For Requests: Call `create-request`.
745
+ 3. **Perform Intelligent Decomposition**:
746
+ - **NEVER** let the system create mindless WorkItems.
747
+ - If you created a **Mission**: IMMEDIATELY call `decompose-mission` (orchestrator skill). The skill will prompt you for a detailed breakdown. Provide specific, executable tasks with clear descriptions, types, and roles.
748
+ - If you created a **Request**: If it's complex (L2/L3), call `break-down-request` (agent skill) to generate specific WorkItems.
749
+ 4. **Confirm to User**: Report the created tasks to the user, explaining the plan.
750
+
751
+ **Rule**: A user message like "Build a login page" should result in 5-8 specific WorkItems (e.g., "Design login UI", "Implement auth API", "Write integration tests", etc.), NOT 3 generic ones.
752
+
737
753
  ---
738
754
 
739
755
  ## IMPORTANT: Session Management
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: Get My Active Work
3
+ description: Retrieve the live Request + WorkItem briefing for your session. Use this when the startup briefing is stale or truncated.
4
+ natural_language_description: Show me the active Requests and WorkItems I am currently on the hook for, plus anything that auto-resolved in the last 30 minutes.
5
+ version: 1.0.0
6
+ category: state-recovery
7
+ skillType: claude-skill
8
+ assignableRoles:
9
+ - developer
10
+ - qa
11
+ - tpm
12
+ - designer
13
+ - frontend-developer
14
+ - backend-developer
15
+ - fullstack-dev
16
+ - qa-engineer
17
+ - product-manager
18
+ - architect
19
+ - generalist
20
+ - sales
21
+ - support
22
+ - team-lead
23
+ - team_lead
24
+ - orchestrator
25
+ triggers:
26
+ - get my active work
27
+ - active work
28
+ - what am I on the hook for
29
+ - refresh state
30
+ tags:
31
+ - state
32
+ - recovery
33
+ - request
34
+ - workitem
35
+ execution:
36
+ type: script
37
+ script:
38
+ file: execute.sh
39
+ interpreter: bash
40
+ timeoutMs: 15000
41
+ ---
42
+
43
+ # Get My Active Work
44
+
45
+ Returns the authoritative live state — open Requests you are on the hook for,
46
+ in-flight WorkItems targeted at you (or claimed by you), pending reviews where
47
+ you are the verifier, outbound delegations you issued, and recently
48
+ auto-resolved items from the last 30 minutes.
49
+
50
+ This is the **freshness escape hatch** for the recovery protocol:
51
+
52
+ - The same briefing is auto-injected into your system prompt at session
53
+ registration — you don't normally need to call this skill on startup.
54
+ - Call this skill mid-session if (a) the briefing was truncated (more than
55
+ the 45-item cap had to be dropped), or (b) the snapshot is stale (>5
56
+ minutes since registration, especially after long-running tasks).
57
+
58
+ State is the source of truth. Memory is supplementary. If the briefing shows
59
+ something your memory disagrees with, **trust the state** — investigate the
60
+ divergence rather than override it.
61
+
62
+ ## Parameters
63
+
64
+ | Flag | JSON Field | Required | Description |
65
+ |------|-----------|----------|-------------|
66
+ | `--session` / `-s` | `sessionName` | Yes | Your agent session name |
67
+ | `--role` / `-r` | `role` | No | Agent role (default `developer`; orchestrator gets 3× cap) |
68
+ | `--format` / `-f` | `format` | No | `json` (default) or `markdown` |
69
+ | `--window` / `-w` | `recentlyResolvedWindowMs` | No | Window for recently auto-resolved items in ms (default `1800000` / 30min) |
70
+
71
+ ## Examples — CLI Flags (preferred)
72
+
73
+ ```bash
74
+ # Default JSON briefing
75
+ bash config/skills/agent/core/get-my-active-work/execute.sh --session dev-1
76
+
77
+ # Markdown rendering — pipe straight into your context
78
+ bash config/skills/agent/core/get-my-active-work/execute.sh --session dev-1 --format markdown
79
+
80
+ # Orchestrator system-wide briefing
81
+ bash config/skills/agent/core/get-my-active-work/execute.sh --session crewly-orc --role orchestrator
82
+ ```
83
+
84
+ ## Output
85
+
86
+ JSON (default): `{ success: true, data: ActiveWorkBriefing }`. The shape is:
87
+
88
+ ```jsonc
89
+ {
90
+ "openRequests": [{ "id": "req-abc", "title": "...", "status": "running", "priority": "high", "ageHours": 2.1 }],
91
+ "activeWorkItems": [{ "id": "wi-123", "title": "...", "status": "running", "ageHours": 0.5, "requestId": "req-abc" }],
92
+ "pendingReviews": [{ "id": "wi-456", "title": "...", "ageHours": 1.0, "claimedBy": "dev-x" }],
93
+ "outboundDelegations": [{ "id": "wi-789", "title": "...", "status": "running", "target": "dev-leo" }],
94
+ "recentlyAutoResolved": [{ "id": "wi-old", "title": "...", "resolvedAt": "...", "resolvedReason": "sla_close_run" }],
95
+ "truncated": false,
96
+ "totalCounts": { "requests": 12, "workItems": 47 }
97
+ }
98
+ ```
99
+
100
+ When `--format markdown` is set, the response is `text/markdown` rendering of
101
+ the briefing — append it directly to your working context.
@@ -0,0 +1,122 @@
1
+ #!/bin/bash
2
+ # get-my-active-work — fetch the live Request + WorkItem briefing for this
3
+ # agent. Backs the recovery protocol's Step 1.5 freshness escape hatch:
4
+ # the startup briefing is already injected at registration time, but a
5
+ # long-running session can call this skill to refresh after the snapshot
6
+ # ages out (e.g. >5min after registration).
7
+ #
8
+ # Mirrors the get-my-tasks skill argument shape for consistency.
9
+ set -euo pipefail
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ source "${SCRIPT_DIR}/../../_common/lib.sh"
12
+
13
+ print_usage() {
14
+ cat <<'EOF_USAGE'
15
+ Usage:
16
+ # CLI flags (preferred — avoids shell escaping issues)
17
+ bash execute.sh --session dev-1
18
+ bash execute.sh --session dev-1 --role developer --format markdown
19
+
20
+ # Legacy JSON argument (backward compatible)
21
+ bash execute.sh '{"sessionName":"dev-1","role":"developer"}'
22
+
23
+ Options:
24
+ --session | -s Agent session name (required)
25
+ --role | -r Agent role (default: developer; orchestrator gets 3x cap)
26
+ --format | -f "json" (default) or "markdown"
27
+ --window | -w Recently-resolved window in milliseconds (default: 1800000 / 30min)
28
+ --json | -j Raw JSON payload (same as legacy)
29
+ --help | -h Show this help
30
+ EOF_USAGE
31
+ }
32
+
33
+ INPUT_JSON=""
34
+ SESSION_NAME=""
35
+ ROLE=""
36
+ FORMAT=""
37
+ WINDOW_MS=""
38
+
39
+ # Detect legacy JSON argument as the first parameter
40
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
41
+ INPUT_JSON="$1"
42
+ shift || true
43
+ fi
44
+
45
+ while [[ $# -gt 0 ]]; do
46
+ case "$1" in
47
+ --session|-s)
48
+ SESSION_NAME="$2"
49
+ shift 2
50
+ ;;
51
+ --role|-r)
52
+ ROLE="$2"
53
+ shift 2
54
+ ;;
55
+ --format|-f)
56
+ FORMAT="$2"
57
+ shift 2
58
+ ;;
59
+ --window|-w)
60
+ WINDOW_MS="$2"
61
+ shift 2
62
+ ;;
63
+ --json|-j)
64
+ INPUT_JSON="$2"
65
+ shift 2
66
+ ;;
67
+ --help|-h)
68
+ print_usage
69
+ exit 0
70
+ ;;
71
+ --)
72
+ shift
73
+ break
74
+ ;;
75
+ *)
76
+ if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then
77
+ INPUT_JSON="$1"
78
+ shift
79
+ else
80
+ error_exit "Unknown argument: $1. Use --help for usage."
81
+ fi
82
+ ;;
83
+ esac
84
+ done
85
+
86
+ # If nothing provided yet but stdin has data, read it as JSON
87
+ if [ -z "$INPUT_JSON" ] && [ -z "$SESSION_NAME" ] && [ ! -t 0 ]; then
88
+ STDIN_DATA="$(cat)"
89
+ if [[ ${STDIN_DATA:0:1} == '{' ]]; then
90
+ INPUT_JSON="$STDIN_DATA"
91
+ fi
92
+ fi
93
+
94
+ # Parse JSON input if provided (backward compatible)
95
+ if [ -n "$INPUT_JSON" ]; then
96
+ INPUT=$(read_json_input "$INPUT_JSON")
97
+ [ -z "$SESSION_NAME" ] && SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
98
+ [ -z "$ROLE" ] && ROLE=$(printf '%s' "$INPUT" | jq -r '.role // empty')
99
+ [ -z "$FORMAT" ] && FORMAT=$(printf '%s' "$INPUT" | jq -r '.format // empty')
100
+ [ -z "$WINDOW_MS" ] && WINDOW_MS=$(printf '%s' "$INPUT" | jq -r '(.recentlyResolvedWindowMs // empty) | tostring')
101
+ # `jq` returns the literal string "null" when the field is missing — coerce.
102
+ [ "$WINDOW_MS" = "null" ] && WINDOW_MS=""
103
+ fi
104
+
105
+ require_param "sessionName (--session)" "$SESSION_NAME"
106
+
107
+ # Defaults for optional knobs
108
+ [ -z "$ROLE" ] && ROLE="developer"
109
+ [ -z "$FORMAT" ] && FORMAT="json"
110
+
111
+ # URL-encode the session name and build the query string
112
+ ENCODED_SESSION=$(printf '%s' "$SESSION_NAME" | jq -sRr @uri)
113
+ ENCODED_ROLE=$(printf '%s' "$ROLE" | jq -sRr @uri)
114
+ ENCODED_FORMAT=$(printf '%s' "$FORMAT" | jq -sRr @uri)
115
+
116
+ QUERY="role=${ENCODED_ROLE}&format=${ENCODED_FORMAT}"
117
+ if [ -n "$WINDOW_MS" ]; then
118
+ ENCODED_WINDOW=$(printf '%s' "$WINDOW_MS" | jq -sRr @uri)
119
+ QUERY="${QUERY}&recentlyResolvedWindowMs=${ENCODED_WINDOW}"
120
+ fi
121
+
122
+ api_call GET "/v3/agents/${ENCODED_SESSION}/active-work?${QUERY}"
@@ -50,6 +50,35 @@ Record a learning or insight gained during task execution. These learnings are s
50
50
  | `--learning` / `-l` | `learning` | Yes | The learning or insight (or pipe via stdin) |
51
51
  | `--learning-file` | — | No | Read learning from a file path |
52
52
 
53
+ ---
54
+
55
+ ## Mandated Format: Karpathy-lite (Entity-Centric)
56
+
57
+ To support future automated knowledge synthesis, all new learnings MUST follow the **Entity-Centric** format. This moves from "logging what happened" to "building a compounding wiki."
58
+
59
+ ### Formatting Rules:
60
+ 1. **Entity First**: Start with the primary entity (concept, file, function, or component) in brackets: `[[Entity Name]]`.
61
+ 2. **Concise**: 1-3 sentences maximum. No fluff.
62
+ 3. **Linked**: Reference related entities or components.
63
+ 4. **Sourced**: Reference the specific Task ID, PR, or Log line where this was learned.
64
+
65
+ ### Examples:
66
+
67
+ **✅ CORRECT (Entity-Centric):**
68
+ > `[[Fts5IndexService]] SQLite FTS5 rank is a negative double (more-negative = more-relevant). Invert to 100 - rank for score consistency. Learned during PR #320.`
69
+
70
+ **✅ CORRECT (Component Relationship):**
71
+ > `[[LearningReferenceModule]] injects memory usage instructions via PromptAssemblyService. Related to [[record-learning]] skill. Ref: backend/src/services/ai/prompt-modules/index.ts.`
72
+
73
+ **❌ INCORRECT (Log-style):**
74
+ > `I fixed a bug today in the FTS5 service where the ranking was inverted. It took me 2 hours because I didn't know SQLite's sign convention.`
75
+
76
+ ### Why this format
77
+
78
+ The `LearningReferenceModule` (prompt-layer) and the LEARN-1 auto-record subscriber both join learnings on entity references. Free-form prose breaks that join. The `[[Entity]]` bracket convention also matches the cross-doc linking pattern used elsewhere in the project (mirrors Obsidian/Roam-style backlinks for future synthesis tooling).
79
+
80
+ ---
81
+
53
82
  ## Examples — CLI Flags (preferred)
54
83
 
55
84
  ```bash
@@ -0,0 +1,41 @@
1
+ # reply-channel
2
+
3
+ Send an agent-authored message back to a chat channel. Used by the chat MVP
4
+ dispatch loop: when an agent receives a `[CHAT:<channelId>] ...` prompt from
5
+ the user, it processes the request, then calls this skill to publish its
6
+ reply into the same channel.
7
+
8
+ ## When to invoke
9
+
10
+ After you receive a message that begins with `[CHAT:<channelId>]` from the
11
+ dispatch runtime. The reply must be written to the same channel so the
12
+ user's chat UI sees it.
13
+
14
+ ## Invocation
15
+
16
+ ```bash
17
+ bash config/skills/agent/core/reply-channel/execute.sh \
18
+ --channel <channelId> \
19
+ --content "your reply text" \
20
+ [--cmid <clientMessageId>]
21
+ ```
22
+
23
+ Or with JSON:
24
+
25
+ ```bash
26
+ bash config/skills/agent/core/reply-channel/execute.sh \
27
+ '{"channelId":"chan-1","content":"hello back","clientMessageId":"cmid-abc"}'
28
+ ```
29
+
30
+ ## Environment
31
+
32
+ - `CREWLY_SESSION_NAME` — your agent session id. Auto-set in agent sessions.
33
+ The skill attaches it as `X-Agent-Session` so the backend routes the
34
+ reply as `senderType:"agent"`.
35
+ - `CREWLY_API_URL` — defaults to `http://localhost:8787`.
36
+
37
+ ## Success / failure
38
+
39
+ On success prints `{"success":true, "messageId":"..."}` to stdout.
40
+ On failure prints `{"success":false, "error":"..."}` to stdout and exits
41
+ with a non-zero code.
@@ -0,0 +1,165 @@
1
+ #!/bin/bash
2
+ # reply-channel — post an agent-authored reply to a chat channel.
3
+ # Used by the Chat MVP dispatch loop: the runtime hands the agent a prompt
4
+ # prefixed `[CHAT:<channelId>]`; the agent processes it, then invokes this
5
+ # skill to write its reply back to the channel.
6
+ #
7
+ # The shared `api_call` helper attaches `X-Agent-Session: $CREWLY_SESSION_NAME`
8
+ # automatically, which the chat-v2 controller uses to route the message as
9
+ # `senderType:"agent"` instead of `user`.
10
+ set -euo pipefail
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ source "${SCRIPT_DIR}/../../_common/lib.sh"
13
+
14
+ print_usage() {
15
+ cat <<'EOF_USAGE'
16
+ Usage:
17
+ # CLI flags (preferred)
18
+ bash execute.sh --channel <channelId> --content "reply text" [--cmid <clientMessageId>]
19
+
20
+ # Content from stdin
21
+ echo "multi-line reply" | bash execute.sh --channel chan-1
22
+
23
+ # JSON
24
+ bash execute.sh '{"channelId":"chan-1","content":"hi","clientMessageId":"cmid-abc"}'
25
+
26
+ Options:
27
+ --channel | -c Target channel id (required)
28
+ --content | -m Reply text (required unless piped via stdin)
29
+ --content-file Read reply text from a file path
30
+ --cmid Optional client-message-id for idempotency
31
+ --json | -j Raw JSON payload
32
+ --help | -h Show this help
33
+ EOF_USAGE
34
+ }
35
+
36
+ INPUT_JSON=""
37
+ CHANNEL_ID=""
38
+ CONTENT=""
39
+ CMID=""
40
+
41
+ # Detect legacy JSON argument as $1
42
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
43
+ INPUT_JSON="$1"
44
+ shift || true
45
+ fi
46
+
47
+ while [[ $# -gt 0 ]]; do
48
+ case "$1" in
49
+ --channel|-c)
50
+ CHANNEL_ID="$2"
51
+ shift 2
52
+ ;;
53
+ --content|-m)
54
+ CONTENT="$2"
55
+ shift 2
56
+ ;;
57
+ --content-file)
58
+ CONTENT="$(cat "$2")"
59
+ shift 2
60
+ ;;
61
+ --cmid)
62
+ CMID="$2"
63
+ shift 2
64
+ ;;
65
+ --json|-j)
66
+ INPUT_JSON="$2"
67
+ shift 2
68
+ ;;
69
+ --help|-h)
70
+ print_usage
71
+ exit 0
72
+ ;;
73
+ *)
74
+ echo "Unknown argument: $1" >&2
75
+ print_usage >&2
76
+ exit 2
77
+ ;;
78
+ esac
79
+ done
80
+
81
+ # Fall back to stdin when --content and legacy JSON are both missing
82
+ if [ -z "$CONTENT" ] && [ -z "$INPUT_JSON" ] && [ ! -t 0 ]; then
83
+ CONTENT="$(cat)"
84
+ fi
85
+
86
+ # When given JSON, extract fields via python (portable — awk/sed + json is fragile)
87
+ if [ -n "$INPUT_JSON" ]; then
88
+ if command -v python3 >/dev/null 2>&1; then
89
+ EXTRACTED=$(python3 - <<PY
90
+ import json, sys
91
+ try:
92
+ d = json.loads('''$INPUT_JSON''')
93
+ except Exception as e:
94
+ print('PARSE_ERROR:' + str(e))
95
+ sys.exit(0)
96
+ print('CHANNEL=' + str(d.get('channelId', '')))
97
+ print('CMID=' + str(d.get('clientMessageId', '')))
98
+ # content is multi-line safe — use base64
99
+ import base64
100
+ c = d.get('content', '')
101
+ print('CONTENT_B64=' + base64.b64encode(c.encode('utf-8')).decode('ascii'))
102
+ PY
103
+ )
104
+ if echo "$EXTRACTED" | grep -q '^PARSE_ERROR'; then
105
+ echo '{"success":false,"error":"invalid JSON payload"}' >&2
106
+ exit 2
107
+ fi
108
+ while IFS= read -r line; do
109
+ case "$line" in
110
+ CHANNEL=*) [ -z "$CHANNEL_ID" ] && CHANNEL_ID="${line#CHANNEL=}";;
111
+ CMID=*) [ -z "$CMID" ] && CMID="${line#CMID=}";;
112
+ CONTENT_B64=*) [ -z "$CONTENT" ] && CONTENT="$(echo "${line#CONTENT_B64=}" | base64 -d 2>/dev/null)";;
113
+ esac
114
+ done <<< "$EXTRACTED"
115
+ else
116
+ echo '{"success":false,"error":"python3 required to parse JSON payload"}' >&2
117
+ exit 2
118
+ fi
119
+ fi
120
+
121
+ if [ -z "$CHANNEL_ID" ]; then
122
+ echo '{"success":false,"error":"--channel is required"}' >&2
123
+ exit 2
124
+ fi
125
+
126
+ if [ -z "$CONTENT" ]; then
127
+ echo '{"success":false,"error":"--content is required (or pipe via stdin)"}' >&2
128
+ exit 2
129
+ fi
130
+
131
+ # Build JSON body. Export CONTENT/CMID so python can read them safely without
132
+ # quoting the values through the shell (avoids escaping hell for multi-line
133
+ # content with quotes, backslashes, backticks, etc.).
134
+ BODY=$(CONTENT="$CONTENT" CMID="$CMID" python3 -c '
135
+ import os, json
136
+ p = {"content": os.environ["CONTENT"], "contentType": "markdown"}
137
+ cmid = os.environ.get("CMID", "")
138
+ if cmid:
139
+ p["clientMessageId"] = cmid
140
+ print(json.dumps(p))
141
+ ')
142
+
143
+ ENDPOINT="/chat/channels/${CHANNEL_ID}/messages"
144
+
145
+ if RESPONSE=$(api_call POST "$ENDPOINT" "$BODY" 2>&1); then
146
+ # Successful 2xx — surface the message id
147
+ MESSAGE_ID=$(echo "$RESPONSE" | python3 -c '
148
+ import json,sys
149
+ try:
150
+ d=json.load(sys.stdin)
151
+ print((d.get("data") or {}).get("id",""))
152
+ except Exception:
153
+ pass
154
+ ' 2>/dev/null || echo "")
155
+ if [ -n "$MESSAGE_ID" ]; then
156
+ echo "{\"success\":true,\"messageId\":\"$MESSAGE_ID\",\"channelId\":\"$CHANNEL_ID\"}"
157
+ else
158
+ # Success code but unexpected body — still return success with raw response
159
+ echo "{\"success\":true,\"channelId\":\"$CHANNEL_ID\",\"raw\":$(echo "$RESPONSE" | python3 -c 'import json,sys;print(json.dumps(sys.stdin.read()))')}"
160
+ fi
161
+ exit 0
162
+ else
163
+ echo "{\"success\":false,\"error\":$(echo "$RESPONSE" | python3 -c 'import json,sys;print(json.dumps(sys.stdin.read()))')}"
164
+ exit 1
165
+ fi
@@ -0,0 +1,148 @@
1
+ #!/bin/bash
2
+ # Co-located bash test for reply-channel skill.
3
+ # Runs a tiny python HTTP stub to capture the outgoing request, then
4
+ # asserts both the URL and the JSON body match the documented contract.
5
+ #
6
+ # Usage: bash execute.test.sh (exit 0 on pass)
7
+ set -euo pipefail
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ SKILL="${SCRIPT_DIR}/execute.sh"
10
+
11
+ if [ ! -x "$SKILL" ]; then
12
+ echo "FAIL: skill not executable at $SKILL" >&2
13
+ exit 1
14
+ fi
15
+
16
+ PASS=0
17
+ FAIL=0
18
+ PORT=18787
19
+
20
+ # --- Start stub backend on a fixed test port ---
21
+ # Env MUST be exported BEFORE the python fork so the child inherits.
22
+ STUB_LOG="$(mktemp)"
23
+ export STUB_LOG
24
+ export STUB_PORT="${PORT}"
25
+
26
+ python3 -u <<'PY' >/tmp/reply-channel-stub.log 2>&1 &
27
+ from http.server import BaseHTTPRequestHandler, HTTPServer
28
+ import json, os, sys
29
+
30
+ LOG_PATH = os.environ['STUB_LOG']
31
+ PORT = int(os.environ['STUB_PORT'])
32
+
33
+ class H(BaseHTTPRequestHandler):
34
+ def do_POST(self):
35
+ length = int(self.headers.get('content-length', '0'))
36
+ body = self.rfile.read(length).decode('utf-8') if length else ''
37
+ log = {
38
+ 'path': self.path,
39
+ 'body': body,
40
+ 'agentSession': self.headers.get('x-agent-session', ''),
41
+ 'contentType': self.headers.get('content-type', ''),
42
+ }
43
+ with open(LOG_PATH, 'w') as f:
44
+ f.write(json.dumps(log))
45
+ self.send_response(201)
46
+ self.send_header('Content-Type', 'application/json')
47
+ self.end_headers()
48
+ self.wfile.write(json.dumps({'success': True, 'data': {'id': 'm-stub-123', 'channelId': 'chan-xyz'}}).encode('utf-8'))
49
+ def log_message(self, *a, **k):
50
+ pass
51
+
52
+ srv = HTTPServer(('127.0.0.1', PORT), H)
53
+ srv.serve_forever()
54
+ PY
55
+ STUB_PID=$!
56
+
57
+ cleanup() { kill "$STUB_PID" >/dev/null 2>&1 || true; rm -f "$STUB_LOG" || true; }
58
+ trap cleanup EXIT
59
+
60
+ # Wait until the port actually accepts a connection (up to ~3s). This is
61
+ # more reliable than a fixed sleep on slower boxes.
62
+ for i in $(seq 1 30); do
63
+ if curl -s -o /dev/null -m 0.2 "http://127.0.0.1:${PORT}/__probe__" 2>/dev/null; then
64
+ break
65
+ fi
66
+ sleep 0.1
67
+ done
68
+
69
+ assert_contains() {
70
+ local name="$1" haystack="$2" needle="$3"
71
+ if echo "$haystack" | grep -q -- "$needle"; then
72
+ PASS=$((PASS + 1))
73
+ echo " ✓ $name"
74
+ else
75
+ FAIL=$((FAIL + 1))
76
+ echo " ✗ $name (wanted: $needle)"
77
+ echo " in: $haystack"
78
+ fi
79
+ }
80
+
81
+ run_skill() {
82
+ CREWLY_API_URL="http://127.0.0.1:${PORT}" \
83
+ CREWLY_SESSION_NAME="crewly-product-sam-TEST" \
84
+ bash "$SKILL" "$@"
85
+ }
86
+
87
+ # --- Test 1: flag form, single-line content ---
88
+ echo "test 1: --channel + --content"
89
+ : > "$STUB_LOG"
90
+ OUT=$(run_skill --channel chan-xyz --content "hello from agent" 2>&1 || true)
91
+ LOG=$(cat "$STUB_LOG" 2>/dev/null || echo '{}')
92
+ assert_contains "success echoed" "$OUT" '"success":true'
93
+ assert_contains "messageId echoed" "$OUT" 'm-stub-123'
94
+ assert_contains "path targets /api/chat/channels/:id/messages" "$LOG" '/api/chat/channels/chan-xyz/messages'
95
+ assert_contains "body carries content" "$LOG" 'hello from agent'
96
+ assert_contains "body contentType markdown" "$LOG" 'markdown'
97
+ assert_contains "X-Agent-Session header present" "$LOG" 'crewly-product-sam-TEST'
98
+
99
+ # --- Test 2: JSON argument form ---
100
+ echo "test 2: JSON payload"
101
+ : > "$STUB_LOG"
102
+ OUT=$(run_skill '{"channelId":"chan-xyz","content":"via json","clientMessageId":"cmid-123"}' 2>&1 || true)
103
+ LOG=$(cat "$STUB_LOG" 2>/dev/null || echo '{}')
104
+ assert_contains "success echoed (json form)" "$OUT" '"success":true'
105
+ assert_contains "body has content (json form)" "$LOG" 'via json'
106
+ assert_contains "body includes clientMessageId" "$LOG" 'cmid-123'
107
+
108
+ # --- Test 3: multiline content via stdin ---
109
+ echo "test 3: stdin pipe"
110
+ : > "$STUB_LOG"
111
+ OUT=$(printf 'line one\nline two\n' | run_skill --channel chan-xyz 2>&1 || true)
112
+ LOG=$(cat "$STUB_LOG" 2>/dev/null || echo '{}')
113
+ assert_contains "success echoed (stdin form)" "$OUT" '"success":true'
114
+ assert_contains "body contains line one" "$LOG" 'line one'
115
+ assert_contains "body contains line two" "$LOG" 'line two'
116
+
117
+ # --- Test 4: missing --channel errors out ---
118
+ echo "test 4: missing channel"
119
+ if OUT=$(run_skill --content "no channel" 2>&1); then
120
+ FAIL=$((FAIL + 1))
121
+ echo " ✗ expected non-zero exit when --channel missing"
122
+ else
123
+ PASS=$((PASS + 1))
124
+ echo " ✓ non-zero exit when --channel missing"
125
+ fi
126
+ assert_contains "error surfaces" "$OUT" '--channel is required'
127
+
128
+ # --- Test 5: missing content errors out ---
129
+ echo "test 5: missing content"
130
+ if OUT=$(run_skill --channel chan-xyz 2>&1 </dev/null); then
131
+ FAIL=$((FAIL + 1))
132
+ echo " ✗ expected non-zero exit when --content missing"
133
+ else
134
+ PASS=$((PASS + 1))
135
+ echo " ✓ non-zero exit when --content missing"
136
+ fi
137
+ assert_contains "content-required error surfaces" "$OUT" '--content is required'
138
+
139
+ echo
140
+ echo "========================================"
141
+ echo "reply-channel skill: PASS=$PASS FAIL=$FAIL"
142
+ echo "========================================"
143
+ if [ "$FAIL" -gt 0 ]; then
144
+ echo "--- stub server log ---"
145
+ cat /tmp/reply-channel-stub.log 2>/dev/null | tail -40
146
+ exit 1
147
+ fi
148
+ exit 0