crewly 1.20.186 → 1.20.188

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 (321) hide show
  1. package/config/skills/agent/core/project-tickets/SKILL.md +3 -2
  2. package/config/skills/agent/core/project-tickets/execute.sh +4 -4
  3. package/config/skills/agent/core/project-tickets/execute.test.sh +2 -2
  4. package/config/skills/agent/core/remember/SKILL.md +1 -0
  5. package/config/skills/agent/core/remember/execute.sh +12 -0
  6. package/config/skills/agent/core/report-status/SKILL.md +7 -1
  7. package/config/skills/agent/core/report-status/execute.sh +41 -0
  8. package/config/skills/agent/core/slack-post/SKILL.md +1 -0
  9. package/config/skills/agent/core/slack-post/execute.sh +9 -2
  10. package/config/skills/team-leader/_common/lib.sh +45 -0
  11. package/config/skills/team-leader/start-agent/SKILL.md +6 -6
  12. package/config/skills/team-leader/start-agent/execute.sh +3 -12
  13. package/config/skills/team-leader/stop-agent/SKILL.md +6 -6
  14. package/config/skills/team-leader/stop-agent/execute.sh +3 -12
  15. package/dist/backend/backend/src/constants.d.ts +114 -2
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +114 -2
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  20. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +62 -0
  21. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  22. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +1 -1
  23. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
  24. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +5 -1
  25. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +1 -1
  27. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +1 -1
  28. package/dist/backend/backend/src/controllers/request/open-items.controller.js +1 -1
  29. package/dist/backend/backend/src/controllers/request/open-items.controller.js.map +1 -1
  30. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  31. package/dist/backend/backend/src/controllers/slack/slack.controller.js +4 -1
  32. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  33. package/dist/backend/backend/src/controllers/standing/standing.controller.d.ts +18 -1
  34. package/dist/backend/backend/src/controllers/standing/standing.controller.d.ts.map +1 -1
  35. package/dist/backend/backend/src/controllers/standing/standing.controller.js +77 -4
  36. package/dist/backend/backend/src/controllers/standing/standing.controller.js.map +1 -1
  37. package/dist/backend/backend/src/controllers/system/system.controller.d.ts +12 -0
  38. package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
  39. package/dist/backend/backend/src/controllers/system/system.controller.js +28 -3
  40. package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
  41. package/dist/backend/backend/src/controllers/system/usage.controller.d.ts +46 -0
  42. package/dist/backend/backend/src/controllers/system/usage.controller.d.ts.map +1 -0
  43. package/dist/backend/backend/src/controllers/system/usage.controller.js +181 -0
  44. package/dist/backend/backend/src/controllers/system/usage.controller.js.map +1 -0
  45. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +7 -0
  46. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  47. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +64 -1
  48. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  49. package/dist/backend/backend/src/index.d.ts +7 -0
  50. package/dist/backend/backend/src/index.d.ts.map +1 -1
  51. package/dist/backend/backend/src/index.js +115 -1
  52. package/dist/backend/backend/src/index.js.map +1 -1
  53. package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
  54. package/dist/backend/backend/src/routes/modules/system.routes.js +3 -0
  55. package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
  56. package/dist/backend/backend/src/scripts/open-items-stale-followups.d.ts +51 -0
  57. package/dist/backend/backend/src/scripts/open-items-stale-followups.d.ts.map +1 -0
  58. package/dist/backend/backend/src/scripts/open-items-stale-followups.js +142 -0
  59. package/dist/backend/backend/src/scripts/open-items-stale-followups.js.map +1 -0
  60. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  61. package/dist/backend/backend/src/services/agent/agent-registration.service.js +32 -1
  62. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  63. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +28 -0
  64. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  65. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +83 -2
  66. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  67. package/dist/backend/backend/src/services/memory/memory.service.d.ts +14 -2
  68. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/memory/memory.service.js +12 -1
  70. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  71. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts +18 -1
  72. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  73. package/dist/backend/backend/src/services/memory/project-memory.service.js +38 -1
  74. package/dist/backend/backend/src/services/memory/project-memory.service.js.map +1 -1
  75. package/dist/backend/backend/src/services/memory/standing-answers.service.d.ts +11 -0
  76. package/dist/backend/backend/src/services/memory/standing-answers.service.d.ts.map +1 -1
  77. package/dist/backend/backend/src/services/memory/standing-answers.service.js +40 -2
  78. package/dist/backend/backend/src/services/memory/standing-answers.service.js.map +1 -1
  79. package/dist/backend/backend/src/services/messaging/offline-agent-message.d.ts +70 -0
  80. package/dist/backend/backend/src/services/messaging/offline-agent-message.d.ts.map +1 -0
  81. package/dist/backend/backend/src/services/messaging/offline-agent-message.js +92 -0
  82. package/dist/backend/backend/src/services/messaging/offline-agent-message.js.map +1 -0
  83. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +7 -1
  84. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +16 -2
  86. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  87. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
  88. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +2 -0
  89. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
  90. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +9 -1
  92. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +41 -1
  94. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +87 -2
  96. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  97. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts +30 -12
  98. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  99. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +87 -15
  100. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  101. package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.d.ts +130 -0
  102. package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.d.ts.map +1 -0
  103. package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.js +274 -0
  104. package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.js.map +1 -0
  105. package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.d.ts +152 -0
  106. package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.d.ts.map +1 -0
  107. package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.js +311 -0
  108. package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.js.map +1 -0
  109. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +78 -1
  110. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  111. package/dist/backend/backend/src/services/monitoring/token-usage.service.js +96 -4
  112. package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  113. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts +10 -1
  114. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  115. package/dist/backend/backend/src/services/open-items/open-item-extractor.js +86 -5
  116. package/dist/backend/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  117. package/dist/backend/backend/src/services/open-items/open-items-backfill.d.ts +2 -1
  118. package/dist/backend/backend/src/services/open-items/open-items-backfill.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/open-items/open-items-backfill.js +17 -6
  120. package/dist/backend/backend/src/services/open-items/open-items-backfill.js.map +1 -1
  121. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +62 -1
  122. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  123. package/dist/backend/backend/src/services/open-items/open-items.service.js +203 -9
  124. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  125. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts +4 -4
  126. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -1
  127. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +1 -1
  128. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -1
  129. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +4 -3
  130. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -1
  131. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +7 -4
  132. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -1
  133. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +40 -9
  134. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
  135. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +68 -20
  136. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
  137. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.d.ts +40 -0
  138. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.js +82 -0
  140. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.js.map +1 -0
  141. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +29 -0
  142. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  143. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +49 -0
  144. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  145. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  146. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +6 -11
  147. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  148. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +23 -0
  149. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  150. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +55 -1
  151. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  152. package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts.map +1 -1
  153. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js +10 -4
  154. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js.map +1 -1
  155. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +13 -2
  156. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  157. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +19 -5
  158. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  159. package/dist/backend/backend/src/services/spend/spend-cap-command.d.ts +129 -0
  160. package/dist/backend/backend/src/services/spend/spend-cap-command.d.ts.map +1 -0
  161. package/dist/backend/backend/src/services/spend/spend-cap-command.js +323 -0
  162. package/dist/backend/backend/src/services/spend/spend-cap-command.js.map +1 -0
  163. package/dist/backend/backend/src/services/spend/spend-cap.gate.d.ts +60 -0
  164. package/dist/backend/backend/src/services/spend/spend-cap.gate.d.ts.map +1 -0
  165. package/dist/backend/backend/src/services/spend/spend-cap.gate.js +66 -0
  166. package/dist/backend/backend/src/services/spend/spend-cap.gate.js.map +1 -0
  167. package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts +340 -0
  168. package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts.map +1 -0
  169. package/dist/backend/backend/src/services/spend/spend-cap.service.js +760 -0
  170. package/dist/backend/backend/src/services/spend/spend-cap.service.js.map +1 -0
  171. package/dist/backend/backend/src/services/spend/spend-cap.store.d.ts +126 -0
  172. package/dist/backend/backend/src/services/spend/spend-cap.store.d.ts.map +1 -0
  173. package/dist/backend/backend/src/services/spend/spend-cap.store.js +141 -0
  174. package/dist/backend/backend/src/services/spend/spend-cap.store.js.map +1 -0
  175. package/dist/backend/backend/src/services/spend/spend-cap.wiring.d.ts +52 -0
  176. package/dist/backend/backend/src/services/spend/spend-cap.wiring.d.ts.map +1 -0
  177. package/dist/backend/backend/src/services/spend/spend-cap.wiring.js +112 -0
  178. package/dist/backend/backend/src/services/spend/spend-cap.wiring.js.map +1 -0
  179. package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts +145 -0
  180. package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts.map +1 -0
  181. package/dist/backend/backend/src/services/spend/spend-ledger.service.js +214 -0
  182. package/dist/backend/backend/src/services/spend/spend-ledger.service.js.map +1 -0
  183. package/dist/backend/backend/src/services/task-pool/claim-target-waker.d.ts +51 -0
  184. package/dist/backend/backend/src/services/task-pool/claim-target-waker.d.ts.map +1 -0
  185. package/dist/backend/backend/src/services/task-pool/claim-target-waker.js +43 -0
  186. package/dist/backend/backend/src/services/task-pool/claim-target-waker.js.map +1 -0
  187. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +38 -0
  188. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  189. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +73 -1
  190. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  191. package/dist/backend/backend/src/services/task-pool/work-item-usage.d.ts +53 -0
  192. package/dist/backend/backend/src/services/task-pool/work-item-usage.d.ts.map +1 -0
  193. package/dist/backend/backend/src/services/task-pool/work-item-usage.js +39 -0
  194. package/dist/backend/backend/src/services/task-pool/work-item-usage.js.map +1 -0
  195. package/dist/backend/backend/src/services/usage/token-format.d.ts +49 -0
  196. package/dist/backend/backend/src/services/usage/token-format.d.ts.map +1 -0
  197. package/dist/backend/backend/src/services/usage/token-format.js +81 -0
  198. package/dist/backend/backend/src/services/usage/token-format.js.map +1 -0
  199. package/dist/backend/backend/src/services/usage/usage-stats.service.d.ts +132 -0
  200. package/dist/backend/backend/src/services/usage/usage-stats.service.d.ts.map +1 -0
  201. package/dist/backend/backend/src/services/usage/usage-stats.service.js +226 -0
  202. package/dist/backend/backend/src/services/usage/usage-stats.service.js.map +1 -0
  203. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  204. package/dist/backend/backend/src/services/v3/v3-data.service.js +11 -14
  205. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  206. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +25 -0
  207. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  208. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +50 -0
  209. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  210. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +9 -1
  211. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  212. package/dist/backend/backend/src/services/workflow/scheduler.service.js +16 -2
  213. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  214. package/dist/backend/backend/src/types/decision.types.d.ts +3 -1
  215. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  216. package/dist/backend/backend/src/types/event-bus.types.d.ts +9 -1
  217. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  218. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  219. package/dist/backend/backend/src/types/review-reason.types.d.ts +3 -1
  220. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -1
  221. package/dist/backend/backend/src/types/review-reason.types.js +1 -0
  222. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -1
  223. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts +24 -7
  224. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  225. package/dist/backend/backend/src/types/ticket-autopilot.types.js +29 -13
  226. package/dist/backend/backend/src/types/ticket-autopilot.types.js.map +1 -1
  227. package/dist/backend/backend/src/types/v2/open-item.types.d.ts +5 -1
  228. package/dist/backend/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  229. package/dist/backend/backend/src/types/v2/open-item.types.js +1 -1
  230. package/dist/backend/backend/src/types/v2/open-item.types.js.map +1 -1
  231. package/dist/backend/build-info.json +2 -2
  232. package/dist/cli/backend/src/constants.d.ts +114 -2
  233. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  234. package/dist/cli/backend/src/constants.js +114 -2
  235. package/dist/cli/backend/src/constants.js.map +1 -1
  236. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  237. package/dist/cli/backend/src/services/agent/agent-registration.service.js +32 -1
  238. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  239. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts +28 -0
  240. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  241. package/dist/cli/backend/src/services/event-bus/event-bus.service.js +83 -2
  242. package/dist/cli/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  243. package/dist/cli/backend/src/services/memory/memory.service.d.ts +14 -2
  244. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  245. package/dist/cli/backend/src/services/memory/memory.service.js +12 -1
  246. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  247. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +18 -1
  248. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  249. package/dist/cli/backend/src/services/memory/project-memory.service.js +38 -1
  250. package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -1
  251. package/dist/cli/backend/src/services/memory/standing-answers.service.d.ts +11 -0
  252. package/dist/cli/backend/src/services/memory/standing-answers.service.d.ts.map +1 -1
  253. package/dist/cli/backend/src/services/memory/standing-answers.service.js +40 -2
  254. package/dist/cli/backend/src/services/memory/standing-answers.service.js.map +1 -1
  255. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +7 -1
  256. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  257. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +16 -2
  258. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  259. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  260. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +9 -1
  261. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  262. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +41 -1
  263. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  264. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +87 -2
  265. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  266. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts +30 -12
  267. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  268. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js +87 -15
  269. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  270. package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts +97 -0
  271. package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts.map +1 -0
  272. package/dist/cli/backend/src/services/monitoring/model-pricing.js +120 -0
  273. package/dist/cli/backend/src/services/monitoring/model-pricing.js.map +1 -0
  274. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +78 -1
  275. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  276. package/dist/cli/backend/src/services/monitoring/token-usage.service.js +96 -4
  277. package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  278. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts +10 -1
  279. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  280. package/dist/cli/backend/src/services/open-items/open-item-extractor.js +86 -5
  281. package/dist/cli/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  282. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +13 -2
  283. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  284. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +19 -5
  285. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  286. package/dist/cli/backend/src/services/spend/spend-cap.gate.d.ts +60 -0
  287. package/dist/cli/backend/src/services/spend/spend-cap.gate.d.ts.map +1 -0
  288. package/dist/cli/backend/src/services/spend/spend-cap.gate.js +66 -0
  289. package/dist/cli/backend/src/services/spend/spend-cap.gate.js.map +1 -0
  290. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +38 -0
  291. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  292. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +73 -1
  293. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  294. package/dist/cli/backend/src/services/task-pool/work-item-usage.d.ts +53 -0
  295. package/dist/cli/backend/src/services/task-pool/work-item-usage.d.ts.map +1 -0
  296. package/dist/cli/backend/src/services/task-pool/work-item-usage.js +39 -0
  297. package/dist/cli/backend/src/services/task-pool/work-item-usage.js.map +1 -0
  298. package/dist/cli/backend/src/services/usage/token-format.d.ts +49 -0
  299. package/dist/cli/backend/src/services/usage/token-format.d.ts.map +1 -0
  300. package/dist/cli/backend/src/services/usage/token-format.js +81 -0
  301. package/dist/cli/backend/src/services/usage/token-format.js.map +1 -0
  302. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  303. package/dist/cli/backend/src/services/v3/v3-data.service.js +11 -14
  304. package/dist/cli/backend/src/services/v3/v3-data.service.js.map +1 -1
  305. package/dist/cli/backend/src/types/decision.types.d.ts +3 -1
  306. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  307. package/dist/cli/backend/src/types/event-bus.types.d.ts +9 -1
  308. package/dist/cli/backend/src/types/event-bus.types.d.ts.map +1 -1
  309. package/dist/cli/backend/src/types/event-bus.types.js.map +1 -1
  310. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts +24 -7
  311. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  312. package/dist/cli/backend/src/types/ticket-autopilot.types.js +29 -13
  313. package/dist/cli/backend/src/types/ticket-autopilot.types.js.map +1 -1
  314. package/dist/cli/backend/src/types/v2/open-item.types.d.ts +5 -1
  315. package/dist/cli/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  316. package/dist/cli/backend/src/types/v2/open-item.types.js +1 -1
  317. package/dist/cli/backend/src/types/v2/open-item.types.js.map +1 -1
  318. package/frontend/dist/assets/{index-a79c7852.css → index-20a67829.css} +1 -1
  319. package/frontend/dist/assets/{index-1ee8a9a2.js → index-49f50b45.js} +282 -282
  320. package/frontend/dist/index.html +2 -2
  321. package/package.json +1 -1
