crewly 1.6.1 → 1.6.2

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 (363) 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/sops/developer/git-workflow.md +38 -3
  15. package/dist/backend/backend/src/constants.d.ts +69 -1
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +69 -2
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts +53 -0
  20. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -0
  21. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +92 -0
  22. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -0
  23. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
  24. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +18 -1
  25. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +68 -0
  27. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  28. package/dist/backend/backend/src/controllers/browser/browser.controller.js +233 -5
  29. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  30. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  31. package/dist/backend/backend/src/controllers/browser/browser.routes.js +10 -1
  32. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  33. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  34. package/dist/backend/backend/src/controllers/chat/chat.controller.js +8 -3
  35. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  36. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +132 -0
  37. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -0
  38. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +401 -0
  39. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -0
  40. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +29 -0
  41. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -0
  42. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +39 -0
  43. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -0
  44. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts +8 -0
  45. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts.map +1 -0
  46. package/dist/backend/backend/src/controllers/chat-v2/index.js +8 -0
  47. package/dist/backend/backend/src/controllers/chat-v2/index.js.map +1 -0
  48. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +13 -13
  49. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
  50. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +74 -234
  51. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
  52. package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
  53. package/dist/backend/backend/src/controllers/request/request.controller.js +4 -6
  54. package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
  55. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts +43 -0
  56. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
  57. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +200 -72
  58. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
  59. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  60. package/dist/backend/backend/src/controllers/team/team.controller.js +46 -0
  61. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  62. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts +59 -0
  63. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts.map +1 -0
  64. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js +127 -0
  65. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js.map +1 -0
  66. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts +13 -0
  67. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts.map +1 -0
  68. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js +20 -0
  69. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js.map +1 -0
  70. package/dist/backend/backend/src/index.d.ts +9 -0
  71. package/dist/backend/backend/src/index.d.ts.map +1 -1
  72. package/dist/backend/backend/src/index.js +233 -0
  73. package/dist/backend/backend/src/index.js.map +1 -1
  74. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  75. package/dist/backend/backend/src/routes/api.routes.js +40 -6
  76. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  77. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +498 -0
  78. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  79. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +759 -0
  80. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  81. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +25 -0
  82. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/agent/agent-registration.service.js +193 -57
  84. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  85. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +9 -2
  86. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +35 -2
  88. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  89. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +8 -2
  90. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +1 -0
  92. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  93. package/dist/backend/backend/src/services/agent/tmux-command.service.d.ts.map +1 -1
  94. package/dist/backend/backend/src/services/agent/tmux-command.service.js +2 -1
  95. package/dist/backend/backend/src/services/agent/tmux-command.service.js.map +1 -1
  96. package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
  98. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  99. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +148 -3
  100. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +241 -2
  102. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -1
  104. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +13 -0
  105. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -1
  106. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +26 -1
  108. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
  109. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  110. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  111. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  112. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  113. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +161 -0
  114. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  115. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +382 -2
  116. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  117. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +105 -0
  118. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +232 -13
  120. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  121. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +178 -0
  122. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
  123. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +254 -0
  124. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
  125. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
  126. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
  127. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
  128. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
  129. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts +25 -0
  130. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts.map +1 -0
  131. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js +23 -0
  132. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js.map +1 -0
  133. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +254 -0
  134. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  135. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +467 -0
  136. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  137. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  138. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  140. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  141. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts +43 -0
  142. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts.map +1 -0
  143. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js +54 -0
  144. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js.map +1 -0
  145. package/dist/backend/backend/src/services/chat-v2/config.d.ts +100 -0
  146. package/dist/backend/backend/src/services/chat-v2/config.d.ts.map +1 -0
  147. package/dist/backend/backend/src/services/chat-v2/config.js +174 -0
  148. package/dist/backend/backend/src/services/chat-v2/config.js.map +1 -0
  149. package/dist/backend/backend/src/services/chat-v2/index.d.ts +11 -0
  150. package/dist/backend/backend/src/services/chat-v2/index.d.ts.map +1 -0
  151. package/dist/backend/backend/src/services/chat-v2/index.js +12 -0
  152. package/dist/backend/backend/src/services/chat-v2/index.js.map +1 -0
  153. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +114 -0
  154. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  155. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +194 -0
  156. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  157. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +100 -0
  158. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  159. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +351 -0
  160. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  161. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +132 -0
  162. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  163. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +281 -0
  164. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  165. package/dist/backend/backend/src/services/chat-v2/types.d.ts +295 -0
  166. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -0
  167. package/dist/backend/backend/src/services/chat-v2/types.js +61 -0
  168. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -0
  169. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +113 -0
  170. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +1 -0
  171. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +179 -0
  172. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +1 -0
  173. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +131 -0
  174. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +1 -0
  175. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +227 -0
  176. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +1 -0
  177. package/dist/backend/backend/src/services/core/config.service.js +3 -3
  178. package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
  179. package/dist/backend/backend/src/services/core/storage.service.d.ts +7 -0
  180. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  181. package/dist/backend/backend/src/services/core/storage.service.js +15 -0
  182. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  183. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +69 -1
  184. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  185. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +118 -0
  186. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  187. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +275 -0
  188. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -0
  189. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +736 -0
  190. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -0
  191. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  192. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -2
  193. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  194. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  195. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  196. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  197. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  198. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
  199. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
  200. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js +304 -0
  201. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
  202. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  203. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +24 -4
  204. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  205. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +174 -0
  206. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -0
  207. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +375 -0
  208. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -0
  209. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +97 -0
  210. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +1 -0
  211. package/dist/backend/backend/src/services/memory/learning-format.validator.js +209 -0
  212. package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +1 -0
  213. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
  214. package/dist/backend/backend/src/services/memory/vector-store.service.js +19 -4
  215. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
  216. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts +16 -5
  217. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts.map +1 -1
  218. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js +32 -5
  219. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js.map +1 -1
  220. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +157 -0
  221. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -0
  222. package/dist/backend/backend/src/services/onboarding/onboarding.service.js +229 -0
  223. package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -0
  224. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +141 -0
  225. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -0
  226. package/dist/backend/backend/src/services/onboarding/onboarding.types.js +18 -0
  227. package/dist/backend/backend/src/services/onboarding/onboarding.types.js.map +1 -0
  228. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -1
  229. package/dist/backend/backend/src/services/pr-review/pr-review.service.js +1 -1
  230. package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -1
  231. package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
  232. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +17 -1
  233. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
  234. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +39 -1
  235. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +158 -26
  237. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  238. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +248 -6
  239. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +531 -51
  241. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  242. package/dist/backend/backend/src/services/team-health/index.d.ts +16 -0
  243. package/dist/backend/backend/src/services/team-health/index.d.ts.map +1 -0
  244. package/dist/backend/backend/src/services/team-health/index.js +16 -0
  245. package/dist/backend/backend/src/services/team-health/index.js.map +1 -0
  246. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts +52 -0
  247. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -0
  248. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +161 -0
  249. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -0
  250. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts +53 -0
  251. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts.map +1 -0
  252. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js +88 -0
  253. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js.map +1 -0
  254. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts +44 -0
  255. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts.map +1 -0
  256. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js +83 -0
  257. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js.map +1 -0
  258. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts +92 -0
  259. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts.map +1 -0
  260. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js +328 -0
  261. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js.map +1 -0
  262. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts +41 -0
  263. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts.map +1 -0
  264. package/dist/backend/backend/src/services/team-health/team-health-config.js +213 -0
  265. package/dist/backend/backend/src/services/team-health/team-health-config.js.map +1 -0
  266. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts +46 -0
  267. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts.map +1 -0
  268. package/dist/backend/backend/src/services/team-health/team-health-detector.js +347 -0
  269. package/dist/backend/backend/src/services/team-health/team-health-detector.js.map +1 -0
  270. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts +154 -0
  271. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts.map +1 -0
  272. package/dist/backend/backend/src/services/team-health/team-health-types.js +94 -0
  273. package/dist/backend/backend/src/services/team-health/team-health-types.js.map +1 -0
  274. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts +111 -0
  275. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts.map +1 -0
  276. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js +226 -0
  277. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js.map +1 -0
  278. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +148 -0
  279. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -0
  280. package/dist/backend/backend/src/services/v3/mission-reminder.service.js +545 -0
  281. package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -0
  282. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +499 -0
  283. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  284. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +1105 -0
  285. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  286. package/dist/backend/backend/src/services/v3/request.service.d.ts +22 -0
  287. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  288. package/dist/backend/backend/src/services/v3/request.service.js +71 -0
  289. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  290. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +1 -0
  291. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  292. package/dist/backend/backend/src/services/v3/v3-data.service.js +22 -6
  293. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  294. package/dist/backend/backend/src/types/event-bus.types.d.ts +19 -1
  295. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  296. package/dist/backend/backend/src/types/event-bus.types.js +43 -0
  297. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  298. package/dist/backend/backend/src/types/index.d.ts +22 -1
  299. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  300. package/dist/backend/backend/src/types/index.js.map +1 -1
  301. package/dist/backend/backend/src/types/review-reason.types.d.ts +63 -0
  302. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -0
  303. package/dist/backend/backend/src/types/review-reason.types.js +50 -0
  304. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -0
  305. package/dist/backend/backend/src/types/slack.types.d.ts +4 -1
  306. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  307. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  308. package/dist/backend/backend/src/types/v2/mission.types.d.ts +18 -0
  309. package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
  310. package/dist/backend/backend/src/types/v2/mission.types.js +1 -0
  311. package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
  312. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  313. package/dist/backend/backend/src/types/v2/work-item.types.js +25 -1
  314. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  315. package/dist/backend/backend/src/utils/team.utils.d.ts +38 -0
  316. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -0
  317. package/dist/backend/backend/src/utils/team.utils.js +45 -0
  318. package/dist/backend/backend/src/utils/team.utils.js.map +1 -0
  319. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +195 -0
  320. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -0
  321. package/dist/backend/backend/src/websocket/chat-v2.gateway.js +401 -0
  322. package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -0
  323. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +37 -2
  324. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  325. package/dist/backend/backend/src/websocket/terminal.gateway.js +106 -5
  326. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  327. package/dist/cli/backend/src/constants.d.ts +69 -1
  328. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  329. package/dist/cli/backend/src/constants.js +69 -2
  330. package/dist/cli/backend/src/constants.js.map +1 -1
  331. package/dist/cli/backend/src/services/core/config.service.js +3 -3
  332. package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
  333. package/dist/cli/backend/src/services/core/storage.service.d.ts +7 -0
  334. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  335. package/dist/cli/backend/src/services/core/storage.service.js +15 -0
  336. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  337. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  338. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -2
  339. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  340. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  341. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  342. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  343. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  344. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  345. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +24 -4
  346. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  347. package/dist/cli/backend/src/types/index.d.ts +22 -1
  348. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  349. package/dist/cli/backend/src/types/index.js.map +1 -1
  350. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  351. package/dist/cli/backend/src/types/v2/work-item.types.js +25 -1
  352. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  353. package/frontend/dist/assets/{index-70356616.js → index-7a4e7df5.js} +328 -326
  354. package/frontend/dist/assets/index-b7e59b2b.css +33 -0
  355. package/frontend/dist/index.html +2 -2
  356. package/package.json +2 -1
  357. package/config/skills/orchestrator/recall/SKILL.md +0 -47
  358. package/config/skills/orchestrator/recall/execute.sh +0 -13
  359. package/config/skills/orchestrator/record-learning/SKILL.md +0 -47
  360. package/config/skills/orchestrator/record-learning/execute.sh +0 -13
  361. package/config/skills/orchestrator/remember/SKILL.md +0 -55
  362. package/config/skills/orchestrator/remember/execute.sh +0 -15
  363. package/frontend/dist/assets/index-6aaa0630.css +0 -33
