crewly 1.20.202 → 1.20.204

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 (230) hide show
  1. package/config/skills/agent/core/reply/SKILL.md +1 -0
  2. package/config/skills/agent/core/reply/execute.sh +7 -1
  3. package/config/skills/agent/core/reply-channel/SKILL.md +4 -0
  4. package/config/skills/agent/core/reply-channel/execute.sh +12 -1
  5. package/dist/backend/backend/src/constants.d.ts +158 -0
  6. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  7. package/dist/backend/backend/src/constants.js +158 -0
  8. package/dist/backend/backend/src/constants.js.map +1 -1
  9. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -1
  10. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +1 -0
  11. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -1
  12. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  13. package/dist/backend/backend/src/controllers/chat/chat.controller.js +11 -1
  14. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  15. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  16. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +50 -0
  17. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  18. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +6 -0
  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 +30 -2
  21. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  22. package/dist/backend/backend/src/controllers/session/session.controller.d.ts.map +1 -1
  23. package/dist/backend/backend/src/controllers/session/session.controller.js +7 -0
  24. package/dist/backend/backend/src/controllers/session/session.controller.js.map +1 -1
  25. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  26. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +4 -1
  27. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  28. package/dist/backend/backend/src/index.d.ts +28 -0
  29. package/dist/backend/backend/src/index.d.ts.map +1 -1
  30. package/dist/backend/backend/src/index.js +141 -35
  31. package/dist/backend/backend/src/index.js.map +1 -1
  32. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  33. package/dist/backend/backend/src/services/agent/agent-registration.service.js +7 -0
  34. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  35. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  36. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +11 -0
  37. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  38. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts +22 -0
  39. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js +39 -3
  41. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  42. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.d.ts +140 -0
  43. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.d.ts.map +1 -0
  44. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.js +267 -0
  45. package/dist/backend/backend/src/services/agent/in-process-turn-failure.service.js.map +1 -0
  46. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +117 -0
  47. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +165 -9
  49. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.d.ts +93 -0
  51. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.d.ts.map +1 -0
  52. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.js +138 -0
  53. package/dist/backend/backend/src/services/chat-v2/room-context-backlog.js.map +1 -0
  54. package/dist/backend/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/decisions/decision-card.js +5 -1
  56. package/dist/backend/backend/src/services/decisions/decision-card.js.map +1 -1
  57. package/dist/backend/backend/src/services/decisions/decision.service.d.ts +43 -1
  58. package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  59. package/dist/backend/backend/src/services/decisions/decision.service.js +110 -7
  60. package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
  61. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts +2 -0
  62. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts.map +1 -1
  63. package/dist/backend/backend/src/services/decisions/decision.wiring.js +1 -0
  64. package/dist/backend/backend/src/services/decisions/decision.wiring.js.map +1 -1
  65. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.d.ts +59 -0
  66. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.d.ts.map +1 -0
  67. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.js +70 -0
  68. package/dist/backend/backend/src/services/messaging/drain-queued-delivery.js.map +1 -0
  69. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +46 -1
  70. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  71. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +109 -0
  72. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  73. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts +2 -0
  74. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
  75. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +6 -0
  76. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
  77. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +51 -1
  78. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  79. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +73 -3
  80. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  81. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.d.ts +168 -0
  82. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.d.ts.map +1 -0
  83. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.js +280 -0
  84. package/dist/backend/backend/src/services/monitoring/liveness-monitor.service.js.map +1 -0
  85. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +21 -0
  86. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/open-items/open-items.service.js +72 -3
  88. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.d.ts +153 -0
  90. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.d.ts.map +1 -0
  91. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.js +276 -0
  92. package/dist/backend/backend/src/services/orc/orc-chat-owner-mirror.js.map +1 -0
  93. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +16 -0
  94. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +22 -2
  96. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
  97. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +9 -0
  98. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -1
  99. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js +11 -0
  100. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -1
  101. package/dist/backend/backend/src/services/slack/room-responder.d.ts +144 -0
  102. package/dist/backend/backend/src/services/slack/room-responder.d.ts.map +1 -0
  103. package/dist/backend/backend/src/services/slack/room-responder.js +236 -0
  104. package/dist/backend/backend/src/services/slack/room-responder.js.map +1 -0
  105. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts +11 -2
  106. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +22 -1
  108. package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  109. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  110. package/dist/backend/backend/src/services/slack/slack-initializer.js +64 -2
  111. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  112. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts +8 -2
  113. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts.map +1 -1
  114. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.js +7 -4
  115. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.js.map +1 -1
  116. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +148 -2
  117. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  118. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +784 -231
  119. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  120. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts +27 -0
  121. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  122. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +52 -0
  123. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  124. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +30 -5
  125. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  126. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +41 -8
  127. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  128. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +1 -0
  129. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  130. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +8 -3
  131. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  132. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts +13 -1
  133. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -1
  134. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js +36 -3
  135. package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
  136. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +54 -3
  137. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  138. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +117 -9
  139. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  140. package/dist/backend/backend/src/types/decision.types.d.ts +7 -0
  141. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  142. package/dist/backend/build-info.json +2 -2
  143. package/dist/cli/backend/src/constants.d.ts +158 -0
  144. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  145. package/dist/cli/backend/src/constants.js +158 -0
  146. package/dist/cli/backend/src/constants.js.map +1 -1
  147. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  148. package/dist/cli/backend/src/services/agent/agent-registration.service.js +7 -0
  149. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  150. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  151. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +11 -0
  152. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  153. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts +22 -0
  154. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  155. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js +39 -3
  156. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  157. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.d.ts +140 -0
  158. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.d.ts.map +1 -0
  159. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.js +267 -0
  160. package/dist/cli/backend/src/services/agent/in-process-turn-failure.service.js.map +1 -0
  161. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +117 -0
  162. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  163. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +165 -9
  164. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  165. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.d.ts +93 -0
  166. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.d.ts.map +1 -0
  167. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.js +138 -0
  168. package/dist/cli/backend/src/services/chat-v2/room-context-backlog.js.map +1 -0
  169. package/dist/cli/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  170. package/dist/cli/backend/src/services/decisions/decision-card.js +5 -1
  171. package/dist/cli/backend/src/services/decisions/decision-card.js.map +1 -1
  172. package/dist/cli/backend/src/services/decisions/decision.service.d.ts +43 -1
  173. package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  174. package/dist/cli/backend/src/services/decisions/decision.service.js +110 -7
  175. package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
  176. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +46 -1
  177. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  178. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +109 -0
  179. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  180. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +51 -1
  181. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  182. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +73 -3
  183. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  184. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +21 -0
  185. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  186. package/dist/cli/backend/src/services/open-items/open-items.service.js +72 -3
  187. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  188. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +9 -0
  189. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -1
  190. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js +11 -0
  191. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -1
  192. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts +66 -0
  193. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -0
  194. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js +211 -0
  195. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js.map +1 -0
  196. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +113 -0
  197. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -0
  198. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js +257 -0
  199. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -0
  200. package/dist/cli/backend/src/services/slack/room-responder.d.ts +144 -0
  201. package/dist/cli/backend/src/services/slack/room-responder.d.ts.map +1 -0
  202. package/dist/cli/backend/src/services/slack/room-responder.js +236 -0
  203. package/dist/cli/backend/src/services/slack/room-responder.js.map +1 -0
  204. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts +11 -2
  205. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.d.ts.map +1 -1
  206. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +22 -1
  207. package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
  208. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +148 -2
  209. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  210. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +784 -231
  211. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  212. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts +27 -0
  213. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  214. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +52 -0
  215. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  216. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +30 -5
  217. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  218. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +41 -8
  219. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  220. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +1 -0
  221. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  222. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +8 -3
  223. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  224. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts +13 -1
  225. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -1
  226. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js +36 -3
  227. package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
  228. package/dist/cli/backend/src/types/decision.types.d.ts +7 -0
  229. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  230. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-time.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/reset-time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mCAAmC;AACnC,MAAM,MAAM,GAAqC;IAChD,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;CACzG,CAAC;AAEF,qBAAqB;AACrB,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAWnC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAA6B;IAC5D,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,IAAI,CAAC;QACJ,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,OAAe,EAAE,EAAsB;IAC3D,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;QAC5C,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;KACjB,CAAC,CAAC;IACH,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AAClH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAe,EAAE,EAAsB;IAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjF,IAAI,KAAK,GAAG,MAAM,CAAC;IACnB,0DAA0D;IAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpF,KAAK,IAAI,MAAM,GAAG,SAAS,CAAC;IAC7B,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAS,KAAK,CAAC,IAAY,EAAE,QAA4B;IACxD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,CAAC,GAAG,QAAQ,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,yDAAyD;AACzD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA,+CAA+C,CAAC;AACxE,mFAAmF;AACnF,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,2FAA2F,CAAC;AACnH,sEAAsE;AACtE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,gEAAgE,CAAC;AAExF,8CAA8C;AAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAA,kIAAkI,CAAC;AAEnK,8DAA8D;AAC9D,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,aAAa,gBAAgB,IAAI,GAAG,KAAK,GAAG,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;AACrG,8CAA8C;AAC9C,MAAM,MAAM,GAAG,4GAA4G,CAAC;AAC5H,oEAAoE;AACpE,MAAM,QAAQ,GAAG,oCAAoC,CAAC;AACtD,4FAA4F;AAC5F,MAAM,WAAW,GAAG,+JAA+J,CAAC;AAEpL;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IACjD,MAAM,EAAE,GAAG,iFAAiF,CAAC;IAC7F,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,KAAK,GAAG,IAAI,CAAC;QACb,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC;aACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;aACtD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;;YACjD,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,GAAW,EAAE,eAAwB;IACjF,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,KAAK;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE1C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC;QACtC,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7G,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC/H,CAAC;IAED,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,GAAG,EAAE,CAAC;QACT,MAAM,EAAE,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO,GAAG,GAAG,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,GAAG,CAAC;QACnG,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,sEAAsE;QACtE,6BAA6B;QAC7B,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1F,MAAM,aAAa,GAAG,QAAQ,IAAI,UAAU,CAAC;QAC7C,MAAM,EAAE,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;QAE3H,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnC,IAAI,SAAS,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACzG,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;YACjE,IAAI,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YACpD,IAAI,EAAE,GAAG,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YACtE,oDAAoD;YACpD,IAAI,CAAC,QAAQ,IAAI,EAAE,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;gBACpC,IAAI,IAAI,CAAC,CAAC;gBACV,EAAE,GAAG,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YACnE,CAAC;YACD,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,EAAE,GAAG,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1G,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;YAC/C,EAAE,GAAG,oBAAoB,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAChH,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Usage-limit rules — per-runtime patterns that mean "this runtime's account