@@ -177,14 +177,15 @@ answered.
177
177
  ```bash
178
178
  bash execute.sh autopilot --project P # show settings + status
179
179
  bash execute.sh autopilot --project P --on # switch on (the owner said so)
180
- bash execute.sh autopilot --project P --on --daily-budget 20 --max-in-flight 1
180
+ bash execute.sh autopilot --project P --on --daily-budget 20M --max-in-flight 1 # budget in tokens
181
181
  bash execute.sh autopilot --project P --driver <lead session> # or --driver default
182
182
  bash execute.sh autopilot --project P --off
183
183
  ```
184
184
 
185
185
  Off by default. While on, Crewly wakes the project's team lead to triage the
186
186
  backlog when someone on the team is idle (make tickets ready and assign them,
187
- split, ask the owner, or cancel), pauses for the day at the daily budget, and
187
+ split, ask the owner, or cancel), pauses for the day at the daily token budget
188
+ (input incl. cached + output; a usage boost on the team raises it for the day), and
188
189
  sends the owner the batched questions plus one evening digest. Only switch it
189
190
  on when the owner asked for it. Refused for anyone but the owner and the
190
191
  orchestrator.
@@ -22,7 +22,7 @@
22
22
  # (owner / orc / lead / assignee)
23
23
  # bash execute.sh ask-owner --project P --id APP-12 --clear [--note "answer"]
