crewly 1.20.176 → 1.20.178

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 (186) hide show
  1. package/config/skills/orchestrator/update-team-member/SKILL.md +1 -1
  2. package/dist/backend/backend/src/constants.d.ts +79 -3
  3. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  4. package/dist/backend/backend/src/constants.js +97 -3
  5. package/dist/backend/backend/src/constants.js.map +1 -1
  6. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  7. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +2 -1
  8. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  9. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts +30 -0
  10. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts.map +1 -0
  11. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js +100 -0
  12. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js.map +1 -0
  13. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/team/team.controller.js +33 -4
  15. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  16. package/dist/backend/backend/src/index.d.ts.map +1 -1
  17. package/dist/backend/backend/src/index.js +25 -0
  18. package/dist/backend/backend/src/index.js.map +1 -1
  19. package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
  20. package/dist/backend/backend/src/routes/modules/system.routes.js +3 -0
  21. package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
  22. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.d.ts.map +1 -1
  23. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js +17 -0
  24. package/dist/backend/backend/src/services/agent/agent-heartbeat-monitor.service.js.map +1 -1
  25. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +10 -1
  26. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  27. package/dist/backend/backend/src/services/agent/agent-registration.service.js +103 -7
  28. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  29. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.d.ts +1 -1
  30. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
  31. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js +3 -2
  32. package/dist/backend/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
  33. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +7 -0
  34. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  35. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +16 -0
  36. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  37. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/agent/idle-detection.service.js +2 -1
  39. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  40. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  41. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +7 -0
  42. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
  43. package/dist/backend/backend/src/services/agent/planned-relaunch.registry.d.ts +61 -0
  44. package/dist/backend/backend/src/services/agent/planned-relaunch.registry.d.ts.map +1 -0
  45. package/dist/backend/backend/src/services/agent/planned-relaunch.registry.js +73 -0
  46. package/dist/backend/backend/src/services/agent/planned-relaunch.registry.js.map +1 -0
  47. package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
  49. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/harness/harness-status.service.d.ts +17 -0
  51. package/dist/backend/backend/src/services/harness/harness-status.service.d.ts.map +1 -1
  52. package/dist/backend/backend/src/services/harness/harness-status.service.js +25 -1
  53. package/dist/backend/backend/src/services/harness/harness-status.service.js.map +1 -1
  54. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +2 -1
  56. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  57. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +3 -2
  59. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
  61. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +10 -0
  62. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
  63. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +28 -1
  64. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  65. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +48 -3
  66. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  67. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +3 -2
  69. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  70. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts +100 -0
  71. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -0
  72. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js +115 -0
  73. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -0
  74. package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts +66 -0
  75. package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -0
  76. package/dist/backend/backend/src/services/runtime-fallback/reset-time.js +211 -0
  77. package/dist/backend/backend/src/services/runtime-fallback/reset-time.js.map +1 -0
  78. package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.d.ts +39 -0
  79. package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.d.ts.map +1 -0
  80. package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.js +56 -0
  81. package/dist/backend/backend/src/services/runtime-fallback/runtime-availability.js.map +1 -0
  82. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts +417 -0
  83. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -0
  84. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +974 -0
  85. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -0
  86. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.store.d.ts +53 -0
  87. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.store.d.ts.map +1 -0
  88. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.store.js +109 -0
  89. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.store.js.map +1 -0
  90. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts +134 -0
  91. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.d.ts.map +1 -0
  92. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.js +152 -0
  93. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.types.js.map +1 -0
  94. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts +95 -0
  95. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -0
  96. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +286 -0
  97. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -0
  98. package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.d.ts +203 -0
  99. package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.d.ts.map +1 -0
  100. package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.js +419 -0
  101. package/dist/backend/backend/src/services/runtime-fallback/runtime-smoke-test.service.js.map +1 -0
  102. package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.d.ts +94 -0
  103. package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.d.ts.map +1 -0
  104. package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.js +186 -0
  105. package/dist/backend/backend/src/services/runtime-fallback/runtime-usage-probe.js.map +1 -0
  106. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +113 -0
  107. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -0
  108. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js +257 -0
  109. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -0
  110. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +8 -0
  111. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  112. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +16 -2
  113. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  114. package/dist/backend/backend/src/services/task-pool/claim.service.d.ts.map +1 -1
  115. package/dist/backend/backend/src/services/task-pool/claim.service.js +3 -1
  116. package/dist/backend/backend/src/services/task-pool/claim.service.js.map +1 -1
  117. package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
  118. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +3 -2
  119. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
  120. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  121. package/dist/backend/backend/src/services/workflow/scheduler.service.js +3 -2
  122. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  123. package/dist/backend/backend/src/types/index.d.ts +14 -0
  124. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  125. package/dist/backend/backend/src/types/index.js.map +1 -1
  126. package/dist/backend/build-info.json +2 -2
  127. package/dist/cli/backend/src/constants.d.ts +79 -3
  128. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  129. package/dist/cli/backend/src/constants.js +97 -3
  130. package/dist/cli/backend/src/constants.js.map +1 -1
  131. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +10 -1
  132. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  133. package/dist/cli/backend/src/services/agent/agent-registration.service.js +103 -7
  134. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  135. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.d.ts +1 -1
  136. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.d.ts.map +1 -1
  137. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js +3 -2
  138. package/dist/cli/backend/src/services/agent/antigravity-runtime.service.js.map +1 -1
  139. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +7 -0
  140. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  141. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +16 -0
  142. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  143. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  144. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +7 -0
  145. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
  146. package/dist/cli/backend/src/services/agent/planned-relaunch.registry.d.ts +61 -0
  147. package/dist/cli/backend/src/services/agent/planned-relaunch.registry.d.ts.map +1 -0
  148. package/dist/cli/backend/src/services/agent/planned-relaunch.registry.js +73 -0
  149. package/dist/cli/backend/src/services/agent/planned-relaunch.registry.js.map +1 -0
  150. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts +17 -0
  151. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts.map +1 -1
  152. package/dist/cli/backend/src/services/harness/harness-status.service.js +25 -1
  153. package/dist/cli/backend/src/services/harness/harness-status.service.js.map +1 -1
  154. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  155. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +2 -1
  156. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  157. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  158. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js +3 -2
  159. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  160. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +28 -1
  161. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  162. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js +48 -3
  163. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  164. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  165. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js +3 -2
  166. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  167. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts +100 -0
  168. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -0
  169. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js +115 -0
  170. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -0
  171. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +8 -0
  172. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  173. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +16 -2
  174. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  175. package/dist/cli/backend/src/services/task-pool/claim.service.d.ts.map +1 -1
  176. package/dist/cli/backend/src/services/task-pool/claim.service.js +3 -1
  177. package/dist/cli/backend/src/services/task-pool/claim.service.js.map +1 -1
  178. package/dist/cli/backend/src/types/index.d.ts +14 -0
  179. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  180. package/dist/cli/backend/src/types/index.js.map +1 -1
  181. package/dist/cli/cli/src/utils/runtime-auth.d.ts +1 -1
  182. package/dist/cli/cli/src/utils/runtime-auth.js +1 -1
  183. package/frontend/dist/assets/{index-0726afab.js → index-69af46c3.js} +275 -275
  184. package/frontend/dist/assets/{index-0c5449b5.css → index-cdc52122.css} +1 -1
  185. package/frontend/dist/index.html +2 -2
  186. package/package.json +1 -1