3
+ * is out of usage", as opposed to a login that expired (login-expiry-rules.ts,
4
+ * the re-login flow) or a short rate limit the runtime retries by itself.
5
+ *
6
+ * Modelled on login-expiry-rules.ts: output is normalized with
7
+ * {@link normalizeTerminalOutput} and every pattern is matched against the
8
+ * normalized text and its spaceless copy (Claude Code places words with
9
+ * cursor moves instead of spaces), so patterns use `\s*` between words.
10
+ *
11
+ * Wording sources:
12
+ * - Claude Code 2.1.287 binary (`strings`, 2026-10-01): `Usage limit
13
+ * reached`, `Usage limit reached again`, `continuing automatically {when}`,
14
+ * `You're out of extra usage`, `You're out of usage credits`, `You've hit
15
+ * your monthly spend limit`, ` resets $…`, `/upgrade to increase your usage
16
+ * limit.`, the API's `billing_error` "spend limit reached (daily; resets …)",
17
+ * and its own note that the client composes "You've hit your limit" from a
18
+ * 429. Older releases print `5-hour limit reached ∙ resets 3pm`, `Claude
19
+ * usage limit reached. Your limit will reset at 3pm (America/Los_Angeles).`
20
+ * and `Claude AI usage limit reached|<epoch>`.
21
+ * - Codex: `You've hit your usage limit. Upgrade to Pro (…) or try again in
22
+ * 4 days 7 hours 3 minutes.` / `… try again at 4:05 PM.`; transient:
23
+ * `exceeded retry limit, last status: 429 Too Many Requests`.
24
+ * - Gemini / Antigravity: `RESOURCE_EXHAUSTED` with `Quota exceeded for quota
25
+ * metric '… per day'`, `You exceeded your current quota`, `You have
26
+ * exhausted your daily quota`; a bare 429 / RESOURCE_EXHAUSTED is transient.
27
+ * - DeepSeek (the in-process Crewly Agent): HTTP 402 `Insufficient Balance`
28
+ * is a `billing` limit (no reset; the owner must top up); HTTP 429 `Rate Limit Reached` is transient.
29
+ *
30
+ * Context requirements keep an agent that merely reads or quotes this kind of
31
+ * text (for example while working on this file) from tripping a rule: the
32
+ * Claude UI rules need the `·` / `∙` separator, a reset time or a slash
33
+ * command next to the message; API rules need the API error context.
34
+ * Warnings that the limit is near ("Approaching usage limit", "You've used
35
+ * 90% of your session limit") are deliberately not matched.
36
+ *
37
+ * @module services/runtime-fallback/usage-limit-rules
38
+ */
39
+ /**
40
+ * `usage_limit`: the account is out of usage until a window resets;
41
+ * `billing`: the account is out of money / credit (DeepSeek 402 "Insufficient
42
+ * Balance", "credit balance is too low") — it has no reset time and only
43
+ * comes back when the owner tops up, so it is never retried on a timer;
44
+ * `transient`: a short rate limit the runtime retries.
45
+ */
46
+ export type UsageLimitKind = 'usage_limit' | 'billing' | 'transient';
47
+ /**
48
+ * Whether a kind means the runtime cannot be used (as opposed to a transient
49
+ * rate limit).
50
+ *
51
+ * @param kind - Match kind
52
+ * @returns True for `usage_limit` and `billing`
53
+ */
54
+ export declare function isExhaustingKind(kind: UsageLimitKind): boolean;
55
+ /** One rule: every pattern must match (AND); `none` must not match. */
56
+ export interface UsageLimitRule {
57
+ /** Stable id, used in logs (never contains output) */
58
+ id: string;
59
+ /** Runtime type the rule belongs to */
60
+ runtime: string;
61
+ kind: UsageLimitKind;
62
+ /** All must match the normalized text or its spaceless copy */
63
+ all: readonly RegExp[];
64
+ /** None of these may match (e.g. a warning, not the limit itself) */
65
+ none?: readonly RegExp[];
66
+ }
67
+ /** What {@link detectUsageLimit} found. */
68
+ export interface UsageLimitMatch {
69
+ /** Runtime the rule belongs to */
70
+ runtime: string;
71
+ ruleId: string;
72
+ kind: UsageLimitKind;
73
+ /** When the limit lifts (epoch ms), when the message says so */
74
+ resetAt: number | null;
75
+ }
76
+ /** Claude Code rules (usage limits first, then transient). */
77
+ export declare const CLAUDE_USAGE_RULES: readonly UsageLimitRule[];
78
+ /** Codex rules. */
79
+ export declare const CODEX_USAGE_RULES: readonly UsageLimitRule[];
80
+ /** Antigravity CLI rules. */
81
+ export declare const ANTIGRAVITY_USAGE_RULES: readonly UsageLimitRule[];
82
+ /** Gemini CLI rules (retired runtime, detect only). */
83
+ export declare const GEMINI_USAGE_RULES: readonly UsageLimitRule[];
84
+ /**
85
+ * In-process Crewly Agent rules. These run on the error of a failed model
86
+ * call (never on text the model wrote), so they need no UI context.
87
+ */
88
+ export declare const CREWLY_AGENT_USAGE_RULES: readonly UsageLimitRule[];
89
+ /**
90
+ * Usage-limit rules for a runtime.
91
+ *
92
+ * @param runtime - Runtime type
93
+ * @returns Rules to try (empty for a runtime without rules)
94
+ */
95
+ export declare function getUsageLimitRules(runtime: string): readonly UsageLimitRule[];
96
+ /**
97
+ * Find a usage-limit (or transient rate-limit) message in a runtime's output.
98
+ * An expired login is never reported here — that is the re-login flow's.
99
+ *
100
+ * @param output - Raw PTY output (escape sequences allowed), captured screen, or an error message
101
+ * @param runtime - The runtime the output came from
102
+ * @param now - Current time (ms), for the reset time
103
+ * @param defaultTimeZone - Zone for reset clock times that name none
104
+ * @returns The match, or null
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * detectUsageLimit("You've hit your limit · resets 3pm (America/Los_Angeles)", 'claude-code');
109
+ * // { runtime: 'claude-code', ruleId: 'claude.hit_your_limit', kind: 'usage_limit', resetAt: <next 3pm LA> }
110
+ * ```
111
+ */
112
+ export declare function detectUsageLimit(output: string, runtime: string, now?: number, defaultTimeZone?: string): UsageLimitMatch | null;
113
+ //# sourceMappingURL=usage-limit-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-limit-rules.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/usage-limit-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAOH;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAE9D;AAED,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC9B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,+DAA+D;IAC/D,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IACvB,qEAAqE;IACrE,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzB;AAED,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC/B,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,gEAAgE;IAChE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AASD,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,EAAE,SAAS,cAAc,EAuDvD,CAAC;AAEF,mBAAmB;AACnB,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EAmBtD,CAAC;AAoBF,6BAA6B;AAC7B,eAAO,MAAM,uBAAuB,EAAE,SAAS,cAAc,EAA8D,CAAC;AAE5H,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,EAAE,SAAS,cAAc,EAAoD,CAAC;AAE7G;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,cAAc,EAyB7D,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CAE7E;AAcD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAoB5I"}
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Usage-limit rules — per-runtime patterns that mean "this runtime's account
3
+ * is out of usage", as opposed to a login that expired (login-expiry-rules.ts,
4
+ * the re-login flow) or a short rate limit the runtime retries by itself.
5
+ *
6
+ * Modelled on login-expiry-rules.ts: output is normalized with
7
+ * {@link normalizeTerminalOutput} and every pattern is matched against the
8
+ * normalized text and its spaceless copy (Claude Code places words with
9
+ * cursor moves instead of spaces), so patterns use `\s*` between words.
10
+ *
11
+ * Wording sources:
12
+ * - Claude Code 2.1.287 binary (`strings`, 2026-10-01): `Usage limit
13
+ * reached`, `Usage limit reached again`, `continuing automatically {when}`,
14
+ * `You're out of extra usage`, `You're out of usage credits`, `You've hit
15
+ * your monthly spend limit`, ` resets $…`, `/upgrade to increase your usage
16
+ * limit.`, the API's `billing_error` "spend limit reached (daily; resets …)",
17
+ * and its own note that the client composes "You've hit your limit" from a
18
+ * 429. Older releases print `5-hour limit reached ∙ resets 3pm`, `Claude
19
+ * usage limit reached. Your limit will reset at 3pm (America/Los_Angeles).`
20
+ * and `Claude AI usage limit reached|<epoch>`.
21
+ * - Codex: `You've hit your usage limit. Upgrade to Pro (…) or try again in
22
+ * 4 days 7 hours 3 minutes.` / `… try again at 4:05 PM.`; transient:
23
+ * `exceeded retry limit, last status: 429 Too Many Requests`.
24
+ * - Gemini / Antigravity: `RESOURCE_EXHAUSTED` with `Quota exceeded for quota
25
+ * metric '… per day'`, `You exceeded your current quota`, `You have
26
+ * exhausted your daily quota`; a bare 429 / RESOURCE_EXHAUSTED is transient.
27
+ * - DeepSeek (the in-process Crewly Agent): HTTP 402 `Insufficient Balance`
28
+ * is a `billing` limit (no reset; the owner must top up); HTTP 429 `Rate Limit Reached` is transient.
29
+ *
30
+ * Context requirements keep an agent that merely reads or quotes this kind of
31
+ * text (for example while working on this file) from tripping a rule: the
32
+ * Claude UI rules need the `·` / `∙` separator, a reset time or a slash
33
+ * command next to the message; API rules need the API error context.
34
+ * Warnings that the limit is near ("Approaching usage limit", "You've used
35
+ * 90% of your session limit") are deliberately not matched.
36
+ *
37
+ * @module services/runtime-fallback/usage-limit-rules
38
+ */
39
+ import { RUNTIME_TYPES } from '../../constants.js';
40
+ import { normalizeTerminalOutput } from '../harness/login-rules.js';
41
+ import { detectLoginExpiry } from '../harness/login-expiry-rules.js';
42
+ import { parseResetTime } from './reset-time.js';
43
+ /**
44
+ * Whether a kind means the runtime cannot be used (as opposed to a transient
45
+ * rate limit).
46
+ *
47
+ * @param kind - Match kind
48
+ * @returns True for `usage_limit` and `billing`
49
+ */
50
+ export function isExhaustingKind(kind) {
51
+ return kind === 'usage_limit' || kind === 'billing';
52
+ }
53
+ /** Claude UI context: the separator, a reset time, or a Claude slash command. */
54
+ const CLAUDE_UI_CONTEXT = /[·∙•]|\bresets?\b|reset\s*at|continuing\s*automatically|\/(?:upgrade|extra-usage|usage-credits|rate-limit-options|model)\b|\|\s*\d{10}\b/i;
55
+ /** API error context for Claude: a 429 / billing error. */
56
+ const CLAUDE_API_429 = /\b429\b|rate_limit_error|billing_error/i;
57
+ /** Wording that means "usage", not a per-minute rate. */
58
+ const USAGE_WORDING = /usage\s*limit|limit\s*reached|hit\s*your\s*(?:[\w-]+\s*)?limit|spend\s*limit|quota|limit\s*will\s*reset|\bresets?\b|out\s*of\s*(?:extra\s*)?usage/i;
59
+ /** Claude Code rules (usage limits first, then transient). */
60
+ export const CLAUDE_USAGE_RULES = [
61
+ {
62
+ id: 'claude.api_usage_429',
63
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
64
+ kind: 'usage_limit',
65
+ all: [/API\s*Error|"type"\s*:\s*"error"/i, CLAUDE_API_429, USAGE_WORDING],
66
+ },
67
+ {
68
+ id: 'claude.api_credit_balance',
69
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
70
+ kind: 'billing',
71
+ all: [/API\s*Error|"type"\s*:\s*"error"/i, /credit\s*balance\s*(?:is\s*)?too\s*low/i],
72
+ },
73
+ {
74
+ id: 'claude.legacy_limit_reached',
75
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
76
+ kind: 'usage_limit',
77
+ all: [/Claude\s*(?:AI\s*)?usage\s*limit\s*reached\s*(?:\|\s*\d{10}|\.\s*Your\s*limit\s*will\s*reset)/i],
78
+ },
79
+ {
80
+ id: 'claude.hit_your_limit',
81
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
82
+ kind: 'usage_limit',
83
+ all: [/You['’]ve\s*hit\s*your\s*(?:[\w-]+\s*){0,3}limit/i, CLAUDE_UI_CONTEXT],
84
+ },
85
+ {
86
+ id: 'claude.usage_limit_reached',
87
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
88
+ kind: 'usage_limit',
89
+ all: [/usage\s*(?:credit\s*)?limit\s*reached/i, CLAUDE_UI_CONTEXT],
90
+ },
91
+ {
92
+ id: 'claude.window_limit_reached',
93
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
94
+ kind: 'usage_limit',
95
+ all: [/(?:5-hour|five-hour|weekly|session|daily|Opus|Sonnet|Fable)\s*limit\s*reached/i, CLAUDE_UI_CONTEXT],
96
+ },
97
+ {
98
+ id: 'claude.out_of_usage',
99
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
100
+ kind: 'usage_limit',
101
+ all: [/You['’]re\s*out\s*of\s*(?:extra\s*usage|usage\s*credits)/i, CLAUDE_UI_CONTEXT],
102
+ },
103
+ {
104
+ id: 'claude.api_rate_limited',
105
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
106
+ kind: 'transient',
107
+ all: [/API\s*Error/i, /\b429\b|rate_limit_error/i],
108
+ },
109
+ {
110
+ id: 'claude.api_overloaded',
111
+ runtime: RUNTIME_TYPES.CLAUDE_CODE,
112
+ kind: 'transient',
113
+ all: [/API\s*Error/i, /\b529\b|overloaded_error/i],
114
+ },
115
+ ];
116
+ /** Codex rules. */
117
+ export const CODEX_USAGE_RULES = [
118
+ {
119
+ id: 'codex.usage_limit',
120
+ runtime: RUNTIME_TYPES.CODEX_CLI,
121
+ kind: 'usage_limit',
122
+ all: [/You['’]ve\s*hit\s*your\s*usage\s*limit/i, /try\s*again|upgrade|resets?/i],
123
+ },
124
+ {
125
+ id: 'codex.quota_exceeded',
126
+ runtime: RUNTIME_TYPES.CODEX_CLI,
127
+ kind: 'billing',
128
+ all: [/insufficient_quota|exceeded\s*your\s*current\s*quota/i],
129
+ },
130
+ {
131
+ id: 'codex.rate_limited',
132
+ runtime: RUNTIME_TYPES.CODEX_CLI,
133
+ kind: 'transient',
134
+ all: [/\b429\b\s*Too\s*Many\s*Requests|exceeded\s*retry\s*limit|rate\s*limit\s*reached\s*for/i],
135
+ },
136
+ ];
137
+ /** Gemini quota rules, shared by Antigravity CLI and Gemini CLI. */
138
+ function geminiRules(runtime, prefix) {
139
+ return [
140
+ {
141
+ id: `${prefix}.quota_exceeded`,
142
+ runtime,
143
+ kind: 'usage_limit',
144
+ all: [/exceeded\s*your\s*current\s*quota|exhausted\s*your\s*(?:daily\s*)?quota|quota\s*exceeded\s*for\s*quota\s*metric[^\n]*per\s*day|daily\s*(?:quota|limit)\s*(?:exceeded|reached)/i],
145
+ },
146
+ {
147
+ id: `${prefix}.rate_limited`,
148
+ runtime,
149
+ kind: 'transient',
150
+ all: [/RESOURCE_EXHAUSTED|\b429\b\s*Too\s*Many\s*Requests|status\s*(?:code\s*)?:?\s*429|Resource\s*has\s*been\s*exhausted/i],
151
+ },
152
+ ];
153
+ }
154
+ /** Antigravity CLI rules. */
155
+ export const ANTIGRAVITY_USAGE_RULES = geminiRules(RUNTIME_TYPES.ANTIGRAVITY_CLI, 'antigravity');
156
+ /** Gemini CLI rules (retired runtime, detect only). */
157
+ export const GEMINI_USAGE_RULES = geminiRules(RUNTIME_TYPES.GEMINI_CLI, 'gemini');
158
+ /**
159
+ * In-process Crewly Agent rules. These run on the error of a failed model
160
+ * call (never on text the model wrote), so they need no UI context.
161
+ */
162
+ export const CREWLY_AGENT_USAGE_RULES = [
163
+ {
164
+ id: 'crewly-agent.insufficient_balance',
165
+ runtime: RUNTIME_TYPES.CREWLY_AGENT,
166
+ kind: 'billing',
167
+ all: [/Insufficient\s*Balance|\b402\b[^\n]*(?:Payment\s*Required|balance)/i],
168
+ },
169
+ {
170
+ id: 'crewly-agent.out_of_credit',
171
+ runtime: RUNTIME_TYPES.CREWLY_AGENT,
172
+ kind: 'billing',
173
+ all: [/insufficient_quota|credit\s*balance\s*(?:is\s*)?too\s*low/i],
174
+ },
175
+ {
176
+ id: 'crewly-agent.quota_exceeded',
177
+ runtime: RUNTIME_TYPES.CREWLY_AGENT,
178
+ kind: 'usage_limit',
179
+ all: [/exceeded\s*your\s*current\s*quota|exhausted\s*your\s*(?:daily\s*)?quota|usage\s*limit\s*reached/i],
180
+ },
181
+ {
182
+ id: 'crewly-agent.rate_limited',
183
+ runtime: RUNTIME_TYPES.CREWLY_AGENT,
184
+ kind: 'transient',
185
+ all: [/statusCode:?\s*429\b|status\s*(?:code\s*)?:?\s*429\b|\b429\s*Too\s*Many|Rate\s*Limit\s*Reached|Too\s*Many\s*Requests|RESOURCE_EXHAUSTED|overloaded_error|\bOverloaded\b/i],
186
+ },
187
+ ];
188
+ /** Rules by runtime. */
189
+ const RULES_BY_RUNTIME = {
190
+ [RUNTIME_TYPES.CLAUDE_CODE]: CLAUDE_USAGE_RULES,
191
+ [RUNTIME_TYPES.CODEX_CLI]: CODEX_USAGE_RULES,
192
+ [RUNTIME_TYPES.ANTIGRAVITY_CLI]: ANTIGRAVITY_USAGE_RULES,
193
+ [RUNTIME_TYPES.GEMINI_CLI]: GEMINI_USAGE_RULES,
194
+ [RUNTIME_TYPES.CREWLY_AGENT]: CREWLY_AGENT_USAGE_RULES,
195
+ };
196
+ /**
197
+ * Usage-limit rules for a runtime.
198
+ *
199
+ * @param runtime - Runtime type
200
+ * @returns Rules to try (empty for a runtime without rules)
201
+ */
202
+ export function getUsageLimitRules(runtime) {
203
+ return RULES_BY_RUNTIME[runtime] ?? [];
204
+ }
205
+ /**
206
+ * Whether a pattern matches the normalized text or its spaceless copy.
207
+ *
208
+ * @param pattern - Pattern
209
+ * @param screen - Normalized screen
210
+ * @returns True on a match
211
+ */
212
+ function matches(pattern, screen) {
213
+ const nonGlobal = new RegExp(pattern.source, pattern.flags.replace('g', ''));
214
+ return nonGlobal.test(screen.text) || nonGlobal.test(screen.spaceless);
215
+ }
216
+ /**
217
+ * Find a usage-limit (or transient rate-limit) message in a runtime's output.
218
+ * An expired login is never reported here — that is the re-login flow's.
219
+ *
220
+ * @param output - Raw PTY output (escape sequences allowed), captured screen, or an error message
221
+ * @param runtime - The runtime the output came from
222
+ * @param now - Current time (ms), for the reset time
223
+ * @param defaultTimeZone - Zone for reset clock times that name none
224
+ * @returns The match, or null
225
+ *
226
+ * @example
227
+ * ```ts
228
+ * detectUsageLimit("You've hit your limit · resets 3pm (America/Los_Angeles)", 'claude-code');
229
+ * // { runtime: 'claude-code', ruleId: 'claude.hit_your_limit', kind: 'usage_limit', resetAt: <next 3pm LA> }
230
+ * ```
231
+ */
232
+ export function detectUsageLimit(output, runtime, now = Date.now(), defaultTimeZone) {
233
+ if (!output)
234
+ return null;
235
+ const rules = getUsageLimitRules(runtime);
236
+ if (rules.length === 0)
237
+ return null;
238
+ if (detectLoginExpiry(output, runtime === RUNTIME_TYPES.CLAUDE_CODE || runtime === RUNTIME_TYPES.CODEX_CLI ? runtime : null)) {
239
+ return null;
240
+ }
241
+ const screen = normalizeTerminalOutput(output);
242
+ for (const rule of rules) {
243
+ if (!rule.all.every((pattern) => matches(pattern, screen)))
244
+ continue;
245
+ if (rule.none?.some((pattern) => matches(pattern, screen)))
246
+ continue;
247
+ return {
248
+ runtime: rule.runtime,
249
+ ruleId: rule.id,
250
+ kind: rule.kind,
251
+ // A billing limit has no reset time: it lifts when the owner tops up.
252
+ resetAt: rule.kind === 'usage_limit' ? parseResetTime(screen.text, now, defaultTimeZone) : null,
253
+ };
254
+ }
255
+ return null;
256
+ }
257
+ //# sourceMappingURL=usage-limit-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-limit-rules.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/usage-limit-rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * One responder per owner message in Slack rooms — the pure parts
3
+ * (specs/2026-10-03-one-responder-per-message.md).
4
+ *
5
+ * - {@link threadOwnerFromSlack}: who owns a Slack thread, read from the
6
+ * thread itself, so every machine names the same agent.
7
+ * - {@link findPriorRoomAnswer} / {@link heldReplyMessage}: the reply gate —
8
+ * a colleague already answered the owner's latest message in this thread.
9
+ *
10
+ * Incident (2026-10-03, #content-team): the owner's un-@'d reply to Atlas's
11
+ * D-92 reminder resolved the card (delivered to Atlas) and was also
12
+ * broadcast to the room; Atlas answered, and Ella answered the same thing
13
+ * six minutes later.
14
+ *
15
+ * @module services/slack/room-responder
16
+ */
17
+ import type { SlackContextMessage, SlackThreadContext } from '../../types/slack.types.js';
18
+ import type { ChatMessageDTO } from '../chat-v2/types.js';
19
+ /** An agent of the room, on this machine or another. */
20
+ export interface RoomAgentRef {
21
+ /** Session name (as this machine knows it; Cloud's for a remote agent) */
22
+ session: string;
23
+ /** Display name */
24
+ name: string;
25
+ /** Whether it runs on this machine */
26
+ local: boolean;
27
+ }
28
+ /** What {@link buildRoomAgentDirectory} needs. */
29
+ export interface RoomAgentDirectoryInput {
30
+ /** This machine's room members, with their own bot user id when installed */
31
+ local: ReadonlyArray<{
32
+ session: string;
33
+ name: string;
34
+ botUserId?: string | null;
35
+ }>;
36
+ /** Room members on other machines (Cloud's room roster minus this machine) */
37
+ remote: ReadonlyArray<{
38
+ session: string;
39
+ name: string;
40
+ }>;
41
+ }
42
+ /** Maps Slack authors and names to room agents. */
43
+ export interface RoomAgentDirectory {
44
+ /** The agent that wrote a Slack message, or null (a person, an unknown bot, or an unclear name) */
45
+ authorOf(m: SlackContextMessage): RoomAgentRef | null;
46
+ }
47
+ /**
48
+ * Whether two display names name the same agent: equal (case-insensitive),
49
+ * or one is the other plus a team suffix — "Ella" / "Ella (Crewly Marketing)".
50
+ *
51
+ * @param a - A name
52
+ * @param b - Another name
53
+ * @returns True when they match
54
+ */
55
+ export declare function sameAgentName(a: string, b: string): boolean;
56
+ /**
57
+ * Build the directory every machine uses to read the same thread the same way.
58
+ *
59
+ * A post by a local agent's own bot is that agent. Any other bot post is
60
+ * matched by name against the remote members — and against local members
61
+ * when it was posted with a username override (an agent with no app of its
62
+ * own). A name that matches several agents is unclear and maps to nobody.
63
+ *
64
+ * @param input - Local and remote room members
65
+ * @returns The directory
66
+ */
67
+ export declare function buildRoomAgentDirectory(input: RoomAgentDirectoryInput): RoomAgentDirectory;
68
+ /**
69
+ * Whether a Slack post is a decision card or a card reminder — the post an
70
+ * owner's reply in that thread answers. Cards carry `Decision D-n` (or
71
+ * `[D-n]` when titled by a ticket); the reminder says "Still waiting on you".
72
+ *
73
+ * @param text - Normalised Slack text
74
+ * @returns True for a card or reminder
75
+ */
76
+ export declare function isDecisionCardText(text: string): boolean;
77
+ /** Who owns a Slack thread, and by which rule. */
78
+ export interface SlackThreadOwner {
79
+ agent: RoomAgentRef;
80
+ /**
81
+ * `card`: a decision card / reminder went up since a person last spoke —
82
+ * the reply answers it, and the card's machine handles it whatever Cloud's
83
+ * presence says. `last-speaker`: the agent that spoke last.
84
+ */
85
+ via: 'card' | 'last-speaker';
86
+ }
87
+ /**
88
+ * Who owns a Slack thread (specs/2026-10-03-one-responder-per-message.md §1 c):
89
+ *
90
+ * 1. a decision card or reminder an agent posted since a person last spoke
91
+ * in the thread — the reply answers that card (the decision path's own
92
+ * rule, read from Slack so every machine agrees);
93
+ * 2. otherwise the agent that spoke last (owner's rule, 2026-09-21: a bare
94
+ * follow-up addresses whoever just spoke).
95
+ *
96
+ * @param ctx - The Slack thread before the owner's message (oldest first)
97
+ * @param dir - Room directory
98
+ * @returns The owner and the rule, or null when no agent has spoken in the thread
99
+ */
100
+ export declare function threadOwnerFromSlack(ctx: SlackThreadContext | null | undefined, dir: RoomAgentDirectory): SlackThreadOwner | null;
101
+ /** An answer already in the thread after the owner's latest message. */
102
+ export interface PriorRoomAnswer {
103
+ /** Who wrote it (display name when known, else its session) */
104
+ by: string;
105
+ /** The agent's session (local) or the recorded sender id (a colleague's Slack post) */
106
+ bySession: string;
107
+ /** The start of the answer */
108
+ excerpt: string;
109
+ /** Its chat message id */
110
+ messageId: string;
111
+ }
112
+ /**
113
+ * The responders the harness chose for a room message, as recorded on its row.
114
+ *
115
+ * @param m - Chat row
116
+ * @returns Sessions (local or Cloud names), empty when none was recorded
117
+ */
118
+ export declare function chosenRespondersOf(m: Pick<ChatMessageDTO, 'metadata'>): string[];
119
+ /**
120
+ * The reply gate (specs/2026-10-03-one-responder-per-message.md §2). A post
121
+ * is held only when ALL of these hold:
122
+ *
123
+ * - the owner's latest message in the thread has recorded responders, and
124
+ * the agent posting is not one of them nor @'d in it;
125
+ * - the agent owes no earlier owner message in this thread (it was the
126
+ * responder for, or @'d in, one it has not posted after);
127
+ * - one of those responders already answered (an interim note is not an
128
+ * answer), and that answer does not @ the agent posting.
129
+ *
130
+ * @param thread - The thread's rows, oldest first
131
+ * @param session - The agent about to post
132
+ * @param nameFor - Display name of a session, when known
133
+ * @returns The responder's answer when the post should be held, else null
134
+ */
135
+ export declare function findPriorRoomAnswer(thread: readonly ChatMessageDTO[], session: string, nameFor?: (session: string) => string | undefined): PriorRoomAnswer | null;
136
+ /**
137
+ * What the agent is told when its post is held. Never "drop it": an agent
138
+ * that was asked must still be able to answer.
139
+ *
140
+ * @param prior - The answer already there
141
+ * @returns English harness text
142
+ */
143
+ export declare function heldReplyMessage(prior: Pick<PriorRoomAnswer, 'by' | 'excerpt'>): string;
144
+ //# sourceMappingURL=room-responder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-responder.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/room-responder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,KAAK,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IACnF,8EAA8E;IAC9E,MAAM,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,mDAAmD;AACnD,MAAM,WAAW,kBAAkB;IACjC,mGAAmG;IACnG,QAAQ,CAAC,CAAC,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAAC;CACvD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAK3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,uBAAuB,GAAG,kBAAkB,CAqB1F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC;CAC9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,IAAI,CAoBjI;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAkBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAGhF;AAkBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAChD,eAAe,GAAG,IAAI,CAwCxB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,CAKvF"}