@@ -5,6 +5,22 @@
5
5
  # Sends commands to the backend /api/browser/* HTTP endpoints, which
6
6
  # forward them to the Chrome Extension over WebSocket.
7
7
  #
8
+ # Per-tab dispatch (§3.2 of the per-tab-fix spec):
9
+ # When `CREWLY_SESSION_NAME` is set in the agent's environment,
10
+ # `_common/lib.sh::api_call` automatically forwards it as the
11
+ # `X-Agent-Session` header. Backend uses this to dispatch each
12
+ # command to the agent's bound Chrome tab instead of the user's
13
+ # currently-active tab.
14
+ #
15
+ # The first command from a fresh agent triggers backend auto-bind
16
+ # (creates a new background tab). The skill caches the resulting
17
+ # tabId in `~/.crewly/runtime/<agentSession>/browser-tab-id` so
18
+ # subsequent calls skip the auto-bind round-trip.
19
+ #
20
+ # Backward compat: when `CREWLY_SESSION_NAME` is unset OR the
21
+ # `--no-bind` flag is given, behavior reverts to the legacy
22
+ # active-tab path (existing scripts work unchanged).
23
+ #
8
24
  # Usage:
9
25
  # bash execute.sh '{"action":"navigate","url":"https://example.com"}'
10
26
  # bash execute.sh '{"action":"screenshot"}'
