crewly 1.20.186 → 1.20.187

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 (271) hide show
  1. package/config/skills/agent/core/remember/SKILL.md +1 -0
  2. package/config/skills/agent/core/remember/execute.sh +12 -0
  3. package/config/skills/agent/core/report-status/SKILL.md +7 -1
  4. package/config/skills/agent/core/report-status/execute.sh +41 -0
  5. package/config/skills/agent/core/slack-post/SKILL.md +1 -0
  6. package/config/skills/agent/core/slack-post/execute.sh +9 -2
  7. package/config/skills/team-leader/_common/lib.sh +45 -0
  8. package/config/skills/team-leader/start-agent/SKILL.md +6 -6
  9. package/config/skills/team-leader/start-agent/execute.sh +3 -12
  10. package/config/skills/team-leader/stop-agent/SKILL.md +6 -6
  11. package/config/skills/team-leader/stop-agent/execute.sh +3 -12
  12. package/dist/backend/backend/src/constants.d.ts +54 -0
  13. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  14. package/dist/backend/backend/src/constants.js +54 -0
  15. package/dist/backend/backend/src/constants.js.map +1 -1
  16. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  17. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +62 -0
  18. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/request/open-items.controller.js +1 -1
  20. package/dist/backend/backend/src/controllers/request/open-items.controller.js.map +1 -1
  21. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  22. package/dist/backend/backend/src/controllers/slack/slack.controller.js +4 -1
  23. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  24. package/dist/backend/backend/src/controllers/standing/standing.controller.d.ts +18 -1
  25. package/dist/backend/backend/src/controllers/standing/standing.controller.d.ts.map +1 -1
  26. package/dist/backend/backend/src/controllers/standing/standing.controller.js +77 -4
  27. package/dist/backend/backend/src/controllers/standing/standing.controller.js.map +1 -1
  28. package/dist/backend/backend/src/controllers/system/spend.controller.d.ts +32 -0
  29. package/dist/backend/backend/src/controllers/system/spend.controller.d.ts.map +1 -0
  30. package/dist/backend/backend/src/controllers/system/spend.controller.js +100 -0
  31. package/dist/backend/backend/src/controllers/system/spend.controller.js.map +1 -0
  32. package/dist/backend/backend/src/controllers/system/system.controller.d.ts +12 -0
  33. package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
  34. package/dist/backend/backend/src/controllers/system/system.controller.js +28 -3
  35. package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
  36. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +7 -0
  37. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  38. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +64 -1
  39. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  40. package/dist/backend/backend/src/index.d.ts.map +1 -1
  41. package/dist/backend/backend/src/index.js +59 -0
  42. package/dist/backend/backend/src/index.js.map +1 -1
  43. package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
  44. package/dist/backend/backend/src/routes/modules/system.routes.js +3 -0
  45. package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
  46. package/dist/backend/backend/src/scripts/open-items-stale-followups.d.ts +51 -0
  47. package/dist/backend/backend/src/scripts/open-items-stale-followups.d.ts.map +1 -0
  48. package/dist/backend/backend/src/scripts/open-items-stale-followups.js +142 -0
  49. package/dist/backend/backend/src/scripts/open-items-stale-followups.js.map +1 -0
  50. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  51. package/dist/backend/backend/src/services/agent/agent-registration.service.js +32 -1
  52. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  53. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +28 -0
  54. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +83 -2
  56. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  57. package/dist/backend/backend/src/services/memory/memory.service.d.ts +14 -2
  58. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  59. package/dist/backend/backend/src/services/memory/memory.service.js +12 -1
  60. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  61. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts +18 -1
  62. package/dist/backend/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  63. package/dist/backend/backend/src/services/memory/project-memory.service.js +38 -1
  64. package/dist/backend/backend/src/services/memory/project-memory.service.js.map +1 -1
  65. package/dist/backend/backend/src/services/memory/standing-answers.service.d.ts +11 -0
  66. package/dist/backend/backend/src/services/memory/standing-answers.service.d.ts.map +1 -1
  67. package/dist/backend/backend/src/services/memory/standing-answers.service.js +40 -2
  68. package/dist/backend/backend/src/services/memory/standing-answers.service.js.map +1 -1
  69. package/dist/backend/backend/src/services/messaging/offline-agent-message.d.ts +70 -0
  70. package/dist/backend/backend/src/services/messaging/offline-agent-message.d.ts.map +1 -0
  71. package/dist/backend/backend/src/services/messaging/offline-agent-message.js +92 -0
  72. package/dist/backend/backend/src/services/messaging/offline-agent-message.js.map +1 -0
  73. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +5 -1
  74. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +11 -2
  76. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  77. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
  78. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +2 -0
  79. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
  80. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  81. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +9 -1
  82. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  83. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +41 -1
  84. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +87 -2
  86. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  87. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts +30 -12
  88. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  89. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +83 -13
  90. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  91. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +25 -0
  92. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  93. package/dist/backend/backend/src/services/monitoring/token-usage.service.js +45 -1
  94. package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  95. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts +10 -1
  96. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/open-items/open-item-extractor.js +86 -5
  98. package/dist/backend/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  99. package/dist/backend/backend/src/services/open-items/open-items-backfill.d.ts +2 -1
  100. package/dist/backend/backend/src/services/open-items/open-items-backfill.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/open-items/open-items-backfill.js +17 -6
  102. package/dist/backend/backend/src/services/open-items/open-items-backfill.js.map +1 -1
  103. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +62 -1
  104. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/open-items/open-items.service.js +203 -9
  106. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  107. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.d.ts +40 -0
  108. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.d.ts.map +1 -0
  109. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.js +82 -0
  110. package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.js.map +1 -0
  111. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +29 -0
  112. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +49 -0
  114. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  115. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  116. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +6 -11
  117. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  118. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +23 -0
  119. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  120. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +55 -1
  121. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  122. package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts.map +1 -1
  123. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js +10 -4
  124. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js.map +1 -1
  125. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +13 -2
  126. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  127. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +19 -5
  128. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  129. package/dist/backend/backend/src/services/spend/spend-cap-command.d.ts +99 -0
  130. package/dist/backend/backend/src/services/spend/spend-cap-command.d.ts.map +1 -0
  131. package/dist/backend/backend/src/services/spend/spend-cap-command.js +190 -0
  132. package/dist/backend/backend/src/services/spend/spend-cap-command.js.map +1 -0
  133. package/dist/backend/backend/src/services/spend/spend-cap.gate.d.ts +64 -0
  134. package/dist/backend/backend/src/services/spend/spend-cap.gate.d.ts.map +1 -0
  135. package/dist/backend/backend/src/services/spend/spend-cap.gate.js +71 -0
  136. package/dist/backend/backend/src/services/spend/spend-cap.gate.js.map +1 -0
  137. package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts +225 -0
  138. package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/spend/spend-cap.service.js +503 -0
  140. package/dist/backend/backend/src/services/spend/spend-cap.service.js.map +1 -0
  141. package/dist/backend/backend/src/services/spend/spend-cap.store.d.ts +85 -0
  142. package/dist/backend/backend/src/services/spend/spend-cap.store.d.ts.map +1 -0
  143. package/dist/backend/backend/src/services/spend/spend-cap.store.js +95 -0
  144. package/dist/backend/backend/src/services/spend/spend-cap.store.js.map +1 -0
  145. package/dist/backend/backend/src/services/spend/spend-cap.wiring.d.ts +50 -0
  146. package/dist/backend/backend/src/services/spend/spend-cap.wiring.d.ts.map +1 -0
  147. package/dist/backend/backend/src/services/spend/spend-cap.wiring.js +98 -0
  148. package/dist/backend/backend/src/services/spend/spend-cap.wiring.js.map +1 -0
  149. package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts +124 -0
  150. package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts.map +1 -0
  151. package/dist/backend/backend/src/services/spend/spend-ledger.service.js +189 -0
  152. package/dist/backend/backend/src/services/spend/spend-ledger.service.js.map +1 -0
  153. package/dist/backend/backend/src/services/task-pool/claim-target-waker.d.ts +51 -0
  154. package/dist/backend/backend/src/services/task-pool/claim-target-waker.d.ts.map +1 -0
  155. package/dist/backend/backend/src/services/task-pool/claim-target-waker.js +43 -0
  156. package/dist/backend/backend/src/services/task-pool/claim-target-waker.js.map +1 -0
  157. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +38 -0
  158. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  159. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +73 -1
  160. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  161. package/dist/backend/backend/src/services/task-pool/work-item-usage.d.ts +44 -0
  162. package/dist/backend/backend/src/services/task-pool/work-item-usage.d.ts.map +1 -0
  163. package/dist/backend/backend/src/services/task-pool/work-item-usage.js +37 -0
  164. package/dist/backend/backend/src/services/task-pool/work-item-usage.js.map +1 -0
  165. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  166. package/dist/backend/backend/src/services/v3/v3-data.service.js +11 -14
  167. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  168. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +25 -0
  169. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  170. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +50 -0
  171. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  172. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +9 -1
  173. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  174. package/dist/backend/backend/src/services/workflow/scheduler.service.js +16 -2
  175. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  176. package/dist/backend/backend/src/types/decision.types.d.ts +3 -1
  177. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  178. package/dist/backend/backend/src/types/event-bus.types.d.ts +9 -1
  179. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  180. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  181. package/dist/backend/backend/src/types/review-reason.types.d.ts +3 -1
  182. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -1
  183. package/dist/backend/backend/src/types/review-reason.types.js +1 -0
  184. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -1
  185. package/dist/backend/backend/src/types/v2/open-item.types.d.ts +5 -1
  186. package/dist/backend/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  187. package/dist/backend/backend/src/types/v2/open-item.types.js +1 -1
  188. package/dist/backend/backend/src/types/v2/open-item.types.js.map +1 -1
  189. package/dist/backend/build-info.json +2 -2
  190. package/dist/cli/backend/src/constants.d.ts +54 -0
  191. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  192. package/dist/cli/backend/src/constants.js +54 -0
  193. package/dist/cli/backend/src/constants.js.map +1 -1
  194. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  195. package/dist/cli/backend/src/services/agent/agent-registration.service.js +32 -1
  196. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  197. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts +28 -0
  198. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  199. package/dist/cli/backend/src/services/event-bus/event-bus.service.js +83 -2
  200. package/dist/cli/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  201. package/dist/cli/backend/src/services/memory/memory.service.d.ts +14 -2
  202. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  203. package/dist/cli/backend/src/services/memory/memory.service.js +12 -1
  204. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  205. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +18 -1
  206. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
  207. package/dist/cli/backend/src/services/memory/project-memory.service.js +38 -1
  208. package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -1
  209. package/dist/cli/backend/src/services/memory/standing-answers.service.d.ts +11 -0
  210. package/dist/cli/backend/src/services/memory/standing-answers.service.d.ts.map +1 -1
  211. package/dist/cli/backend/src/services/memory/standing-answers.service.js +40 -2
  212. package/dist/cli/backend/src/services/memory/standing-answers.service.js.map +1 -1
  213. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +5 -1
  214. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  215. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +11 -2
  216. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  217. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  218. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +9 -1
  219. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  220. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +41 -1
  221. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  222. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +87 -2
  223. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  224. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts +30 -12
  225. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  226. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js +83 -13
  227. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  228. package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts +97 -0
  229. package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts.map +1 -0
  230. package/dist/cli/backend/src/services/monitoring/model-pricing.js +120 -0
  231. package/dist/cli/backend/src/services/monitoring/model-pricing.js.map +1 -0
  232. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +25 -0
  233. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  234. package/dist/cli/backend/src/services/monitoring/token-usage.service.js +45 -1
  235. package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  236. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts +10 -1
  237. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  238. package/dist/cli/backend/src/services/open-items/open-item-extractor.js +86 -5
  239. package/dist/cli/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  240. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +13 -2
  241. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  242. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +19 -5
  243. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  244. package/dist/cli/backend/src/services/spend/spend-cap.gate.d.ts +64 -0
  245. package/dist/cli/backend/src/services/spend/spend-cap.gate.d.ts.map +1 -0
  246. package/dist/cli/backend/src/services/spend/spend-cap.gate.js +71 -0
  247. package/dist/cli/backend/src/services/spend/spend-cap.gate.js.map +1 -0
  248. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +38 -0
  249. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  250. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +73 -1
  251. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  252. package/dist/cli/backend/src/services/task-pool/work-item-usage.d.ts +44 -0
  253. package/dist/cli/backend/src/services/task-pool/work-item-usage.d.ts.map +1 -0
  254. package/dist/cli/backend/src/services/task-pool/work-item-usage.js +37 -0
  255. package/dist/cli/backend/src/services/task-pool/work-item-usage.js.map +1 -0
  256. package/dist/cli/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  257. package/dist/cli/backend/src/services/v3/v3-data.service.js +11 -14
  258. package/dist/cli/backend/src/services/v3/v3-data.service.js.map +1 -1
  259. package/dist/cli/backend/src/types/decision.types.d.ts +3 -1
  260. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  261. package/dist/cli/backend/src/types/event-bus.types.d.ts +9 -1
  262. package/dist/cli/backend/src/types/event-bus.types.d.ts.map +1 -1
  263. package/dist/cli/backend/src/types/event-bus.types.js.map +1 -1
  264. package/dist/cli/backend/src/types/v2/open-item.types.d.ts +5 -1
  265. package/dist/cli/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  266. package/dist/cli/backend/src/types/v2/open-item.types.js +1 -1
  267. package/dist/cli/backend/src/types/v2/open-item.types.js.map +1 -1
  268. package/frontend/dist/assets/{index-1ee8a9a2.js → index-15c2faf2.js} +279 -279
  269. package/frontend/dist/assets/{index-a79c7852.css → index-20a67829.css} +1 -1
  270. package/frontend/dist/index.html +2 -2
  271. package/package.json +1 -1
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Spend caps from the owner's DM with the orc. Handled by the backend, not
3
+ * the orc — so it works while the orc itself is stopped by its cap:
4
+ *
5
+ * - `set daily cap for crewly-orc to $5` / `set daily cap for Ella to 3`
6
+ * - `set daily cap to $5` (the default for every agent)
7
+ * - `set daily total cap to $20` (all agents together)
8
+ * - `remove daily cap for Ella` / `remove daily cap` / `remove daily total cap`
9
+ * - `raise cap for orc to $10 today` / `raise total cap to $40 today`
10
+ *
11
+ * While the orc is stopped by a cap, every other owner DM to it gets one
12
+ * harness line saying so (the message itself stays queued for the orc).
13
+ *
14
+ * specs/2026-10-02-spend-cap.md
15
+ *
16
+ * @module services/spend/spend-cap-command
17
+ */
18
+ import type { SlackIncomingMessage } from '../../types/slack.types.js';
19
+ import { type SpendStop } from './spend-cap.gate.js';
20
+ import { type SpendCapPatch } from './spend-cap.service.js';
21
+ /** A parsed command. */
22
+ export type SpendCapCommand = {
23
+ kind: 'set';
24
+ target: string | null;
25
+ usd: number;
26
+ } | {
27
+ kind: 'set_total';
28
+ usd: number;
29
+ } | {
30
+ kind: 'remove';
31
+ target: string | null;
32
+ } | {
33
+ kind: 'remove_total';
34
+ } | {
35
+ kind: 'raise';
36
+ target: string;
37
+ usd: number;
38
+ };
39
+ /**
40
+ * Parse a spend cap command.
41
+ *
42
+ * @param text - Message text
43
+ * @returns The command, or null when the message is not one
44
+ *
45
+ * @example
46
+ * parseSpendCapCommand('set daily cap for crewly-orc to $5') // { kind: 'set', target: 'crewly-orc', usd: 5 }
47
+ * parseSpendCapCommand('raise cap for orc to $10 today') // { kind: 'raise', target: 'orc', usd: 10 }
48
+ */
49
+ export declare function parseSpendCapCommand(text: string | undefined): SpendCapCommand | null;
50
+ /** An agent the owner can name. */
51
+ export interface NamedAgent {
52
+ session: string;
53
+ name: string;
54
+ }
55
+ /**
56
+ * Resolve the agent the owner named.
57
+ *
58
+ * @param who - Session name, member name, or "orc" / "orchestrator"
59
+ * @param agents - Configured agents
60
+ * @returns Session, or null when unknown / ambiguous
61
+ */
62
+ export declare function resolveAgent(who: string, agents: NamedAgent[]): string | null;
63
+ /** What the interceptor needs. */
64
+ export interface SpendCapCommandDeps {
65
+ /** `orc` when the message is the owner writing in their DM with the orc */
66
+ ownerDmScope: (message: SlackIncomingMessage) => 'orc' | 'agent' | null;
67
+ replyTargetOf: (message: SlackIncomingMessage) => unknown;
68
+ reply: (text: string, target: unknown) => Promise<unknown>;
69
+ /** Configured agents (orc included) */
70
+ agents: () => Promise<NamedAgent[]>;
71
+ setCaps: (patch: SpendCapPatch) => Promise<unknown>;
72
+ raiseToday: (target: string, usd: number) => Promise<number>;
73
+ /** The orc's stop, or null */
74
+ orcStop: () => SpendStop | null;
75
+ onError?: (err: unknown) => void;
76
+ }
77
+ /**
78
+ * The orc's harness line while it is stopped by a cap.
79
+ *
80
+ * @param stop - The orc's stop
81
+ * @returns One line
82
+ */
83
+ export declare function orcCappedReply(stop: SpendStop): string;
84
+ /**
85
+ * Run a parsed command.
86
+ *
87
+ * @param cmd - Command
88
+ * @param deps - Collaborators
89
+ * @returns The owner's one-line answer
90
+ */
91
+ export declare function runSpendCapCommand(cmd: SpendCapCommand, deps: Pick<SpendCapCommandDeps, 'agents' | 'setCaps' | 'raiseToday'>): Promise<string>;
92
+ /**
93
+ * The Slack bridge interceptor for the owner's orc DM.
94
+ *
95
+ * @param deps - Collaborators
96
+ * @returns Interceptor: true when the message was a cap command (consumed)
97
+ */
98
+ export declare function createSpendCapInterceptor(deps: SpendCapCommandDeps): (message: SlackIncomingMessage) => boolean;
99
+ //# sourceMappingURL=spend-cap-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-cap-command.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/spend/spend-cap-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5E,wBAAwB;AACxB,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAsBnD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAmBrF;AAED,mCAAmC;AACnC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI,CAO7E;AAED,kCAAkC;AAClC,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,YAAY,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC;IAC1D,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,uCAAuC;IACvC,MAAM,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,8BAA8B;IAC9B,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAItD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CpJ;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAqB/G"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Spend caps from the owner's DM with the orc. Handled by the backend, not
3
+ * the orc — so it works while the orc itself is stopped by its cap:
4
+ *
5
+ * - `set daily cap for crewly-orc to $5` / `set daily cap for Ella to 3`
6
+ * - `set daily cap to $5` (the default for every agent)
7
+ * - `set daily total cap to $20` (all agents together)
8
+ * - `remove daily cap for Ella` / `remove daily cap` / `remove daily total cap`
9
+ * - `raise cap for orc to $10 today` / `raise total cap to $40 today`
10
+ *
11
+ * While the orc is stopped by a cap, every other owner DM to it gets one
12
+ * harness line saying so (the message itself stays queued for the orc).
13
+ *
14
+ * specs/2026-10-02-spend-cap.md
15
+ *
16
+ * @module services/spend/spend-cap-command
17
+ */
18
+ import { ORCHESTRATOR_SESSION_NAME, SPEND_CAP_CONSTANTS as C } from '../../constants.js';
19
+ import { formatUsd, spendCapReason } from './spend-cap.gate.js';
20
+ import { suggestedRaise } from './spend-cap.service.js';
21
+ const AMOUNT = String.raw `\$?\s*(\d+(?:\.\d{1,2})?)\s*(?:usd|dollars?)?`;
22
+ const CAP = String.raw `(?:daily\s+)?(?:spend(?:ing)?\s+)?cap`;
23
+ /**
24
+ * Normalise a message for matching.
25
+ *
26
+ * @param text - Raw text
27
+ * @returns Lower-cased, mentions and trailing punctuation removed
28
+ */
29
+ function norm(text) {
30
+ return text
31
+ .replace(/<@[A-Z0-9]+>/g, '')
32
+ .replace(/[`*_]/g, '')
33
+ .toLowerCase()
34
+ .replace(/[\s.。!!~~]+$/u, '')
35
+ .replace(/^(?:please|pls)\s+/, '')
36
+ .replace(/\s+/g, ' ')
37
+ .trim();
38
+ }
39
+ /**
40
+ * Parse a spend cap command.
41
+ *
42
+ * @param text - Message text
43
+ * @returns The command, or null when the message is not one
44
+ *
45
+ * @example
46
+ * parseSpendCapCommand('set daily cap for crewly-orc to $5') // { kind: 'set', target: 'crewly-orc', usd: 5 }
47
+ * parseSpendCapCommand('raise cap for orc to $10 today') // { kind: 'raise', target: 'orc', usd: 10 }
48
+ */
49
+ export function parseSpendCapCommand(text) {
50
+ if (!text)
51
+ return null;
52
+ const t = norm(text);
53
+ let m = new RegExp(String.raw `^set (?:the )?(?:daily total|total daily|total)(?: spend(?:ing)?)? cap to ${AMOUNT}$`).exec(t);
54
+ if (m)
55
+ return { kind: 'set_total', usd: Number(m[1]) };
56
+ m = new RegExp(String.raw `^set (?:the )?${CAP}(?: for (.+?))? to ${AMOUNT}(?: (?:a|per) day)?$`).exec(t);
57
+ if (m)
58
+ return { kind: 'set', target: m[1]?.trim() || null, usd: Number(m[2]) };
59
+ m = /^(?:remove|clear|turn off|disable) (?:the )?(?:daily total|total daily|total)(?: spend(?:ing)?)? cap$/.exec(t);
60
+ if (m)
61
+ return { kind: 'remove_total' };
62
+ m = new RegExp(String.raw `^(?:remove|clear|turn off|disable) (?:the )?${CAP}(?: for (.+))?$`).exec(t);
63
+ if (m)
64
+ return { kind: 'remove', target: m[1]?.trim() || null };
65
+ m = new RegExp(String.raw `^raise (?:the )?(?:daily total|total daily|total)(?: spend(?:ing)?)? cap to ${AMOUNT}(?: (?:for )?today)?$`).exec(t);
66
+ if (m)
67
+ return { kind: 'raise', target: C.TOTAL_TARGET, usd: Number(m[1]) };
68
+ m = new RegExp(String.raw `^raise (?:the )?${CAP} for (.+?) to ${AMOUNT}(?: (?:for )?today)?$`).exec(t);
69
+ if (m) {
70
+ const target = m[1].trim();
71
+ return { kind: 'raise', target: ['total', 'all', 'all agents'].includes(target) ? C.TOTAL_TARGET : target, usd: Number(m[2]) };
72
+ }
73
+ return null;
74
+ }
75
+ /**
76
+ * Resolve the agent the owner named.
77
+ *
78
+ * @param who - Session name, member name, or "orc" / "orchestrator"
79
+ * @param agents - Configured agents
80
+ * @returns Session, or null when unknown / ambiguous
81
+ */
82
+ export function resolveAgent(who, agents) {
83
+ const w = who.trim().toLowerCase().replace(/^@/, '');
84
+ if (['orc', 'the orc', 'orchestrator', 'the orchestrator', 'crewly orc', ORCHESTRATOR_SESSION_NAME].includes(w))
85
+ return ORCHESTRATOR_SESSION_NAME;
86
+ const bySession = agents.find((a) => a.session.toLowerCase() === w);
87
+ if (bySession)
88
+ return bySession.session;
89
+ const byName = agents.filter((a) => a.name.toLowerCase() === w);
90
+ return byName.length === 1 ? byName[0].session : null;
91
+ }
92
+ /**
93
+ * The orc's harness line while it is stopped by a cap.
94
+ *
95
+ * @param stop - The orc's stop
96
+ * @returns One line
97
+ */
98
+ export function orcCappedReply(stop) {
99
+ const raise = suggestedRaise(stop.capUsd, stop.spentUsd);
100
+ const target = stop.scope === 'total' ? 'total' : 'orc';
101
+ return `${spendCapReason(stop, 'Orc')}. No new turns start until midnight; your message is queued. To raise it for today, reply \`raise cap for ${target} to $${raise} today\` (or Settings → System → Spend).`;
102
+ }
103
+ /**
104
+ * Run a parsed command.
105
+ *
106
+ * @param cmd - Command
107
+ * @param deps - Collaborators
108
+ * @returns The owner's one-line answer
109
+ */
110
+ export async function runSpendCapCommand(cmd, deps) {
111
+ const agents = await deps.agents();
112
+ const who = (target) => {
113
+ const session = resolveAgent(target, agents);
114
+ if (!session)
115
+ return `I don't know an agent called "${target}". Use its name or session name (e.g. crewly-orc).`;
116
+ const name = session === ORCHESTRATOR_SESSION_NAME ? 'Orc' : agents.find((a) => a.session === session)?.name ?? session;
117
+ return { session, name };
118
+ };
119
+ switch (cmd.kind) {
120
+ case 'set_total':
121
+ await deps.setCaps({ totalCapUsd: cmd.usd });
122
+ return `Daily total spend cap set to ${formatUsd(cmd.usd)} for all agents together.`;
123
+ case 'remove_total':
124
+ await deps.setCaps({ totalCapUsd: null });
125
+ return 'Daily total spend cap removed.';
126
+ case 'set': {
127
+ if (!cmd.target) {
128
+ await deps.setCaps({ defaultAgentCapUsd: cmd.usd });
129
+ return `Daily spend cap set to ${formatUsd(cmd.usd)} per agent (agents with their own cap keep it).`;
130
+ }
131
+ const a = who(cmd.target);
132
+ if (typeof a === 'string')
133
+ return a;
134
+ await deps.setCaps({ agents: { [a.session]: cmd.usd } });
135
+ return `Daily spend cap for ${a.name} set to ${formatUsd(cmd.usd)}.`;
136
+ }
137
+ case 'remove': {
138
+ if (!cmd.target) {
139
+ await deps.setCaps({ defaultAgentCapUsd: null });
140
+ return 'Default daily spend cap removed (agents with their own cap keep it).';
141
+ }
142
+ const a = who(cmd.target);
143
+ if (typeof a === 'string')
144
+ return a;
145
+ await deps.setCaps({ agents: { [a.session]: null } });
146
+ return `${a.name} has no daily spend cap now.`;
147
+ }
148
+ case 'raise': {
149
+ if (cmd.target === C.TOTAL_TARGET) {
150
+ const cap = await deps.raiseToday(C.TOTAL_TARGET, cmd.usd);
151
+ return `Daily total spend cap raised to ${formatUsd(cap)} for today.`;
152
+ }
153
+ const a = who(cmd.target);
154
+ if (typeof a === 'string')
155
+ return a;
156
+ const cap = await deps.raiseToday(a.session, cmd.usd);
157
+ return `${a.name}'s daily spend cap raised to ${formatUsd(cap)} for today. Queued messages are being delivered.`;
158
+ }
159
+ }
160
+ }
161
+ /**
162
+ * The Slack bridge interceptor for the owner's orc DM.
163
+ *
164
+ * @param deps - Collaborators
165
+ * @returns Interceptor: true when the message was a cap command (consumed)
166
+ */
167
+ export function createSpendCapInterceptor(deps) {
168
+ return (message) => {
169
+ if (deps.ownerDmScope(message) !== 'orc')
170
+ return false;
171
+ const target = deps.replyTargetOf(message);
172
+ const cmd = message.hasFiles ? null : parseSpendCapCommand(message.text);
173
+ if (cmd) {
174
+ void runSpendCapCommand(cmd, deps)
175
+ .then((text) => deps.reply(text, target))
176
+ .catch((err) => {
177
+ deps.onError?.(err);
178
+ return deps.reply(`Couldn't change the cap: ${err instanceof Error ? err.message : String(err)}`, target).catch(() => undefined);
179
+ });
180
+ return true;
181
+ }
182
+ const stop = deps.orcStop();
183
+ if (stop) {
184
+ // Not consumed: the message goes on to the orc's queue and waits there.
185
+ void deps.reply(orcCappedReply(stop), target).catch((err) => deps.onError?.(err));
186
+ }
187
+ return false;
188
+ };
189
+ }
190
+ //# sourceMappingURL=spend-cap-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-cap-command.js","sourceRoot":"","sources":["../../../../../../backend/src/services/spend/spend-cap-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Spend cap gate — the process-wide hook the delivery and wake paths ask
3
+ * "may this agent start a new turn?". Kept apart from the service so the
4
+ * hot paths (agent registration, the orc queue processor, the owner-message
5
+ * watchdog) import a tiny module with no dependencies of its own.
6
+ *
7
+ * specs/2026-10-02-spend-cap.md
8
+ *
9
+ * @module services/spend/spend-cap.gate
10
+ */
11
+ /** Why an agent may not start a new turn today. */
12
+ export interface SpendStop {
13
+ session: string;
14
+ /** `agent`: its own cap; `total`: the all-agents daily total cap */
15
+ scope: 'agent' | 'total';
16
+ /** The cap in force (USD) */
17
+ capUsd: number;
18
+ /** What was spent today against it (USD) */
19
+ spentUsd: number;
20
+ }
21
+ /** What the service exposes to the gate. */
22
+ export interface SpendCapGate {
23
+ /** The stop in force for a session, or null when it may run */
24
+ stopOf(session: string): SpendStop | null;
25
+ /** Owner-facing name of a session ("Orc", "Ella") */
26
+ displayNameOf?(session: string): string;
27
+ }
28
+ /**
29
+ * Install (or clear) the gate.
30
+ *
31
+ * @param next - Gate, or null
32
+ */
33
+ export declare function setSpendCapGate(next: SpendCapGate | null): void;
34
+ /**
35
+ * The stop in force for a session. Never throws: a broken gate lets the
36
+ * agent run rather than silently dropping its work.
37
+ *
38
+ * @param session - Agent session
39
+ * @returns Stop, or null
40
+ */
41
+ export declare function spendCapStopOf(session: string): SpendStop | null;
42
+ /**
43
+ * Owner-facing name of a session.
44
+ *
45
+ * @param session - Agent session
46
+ * @returns Name (the session name when unknown)
47
+ */
48
+ export declare function spendCapNameOf(session: string): string;
49
+ /**
50
+ * USD for owner text.
51
+ *
52
+ * @param usd - Amount
53
+ * @returns e.g. `$5.00`
54
+ */
55
+ export declare function formatUsd(usd: number): string;
56
+ /**
57
+ * The one-line reason, e.g. "Orc hit its daily spend cap ($5.00)".
58
+ *
59
+ * @param stop - The stop
60
+ * @param name - Owner-facing name (default: looked up)
61
+ * @returns Reason text
62
+ */
63
+ export declare function spendCapReason(stop: SpendStop, name?: string): string;
64
+ //# sourceMappingURL=spend-cap.gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-cap.gate.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/spend/spend-cap.gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C,qDAAqD;IACrD,aAAa,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACzC;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMhE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,GAAE,MAAqC,GAAG,MAAM,CAKnG"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Spend cap gate — the process-wide hook the delivery and wake paths ask
3
+ * "may this agent start a new turn?". Kept apart from the service so the
4
+ * hot paths (agent registration, the orc queue processor, the owner-message
5
+ * watchdog) import a tiny module with no dependencies of its own.
6
+ *
7
+ * specs/2026-10-02-spend-cap.md
8
+ *
9
+ * @module services/spend/spend-cap.gate
10
+ */
11
+ let gate = null;
12
+ /**
13
+ * Install (or clear) the gate.
14
+ *
15
+ * @param next - Gate, or null
16
+ */
17
+ export function setSpendCapGate(next) {
18
+ gate = next;
19
+ }
20
+ /**
21
+ * The stop in force for a session. Never throws: a broken gate lets the
22
+ * agent run rather than silently dropping its work.
23
+ *
24
+ * @param session - Agent session
25
+ * @returns Stop, or null
26
+ */
27
+ export function spendCapStopOf(session) {
28
+ try {
29
+ return gate?.stopOf(session) ?? null;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Owner-facing name of a session.
37
+ *
38
+ * @param session - Agent session
39
+ * @returns Name (the session name when unknown)
40
+ */
41
+ export function spendCapNameOf(session) {
42
+ try {
43
+ return gate?.displayNameOf?.(session) || session;
44
+ }
45
+ catch {
46
+ return session;
47
+ }
48
+ }
49
+ /**
50
+ * USD for owner text.
51
+ *
52
+ * @param usd - Amount
53
+ * @returns e.g. `$5.00`
54
+ */
55
+ export function formatUsd(usd) {
56
+ return `$${(Math.round(usd * 100) / 100).toFixed(2)}`;
57
+ }
58
+ /**
59
+ * The one-line reason, e.g. "Orc hit its daily spend cap ($5.00)".
60
+ *
61
+ * @param stop - The stop
62
+ * @param name - Owner-facing name (default: looked up)
63
+ * @returns Reason text
64
+ */
65
+ export function spendCapReason(stop, name = spendCapNameOf(stop.session)) {
66
+ if (stop.scope === 'total') {
67
+ return `${name} is stopped: all agents together hit the daily total spend cap (${formatUsd(stop.capUsd)})`;
68
+ }
69
+ return `${name} hit its daily spend cap (${formatUsd(stop.capUsd)})`;
70
+ }
71
+ //# sourceMappingURL=spend-cap.gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-cap.gate.js","sourceRoot":"","sources":["../../../../../../backend/src/services/spend/spend-cap.gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqBH,IAAI,IAAI,GAAwB,IAAI,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,IAAI,GAAG,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,aAAa,EAAE,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAe,EAAE,OAAe,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;IACzF,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,GAAG,IAAI,mEAAmE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC7G,CAAC;IACD,OAAO,GAAG,IAAI,6BAA6B,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;AACvE,CAAC"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Per-agent daily spend cap with a hard stop.
3
+ *
4
+ * - Caps are the owner's own limits (unlike the runtime fallback, which
5
+ * reacts to a provider's usage limit). All are OFF until the owner sets
6
+ * one: a default per-agent cap, per-agent overrides, and an optional
7
+ * all-agents daily total.
8
+ * - At {@link SPEND_CAP_CONSTANTS.WARN_FRACTION} of a cap the owner gets ONE
9
+ * heads-up.
10
+ * - At 100% the agent is hard-stopped: {@link stopOf} answers the delivery
11
+ * and wake gates, so no new turn starts (the current one may finish) and
12
+ * messages stay queued. The owner gets ONE decision card: "Raise to $Y
13
+ * today" / "Keep stopped".
14
+ * - Local midnight resets everything; raises last for the day they were
15
+ * made. When a stop lifts (midnight, raise, cap change) the queued
16
+ * messages are released.
17
+ *
18
+ * Spend comes from {@link SpendLedger} (the shared token ledger and its one
19
+ * cost computation).
20
+ *
21
+ * specs/2026-10-02-spend-cap.md
22
+ *
23
+ * @module services/spend/spend-cap.service
24
+ */
25
+ import type { OwnerDecision } from '../../types/decision.types.js';
26
+ import type { SystemAskInput } from '../decisions/decision.service.js';
27
+ import { type SpendCapGate, type SpendStop } from './spend-cap.gate.js';
28
+ import { type SpendLedger, type SpendSummary } from './spend-ledger.service.js';
29
+ import { type SpendCapConfig, type SpendCapStoreLike } from './spend-cap.store.js';
30
+ /** Minimal logger. */
31
+ export interface SpendCapLogger {
32
+ info(message: string, meta?: Record<string, unknown>): void;
33
+ warn(message: string, meta?: Record<string, unknown>): void;
34
+ }
35
+ /** The decision-card calls the service makes. */
36
+ export interface SpendCapDecisions {
37
+ askSystem(input: SystemAskInput): Promise<OwnerDecision>;
38
+ replyInThread(id: string, text: string): Promise<boolean>;
39
+ }
40
+ /** Collaborators. */
41
+ export interface SpendCapServiceDeps {
42
+ store: SpendCapStoreLike;
43
+ ledger: Pick<SpendLedger, 'spentToday' | 'totalToday' | 'summarize' | 'invalidate'>;
44
+ /** One line to the owner (Slack DM from this machine's orc bot); false/throw = not sent */
45
+ notifyOwner: (text: string) => Promise<unknown>;
46
+ /** Decision cards (null before they are wired: the stop is then a plain notice) */
47
+ decisions?: () => SpendCapDecisions | null;
48
+ /** Owner-facing name of a session ("Orc", "Ella") */
49
+ displayNameOf?: (session: string) => string;
50
+ /** Sessions the owner configured (orc + team members), for the caps view */
51
+ knownSessions?: () => Promise<string[]>;
52
+ /** Stops lifted: deliver what was queued for these sessions */
53
+ onReleased?: (sessions: string[]) => Promise<void>;
54
+ now?: () => Date;
55
+ logger?: SpendCapLogger;
56
+ }
57
+ /** Body of `PUT /api/system/spend/caps`. */
58
+ export interface SpendCapPatch {
59
+ /** Default per-agent cap (USD); null turns it off */
60
+ defaultAgentCapUsd?: number | null;
61
+ /** All-agents total cap (USD); null turns it off */
62
+ totalCapUsd?: number | null;
63
+ /** Session → cap (USD), `null` = no cap for this agent, `"default"` = drop the override */
64
+ agents?: Record<string, number | null | 'default'>;
65
+ }
66
+ /** A rejected cap change. */
67
+ export declare class SpendCapError extends Error {
68
+ readonly status: number;
69
+ /**
70
+ * @param status - HTTP status
71
+ * @param message - Owner-facing reason
72
+ */
73
+ constructor(status: number, message: string);
74
+ }
75
+ /** One agent in the view. */
76
+ export interface SpendCapAgentView {
77
+ session: string;
78
+ name: string;
79
+ runtimes: string[];
80
+ todayUsd: number;
81
+ windowUsd: number;
82
+ daily: number[];
83
+ /** Cap in force today (USD), null = none */
84
+ capUsd: number | null;
85
+ /** Where the cap comes from */
86
+ capSource: 'override' | 'default' | 'raised' | 'none' | 'exempt';
87
+ /** Stopped right now, and why */
88
+ stopped: boolean;
89
+ stopReason?: string;
90
+ }
91
+ /** What `GET /api/system/spend` returns. */
92
+ export interface SpendView extends Omit<SpendSummary, 'agents'> {
93
+ agents: SpendCapAgentView[];
94
+ caps: SpendCapConfig;
95
+ /** Raises in force today: target → USD */
96
+ raisedToday: Record<string, number>;
97
+ /** Total cap in force today (raise included), null = off */
98
+ totalCapTodayUsd: number | null;
99
+ /** Suggested default per-agent cap: last window's p90 agent-day, rounded up to whole dollars (null = no data) */
100
+ suggestedAgentCapUsd: number | null;
101
+ /** All agents together stopped by the total cap */
102
+ totalStopped: boolean;
103
+ }
104
+ /**
105
+ * The "Raise to $Y today" amount: the cap times RAISE_FACTOR, rounded up to
106
+ * whole dollars, and always above what was already spent.
107
+ *
108
+ * @param capUsd - Cap in force
109
+ * @param spentUsd - Spent today
110
+ * @returns USD
111
+ */
112
+ export declare function suggestedRaise(capUsd: number, spentUsd: number): number;
113
+ /**
114
+ * Read the amount out of a "Raise to $Y today" option label.
115
+ *
116
+ * @param label - Option label
117
+ * @returns USD, or null when the label is not a raise
118
+ */
119
+ export declare function raiseAmountOf(label: string | undefined): number | null;
120
+ /**
121
+ * Per-agent daily spend cap service.
122
+ */
123
+ export declare class SpendCapService implements SpendCapGate {
124
+ private readonly deps;
125
+ private file;
126
+ private readonly now;
127
+ private readonly logger;
128
+ private timer;
129
+ /** Sessions stopped at the last evaluation (to release them when the stop lifts) */
130
+ private lastStopped;
131
+ /** Evaluation passes run one after another */
132
+ private chain;
133
+ private queuedPass;
134
+ /**
135
+ * @param deps - Collaborators
136
+ */
137
+ constructor(deps: SpendCapServiceDeps);
138
+ /** Start the enforcement tick. */
139
+ start(): void;
140
+ /** Stop the tick. */
141
+ stop(): void;
142
+ /** @returns The owner's caps (a copy) */
143
+ getConfig(): SpendCapConfig;
144
+ /**
145
+ * Change caps. Takes effect at once (a stop can lift or start).
146
+ *
147
+ * @param patch - Changes
148
+ * @returns The new caps
149
+ * @throws SpendCapError on a bad value
150
+ */
151
+ setCaps(patch: SpendCapPatch): Promise<SpendCapConfig>;
152
+ /**
153
+ * Lift a cap for today only.
154
+ *
155
+ * @param target - Agent session, or `*` for the all-agents total
156
+ * @param usd - New cap for today (must be above today's spend)
157
+ * @returns The new cap for today
158
+ * @throws SpendCapError when the amount is not above today's spend
159
+ */
160
+ raiseToday(target: string, usd: unknown): Promise<number>;
161
+ /**
162
+ * The stop in force for a session (the delivery / wake gate). Synchronous
163
+ * and live: it reads today's spend now, not at the last tick.
164
+ *
165
+ * @param session - Agent session
166
+ * @returns Stop, or null when the agent may run
167
+ */
168
+ stopOf(session: string): SpendStop | null;
169
+ /**
170
+ * Owner-facing name.
171
+ *
172
+ * @param session - Agent session
173
+ * @returns Name
174
+ */
175
+ displayNameOf(session: string): string;
176
+ /**
177
+ * Cap in force today for a target, and where it comes from.
178
+ *
179
+ * @param target - Agent session, or `*`
180
+ * @returns Cap (null = none) and source
181
+ */
182
+ capOf(target: string): {
183
+ capUsd: number | null;
184
+ source: SpendCapAgentView['capSource'];
185
+ };
186
+ /**
187
+ * Spend plus caps for the API / Settings panel.
188
+ *
189
+ * @param days - Window
190
+ * @returns View
191
+ */
192
+ view(days?: number): Promise<SpendView>;
193
+ /**
194
+ * One enforcement pass: day roll, 80% notices, stop announcements (one
195
+ * card per stop), and releasing agents whose stop lifted. Passes run
196
+ * one at a time; a call during a pass gets another pass after it.
197
+ */
198
+ evaluate(): Promise<void>;
199
+ /**
200
+ * React to a settled "cap reached" card (decision kind `spend_cap`).
201
+ *
202
+ * @param d - The settled decision
203
+ * @returns Always null (nobody else is told)
204
+ */
205
+ onSettled(d: OwnerDecision): Promise<null>;
206
+ private evaluateOnce;
207
+ private checkThresholds;
208
+ private announceStop;
209
+ private anyCap;
210
+ private computeStop;
211
+ private stopKey;
212
+ private scheduleEvaluate;
213
+ /** Reset today's bookkeeping when the local day changed. */
214
+ private rollDay;
215
+ private nextMidnight;
216
+ private nameOf;
217
+ private notify;
218
+ private reply;
219
+ private persist;
220
+ }
221
+ /** @returns The backend's service, or null before it is wired */
222
+ export declare function getSpendCapService(): SpendCapService | null;
223
+ /** @param service - Instance (null clears) */
224
+ export declare function setSpendCapService(service: SpendCapService | null): void;
225
+ //# sourceMappingURL=spend-cap.service.d.ts.map