24
24
  # bash execute.sh autopilot --project P [--on|--off] [--driver <session>|--driver default]
25
- # [--daily-budget <usd>] [--max-in-flight <n>] (owner / orchestrator)
25
+ # [--daily-budget <tokens, e.g. 20M>] [--max-in-flight <n>] (owner / orchestrator)
26
26
  # bash execute.sh '{"action":"create","project":"P","title":"…"}'
27
27
  #
28
28
  # P = project id, name, or absolute path.
@@ -58,7 +58,7 @@ Usage:
58
58
  bash execute.sh ask-owner --project P --id APP-12 --clear [--note "answer"]
59
59
  The owner answered: remove the needs-owner mark
60
60
  bash execute.sh autopilot --project P [--on|--off] [--driver <session>|default]
61
- [--daily-budget <usd>] [--max-in-flight <n>]
61
+ [--daily-budget <tokens, e.g. 20M>] [--max-in-flight <n>]
62
62
  Owner / orchestrator: show or change the ticket
63
63
  autopilot (no flags = show)
64
64
 
@@ -102,7 +102,7 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
102
102
  SENSITIVE=$(printf '%s' "$J" | jq -r '.sensitive // empty')
103
103
  AP_ENABLED=$(printf '%s' "$J" | jq -r 'if (.enabled|type) == "boolean" then (.enabled|tostring) else empty end')
104
104
  AP_DRIVER=$(printf '%s' "$J" | jq -r '.driver // empty')
105
- AP_BUDGET=$(printf '%s' "$J" | jq -r '.dailyBudgetUsd // empty')
105
+ AP_BUDGET=$(printf '%s' "$J" | jq -r '.dailyBudgetTokens // empty')
106
106
  AP_MAX=$(printf '%s' "$J" | jq -r '.maxInFlightPerMember // empty')
107
107
  fi