@@ -12,6 +28,21 @@
12
28
  # bash execute.sh '{"action":"status"}'
13
29
  # bash execute.sh --action navigate --url https://example.com
14
30
  #
31
+ # Per-tab actions:
32
+ # bind-tab — Explicitly bind a tab for this agent.
33
+ # Returns { tabId }. Caches tabId locally.
34
+ # Optional flag: --active (foreground new tab; default off)
35
+ # unbind-tab — Release this agent's bound tab and (by
36
+ # default) close it.
37
+ #
38
+ # Per-tab flags (apply to any action):
39
+ # --tab-id <number> Pin the call to a specific tabId. Skips
40
+ # binding lookup. Used for tests + debugging.
41
+ # --no-bind Force the legacy active-tab path for this
42
+ # call (drops the X-Agent-Session header).
43
+ # --active Only meaningful with `bind-tab`: foreground
44
+ # the new tab on creation.
45
+ #
15
46
  # Supported actions and their parameters:
16
47
  # status — connection status (no params)
17
48
  # navigate — { url: string }
@@ -34,7 +65,11 @@
34
65
  # get-interactive-elements — { textContains?: string }
35
66
  # search-text — { text: string, exact?: boolean }
36
67
  # list-options — { selector: string }
68
+ # select-option — { selector: string, value?: string, label?: string,
69
+ # index?: number, strategy?: "native" | "aria" }
37
70
  # set-file-input — { selector: string, filePaths: string[] }