@@ -0,0 +1,115 @@
1
+ /**
2
+ * The runtime an agent really runs on, for code that only knows the
3
+ * member's configured runtime.
4
+ *
5
+ * While an agent runs on a fallback runtime (its runtime ran out of usage)
6
+ * the member record still names its configured runtime. Every place that
7
+ * decides HOW to talk to a session (PTY heuristics, Ctrl+C, delivery,
8
+ * activity detection) asks {@link effectiveRuntimeType} instead.
9
+ *
10
+ * This module holds only the hooks the RuntimeFallbackService registers, so
11
+ * importing it is cheap and cycle-free; with no service registered every
12
+ * function is a no-op that returns the configured value.
13
+ *
14
+ * @module services/runtime-fallback/effective-runtime
15
+ */
16
+ let hooks = null;
17
+ /**
18
+ * Register (or clear) the hooks.
19
+ *
20
+ * @param next - Hooks, or null
21
+ */
22
+ export function setRuntimeFallbackHooks(next) {
23
+ hooks = next;
24
+ }
25
+ /**
26
+ * The runtime a session actually runs on.
27
+ *
28
+ * @param sessionName - Session name (undefined → configured)
29
+ * @param configured - Its configured runtime
30
+ * @returns The fallback runtime while one is active, else `configured`
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const runtime = effectiveRuntimeType(member.sessionName, member.runtimeType as RuntimeType);
35
+ * ```
36
+ */
37
+ export function effectiveRuntimeType(sessionName, configured) {
38
+ if (!hooks || !sessionName)
39
+ return configured;
40
+ try {
41
+ return hooks.overrideFor(sessionName) ?? configured;
42
+ }
43
+ catch {
44
+ return configured;
45
+ }
46
+ }
47
+ /**
48
+ * Decide the runtime to launch a session on.
49
+ *
50
+ * @param input - Session and its configured runtime
51
+ * @returns The decision (configured runtime when no hooks are registered)
52
+ */
53
+ export async function resolveLaunchRuntime(input) {
54
+ if (!hooks)
55
+ return { runtime: input.configured, overridden: false };
56
+ try {
57
+ return await hooks.resolveLaunch(input);
58
+ }
59
+ catch {
60
+ return { runtime: input.configured, overridden: false };
61
+ }
62
+ }
63
+ /**
64
+ * Gate before a delivery.
65
+ *
66
+ * @param sessionName - Target session
67
+ * @param runtime - Runtime the caller resolved
68
+ * @returns `queue` when the message must wait for a runtime switch
69
+ */
70
+ export function runtimeFallbackBeforeDelivery(sessionName, runtime) {
71
+ if (!hooks)
72
+ return 'deliver';
73
+ try {
74
+ return hooks.beforeDelivery(sessionName, runtime);
75
+ }
76
+ catch {
77
+ return 'deliver';
78
+ }
79
+ }
80
+ /**
81
+ * Report runtime output (live chunk, screen, or an error) for usage-limit detection.
82
+ *
83
+ * @param sessionName - Session
84
+ * @param runtime - Runtime it runs on
85
+ * @param text - Output / error text (never logged)
86
+ * @param source - Where it came from
87
+ * @returns True when a usage limit was recognised
88
+ */
89
+ export function reportRuntimeOutput(sessionName, runtime, text, source) {
90
+ if (!hooks || !text)
91
+ return false;
92
+ try {
93
+ return hooks.reportOutput(sessionName, runtime, text, source);
94
+ }
95
+ catch {
96
+ return false;
97
+ }
98
+ }
99
+ /**
100
+ * Take the note a session's next kickoff should carry after a switch.
101
+ *
102
+ * @param sessionName - Session
103
+ * @returns The note, once, or null
104
+ */
105
+ export function takeRuntimeSwitchKickoffNote(sessionName) {
106
+ if (!hooks)
107
+ return null;
108
+ try {
109
+ return hooks.takeKickoffNote(sessionName);
110
+ }
111
+ catch {
112
+ return null;
113
+ }
114
+ }
115
+ //# sourceMappingURL=effective-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effective-runtime.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/effective-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAuCH,IAAI,KAAK,GAAgC,IAAI,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAiC;IACxE,KAAK,GAAG,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAmB,WAAsC,EAAE,UAAa;IAC3G,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW;QAAE,OAAO,UAAU,CAAC;IAC9C,IAAI,CAAC;QACJ,OAAQ,KAAK,CAAC,WAAW,CAAC,WAAW,CAAc,IAAI,UAAU,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,UAAU,CAAC;IACnB,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAyB;IACnE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACpE,IAAI,CAAC;QACJ,OAAO,MAAM,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAAC,WAAmB,EAAE,OAAe;IACjF,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,IAAI,CAAC;QACJ,OAAO,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB,EAAE,OAAe,EAAE,IAAY,EAAE,MAA2B;IAClH,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,CAAC;QACJ,OAAO,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,WAAmB;IAC/D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACJ,OAAO,KAAK,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Reset-time parsing for usage-limit messages.
3
+ *
4
+ * Runtimes say when a usage limit lifts in many shapes:
5
+ *
6
+ * - Claude Code: `You've hit your limit · resets 3pm (America/Los_Angeles)`,
7
+ * `resets Oct 6, 9am`, `Your limit will reset at 5pm (Asia/Shanghai).`,
8
+ * `continuing automatically at 3pm`, the old `usage limit reached|1767225600`
9
+ * (epoch seconds) and the API's `resets 2026-08-08 00:00 UTC`.
10
+ * - Codex: `try again at 4:05 PM`, `try again at Oct 3rd, 2026 4:05 PM`,
11
+ * `try again in 4 days 7 hours 3 minutes`.
12
+ * - Others: `retry in 45s`, `resets in 2h 5m`.
13
+ *
14
+ * A clock time without a date is the next time that clock time comes round
15
+ * (in the named IANA time zone, else this machine's). Unparseable text
16
+ * gives null — the caller then relies on the switch-back probe.
17
+ *
18
+ * @module services/runtime-fallback/reset-time
19
+ */
20
+ /** Wall-clock parts in a time zone. */
21
+ interface WallParts {
22
+ year: number;
23
+ month: number;
24
+ day: number;
25
+ hour: number;
26
+ minute: number;
27
+ }
28
+ /**
29
+ * Whether a string is a time zone `Intl` accepts.
30
+ *
31
+ * @param tz - Candidate (IANA name or `UTC`)
32
+ * @returns True when usable
33
+ */
34
+ export declare function isValidTimeZone(tz: string | null | undefined): tz is string;
35
+ /**
36
+ * The instant at which a wall-clock time occurs in a time zone.
37
+ *
38
+ * @param wall - Wall-clock parts
39
+ * @param tz - Time zone (undefined = this machine's)
40
+ * @returns Epoch ms
41
+ */
42
+ export declare function zonedWallTimeToEpoch(wall: WallParts, tz: string | undefined): number;
43
+ /**
44
+ * Parse a relative duration like `4 days 7 hours 3 minutes` / `2h 5m`.
45
+ *
46
+ * @param text - Duration text
47
+ * @returns Milliseconds, or null
48
+ */
49
+ export declare function parseRelativeDuration(text: string): number | null;
50
+ /**
51
+ * Find when a usage limit resets, from the text of the limit message.
52
+ *
53
+ * @param text - Normalized terminal / error text
54
+ * @param now - Current time (ms)
55
+ * @param defaultTimeZone - Zone for clock times that name none (default: this machine's)
56
+ * @returns Epoch ms of the reset, or null when the text names none
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * parseResetTime("You've hit your limit · resets 3pm (UTC)", Date.UTC(2026, 9, 1, 12));
61
+ * // Date.UTC(2026, 9, 1, 15)
62
+ * ```
63
+ */
64
+ export declare function parseResetTime(text: string, now: number, defaultTimeZone?: string): number | null;
65
+ export {};
66
+ //# sourceMappingURL=reset-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-time.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/reset-time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAUH,uCAAuC;AACvC,UAAU,SAAS;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,EAAE,IAAI,MAAM,CAQ3E;AA0BD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUpF;AAsCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcjE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqDjG"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Reset-time parsing for usage-limit messages.
3
+ *
4
+ * Runtimes say when a usage limit lifts in many shapes:
5
+ *
6
+ * - Claude Code: `You've hit your limit · resets 3pm (America/Los_Angeles)`,
7
+ * `resets Oct 6, 9am`, `Your limit will reset at 5pm (Asia/Shanghai).`,
8
+ * `continuing automatically at 3pm`, the old `usage limit reached|1767225600`
9
+ * (epoch seconds) and the API's `resets 2026-08-08 00:00 UTC`.
10
+ * - Codex: `try again at 4:05 PM`, `try again at Oct 3rd, 2026 4:05 PM`,
11
+ * `try again in 4 days 7 hours 3 minutes`.
12
+ * - Others: `retry in 45s`, `resets in 2h 5m`.
13
+ *
14
+ * A clock time without a date is the next time that clock time comes round
15
+ * (in the named IANA time zone, else this machine's). Unparseable text
16
+ * gives null — the caller then relies on the switch-back probe.
17
+ *
18
+ * @module services/runtime-fallback/reset-time
19
+ */
20
+ /** Month names → 0-based month. */
21
+ const MONTHS = {
22
+ jan: 0, feb: 1, mar: 2, apr: 3, may: 4, jun: 5, jul: 6, aug: 7, sep: 8, sept: 8, oct: 9, nov: 10, dec: 11,
23
+ };
24
+ /** One day in ms. */
25
+ const DAY_MS = 24 * 60 * 60 * 1000;
26
+ /**
27
+ * Whether a string is a time zone `Intl` accepts.
28
+ *
29
+ * @param tz - Candidate (IANA name or `UTC`)
30
+ * @returns True when usable
31
+ */
32
+ export function isValidTimeZone(tz) {
33
+ if (!tz)
34
+ return false;
35
+ try {
36
+ new Intl.DateTimeFormat('en-US', { timeZone: tz });
37
+ return true;
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ /**
44
+ * Wall-clock parts of an instant in a time zone.
45
+ *
46
+ * @param epochMs - Instant
47
+ * @param tz - Time zone (undefined = this machine's)
48
+ * @returns Parts
49
+ */
50
+ function wallPartsAt(epochMs, tz) {
51
+ const fmt = new Intl.DateTimeFormat('en-US', {
52
+ timeZone: tz,
53
+ hourCycle: 'h23',
54
+ year: 'numeric',
55
+ month: 'numeric',
56
+ day: 'numeric',
57
+ hour: 'numeric',
58
+ minute: 'numeric',
59
+ });
60
+ const parts = {};
61
+ for (const p of fmt.formatToParts(new Date(epochMs))) {
62
+ if (p.type !== 'literal')
63
+ parts[p.type] = Number(p.value);
64
+ }
65
+ return { year: parts.year, month: parts.month - 1, day: parts.day, hour: parts.hour % 24, minute: parts.minute };
66
+ }
67
+ /**
68
+ * The instant at which a wall-clock time occurs in a time zone.
69
+ *
70
+ * @param wall - Wall-clock parts
71
+ * @param tz - Time zone (undefined = this machine's)
72
+ * @returns Epoch ms
73
+ */
74
+ export function zonedWallTimeToEpoch(wall, tz) {
75
+ const target = Date.UTC(wall.year, wall.month, wall.day, wall.hour, wall.minute);
76
+ let guess = target;
77
+ // Two passes settle the offset, also across a DST change.
78
+ for (let i = 0; i < 2; i += 1) {
79
+ const seen = wallPartsAt(guess, tz);
80
+ const seenAsUtc = Date.UTC(seen.year, seen.month, seen.day, seen.hour, seen.minute);
81
+ guess += target - seenAsUtc;
82
+ }
83
+ return guess;
84
+ }
85
+ /**
86
+ * Convert a 12/24-hour clock reading to 24-hour.
87
+ *
88
+ * @param hour - Hour as written
89
+ * @param meridiem - `am` / `pm` / undefined
90
+ * @returns Hour 0–23, or null when invalid
91
+ */
92
+ function to24h(hour, meridiem) {
93
+ if (!Number.isFinite(hour))
94
+ return null;
95
+ const m = meridiem?.toLowerCase().replace(/\./g, '');
96
+ if (m === 'am' || m === 'pm') {
97
+ if (hour < 1 || hour > 12)
98
+ return null;
99
+ return (hour % 12) + (m === 'pm' ? 12 : 0);
100
+ }
101
+ return hour >= 0 && hour <= 23 ? hour : null;
102
+ }
103
+ /** A clock reading: `3pm`, `4:05 PM`, `15:00`, `9am`. */
104
+ const CLOCK = String.raw `(\d{1,2})(?::(\d{2}))?\s*(a\.?m\.?|p\.?m\.?)?`;
105
+ /** An optional date before the clock: `Oct 6,`, `Oct 3rd, 2026`, `on Oct 6 at`. */
106
+ const DATE = String.raw `(?:(?:on\s+)?([A-Za-z]{3,9})\.?\s+(\d{1,2})(?:st|nd|rd|th)?,?\s*(\d{4})?,?\s*(?:at\s+)?)?`;
107
+ /** A trailing time zone: `(America/Los_Angeles)`, `(UTC)`, ` UTC`. */
108
+ const ZONE = String.raw `(?:\s*\(([A-Za-z_]+(?:\/[A-Za-z0-9_+\-]+)*)\)|\s+(UTC|GMT)\b)?`;
109
+ /** What introduces an absolute reset time. */
110
+ const ABSOLUTE_LEAD = String.raw `(?:resets?|reset\s+at|resets?\s+at|try\s+again\s+(?:at|after)|available\s+again\s+at|continuing\s+automatically(?:\s+at)?|until)`;
111
+ /** Absolute: lead + optional date + clock + optional zone. */
112
+ const ABSOLUTE_RE = new RegExp(String.raw `${ABSOLUTE_LEAD}\s+(?:at\s+)?${DATE}${CLOCK}${ZONE}`, 'i');
113
+ /** ISO-ish: `resets 2026-08-08 00:00 UTC`. */
114
+ const ISO_RE = /(?:resets?|try\s+again\s+at|until)\s+(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})(?::\d{2})?\s*(Z|UTC|GMT)?/i;
115
+ /** Epoch seconds after a pipe: `usage limit reached|1767225600`. */
116
+ const EPOCH_RE = /limit\s*reached\s*\|\s*(\d{10})\b/i;
117
+ /** Relative: `try again in 4 days 7 hours 3 minutes`, `resets in 2h 5m`, `retry in 45s`. */
118
+ const RELATIVE_RE = /(?:try\s+again|resets?|retry|available\s+again)\s+in\s+((?:\d+(?:\.\d+)?\s*(?:days?|d|hours?|hrs?|h|minutes?|mins?|m|seconds?|secs?|s)\b[\s,]*(?:and\s+)?)+)/i;
119
+ /**
120
+ * Parse a relative duration like `4 days 7 hours 3 minutes` / `2h 5m`.
121
+ *
122
+ * @param text - Duration text
123
+ * @returns Milliseconds, or null
124
+ */
125
+ export function parseRelativeDuration(text) {
126
+ const re = /(\d+(?:\.\d+)?)\s*(days?|d|hours?|hrs?|h|minutes?|mins?|m|seconds?|secs?|s)\b/gi;
127
+ let total = 0;
128
+ let found = false;
129
+ for (const m of text.matchAll(re)) {
130
+ const n = Number(m[1]);
131
+ const unit = m[2].toLowerCase();
132
+ found = true;
133
+ if (unit.startsWith('d'))
134
+ total += n * DAY_MS;
135
+ else if (unit.startsWith('h'))
136
+ total += n * 60 * 60 * 1000;
137
+ else if (unit.startsWith('m'))
138
+ total += n * 60 * 1000;
139
+ else
140
+ total += n * 1000;
141
+ }
142
+ return found && total > 0 ? total : null;
143
+ }
144
+ /**
145
+ * Find when a usage limit resets, from the text of the limit message.
146
+ *
147
+ * @param text - Normalized terminal / error text
148
+ * @param now - Current time (ms)
149
+ * @param defaultTimeZone - Zone for clock times that name none (default: this machine's)
150
+ * @returns Epoch ms of the reset, or null when the text names none
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * parseResetTime("You've hit your limit · resets 3pm (UTC)", Date.UTC(2026, 9, 1, 12));
155
+ * // Date.UTC(2026, 9, 1, 15)
156
+ * ```
157
+ */
158
+ export function parseResetTime(text, now, defaultTimeZone) {
159
+ if (!text)
160
+ return null;
161
+ const epoch = EPOCH_RE.exec(text);
162
+ if (epoch)
163
+ return Number(epoch[1]) * 1000;
164
+ const iso = ISO_RE.exec(text);
165
+ if (iso) {
166
+ const [, y, mo, d, h, mi, zone] = iso;
167
+ const wall = { year: Number(y), month: Number(mo) - 1, day: Number(d), hour: Number(h), minute: Number(mi) };
168
+ return zone ? Date.UTC(wall.year, wall.month, wall.day, wall.hour, wall.minute) : zonedWallTimeToEpoch(wall, defaultTimeZone);
169
+ }
170
+ const rel = RELATIVE_RE.exec(text);
171
+ if (rel) {
172
+ const ms = parseRelativeDuration(rel[1]);
173
+ if (ms !== null)
174
+ return now + ms;
175
+ }
176
+ const abs = ABSOLUTE_RE.exec(text);
177
+ if (abs) {
178
+ const [, monthName, dayText, yearText, hourText, minuteText, meridiem, zoneName, zoneAbbrev] = abs;
179
+ const hour = to24h(Number(hourText), meridiem);
180
+ const minute = minuteText ? Number(minuteText) : 0;
181
+ // A bare number with no meridiem, no minutes and no date ("resets 3")
182
+ // is too ambiguous to trust.
183
+ if (hour === null || minute > 59 || (!meridiem && !minuteText && !monthName))
184
+ return null;
185
+ const zoneCandidate = zoneName ?? zoneAbbrev;
186
+ const tz = isValidTimeZone(zoneCandidate) ? zoneCandidate : isValidTimeZone(defaultTimeZone) ? defaultTimeZone : undefined;
187
+ const today = wallPartsAt(now, tz);
188
+ if (monthName) {
189
+ const month = MONTHS[monthName.slice(0, 4).toLowerCase()] ?? MONTHS[monthName.slice(0, 3).toLowerCase()];
190
+ const day = Number(dayText);
191
+ if (month === undefined || !(day >= 1 && day <= 31))
192
+ return null;
193
+ let year = yearText ? Number(yearText) : today.year;
194
+ let at = zonedWallTimeToEpoch({ year, month, day, hour, minute }, tz);
195
+ // "Jan 2" written in late December means next year.
196
+ if (!yearText && at < now - DAY_MS) {
197
+ year += 1;
198
+ at = zonedWallTimeToEpoch({ year, month, day, hour, minute }, tz);
199
+ }
200
+ return at;
201
+ }
202
+ let at = zonedWallTimeToEpoch({ year: today.year, month: today.month, day: today.day, hour, minute }, tz);
203
+ if (at <= now) {
204
+ const tomorrow = wallPartsAt(now + DAY_MS, tz);
205
+ at = zonedWallTimeToEpoch({ year: tomorrow.year, month: tomorrow.month, day: tomorrow.day, hour, minute }, tz);
206
+ }
207
+ return at;
208
+ }
209
+ return null;
210
+ }
211
+ //# sourceMappingURL=reset-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-time.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/reset-time.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Which runtimes can be a fallback right now: installed and signed in.
3
+ *
4
+ * - Harness runtimes (Claude Code, Codex, Antigravity): the harness status
5
+ * (`GET /api/harness`) must say installed and `logged_in`.
6
+ * - The Crewly Agent ships with Crewly; it needs an API key for its model's
7
+ * provider (DeepSeek by default).
8
+ * - Gemini CLI is retired; OpenCode has no login check Crewly can run.
9
+ *
10
+ * @module services/runtime-fallback/runtime-availability
11
+ */
12
+ import { type RuntimeAvailability } from './runtime-fallback.types.js';
13
+ /** The harness facts availability needs. */
14
+ export interface HarnessFacts {
15
+ id: string;
16
+ installed: boolean;
17
+ loginState: 'logged_in' | 'logged_out' | 'unknown';
18
+ }
19
+ /** Inputs of {@link computeRuntimeAvailability}. */
20
+ export interface AvailabilityInput {
21
+ harnesses: readonly HarnessFacts[];
22
+ /** provider/model the Crewly Agent fallback runs */
23
+ crewlyAgentModel: string;
24
+ /** Whether an API key is configured for a provider (`deepseek`, `google`, …) */
25
+ hasProviderKey: (provider: string) => boolean;
26
+ }
27
+ /**
28
+ * Availability of every runtime.
29
+ *
30
+ * @param input - Harness facts, Crewly Agent model, key lookup
31
+ * @returns One entry per known runtime, in a stable order
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * computeRuntimeAvailability({ harnesses: [{ id: 'claude-code', installed: true, loginState: 'logged_in' }], crewlyAgentModel: 'deepseek/deepseek-chat', hasProviderKey: () => true });
36
+ * ```
37
+ */
38
+ export declare function computeRuntimeAvailability(input: AvailabilityInput): RuntimeAvailability[];
39
+ //# sourceMappingURL=runtime-availability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-availability.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/runtime-availability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAErG,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;CACnD;AAED,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,SAAS,YAAY,EAAE,CAAC;IACnC,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CAC9C;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,GAAG,mBAAmB,EAAE,CAgB1F"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Which runtimes can be a fallback right now: installed and signed in.
3
+ *
4
+ * - Harness runtimes (Claude Code, Codex, Antigravity): the harness status
5
+ * (`GET /api/harness`) must say installed and `logged_in`.
6
+ * - The Crewly Agent ships with Crewly; it needs an API key for its model's
7
+ * provider (DeepSeek by default).
8
+ * - Gemini CLI is retired; OpenCode has no login check Crewly can run.
9
+ *
10
+ * @module services/runtime-fallback/runtime-availability
11
+ */
12
+ import { RUNTIME_TYPES } from '../../constants.js';
13
+ import { KNOWN_RUNTIMES, runtimeLabel } from './runtime-fallback.types.js';
14
+ /** Provider display names. */
15
+ const PROVIDER_NAMES = {
16
+ deepseek: 'DeepSeek',
17
+ google: 'Gemini',
18
+ anthropic: 'Anthropic',
19
+ openai: 'OpenAI',
20
+ ollama: 'Ollama',
21
+ };
22
+ /**
23
+ * Availability of every runtime.
24
+ *
25
+ * @param input - Harness facts, Crewly Agent model, key lookup
26
+ * @returns One entry per known runtime, in a stable order
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * computeRuntimeAvailability({ harnesses: [{ id: 'claude-code', installed: true, loginState: 'logged_in' }], crewlyAgentModel: 'deepseek/deepseek-chat', hasProviderKey: () => true });
31
+ * ```
32
+ */
33
+ export function computeRuntimeAvailability(input) {
34
+ return KNOWN_RUNTIMES.map((runtime) => {
35
+ const label = runtimeLabel(runtime, input.crewlyAgentModel);
36
+ if (runtime === RUNTIME_TYPES.CREWLY_AGENT) {
37
+ const provider = input.crewlyAgentModel.split('/')[0] ?? '';
38
+ if (input.hasProviderKey(provider))
39
+ return { runtime, label, selectable: true };
40
+ return { runtime, label, selectable: false, reason: `No ${PROVIDER_NAMES[provider] ?? provider} API key (Settings → API Keys)` };
41
+ }
42
+ if (runtime === RUNTIME_TYPES.GEMINI_CLI)
43
+ return { runtime, label, selectable: false, reason: 'Retired (enterprise only)' };
44
+ if (runtime === RUNTIME_TYPES.OPENCODE_CLI)
45
+ return { runtime, label, selectable: false, reason: "Crewly can't check its sign-in" };
46
+ const harness = input.harnesses.find((h) => h.id === runtime);
47
+ if (!harness || !harness.installed)
48
+ return { runtime, label, selectable: false, reason: 'Not installed' };
49
+ if (harness.loginState === 'logged_out')
50
+ return { runtime, label, selectable: false, reason: 'Not signed in' };
51
+ if (harness.loginState !== 'logged_in')
52
+ return { runtime, label, selectable: false, reason: "Sign-in couldn't be checked" };
53
+ return { runtime, label, selectable: true };
54
+ });
55
+ }
56
+ //# sourceMappingURL=runtime-availability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-availability.js","sourceRoot":"","sources":["../../../../../../backend/src/services/runtime-fallback/runtime-availability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,YAAY,EAA4B,MAAM,6BAA6B,CAAC;AAkBrG,8BAA8B;AAC9B,MAAM,cAAc,GAAqC;IACxD,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;CAChB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAwB;IAClE,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAuB,EAAE;QAC1D,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,aAAa,CAAC,YAAY,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5D,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC;gBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;YAChF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC,QAAQ,CAAC,IAAI,QAAQ,gCAAgC,EAAE,CAAC;QAClI,CAAC;QACD,IAAI,OAAO,KAAK,aAAa,CAAC,UAAU;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;QAC5H,IAAI,OAAO,KAAK,aAAa,CAAC,YAAY;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;QACnI,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAC1G,IAAI,OAAO,CAAC,UAAU,KAAK,YAAY;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAC/G,IAAI,OAAO,CAAC,UAAU,KAAK,WAAW;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;QAC5H,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;AACJ,CAAC"}