108
108
  if [[ -z "$ACTION" && $# -gt 0 && ${1:0:1} != '-' ]]; then ACTION="$1"; shift; fi
@@ -257,7 +257,7 @@ case "$ACTION" in
257
257
  '{}
258
258
  + (if $enabled != "" then {enabled: ($enabled == "true")} else {} end)
259
259
  + (if $driver == "default" then {driver: null} elif $driver != "" then {driver: $driver} else {} end)
260
- + (if $budget == "default" then {dailyBudgetUsd: null} elif $budget != "" then {dailyBudgetUsd: ($budget | tonumber? // $budget)} else {} end)
260
+ + (if $budget == "default" then {dailyBudgetTokens: null} elif $budget != "" then {dailyBudgetTokens: ($budget | tonumber? // $budget)} else {} end)
261
261
  + (if $max == "default" then {maxInFlightPerMember: null} elif $max != "" then {maxInFlightPerMember: ($max | tonumber? // $max)} else {} end)')
262
262
  api_call POST "/project-ticket-autopilot/$(enc "$PROJECT")" "$BODY" | jq '{success, autopilot: .data}'
263
263
  fi
@@ -139,9 +139,9 @@ check "ask-owner: missing question" "$(run_err ask-owner --project p1 --id APP-1
139
139
  OUT=$(run autopilot --project p1)
140
140
  check "autopilot show: GET" "$(last '[.method, .path] | tostring')" '["GET","/api/project-ticket-autopilot/p1"]'
141
141
  check "autopilot show: output" "$(printf '%s' "$OUT" | jq -c '.autopilot.settings')" '{"enabled":false}'
142
- run autopilot --project p1 --on --daily-budget 12.5 --max-in-flight 2 >/dev/null
142
+ run autopilot --project p1 --on --daily-budget 12.5M --max-in-flight 2 >/dev/null
143
143
  check "autopilot on: POST" "$(last '[.method, .path] | tostring')" '["POST","/api/project-ticket-autopilot/p1"]'
144
- check "autopilot on: body" "$(last '.body | tostring')" '{"enabled":true,"dailyBudgetUsd":12.5,"maxInFlightPerMember":2}'
144
+ check "autopilot on: body" "$(last '.body | tostring')" '{"enabled":true,"dailyBudgetTokens":"12.5M","maxInFlightPerMember":2}'
145
145
  run autopilot --project p1 --off --driver default >/dev/null
146
146
  check "autopilot off: body" "$(last '.body | tostring')" '{"enabled":false,"driver":null}'
147
147
  run '{"action":"autopilot","project":"p1","enabled":true,"driver":"ce-owen"}' >/dev/null
@@ -49,6 +49,7 @@ Store a memory entry for future recall. Use this to persist important context, d
49
49
  | `--category` / `-C` | `category` | Yes | See category × scope matrix below |
50
50
  | `--scope` / `-s` | `scope` | Yes | Scope: `agent` or `project` |
51
51
  | `--project` / `-p` | `projectPath` | No | Project path (required for `project` scope) |
52
+ | `--supersedes` | `supersedes` | No | Decision id(s) this decision replaces, comma-separated (`dec:<id>`). When a decision changes an earlier one, always pass it: the old entry is marked superseded and leaves the standing answers. |
52
53
 
53
54
  ### Valid `category` × `scope` matrix
54
55
 
@@ -31,6 +31,8 @@ Options:
31
31
  'workflow' is NOT a public category — use 'pattern' instead.
32
32
  --scope | -s Scope: project or agent (required)
33
33
  --project | -p Project path (required for project scope)
34
+ --supersedes Decision id(s) this decision replaces, comma-separated
35
+ (e.g. "dec:03ce4dda"); they leave standing answers (#884)
34
36
  --json | -j Raw JSON payload
35
37
  --help | -h Show this help
36
38
  EOF_USAGE
@@ -42,6 +44,7 @@ CONTENT=""
42
44
  CATEGORY=""
43
45
  SCOPE=""
44
46
  PROJECT_PATH=""
47
+ SUPERSEDES=""
45
48
 
46
49
  # Detect legacy JSON argument
47
50
  if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
@@ -75,6 +78,10 @@ while [[ $# -gt 0 ]]; do
75
78
  PROJECT_PATH="$2"
76
79
  shift 2
77
80
  ;;
81
+ --supersedes)
82
+ SUPERSEDES="$2"
83
+ shift 2
84
+ ;;
78
85
  --json|-j)
79
86
  INPUT_JSON="$2"
80
87
  shift 2
@@ -116,6 +123,7 @@ if [ -n "$INPUT_JSON" ]; then
116
123
  [ -z "$CATEGORY" ] && CATEGORY=$(printf '%s' "$INPUT" | jq -r '.category // empty')
117
124
  [ -z "$SCOPE" ] && SCOPE=$(printf '%s' "$INPUT" | jq -r '.scope // empty')
118
125
  [ -z "$PROJECT_PATH" ] && PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
126
+ [ -z "$SUPERSEDES" ] && SUPERSEDES=$(printf '%s' "$INPUT" | jq -r '(.supersedes // .metadata.supersedes // empty) | if type == "array" then join(",") else . end')
119
127
  fi
120
128
 
121
129
  require_param "agentId (--agent)" "$AGENT_ID"
@@ -143,4 +151,8 @@ else
143
151
  fi
144
152
  unset _MEM_AGENT _MEM_CONTENT _MEM_CATEGORY _MEM_SCOPE
145
153
 
154
+ if [ -n "$SUPERSEDES" ]; then
155
+ BODY=$(printf '%s' "$BODY" | jq --arg s "$SUPERSEDES" '. + {metadata: {supersedes: ($s | split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0)))}}')
156
+ fi
157
+
146
158
  api_call POST "/memory/remember" "$BODY"
@@ -57,7 +57,7 @@ Pass the `workItemId` of the work you are reporting on (from your `[CREWLY-DISPA
57
57
  | `--task-id` | `taskId` | No | Task ID (for structured StatusReport format) |
58
58
  | `--progress` | `progress` | No | Progress percentage 0-100 |
59
59
  | `--structured` | `structured` | No | Use structured StatusReport format |
60
- | `--work-item-id` / `--wi-id` | `workItemId` | **Pass this when `status=done`** | Which WorkItem to complete. See below — without it the skill infers, and refuses when the choice is ambiguous |
60
+ | `--work-item-id` / `--wi-id` | `workItemId` | **Pass this when `status` is `done`, `blocked` or `failed`** | Which WorkItem to complete, block or fail. See below — without it the skill infers, and refuses when the choice is ambiguous |
61
61
 
62
62
  ## This skill COMPLETES a WorkItem, not just reports
63
63
 
@@ -84,6 +84,12 @@ had never happened.
84
84
  If the completion itself fails, the skill says so explicitly — a reported
85
85
  status never implies the WorkItem actually closed.
86
86
 
87
+ **`blocked` and `failed` move the WorkItem too**, with the same resolution
88
+ order: the item is marked `blocked` (claim released, it waits until someone
89
+ unblocks it) or `failed`, your summary is stored on it as the reason, and its
90
+ team lead is told. Pass `workItemId` here as well; with several items running
91
+ the skill refuses instead of guessing.
92
+
87
93
  ## Examples — CLI Flags (preferred)
88
94
 
89
95
  ```bash
@@ -311,6 +311,47 @@ if [ "$STATUS" = "done" ]; then
311
311
  fi
312
312
  fi
313
313
 
314
+ # A blocked or failed report moves the WorkItem too (#842). It used to reach
315
+ # only the orchestrator's chat: the WorkItem stayed `running` with its claim
316
+ # held, the team lead got no task:blocked / task:failed event, and the reason
317
+ # lived only in a chat message. Same resolution rules as `done` above:
318
+ # explicit workItemId, else the single running item, else refuse.
319
+ if [ "$STATUS" = "blocked" ] || [ "$STATUS" = "failed" ]; then
320
+ STOP_WI_ID="${WORK_ITEM_ID:-}"
321
+ STOP_RESOLUTION="explicit"
322
+
323
+ if [ -z "$STOP_WI_ID" ]; then
324
+ POOL_RESP=$(api_call_full GET "/task-pool/items?status=running&target=${SESSION_NAME}" 2>/dev/null || echo '{}')
325
+ RUNNING_IDS=$(printf '%s' "$POOL_RESP" | jq -r '((.workItems // .data // []) | map(.id)) | .[]' 2>/dev/null || true)
326
+ RUNNING_COUNT=$(printf '%s' "$RUNNING_IDS" | grep -c . || true)
327
+
328
+ if [ "$RUNNING_COUNT" -gt 1 ]; then
329
+ CANDIDATES=$(printf '%s' "$RUNNING_IDS" | tr '\n' ' ')
330
+ error_exit "Status reported, but report-status will not guess which WorkItem is ${STATUS}: ${RUNNING_COUNT} are running for ${SESSION_NAME} (${CANDIDATES}). Run it again with workItemId so the right item is marked ${STATUS} and its team lead is told."
331
+ fi
332
+
333
+ STOP_WI_ID=$(printf '%s' "$RUNNING_IDS" | head -1)
334
+ STOP_RESOLUTION="inferred"
335
+ fi
336
+
337
+ if [ -n "$STOP_WI_ID" ]; then
338
+ if [ "$STATUS" = "blocked" ]; then
339
+ STOP_BODY=$(jq -n --arg agentId "$SESSION_NAME" --arg reason "$SUMMARY" '{agentId: $agentId, reason: $reason}')
340
+ STOP_PATH="/task-pool/block/${STOP_WI_ID}"
341
+ else
342
+ STOP_BODY=$(jq -n --arg agentId "$SESSION_NAME" --arg error "$SUMMARY" '{agentId: $agentId, error: $error}')
343
+ STOP_PATH="/task-pool/fail/${STOP_WI_ID}"
344
+ fi
345
+ if STOP_RESULT=$(api_call POST "$STOP_PATH" "$STOP_BODY" 2>&1); then
346
+ jq -n --arg id "$STOP_WI_ID" --arg how "$STOP_RESOLUTION" --arg status "$STATUS" \
347
+ '{workItem: $id, markedAs: $status, resolvedBy: $how}' >&2
348
+ else
349
+ jq -n --arg id "$STOP_WI_ID" --arg err "$STOP_RESULT" --arg status "$STATUS" \
350
+ '{warning: ("status reported, but marking the WorkItem " + $status + " FAILED — it is still open"), workItemId: $id, error: $err}' >&2
351
+ fi
352
+ fi
353
+ fi
354
+
314
355
  # record_task_learning <label> <summary>
315
356
  #
316
357
  # Records the report as a project learning via POST /memory/record-learning.
@@ -111,6 +111,7 @@ two are told apart. Write ids exactly as Slack shows them.
111
111
  | `--text` | `-m` | Message text (required unless piped or `--text-file`) |
112
112
  | `--text-file` | | Read the text from a file |
113
113
  | `--thread` | `-t` | Slack thread timestamp to reply inside, or the `[SLACK-THREAD:<key>]` key from your prompt |
114
+ | `--new-topic` | | A new top-level message. Use it for scheduled output (a briefing, a triage summary): without it, a post into a conversation where you still owe an answer from the last 30 minutes goes into that thread as the answer |
114
115
  | `--json` | `-j` | Raw JSON payload |
115
116
 
116
117
  ## Environment
@@ -12,7 +12,7 @@ source "${SCRIPT_DIR}/../../_common/lib.sh"
12
12
  print_usage() {
13
13
  cat <<'EOF_USAGE'
14
14
  Usage:
15
- bash execute.sh --target <#channel|@user|C…|D…|U…> --text "message" [--thread <ts>]
15
+ bash execute.sh --target <#channel|@user|C…|D…|U…> --text "message" [--thread <ts> | --new-topic]
16
16
 
17
17
  echo "message" | bash execute.sh --target "#general"
18
18
  bash execute.sh --target "@steve" --text-file /tmp/report.md
@@ -23,6 +23,7 @@ Options:
23
23
  --text | -m Message text (required unless piped or --text-file)
24
24
  --text-file Read the message text from a file
25
25
  --thread | -t Slack thread timestamp to reply inside
26
+ --new-topic A new top-level post (scheduled output), never an answer to an open question
26
27
  --json | -j Raw JSON payload
27
28
  --help | -h Show this help
28
29
  EOF_USAGE
@@ -32,6 +33,7 @@ INPUT_JSON=""
32
33
  TARGET=""
33
34
  TEXT=""
34
35
  THREAD_TS=""
36
+ NEW_TOPIC=""
35
37
 
36
38
  # Legacy JSON as the first positional argument
37
39
  if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
@@ -45,6 +47,7 @@ while [[ $# -gt 0 ]]; do
45
47
  --text|-m) TEXT="$2"; shift 2 ;;
46
48
  --text-file) TEXT="$(cat "$2")"; shift 2 ;;
47
49
  --thread|-t) THREAD_TS="$2"; shift 2 ;;
50
+ --new-topic) NEW_TOPIC="1"; shift ;;
48
51
  --json|-j) INPUT_JSON="$2"; shift 2 ;;
49
52
  --help|-h) print_usage; exit 0 ;;
50
53
  *) echo "Unknown argument: $1" >&2; print_usage >&2; exit 2 ;;
@@ -65,6 +68,7 @@ except Exception as e:
65
68
  print("PARSE_ERROR:" + str(e)); sys.exit(0)
66
69
  print("TARGET=" + str(d.get("target", "")))
67
70
  print("THREAD=" + str(d.get("threadTs", d.get("thread", ""))))
71
+ print("NEW_TOPIC=" + ("1" if d.get("newTopLevel") is True else ""))
68
72
  print("TEXT_B64=" + base64.b64encode(str(d.get("text", "")).encode("utf-8")).decode("ascii"))
69
73
  ')
70
74
  if echo "$EXTRACTED" | grep -q '^PARSE_ERROR'; then
@@ -75,6 +79,7 @@ print("TEXT_B64=" + base64.b64encode(str(d.get("text", "")).encode("utf-8")).dec
75
79
  case "$line" in
76
80
  TARGET=*) [ -z "$TARGET" ] && TARGET="${line#TARGET=}" ;;
77
81
  THREAD=*) [ -z "$THREAD_TS" ] && THREAD_TS="${line#THREAD=}" ;;
82
+ NEW_TOPIC=*) [ -z "$NEW_TOPIC" ] && NEW_TOPIC="${line#NEW_TOPIC=}" ;;
78
83
  TEXT_B64=*) [ -z "$TEXT" ] && TEXT="$(echo "${line#TEXT_B64=}" | base64 -d 2>/dev/null)" ;;
79
84
  esac
80
85
  done <<< "$EXTRACTED"
@@ -96,12 +101,14 @@ fi
96
101
  # Convert literal \n to real newlines, matching the other comm skills
97
102
  _NL=$'\n'; TEXT="${TEXT//\\n/$_NL}"
98
103
 
99
- BODY=$(TARGET="$TARGET" TEXT="$TEXT" THREAD_TS="$THREAD_TS" python3 -c '
104
+ BODY=$(TARGET="$TARGET" TEXT="$TEXT" THREAD_TS="$THREAD_TS" NEW_TOPIC="$NEW_TOPIC" python3 -c '
100
105
  import json, os
101
106
  p = {"target": os.environ["TARGET"], "text": os.environ["TEXT"]}
102
107
  ts = os.environ.get("THREAD_TS", "")
103
108
  if ts:
104
109
  p["threadTs"] = ts
110
+ elif os.environ.get("NEW_TOPIC"):
111
+ p["newTopLevel"] = True
105
112
  print(json.dumps(p))
106
113
  ')
107
114
 
@@ -2,3 +2,48 @@
2
2
  # Team Leader Skills Common Library - delegates to shared library
3
3
  SHARED_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/_common"
4
4
  source "${SHARED_LIB_DIR}/lib.sh"
5
+
6
+ # tl_require_member_scope <team-json> <member-id> <tl-member-id>
7
+ #
8
+ # Exits with an error unless the team lead may start or stop the member.
9
+ # Allowed when:
10
+ # 1. the member reports to this lead (parentMemberId == tlMemberId), or
11
+ # 2. the member has no parent at all, and this lead is a leader of the same
12
+ # team (listed in leaderIds/leaderId, or canDelegate on its member record).
13
+ # Refused: members of another team (not in <team-json>), members whose parent
14
+ # is someone else, and any lead that does not lead this team.
15
+ #
16
+ # Rule 2 exists because many teams were created without a hierarchy: every
17
+ # Marketing member had parentMemberId=null, so the lead could not start a
18
+ # single one of its own members and the orchestrator had to (#930).
19
+ tl_require_member_scope() {
20
+ local team_json="$1" member_id="$2" tl_member_id="$3"
21
+ local verdict
22
+ verdict=$(printf '%s' "$team_json" | jq -r --arg mid "$member_id" --arg tl "$tl_member_id" '
23
+ (.data // .) as $team
24
+ | ($team.members // []) as $members
25
+ | ($members | map(select(.id == $mid)) | first) as $member
26
+ | ($members | map(select(.id == $tl)) | first) as $lead
27
+ | (($team.leaderIds // []) + (if $team.leaderId then [$team.leaderId] else [] end)) as $leaders
28
+ | if $member == null then "not_found"
29
+ elif ($member.parentMemberId // "") == $tl then "ok"
30
+ elif ($member.parentMemberId // "") != "" then "other_parent:" + $member.parentMemberId
31
+ elif $lead == null then "not_in_team"
32
+ elif (($leaders | index($tl)) != null) or ($lead.canDelegate == true) then "ok"
33
+ else "not_leader"
34
+ end' 2>/dev/null || echo "unreadable")
35
+
36
+ case "$verdict" in
37
+ ok) return 0 ;;
38
+ not_found)
39
+ error_exit "Member ${member_id} is not in this team. A team lead can only start or stop members of its own team." ;;
40
+ other_parent:*)
41
+ error_exit "Hierarchy violation: member ${member_id} (parentMemberId=${verdict#other_parent:}) reports to someone else, not to TL ${tl_member_id}" ;;
42
+ not_in_team)
43
+ error_exit "TL ${tl_member_id} is not a member of this team, so it cannot manage member ${member_id}" ;;
44
+ not_leader)
45
+ error_exit "Member ${member_id} has no parent, and TL ${tl_member_id} does not lead this team (not in leaderIds, canDelegate not set)" ;;
46
+ *)
47
+ error_exit "Could not read the team data to check whether TL ${tl_member_id} may manage member ${member_id}" ;;
48
+ esac
49
+ }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Start Agent (TL)
3
- description: "Start a worker agent within the Team Leader's subordinate scope. Validates that the target worker's parentMemberId matches the TL's memberId before starting."
3
+ description: "Start a worker agent within the Team Leader's scope: a member whose parentMemberId is the TL, or a parentless member of a team the TL leads."
4
4
  version: 1.0.0
5
5
  category: management
6
6
  skillType: claude-skill
@@ -50,18 +50,18 @@ bash {{TL_SKILLS_PATH}}/start-agent/execute.sh '{"teamId":"{{TEAM_ID}}","memberI
50
50
 
51
51
  ## Hierarchy Validation
52
52
 
53
- The script fetches team data and validates:
54
- - The target member exists in the team
55
- - The member's `parentMemberId` matches the TL's `memberId`
53
+ The script fetches team data and allows the start when:
54
+ - the member's `parentMemberId` is the TL's `memberId` (a subordinate), or
55
+ - the member has no `parentMemberId`, and the TL is a leader of the same team (listed in the team's `leaderIds`, or `canDelegate` on its own member record).
56
56
 
57
- If validation fails, the start is rejected with a hierarchy violation error. TLs can only start their own subordinates — not agents in other teams or under other TLs.
57
+ It refuses members of other teams, members whose parent is someone else, and parentless members of a team the TL does not lead.
58
58
 
59
59
  ## Differences from Orchestrator start-agent
60
60
 
61
61
  | Aspect | Orchestrator | Team Leader |
62
62
  |--------|-------------|-------------|
63
63
  | Scope | Any agent in any team | Only subordinates |
64
- | Hierarchy check | None | Validates parentMemberId |
64
+ | Hierarchy check | None | Subordinates, or parentless members of the TL's own team |
65
65
  | Extra parameter | None | `tlMemberId` required |
66
66
 
67
67
  ## Output
@@ -1,6 +1,6 @@
1
1
  #!/bin/bash
2
2
  # Start a worker agent within this Team Leader's subordinate scope.
3
- # Validates hierarchy (worker.parentMemberId == TL.memberId) before starting.
3
+ # Validates scope before starting.
4
4
  set -euo pipefail
5
5
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
6
  source "${SCRIPT_DIR}/../_common/lib.sh"
@@ -23,17 +23,8 @@ if [ "$TEAM_SUCCESS" != "true" ]; then
23
23
  error_exit "Failed to fetch team data for team ${TEAM_ID}"
24
24
  fi
25
25
 
26
- # Find the target member and check parentMemberId
27
- WORKER_PARENT=$(echo "$TEAM_DATA" | jq -r --arg mid "$MEMBER_ID" \
28
- '.data.members[] | select(.id == $mid) | .parentMemberId // empty' 2>/dev/null || true)
29
-
30
- if [ -z "$WORKER_PARENT" ]; then
31
- error_exit "Member ${MEMBER_ID} not found in team ${TEAM_ID} or has no parentMemberId set"
32
- fi
33
-
34
- if [ "$WORKER_PARENT" != "$TL_MEMBER_ID" ]; then
35
- error_exit "Hierarchy violation: member ${MEMBER_ID} (parentMemberId=${WORKER_PARENT}) is not a subordinate of TL ${TL_MEMBER_ID}"
36
- fi
26
+ # The member must report to this TL, or be parentless in a team this TL leads (#930)
27
+ tl_require_member_scope "$TEAM_DATA" "$MEMBER_ID" "$TL_MEMBER_ID"
37
28
 
38
29
  # Hierarchy validated — start the agent
39
30
  api_call POST "/teams/${TEAM_ID}/members/${MEMBER_ID}/start"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Stop Agent (TL)
3
- description: "Stop a worker agent within the Team Leader's subordinate scope. Validates that the target worker's parentMemberId matches the TL's memberId before stopping."
3
+ description: "Stop a worker agent within the Team Leader's scope: a member whose parentMemberId is the TL, or a parentless member of a team the TL leads."
4
4
  version: 1.0.0
5
5
  category: management
6
6
  skillType: claude-skill
@@ -50,18 +50,18 @@ bash {{TL_SKILLS_PATH}}/stop-agent/execute.sh '{"teamId":"{{TEAM_ID}}","memberId
50
50
 
51
51
  ## Hierarchy Validation
52
52
 
53
- The script fetches team data and validates:
54
- - The target member exists in the team
55
- - The member's `parentMemberId` matches the TL's `memberId`
53
+ The script fetches team data and allows the stop when:
54
+ - the member's `parentMemberId` is the TL's `memberId` (a subordinate), or
55
+ - the member has no `parentMemberId`, and the TL is a leader of the same team (listed in the team's `leaderIds`, or `canDelegate` on its own member record).
56
56
 
57
- If validation fails, the stop is rejected with a hierarchy violation error. TLs can only stop their own subordinates — not agents in other teams or under other TLs.
57
+ It refuses members of other teams, members whose parent is someone else, and parentless members of a team the TL does not lead.
58
58
 
59
59
  ## Differences from Orchestrator stop-agent
60
60
 
61
61
  | Aspect | Orchestrator | Team Leader |
62
62
  |--------|-------------|-------------|
63
63
  | Scope | Any agent in any team | Only subordinates |
64
- | Hierarchy check | None | Validates parentMemberId |
64
+ | Hierarchy check | None | Subordinates, or parentless members of the TL's own team |
65
65
  | Extra parameter | None | `tlMemberId` required |
66
66
 
67
67
  ## Output
@@ -1,6 +1,6 @@
1
1
  #!/bin/bash
2
2
  # Stop a worker agent within this Team Leader's subordinate scope.
3
- # Validates hierarchy (worker.parentMemberId == TL.memberId) before stopping.
3
+ # Validates scope before stopping.
4
4
  set -euo pipefail
5
5
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
6
  source "${SCRIPT_DIR}/../_common/lib.sh"
@@ -23,17 +23,8 @@ if [ "$TEAM_SUCCESS" != "true" ]; then
23
23
  error_exit "Failed to fetch team data for team ${TEAM_ID}"
24
24
  fi
25
25
 
26
- # Find the target member and check parentMemberId
27
- WORKER_PARENT=$(echo "$TEAM_DATA" | jq -r --arg mid "$MEMBER_ID" \
28
- '.data.members[] | select(.id == $mid) | .parentMemberId // empty' 2>/dev/null || true)
29
-
30
- if [ -z "$WORKER_PARENT" ]; then
31
- error_exit "Member ${MEMBER_ID} not found in team ${TEAM_ID} or has no parentMemberId set"
32
- fi
33
-
34
- if [ "$WORKER_PARENT" != "$TL_MEMBER_ID" ]; then
35
- error_exit "Hierarchy violation: member ${MEMBER_ID} (parentMemberId=${WORKER_PARENT}) is not a subordinate of TL ${TL_MEMBER_ID}"
36
- fi
26
+ # The member must report to this TL, or be parentless in a team this TL leads (#930)
27
+ tl_require_member_scope "$TEAM_DATA" "$MEMBER_ID" "$TL_MEMBER_ID"
37
28
 
38
29
  # Hierarchy validated — stop the agent
39
30
  api_call POST "/teams/${TEAM_ID}/members/${MEMBER_ID}/stop"
@@ -91,8 +91,8 @@ export declare const TICKET_AUTOPILOT_CONSTANTS: {
91
91
  readonly DIGEST_HOUR_LOCAL: 21;
92
92
  /** Max tickets named per digest section (the rest are counted) */
93
93
  readonly DIGEST_MAX_ITEMS_PER_SECTION: 8;
94
- /** Default daily budget (USD) of the project's team agents when the owner sets none */
95
- readonly DEFAULT_DAILY_BUDGET_USD: 20;
94
+ /** Default daily budget (tokens) of the project's team agents when the owner sets none */
95
+ readonly DEFAULT_DAILY_BUDGET_TOKENS: 20000000;
96
96
  /** Default and bounds of in-progress tickets per member */
97
97
  readonly DEFAULT_MAX_IN_FLIGHT_PER_MEMBER: 1;
98
98
  readonly MAX_IN_FLIGHT_PER_MEMBER_LIMIT: 5;
@@ -1205,6 +1205,9 @@ export declare const EVENT_BUS_CONSTANTS: {
1205
1205
  readonly EVENT_MESSAGE_PREFIX: "EVENT";
1206
1206
  /** Threshold for cleaning stale entries from recentPublishMap */
1207
1207
  readonly DEDUP_MAP_CLEANUP_THRESHOLD: 100;
1208
+ /** How long a delivered event id is remembered per subscription, so a
1209
+ * replayed publish of the same event is not delivered twice (#926) */
1210
+ readonly DELIVERED_EVENT_TTL_MS: number;
1208
1211
  };
1209
1212
  /**
1210
1213
  * Constants for Slack thread file storage.
@@ -1378,6 +1381,8 @@ export declare const STANDING_ANSWERS_CONSTANTS: {
1378
1381
  readonly BRIEF_MAX_ENTRIES: 30;
1379
1382
  /** Characters of each entry shown in a refresh brief. */
1380
1383
  readonly BRIEF_ENTRY_MAX_CHARS: 240;
1384
+ /** Shared topic words that flag two same-day entries as a possible supersede pair (#884). */
1385
+ readonly SUPERSEDE_MIN_SHARED_WORDS: 2;
1381
1386
  /** Refresh tick interval when CREWLY_WIKI_REFLECT_INTERVAL_MS is unset (the reflect default). */
1382
1387
  readonly REFRESH_INTERVAL_MS: number;
1383
1388
  /** Minimum time between two refresh WorkItems for the same page. */
@@ -1474,6 +1479,12 @@ export declare const SLACK_TYPING_CONSTANTS: {
1474
1479
  readonly TIMEOUT_MS: number;
1475
1480
  /** A timed-out placeholder is still removed by a reply arriving within this long (ms) */
1476
1481
  readonly EXPIRED_KEEP_MS: number;
1482
+ /**
1483
+ * A `slack-post` that names no thread answers an owed placeholder only if
1484
+ * that placeholder went up this recently. Older ones belong to questions
1485
+ * from another turn; a scheduled post was captured into those threads (#808).
1486
+ */
1487
+ readonly UNTHREADED_ANSWER_MAX_AGE_MS: number;
1477
1488
  /** A placeholder younger than this is not taken down when the turn ends (race with delivery) */
1478
1489
  readonly SETTLE_MIN_AGE_MS: number;
1479
1490
  /**
@@ -1825,6 +1836,8 @@ export declare const OWNER_MESSAGE_WATCHDOG_CONSTANTS: {
1825
1836
  readonly NOTE_SILENT_TEXT: "⏳ {name} got your message but hasn't replied in {waited} min; I've sent a reminder.";
1826
1837
  /** Shown in a note when a failed delivery left no error detail */
1827
1838
  readonly NOTE_UNKNOWN_DETAIL: "reason unknown";
1839
+ /** The agent hit a daily token cap (specs/2026-10-02-spend-cap.md) */
1840
+ readonly NOTE_SPEND_CAP_TEXT: "⏳ Still waiting on {name} — {name} hit its daily token cap ({cap}). Your message is kept and delivered when the cap resets at midnight or you boost it (reply `boost {who} by 10M today` or `unlimited today for {who}`).";
1828
1841
  };
1829
1842
  /**
1830
1843
  * The single `reply` entry point (specs/2026-09-30-owner-message-guarantee.md §B).
@@ -5118,6 +5131,8 @@ export declare const OPEN_ITEMS_CONSTANTS: {
5118
5131
  readonly DEFAULT_DUE_MS: number;
5119
5132
  /** The same words by the same agent this close together are one item (a reply recorded twice) (ms) */
5120
5133
  readonly DUPLICATE_WINDOW_MS: number;
5134
+ /** The same agent's two promises this close together, about the same deliverable, are one (the newer stands) (ms) */
5135
+ readonly PROMISE_DUPLICATE_WINDOW_MS: number;
5121
5136
  /** Max commitments and max questions taken from one reply */
5122
5137
  readonly MAX_ITEMS_PER_REPLY: 3;
5123
5138
  /** Max characters stored for an item's text */
@@ -5136,6 +5151,13 @@ export declare const OPEN_ITEMS_CONSTANTS: {
5136
5151
  readonly EXPIRE_AFTER_MS: number;
5137
5152
  /** Requests looked at by the sweep and the backfill: updated within (ms) */
5138
5153
  readonly LOOKBACK_MS: number;
5154
+ /** The backfill only looks at promises and questions made within this long before it runs (ms) */
5155
+ readonly BACKFILL_MAX_AGE_MS: number;
5156
+ /**
5157
+ * A post made up to this long before the child work's recorded finish still delivers it: a verify
5158
+ * pass overwrites `completedAt` after the agent has already posted (ms)
5159
+ */
5160
+ readonly DELIVERY_FINISH_GRACE_MS: number;
5139
5161
  /** Sweep cadence (ms) */
5140
5162
  readonly SWEEP_INTERVAL_MS: number;
5141
5163
  /** An ask-owner decision this close in time to the reply, by the same agent, is the same question (ms) */
@@ -5165,6 +5187,96 @@ export declare const WORK_ITEM_DESTINATION_CONSTANTS: {
5165
5187
  /** The one line every prompt carries about where to answer */
5166
5188
  readonly PROMPT_LINE: "Answer where you were asked; a new topic goes in a new thread.";
5167
5189
  };
5190
+ /**
5191
+ * Daily token caps with a hard stop, team caps and temporary boosts
5192
+ * (specs/2026-10-02-spend-cap.md). The unit is TOKENS, not dollars (owner,
5193
+ * 2026-10-02): total tokens = input (fresh + cached) + output — see
5194
+ * `eventTokens` in token-usage.service. Caps are OFF until the owner sets
5195
+ * one. All owner-facing text is English.
5196
+ */
5197
+ export declare const SPEND_CAP_CONSTANTS: {
5198
+ /** Caps + boosts + today's bookkeeping, under CREWLY_HOME (tokens) */
5199
+ readonly STORE_FILE: "usage-caps.json";
5200
+ /** The pre-token (USD) store; migrated once with USAGE_CONSTANTS.TOKENS_PER_USD */
5201
+ readonly LEGACY_USD_STORE_FILE: "spend-caps.json";
5202
+ /** Default / max window of GET /api/system/usage and /api/system/spend */
5203
+ readonly DEFAULT_DAYS: 7;
5204
+ readonly MAX_DAYS: 31;
5205
+ /** Fraction of a cap that sends the one heads-up */
5206
+ readonly WARN_FRACTION: 0.8;
5207
+ /** Enforcement tick */
5208
+ readonly TICK_MS: 60000;
5209
+ /** How long the all-agents total is cached for the delivery gate */
5210
+ readonly TOTAL_CACHE_MS: 15000;
5211
+ /** How often the orc's held message queue re-checks the cap */
5212
+ readonly QUEUE_RECHECK_MS: 60000;
5213
+ /** The "Boost +X today" card offers the cap times this (rounded to a whole million) */
5214
+ readonly BOOST_FACTOR: 1;
5215
+ /** Target key of the all-agents total cap / an everyone boost */
5216
+ readonly TOTAL_TARGET: "*";
5217
+ /** Prefix of a team target (`team:<teamId>`) */
5218
+ readonly TEAM_TARGET_PREFIX: "team:";
5219
+ /** Error code of a refused wake */
5220
+ readonly ERROR_CODE: "SPEND_CAP_REACHED";
5221
+ /** Queued-delivery marker in sendMessageToAgent results */
5222
+ readonly QUEUED_MARKER: "[SPEND_CAP]";
5223
+ /** Decision kind of the "cap reached" card */
5224
+ readonly DECISION_KIND: "spend_cap";
5225
+ readonly OPTIONS: {
5226
+ readonly KEEP: "Keep stopped";
5227
+ readonly UNLIMITED: "Unlimited today";
5228
+ };
5229
+ };
5230
+ /**
5231
+ * Token usage: the unit, the stats endpoint, and the Codex / Antigravity
5232
+ * ledgers (specs/2026-10-02-spend-cap.md).
5233
+ */
5234
+ export declare const USAGE_CONSTANTS: {
5235
+ /**
5236
+ * Tokens per US dollar, used ONCE to convert settings written in USD
5237
+ * (the ticket autopilot's `dailyBudgetUsd`, pre-token spend caps) to
5238
+ * tokens; each conversion is logged. A round migration default, not a
5239
+ * price: the owner's Mac blended ~0.66M tokens per API-equivalent $ in the
5240
+ * 7 days to 2026-10-01 (Opus 0.51M/$, Sonnet 2–3M/$, DeepSeek ~11M/$;
5241
+ * cache reads are >99% of the tokens), so a converted budget is within
5242
+ * 1.5× of what the dollar figure bought.
5243
+ */
5244
+ readonly TOKENS_PER_USD: 1000000;
5245
+ /** groupBy values of GET /api/system/usage */
5246
+ readonly GROUP_BY: readonly string[];
5247
+ /** Rows returned for groupBy=workItem (highest first) */
5248
+ readonly MAX_WORK_ITEM_ROWS: 50;
5249
+ /** Label of usage no team / project / work item can be attributed to */
5250
+ readonly UNATTRIBUTED: "(unattributed)";
5251
+ };
5252
+ /** Codex rollout usage sync (`~/.codex/sessions/**\/rollout-*.jsonl`). */
5253
+ export declare const CODEX_USAGE_SYNC_CONSTANTS: {
5254
+ /** Poll interval (ms) */
5255
+ readonly SYNC_INTERVAL_MS: 60000;
5256
+ /** Cursor file under CREWLY_HOME */
5257
+ readonly CURSOR_FILE: "codex-rollout-cursors.json";
5258
+ /** Model recorded when a rollout names none */
5259
+ readonly DEFAULT_MODEL: "codex-cli-default";
5260
+ /** Directory entries visited when looking a rollout up by id */
5261
+ readonly MAX_SCAN_ENTRIES: 20000;
5262
+ };
5263
+ /** Antigravity (`agy`) usage sync — best effort, see the spec. */
5264
+ export declare const ANTIGRAVITY_USAGE_SYNC_CONSTANTS: {
5265
+ /** Poll interval (ms) */
5266
+ readonly SYNC_INTERVAL_MS: 60000;
5267
+ /** Cursor file under CREWLY_HOME */
5268
+ readonly CURSOR_FILE: "antigravity-usage-cursors.json";
5269
+ /** Model recorded (agy stores its model as an enum, not a name) */
5270
+ readonly MODEL: "antigravity-cli-default";
5271
+ /**
5272
+ * Protobuf path of the usage message in a `steps.metadata` blob (field 9),
5273
+ * and its input / output token fields. Undocumented — read from agy 1.x
5274
+ * conversation databases; a blob without them is skipped, never guessed.
5275
+ */
5276
+ readonly USAGE_FIELD: 9;
5277
+ readonly INPUT_FIELD: 2;
5278
+ readonly OUTPUT_FIELD: 3;
5279
+ };
5168
5280
  /**
5169
5281
  * Runtime fallback: switch an agent to another runtime when its runtime runs
5170
5282
  * out of usage, and back when the limit resets.