71
+ # bind-tab — bind a fresh tab for this agent
72
+ # unbind-tab — release this agent's bound tab
38
73
 
39
74
  set -euo pipefail
40
75
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -48,6 +83,9 @@ VALUE=""
48
83
  TEXT=""
49
84
  CODE=""
50
85
  EXTRA_PARAMS=""
86
+ TAB_ID="" # --tab-id <N>: explicit override
87
+ NO_BIND="false" # --no-bind: drop X-Agent-Session for this call
88
+ FOREGROUND="false" # --active: only meaningful with bind-tab
51
89
 
52
90
  # Detect legacy JSON argument
53
91
  if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
@@ -89,6 +127,18 @@ while [[ $# -gt 0 ]]; do
89
127
  INPUT_JSON="$2"
90
128
  shift 2
91
129
  ;;
130
+ --tab-id)
131
+ TAB_ID="$2"
132
+ shift 2
133
+ ;;
134
+ --no-bind)
135
+ NO_BIND="true"
136
+ shift
137
+ ;;
138
+ --active)
139
+ FOREGROUND="true"
140
+ shift
141
+ ;;
92
142
  --help|-h)
93
143
  echo "Usage: execute.sh --action navigate --url https://example.com"
94
144
  echo " execute.sh '{\"action\":\"screenshot\"}'"
@@ -97,7 +147,7 @@ while [[ $# -gt 0 ]]; do
97
147
  echo " scroll, hover, press-key, get-element, wait-for-selector,"
98
148
  echo " execute-js, tabs, cookies, console, local-storage,"
99
149
  echo " get-interactive-elements, search-text, full-page-screenshot,"
100
- echo " list-options, set-file-input"
150
+ echo " list-options, select-option, set-file-input"
101
151
  exit 0
102
152
  ;;
103
153
  --)
@@ -134,14 +184,124 @@ if [ -n "$INPUT_JSON" ]; then
134
184
  [ -z "$VALUE" ] && VALUE=$(printf '%s' "$INPUT" | jq -r '.value // empty')
135
185
  [ -z "$TEXT" ] && TEXT=$(printf '%s' "$INPUT" | jq -r '.text // empty')
136
186
  [ -z "$CODE" ] && CODE=$(printf '%s' "$INPUT" | jq -r '.code // empty')
137
- # Capture all extra fields from JSON input as pass-through params
187
+ # Per-tab dispatch fields surfaced in JSON input. CLI flags win over JSON
188
+ # (CLI is more explicit). Empty string = "not provided".
189
+ if [ -z "$TAB_ID" ]; then
190
+ TAB_ID=$(printf '%s' "$INPUT" | jq -r '.tabId // empty')
191
+ fi
192
+ if [ "$NO_BIND" = "false" ]; then
193
+ json_no_bind=$(printf '%s' "$INPUT" | jq -r '.noBind // empty')
194
+ [ "$json_no_bind" = "true" ] && NO_BIND="true"
195
+ fi
196
+ if [ "$FOREGROUND" = "false" ]; then
197
+ json_active=$(printf '%s' "$INPUT" | jq -r '.active // empty')
198
+ [ "$json_active" = "true" ] && FOREGROUND="true"
199
+ fi
200
+ # Capture all extra fields from JSON input as pass-through params (strip
201
+ # per-tab fields too — they're handled by the dedicated branches below).
138
202
  if [ -z "$EXTRA_PARAMS" ]; then
139
- EXTRA_PARAMS=$(printf '%s' "$INPUT" | jq -c 'del(.action, .url, .selector, .value, .text, .code) | if length == 0 then empty else . end' 2>/dev/null || true)
203
+ EXTRA_PARAMS=$(printf '%s' "$INPUT" | jq -c 'del(.action, .url, .selector, .value, .text, .code, .tabId, .noBind, .active) | if length == 0 then empty else . end' 2>/dev/null || true)
140
204
  fi
141
205
  fi
142
206
 
143
207
  require_param "action (--action)" "$ACTION"
144
208
 
209
+ # ---- Per-tab dispatch helpers (§3.2) ----
210
+ #
211
+ # Cache file lives under each agent's runtime dir so concurrent agents on
212
+ # the same machine don't stomp each other:
213
+ # ~/.crewly/runtime/<agentSession>/browser-tab-id
214
+ #
215
+ # Override-able via $CREWLY_RUNTIME_DIR for test harnesses.
216
+ _tab_cache_path() {
217
+ local agent_session="${1:-}"
218
+ [ -z "$agent_session" ] && return 1
219
+ local runtime_dir="${CREWLY_RUNTIME_DIR:-${HOME}/.crewly/runtime}"
220
+ printf '%s/%s/browser-tab-id' "$runtime_dir" "$agent_session"
221
+ }
222
+
223
+ _load_cached_tab() {
224
+ local cache_path
225
+ cache_path=$(_tab_cache_path "${CREWLY_SESSION_NAME:-}") || return 1
226
+ [ -f "$cache_path" ] || return 1
227
+ local cached
228
+ cached=$(cat "$cache_path" 2>/dev/null | tr -d '[:space:]')
229
+ # Reject non-numeric / empty caches as a defensive measure.
230
+ if [[ "$cached" =~ ^[0-9]+$ ]]; then
231
+ printf '%s' "$cached"
232
+ return 0
233
+ fi
234
+ return 1
235
+ }
236
+
237
+ _store_cached_tab() {
238
+ local tab_id="$1"
239
+ local cache_path
240
+ cache_path=$(_tab_cache_path "${CREWLY_SESSION_NAME:-}") || return 1
241
+ mkdir -p "$(dirname "$cache_path")" 2>/dev/null || true
242
+ printf '%s' "$tab_id" > "$cache_path"
243
+ }
244
+
245
+ _purge_cached_tab() {
246
+ local cache_path
247
+ cache_path=$(_tab_cache_path "${CREWLY_SESSION_NAME:-}") || return 0
248
+ rm -f "$cache_path" 2>/dev/null || true
249
+ }
250
+
251
+ # Returns the JSON body to send: $1 if non-empty, otherwise the canonical
252
+ # empty-object literal `{}`. This replaces the `${EXTRA_PARAMS:-{}}` pattern,
253
+ # which is mis-parsed by bash: the closing `}` of the parameter expansion is
254
+ # the FIRST `}` it sees, so `${EXTRA_PARAMS:-{}}` becomes `${EXTRA_PARAMS:-{}`
255
+ # (default = the literal `{`) followed by a stray literal `}`. The bug only
256
+ # surfaces when EXTRA_PARAMS is set — then the body is `<value>}` with a
257
+ # trailing extra `}` that fails JSON parse server-side, triggering 400 errors
258
+ # on scroll / press-key / local-storage / get-interactive-elements / set-file-input
259
+ # / scroll-in-element / execute-js fallback. When EXTRA_PARAMS is empty, the
260
+ # bug masks itself by accident (the `{` default + stray `}` happen to spell
261
+ # `{}`).
262
+ #
263
+ # @stdout the JSON body string (no trailing newline)
264
+ # @example BODY=$(_body_or_empty "$EXTRA_PARAMS")
265
+ _body_or_empty() {
266
+ local v="${1:-}"
267
+ if [ -n "$v" ]; then
268
+ printf '%s' "$v"
269
+ else
270
+ printf '%s' '{}'
271
+ fi
272
+ }
273
+
274
+ # Inject `tabId` into a JSON body if we have one, leaving an explicit override
275
+ # alone. Reads BODY as input, sets BODY to the augmented version. Always emits
276
+ # compact (single-line) JSON via `jq -c` so downstream consumers and test
277
+ # assertions see a stable wire shape.
278
+ _augment_body_with_tab_id() {
279
+ local tab_id="$1"
280
+ if [ -z "$tab_id" ]; then return 0; fi
281
+ if [ -z "$BODY" ] || [ "$BODY" = "{}" ]; then
282
+ BODY=$(jq -n -c --argjson t "$tab_id" '{tabId: $t}')
283
+ else
284
+ BODY=$(printf '%s' "$BODY" | jq -c --argjson t "$tab_id" '. + {tabId: $t}')
285
+ fi
286
+ }
287
+
288
+ # Effective tabId for this call: explicit --tab-id wins; otherwise look up
289
+ # the local cache when CREWLY_SESSION_NAME is set and --no-bind is NOT in
290
+ # effect. Empty string when nothing is determined.
291
+ _effective_tab_id() {
292
+ if [ -n "$TAB_ID" ]; then
293
+ printf '%s' "$TAB_ID"
294
+ return 0
295
+ fi
296
+ if [ "$NO_BIND" = "true" ]; then
297
+ return 0
298
+ fi
299
+ if [ -z "${CREWLY_SESSION_NAME:-}" ]; then
300
+ return 0
301
+ fi
302
+ _load_cached_tab || true
303
+ }
304
+
145
305
  # ---- Map action to HTTP method + endpoint + body ----
146
306
 
147
307
  METHOD="POST"
@@ -198,11 +358,11 @@ case "$ACTION" in
198
358
  ;;
199
359
  scroll)
200
360
  ENDPOINT="/browser/scroll"
201
- BODY="${EXTRA_PARAMS:-{}}"
361
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
202
362
  ;;
203
363
  scroll-in-element)
204
364
  ENDPOINT="/browser/scroll-in-element"
205
- BODY="${EXTRA_PARAMS:-{}}"
365
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
206
366
  ;;
207
367
  hover)
208
368
  require_param "selector (--selector)" "$SELECTOR"
@@ -211,7 +371,7 @@ case "$ACTION" in
211
371
  ;;
212
372
  press-key)
213
373
  ENDPOINT="/browser/press-key"
214
- BODY="${EXTRA_PARAMS:-{}}"
374
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
215
375
  ;;
216
376
  get-element)
217
377
  require_param "selector (--selector)" "$SELECTOR"
@@ -228,7 +388,7 @@ case "$ACTION" in
228
388
  if [ -n "$CODE" ]; then
229
389
  BODY=$(jq -n --arg c "$CODE" '{code: $c}')
230
390
  else
231
- BODY="${EXTRA_PARAMS:-{}}"
391
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
232
392
  fi
233
393
  ;;
234
394
  tabs)
@@ -245,11 +405,11 @@ case "$ACTION" in
245
405
  ;;
246
406
  local-storage)
247
407
  ENDPOINT="/browser/local-storage"
248
- BODY="${EXTRA_PARAMS:-{}}"
408
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
249
409
  ;;
250
410
  get-interactive-elements)
251
411
  ENDPOINT="/browser/get-interactive-elements"
252
- BODY="${EXTRA_PARAMS:-{}}"
412
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
253
413
  ;;
254
414
  search-text)
255
415
  require_param "text (--text)" "$TEXT"
@@ -261,9 +421,28 @@ case "$ACTION" in
261
421
  ENDPOINT="/browser/list-options"
262
422
  BODY=$(jq -n --arg s "$SELECTOR" '{selector: $s}')
263
423
  ;;
424
+ select-option)
425
+ # Select an option in a native <select> by value / label / index.
426
+ # Resolution priority: value > label > index. The selector itself is
427
+ # always required. When --params is supplied we accept it as the
428
+ # canonical body source (lets agents pass {label,...} or {index,...}
429
+ # without dedicated CLI flags); otherwise we project --selector +
430
+ # --value into the body.
431
+ require_param "selector (--selector)" "$SELECTOR"
432
+ ENDPOINT="/browser/select-option"
433
+ if [ -n "$EXTRA_PARAMS" ]; then
434
+ # Merge --selector into the supplied params so callers don't have
435
+ # to duplicate it. `jq` overwrites EXTRA_PARAMS.selector if absent.
436
+ BODY=$(printf '%s' "$EXTRA_PARAMS" | jq -c --arg s "$SELECTOR" '. + {selector: ($s)}')
437
+ elif [ -n "$VALUE" ]; then
438
+ BODY=$(jq -n -c --arg s "$SELECTOR" --arg v "$VALUE" '{selector: $s, value: $v}')
439
+ else
440
+ error_exit "select-option requires --value (or --params with value/label/index)"
441
+ fi
442
+ ;;
264
443
  set-file-input)
265
444
  ENDPOINT="/browser/set-file-input"
266
- BODY="${EXTRA_PARAMS:-{}}"
445
+ BODY=$(_body_or_empty "$EXTRA_PARAMS")
267
446
  ;;
268
447
  proxy-connect)
269
448
  ENDPOINT="/browser/proxy/connect"
@@ -273,15 +452,118 @@ case "$ACTION" in
273
452
  METHOD="GET"
274
453
  ENDPOINT="/browser/instances"
275
454
  ;;
455
+ bind-tab)
456
+ ENDPOINT="/browser/bind"
457
+ if [ "$FOREGROUND" = "true" ]; then
458
+ BODY=$(jq -n -c '{active: true}')
459
+ else
460
+ BODY="{}"
461
+ fi
462
+ ;;
463
+ unbind-tab)
464
+ ENDPOINT="/browser/unbind"
465
+ BODY="{}"
466
+ ;;
276
467
  *)
277
468
  error_exit "Unknown action: $ACTION. Run with --help for supported actions."
278
469
  ;;
279
470
  esac
280
471
 
281
- # ---- Execute the API call ----
472
+ # ---- Per-tab dispatch: tabId injection + cache handling -----------------
473
+ #
474
+ # For data-plane actions (everything other than bind/unbind/status/instances),
475
+ # fold a tabId into the request body when we know one. The backend treats
476
+ # `tabId` in the body as an explicit override and skips its own binding
477
+ # lookup, so this also covers the cached-tabId fast path.
478
+ case "$ACTION" in
479
+ status|instances|tabs|bind-tab|unbind-tab)
480
+ : # control-plane / read-only — leave BODY alone
481
+ ;;
482
+ *)
483
+ EFFECTIVE_TAB_ID=$(_effective_tab_id || true)
484
+ if [ -n "$EFFECTIVE_TAB_ID" ]; then
485
+ _augment_body_with_tab_id "$EFFECTIVE_TAB_ID"
486
+ fi
487
+ ;;
488
+ esac
489
+
490
+ # ---- Execute the API call ------------------------------------------------
491
+ #
492
+ # `--no-bind` short-circuits backend per-tab routing by stripping the
493
+ # X-Agent-Session header for this single call (api_call reads it from the
494
+ # env). Using a subshell to scope the unset.
495
+
496
+ run_api_call() {
497
+ if [ "$METHOD" = "GET" ]; then
498
+ api_call GET "$ENDPOINT"
499
+ else
500
+ api_call POST "$ENDPOINT" "$BODY"
501
+ fi
502
+ }
282
503
 
283
- if [ "$METHOD" = "GET" ]; then
284
- api_call GET "$ENDPOINT"
504
+ if [ "$NO_BIND" = "true" ]; then
505
+ ( unset CREWLY_SESSION_NAME; run_api_call )
506
+ RESPONSE_EXIT=$?
285
507
  else
286
- api_call POST "$ENDPOINT" "$BODY"
508
+ set +e
509
+ RESPONSE=$(run_api_call 2>/tmp/remote-browser-stderr-$$)
510
+ RESPONSE_EXIT=$?
511
+ set -e
512
+ STDERR_CAPTURE=""
513
+ [ -f /tmp/remote-browser-stderr-$$ ] && STDERR_CAPTURE=$(cat /tmp/remote-browser-stderr-$$)
514
+ rm -f /tmp/remote-browser-stderr-$$ 2>/dev/null || true
515
+ fi
516
+
517
+ # When NO_BIND was true, the call already streamed to stdout/stderr — exit
518
+ # carrying its status. Otherwise, post-process: cache management on
519
+ # bind/unbind, plus a single 404 retry for stale cached tabIds.
520
+ if [ "$NO_BIND" = "true" ]; then
521
+ exit "$RESPONSE_EXIT"
522
+ fi
523
+
524
+ # 404 with `tab_not_found` indicates our cached tabId is stale (Extension
525
+ # closed the tab while we weren't looking). Purge cache and retry the call
526
+ # WITHOUT a cached tabId so the backend auto-binds a fresh one.
527
+ if [ "$RESPONSE_EXIT" -ne 0 ] \
528
+ && [ -n "$STDERR_CAPTURE" ] \
529
+ && printf '%s' "$STDERR_CAPTURE" | grep -q '"status":404' \
530
+ && printf '%s' "$STDERR_CAPTURE" | grep -q 'tab_not_found' \
531
+ && [ -n "${CREWLY_SESSION_NAME:-}" ]; then
532
+ _purge_cached_tab
533
+ # Drop tabId from BODY for the retry — fall through to backend auto-bind.
534
+ if [ -n "$BODY" ] && [ "$BODY" != "{}" ]; then
535
+ BODY=$(printf '%s' "$BODY" | jq -c 'del(.tabId)' 2>/dev/null || printf '%s' "$BODY")
536
+ fi
537
+ set +e
538
+ RESPONSE=$(run_api_call 2>/tmp/remote-browser-stderr-$$)
539
+ RESPONSE_EXIT=$?
540
+ set -e
541
+ STDERR_CAPTURE=""
542
+ [ -f /tmp/remote-browser-stderr-$$ ] && STDERR_CAPTURE=$(cat /tmp/remote-browser-stderr-$$)
543
+ rm -f /tmp/remote-browser-stderr-$$ 2>/dev/null || true
544
+ fi
545
+
546
+ # On a successful bind-tab, persist the new tabId. On unbind-tab, purge.
547
+ if [ "$RESPONSE_EXIT" -eq 0 ] && [ -n "${CREWLY_SESSION_NAME:-}" ]; then
548
+ case "$ACTION" in
549
+ bind-tab)
550
+ new_tab=$(printf '%s' "$RESPONSE" | jq -r '.data.tabId // empty' 2>/dev/null || true)
551
+ if [[ "$new_tab" =~ ^[0-9]+$ ]]; then
552
+ _store_cached_tab "$new_tab"
553
+ fi
554
+ ;;
555
+ unbind-tab)
556
+ _purge_cached_tab
557
+ ;;
558
+ esac
559
+ fi
560
+
561
+ # Re-emit captured streams so the caller sees the same shape api_call
562
+ # would have produced. stdout always goes through; stderr only on failure.
563
+ if [ -n "$RESPONSE" ]; then
564
+ printf '%s\n' "$RESPONSE"
565
+ fi
566
+ if [ "$RESPONSE_EXIT" -ne 0 ] && [ -n "$STDERR_CAPTURE" ]; then
567
+ printf '%s\n' "$STDERR_CAPTURE" >&2
287
568
  fi
569
+ exit "$RESPONSE_EXIT"