@herdctl/core 0.0.1

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 (520) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +219 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/coverage/base.css +224 -0
  5. package/coverage/block-navigation.js +87 -0
  6. package/coverage/coverage-final.json +51 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +251 -0
  9. package/coverage/prettify.css +1 -0
  10. package/coverage/prettify.js +2 -0
  11. package/coverage/sort-arrow-sprite.png +0 -0
  12. package/coverage/sorter.js +210 -0
  13. package/coverage/src/config/index.html +191 -0
  14. package/coverage/src/config/index.ts.html +442 -0
  15. package/coverage/src/config/interpolate.ts.html +652 -0
  16. package/coverage/src/config/loader.ts.html +1501 -0
  17. package/coverage/src/config/merge.ts.html +823 -0
  18. package/coverage/src/config/parser.ts.html +1213 -0
  19. package/coverage/src/config/schema.ts.html +1123 -0
  20. package/coverage/src/fleet-manager/errors.ts.html +2326 -0
  21. package/coverage/src/fleet-manager/event-types.ts.html +1219 -0
  22. package/coverage/src/fleet-manager/fleet-manager.ts.html +7030 -0
  23. package/coverage/src/fleet-manager/index.html +206 -0
  24. package/coverage/src/fleet-manager/index.ts.html +469 -0
  25. package/coverage/src/fleet-manager/job-manager.ts.html +2074 -0
  26. package/coverage/src/fleet-manager/job-queue.ts.html +2479 -0
  27. package/coverage/src/fleet-manager/types.ts.html +2602 -0
  28. package/coverage/src/index.html +116 -0
  29. package/coverage/src/index.ts.html +181 -0
  30. package/coverage/src/runner/errors.ts.html +1006 -0
  31. package/coverage/src/runner/index.html +191 -0
  32. package/coverage/src/runner/index.ts.html +256 -0
  33. package/coverage/src/runner/job-executor.ts.html +1429 -0
  34. package/coverage/src/runner/message-processor.ts.html +1150 -0
  35. package/coverage/src/runner/sdk-adapter.ts.html +658 -0
  36. package/coverage/src/runner/types.ts.html +559 -0
  37. package/coverage/src/scheduler/errors.ts.html +388 -0
  38. package/coverage/src/scheduler/index.html +206 -0
  39. package/coverage/src/scheduler/index.ts.html +244 -0
  40. package/coverage/src/scheduler/interval.ts.html +652 -0
  41. package/coverage/src/scheduler/schedule-runner.ts.html +1411 -0
  42. package/coverage/src/scheduler/schedule-state.ts.html +718 -0
  43. package/coverage/src/scheduler/scheduler.ts.html +1795 -0
  44. package/coverage/src/scheduler/types.ts.html +733 -0
  45. package/coverage/src/state/directory.ts.html +736 -0
  46. package/coverage/src/state/errors.ts.html +376 -0
  47. package/coverage/src/state/fleet-state.ts.html +937 -0
  48. package/coverage/src/state/index.html +221 -0
  49. package/coverage/src/state/index.ts.html +322 -0
  50. package/coverage/src/state/job-metadata.ts.html +1420 -0
  51. package/coverage/src/state/job-output.ts.html +1033 -0
  52. package/coverage/src/state/schemas/fleet-state.ts.html +445 -0
  53. package/coverage/src/state/schemas/index.html +176 -0
  54. package/coverage/src/state/schemas/index.ts.html +286 -0
  55. package/coverage/src/state/schemas/job-metadata.ts.html +628 -0
  56. package/coverage/src/state/schemas/job-output.ts.html +616 -0
  57. package/coverage/src/state/schemas/session-info.ts.html +361 -0
  58. package/coverage/src/state/session.ts.html +844 -0
  59. package/coverage/src/state/types.ts.html +262 -0
  60. package/coverage/src/state/utils/atomic.ts.html +748 -0
  61. package/coverage/src/state/utils/index.html +146 -0
  62. package/coverage/src/state/utils/index.ts.html +103 -0
  63. package/coverage/src/state/utils/reads.ts.html +1621 -0
  64. package/coverage/src/work-sources/adapters/github.ts.html +3583 -0
  65. package/coverage/src/work-sources/adapters/index.html +131 -0
  66. package/coverage/src/work-sources/adapters/index.ts.html +277 -0
  67. package/coverage/src/work-sources/errors.ts.html +298 -0
  68. package/coverage/src/work-sources/index.html +176 -0
  69. package/coverage/src/work-sources/index.ts.html +529 -0
  70. package/coverage/src/work-sources/manager.ts.html +1324 -0
  71. package/coverage/src/work-sources/registry.ts.html +619 -0
  72. package/coverage/src/work-sources/types.ts.html +568 -0
  73. package/dist/config/__tests__/agent.test.d.ts +2 -0
  74. package/dist/config/__tests__/agent.test.d.ts.map +1 -0
  75. package/dist/config/__tests__/agent.test.js +752 -0
  76. package/dist/config/__tests__/agent.test.js.map +1 -0
  77. package/dist/config/__tests__/interpolate.test.d.ts +2 -0
  78. package/dist/config/__tests__/interpolate.test.d.ts.map +1 -0
  79. package/dist/config/__tests__/interpolate.test.js +509 -0
  80. package/dist/config/__tests__/interpolate.test.js.map +1 -0
  81. package/dist/config/__tests__/loader.test.d.ts +2 -0
  82. package/dist/config/__tests__/loader.test.d.ts.map +1 -0
  83. package/dist/config/__tests__/loader.test.js +631 -0
  84. package/dist/config/__tests__/loader.test.js.map +1 -0
  85. package/dist/config/__tests__/merge.test.d.ts +2 -0
  86. package/dist/config/__tests__/merge.test.d.ts.map +1 -0
  87. package/dist/config/__tests__/merge.test.js +672 -0
  88. package/dist/config/__tests__/merge.test.js.map +1 -0
  89. package/dist/config/__tests__/parser.test.d.ts +2 -0
  90. package/dist/config/__tests__/parser.test.d.ts.map +1 -0
  91. package/dist/config/__tests__/parser.test.js +476 -0
  92. package/dist/config/__tests__/parser.test.js.map +1 -0
  93. package/dist/config/__tests__/schema.test.d.ts +2 -0
  94. package/dist/config/__tests__/schema.test.d.ts.map +1 -0
  95. package/dist/config/__tests__/schema.test.js +776 -0
  96. package/dist/config/__tests__/schema.test.js.map +1 -0
  97. package/dist/config/index.d.ts +11 -0
  98. package/dist/config/index.d.ts.map +1 -0
  99. package/dist/config/index.js +26 -0
  100. package/dist/config/index.js.map +1 -0
  101. package/dist/config/interpolate.d.ts +76 -0
  102. package/dist/config/interpolate.d.ts.map +1 -0
  103. package/dist/config/interpolate.js +143 -0
  104. package/dist/config/interpolate.js.map +1 -0
  105. package/dist/config/loader.d.ts +147 -0
  106. package/dist/config/loader.d.ts.map +1 -0
  107. package/dist/config/loader.js +336 -0
  108. package/dist/config/loader.js.map +1 -0
  109. package/dist/config/merge.d.ts +84 -0
  110. package/dist/config/merge.d.ts.map +1 -0
  111. package/dist/config/merge.js +138 -0
  112. package/dist/config/merge.js.map +1 -0
  113. package/dist/config/parser.d.ts +143 -0
  114. package/dist/config/parser.d.ts.map +1 -0
  115. package/dist/config/parser.js +316 -0
  116. package/dist/config/parser.js.map +1 -0
  117. package/dist/config/schema.d.ts +1906 -0
  118. package/dist/config/schema.d.ts.map +1 -0
  119. package/dist/config/schema.js +268 -0
  120. package/dist/config/schema.js.map +1 -0
  121. package/dist/fleet-manager/__tests__/coverage.test.d.ts +13 -0
  122. package/dist/fleet-manager/__tests__/coverage.test.d.ts.map +1 -0
  123. package/dist/fleet-manager/__tests__/coverage.test.js +2282 -0
  124. package/dist/fleet-manager/__tests__/coverage.test.js.map +1 -0
  125. package/dist/fleet-manager/__tests__/errors.test.d.ts +7 -0
  126. package/dist/fleet-manager/__tests__/errors.test.d.ts.map +1 -0
  127. package/dist/fleet-manager/__tests__/errors.test.js +557 -0
  128. package/dist/fleet-manager/__tests__/errors.test.js.map +1 -0
  129. package/dist/fleet-manager/__tests__/event-helpers.test.d.ts +7 -0
  130. package/dist/fleet-manager/__tests__/event-helpers.test.d.ts.map +1 -0
  131. package/dist/fleet-manager/__tests__/event-helpers.test.js +368 -0
  132. package/dist/fleet-manager/__tests__/event-helpers.test.js.map +1 -0
  133. package/dist/fleet-manager/__tests__/integration.test.d.ts +11 -0
  134. package/dist/fleet-manager/__tests__/integration.test.d.ts.map +1 -0
  135. package/dist/fleet-manager/__tests__/integration.test.js +949 -0
  136. package/dist/fleet-manager/__tests__/integration.test.js.map +1 -0
  137. package/dist/fleet-manager/__tests__/job-control.test.d.ts +7 -0
  138. package/dist/fleet-manager/__tests__/job-control.test.d.ts.map +1 -0
  139. package/dist/fleet-manager/__tests__/job-control.test.js +215 -0
  140. package/dist/fleet-manager/__tests__/job-control.test.js.map +1 -0
  141. package/dist/fleet-manager/__tests__/job-manager.test.d.ts +7 -0
  142. package/dist/fleet-manager/__tests__/job-manager.test.d.ts.map +1 -0
  143. package/dist/fleet-manager/__tests__/job-manager.test.js +659 -0
  144. package/dist/fleet-manager/__tests__/job-manager.test.js.map +1 -0
  145. package/dist/fleet-manager/__tests__/job-queue.test.d.ts +5 -0
  146. package/dist/fleet-manager/__tests__/job-queue.test.d.ts.map +1 -0
  147. package/dist/fleet-manager/__tests__/job-queue.test.js +315 -0
  148. package/dist/fleet-manager/__tests__/job-queue.test.js.map +1 -0
  149. package/dist/fleet-manager/__tests__/reload.test.d.ts +7 -0
  150. package/dist/fleet-manager/__tests__/reload.test.d.ts.map +1 -0
  151. package/dist/fleet-manager/__tests__/reload.test.js +609 -0
  152. package/dist/fleet-manager/__tests__/reload.test.js.map +1 -0
  153. package/dist/fleet-manager/__tests__/status-queries.test.d.ts +7 -0
  154. package/dist/fleet-manager/__tests__/status-queries.test.d.ts.map +1 -0
  155. package/dist/fleet-manager/__tests__/status-queries.test.js +488 -0
  156. package/dist/fleet-manager/__tests__/status-queries.test.js.map +1 -0
  157. package/dist/fleet-manager/__tests__/trigger.test.d.ts +7 -0
  158. package/dist/fleet-manager/__tests__/trigger.test.d.ts.map +1 -0
  159. package/dist/fleet-manager/__tests__/trigger.test.js +471 -0
  160. package/dist/fleet-manager/__tests__/trigger.test.js.map +1 -0
  161. package/dist/fleet-manager/errors.d.ts +407 -0
  162. package/dist/fleet-manager/errors.d.ts.map +1 -0
  163. package/dist/fleet-manager/errors.js +569 -0
  164. package/dist/fleet-manager/errors.js.map +1 -0
  165. package/dist/fleet-manager/event-types.d.ts +302 -0
  166. package/dist/fleet-manager/event-types.d.ts.map +1 -0
  167. package/dist/fleet-manager/event-types.js +9 -0
  168. package/dist/fleet-manager/event-types.js.map +1 -0
  169. package/dist/fleet-manager/fleet-manager.d.ts +699 -0
  170. package/dist/fleet-manager/fleet-manager.d.ts.map +1 -0
  171. package/dist/fleet-manager/fleet-manager.js +1906 -0
  172. package/dist/fleet-manager/fleet-manager.js.map +1 -0
  173. package/dist/fleet-manager/index.d.ts +17 -0
  174. package/dist/fleet-manager/index.d.ts.map +1 -0
  175. package/dist/fleet-manager/index.js +29 -0
  176. package/dist/fleet-manager/index.js.map +1 -0
  177. package/dist/fleet-manager/job-manager.d.ts +271 -0
  178. package/dist/fleet-manager/job-manager.d.ts.map +1 -0
  179. package/dist/fleet-manager/job-manager.js +443 -0
  180. package/dist/fleet-manager/job-manager.js.map +1 -0
  181. package/dist/fleet-manager/job-queue.d.ts +422 -0
  182. package/dist/fleet-manager/job-queue.d.ts.map +1 -0
  183. package/dist/fleet-manager/job-queue.js +448 -0
  184. package/dist/fleet-manager/job-queue.js.map +1 -0
  185. package/dist/fleet-manager/types.d.ts +680 -0
  186. package/dist/fleet-manager/types.d.ts.map +1 -0
  187. package/dist/fleet-manager/types.js +8 -0
  188. package/dist/fleet-manager/types.js.map +1 -0
  189. package/dist/index.d.ts +20 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +26 -0
  192. package/dist/index.js.map +1 -0
  193. package/dist/runner/__tests__/errors.test.d.ts +2 -0
  194. package/dist/runner/__tests__/errors.test.d.ts.map +1 -0
  195. package/dist/runner/__tests__/errors.test.js +264 -0
  196. package/dist/runner/__tests__/errors.test.js.map +1 -0
  197. package/dist/runner/__tests__/job-executor.test.d.ts +2 -0
  198. package/dist/runner/__tests__/job-executor.test.d.ts.map +1 -0
  199. package/dist/runner/__tests__/job-executor.test.js +1345 -0
  200. package/dist/runner/__tests__/job-executor.test.js.map +1 -0
  201. package/dist/runner/__tests__/message-processor.test.d.ts +2 -0
  202. package/dist/runner/__tests__/message-processor.test.d.ts.map +1 -0
  203. package/dist/runner/__tests__/message-processor.test.js +768 -0
  204. package/dist/runner/__tests__/message-processor.test.js.map +1 -0
  205. package/dist/runner/__tests__/sdk-adapter.test.d.ts +2 -0
  206. package/dist/runner/__tests__/sdk-adapter.test.d.ts.map +1 -0
  207. package/dist/runner/__tests__/sdk-adapter.test.js +554 -0
  208. package/dist/runner/__tests__/sdk-adapter.test.js.map +1 -0
  209. package/dist/runner/errors.d.ts +121 -0
  210. package/dist/runner/errors.d.ts.map +1 -0
  211. package/dist/runner/errors.js +212 -0
  212. package/dist/runner/errors.js.map +1 -0
  213. package/dist/runner/index.d.ts +12 -0
  214. package/dist/runner/index.d.ts.map +1 -0
  215. package/dist/runner/index.js +15 -0
  216. package/dist/runner/index.js.map +1 -0
  217. package/dist/runner/job-executor.d.ts +98 -0
  218. package/dist/runner/job-executor.d.ts.map +1 -0
  219. package/dist/runner/job-executor.js +333 -0
  220. package/dist/runner/job-executor.js.map +1 -0
  221. package/dist/runner/message-processor.d.ts +45 -0
  222. package/dist/runner/message-processor.d.ts.map +1 -0
  223. package/dist/runner/message-processor.js +294 -0
  224. package/dist/runner/message-processor.js.map +1 -0
  225. package/dist/runner/sdk-adapter.d.ts +60 -0
  226. package/dist/runner/sdk-adapter.d.ts.map +1 -0
  227. package/dist/runner/sdk-adapter.js +138 -0
  228. package/dist/runner/sdk-adapter.js.map +1 -0
  229. package/dist/runner/types.d.ts +135 -0
  230. package/dist/runner/types.d.ts.map +1 -0
  231. package/dist/runner/types.js +7 -0
  232. package/dist/runner/types.js.map +1 -0
  233. package/dist/scheduler/__tests__/errors.test.d.ts +2 -0
  234. package/dist/scheduler/__tests__/errors.test.d.ts.map +1 -0
  235. package/dist/scheduler/__tests__/errors.test.js +101 -0
  236. package/dist/scheduler/__tests__/errors.test.js.map +1 -0
  237. package/dist/scheduler/__tests__/interval.test.d.ts +2 -0
  238. package/dist/scheduler/__tests__/interval.test.d.ts.map +1 -0
  239. package/dist/scheduler/__tests__/interval.test.js +419 -0
  240. package/dist/scheduler/__tests__/interval.test.js.map +1 -0
  241. package/dist/scheduler/__tests__/schedule-runner.test.d.ts +2 -0
  242. package/dist/scheduler/__tests__/schedule-runner.test.d.ts.map +1 -0
  243. package/dist/scheduler/__tests__/schedule-runner.test.js +634 -0
  244. package/dist/scheduler/__tests__/schedule-runner.test.js.map +1 -0
  245. package/dist/scheduler/__tests__/schedule-state.test.d.ts +2 -0
  246. package/dist/scheduler/__tests__/schedule-state.test.d.ts.map +1 -0
  247. package/dist/scheduler/__tests__/schedule-state.test.js +572 -0
  248. package/dist/scheduler/__tests__/schedule-state.test.js.map +1 -0
  249. package/dist/scheduler/__tests__/scheduler.test.d.ts +2 -0
  250. package/dist/scheduler/__tests__/scheduler.test.d.ts.map +1 -0
  251. package/dist/scheduler/__tests__/scheduler.test.js +987 -0
  252. package/dist/scheduler/__tests__/scheduler.test.js.map +1 -0
  253. package/dist/scheduler/errors.d.ts +61 -0
  254. package/dist/scheduler/errors.d.ts.map +1 -0
  255. package/dist/scheduler/errors.js +81 -0
  256. package/dist/scheduler/errors.js.map +1 -0
  257. package/dist/scheduler/index.d.ts +13 -0
  258. package/dist/scheduler/index.d.ts.map +1 -0
  259. package/dist/scheduler/index.js +17 -0
  260. package/dist/scheduler/index.js.map +1 -0
  261. package/dist/scheduler/interval.d.ts +64 -0
  262. package/dist/scheduler/interval.d.ts.map +1 -0
  263. package/dist/scheduler/interval.js +139 -0
  264. package/dist/scheduler/interval.js.map +1 -0
  265. package/dist/scheduler/schedule-runner.d.ts +149 -0
  266. package/dist/scheduler/schedule-runner.d.ts.map +1 -0
  267. package/dist/scheduler/schedule-runner.js +277 -0
  268. package/dist/scheduler/schedule-runner.js.map +1 -0
  269. package/dist/scheduler/schedule-state.d.ts +105 -0
  270. package/dist/scheduler/schedule-state.d.ts.map +1 -0
  271. package/dist/scheduler/schedule-state.js +151 -0
  272. package/dist/scheduler/schedule-state.js.map +1 -0
  273. package/dist/scheduler/scheduler.d.ts +138 -0
  274. package/dist/scheduler/scheduler.d.ts.map +1 -0
  275. package/dist/scheduler/scheduler.js +423 -0
  276. package/dist/scheduler/scheduler.js.map +1 -0
  277. package/dist/scheduler/types.d.ts +160 -0
  278. package/dist/scheduler/types.d.ts.map +1 -0
  279. package/dist/scheduler/types.js +8 -0
  280. package/dist/scheduler/types.js.map +1 -0
  281. package/dist/state/__tests__/directory.test.d.ts +2 -0
  282. package/dist/state/__tests__/directory.test.d.ts.map +1 -0
  283. package/dist/state/__tests__/directory.test.js +414 -0
  284. package/dist/state/__tests__/directory.test.js.map +1 -0
  285. package/dist/state/__tests__/fleet-state.test.d.ts +2 -0
  286. package/dist/state/__tests__/fleet-state.test.d.ts.map +1 -0
  287. package/dist/state/__tests__/fleet-state.test.js +696 -0
  288. package/dist/state/__tests__/fleet-state.test.js.map +1 -0
  289. package/dist/state/__tests__/job-metadata-schema.test.d.ts +2 -0
  290. package/dist/state/__tests__/job-metadata-schema.test.d.ts.map +1 -0
  291. package/dist/state/__tests__/job-metadata-schema.test.js +329 -0
  292. package/dist/state/__tests__/job-metadata-schema.test.js.map +1 -0
  293. package/dist/state/__tests__/job-metadata.test.d.ts +2 -0
  294. package/dist/state/__tests__/job-metadata.test.d.ts.map +1 -0
  295. package/dist/state/__tests__/job-metadata.test.js +667 -0
  296. package/dist/state/__tests__/job-metadata.test.js.map +1 -0
  297. package/dist/state/__tests__/job-output.test.d.ts +2 -0
  298. package/dist/state/__tests__/job-output.test.d.ts.map +1 -0
  299. package/dist/state/__tests__/job-output.test.js +672 -0
  300. package/dist/state/__tests__/job-output.test.js.map +1 -0
  301. package/dist/state/__tests__/session-schema.test.d.ts +2 -0
  302. package/dist/state/__tests__/session-schema.test.d.ts.map +1 -0
  303. package/dist/state/__tests__/session-schema.test.js +323 -0
  304. package/dist/state/__tests__/session-schema.test.js.map +1 -0
  305. package/dist/state/__tests__/session.test.d.ts +2 -0
  306. package/dist/state/__tests__/session.test.d.ts.map +1 -0
  307. package/dist/state/__tests__/session.test.js +468 -0
  308. package/dist/state/__tests__/session.test.js.map +1 -0
  309. package/dist/state/directory.d.ts +42 -0
  310. package/dist/state/directory.d.ts.map +1 -0
  311. package/dist/state/directory.js +170 -0
  312. package/dist/state/directory.js.map +1 -0
  313. package/dist/state/errors.d.ts +44 -0
  314. package/dist/state/errors.d.ts.map +1 -0
  315. package/dist/state/errors.js +82 -0
  316. package/dist/state/errors.js.map +1 -0
  317. package/dist/state/fleet-state.d.ts +126 -0
  318. package/dist/state/fleet-state.d.ts.map +1 -0
  319. package/dist/state/fleet-state.js +196 -0
  320. package/dist/state/fleet-state.js.map +1 -0
  321. package/dist/state/index.d.ts +21 -0
  322. package/dist/state/index.d.ts.map +1 -0
  323. package/dist/state/index.js +30 -0
  324. package/dist/state/index.js.map +1 -0
  325. package/dist/state/job-metadata.d.ts +151 -0
  326. package/dist/state/job-metadata.d.ts.map +1 -0
  327. package/dist/state/job-metadata.js +287 -0
  328. package/dist/state/job-metadata.js.map +1 -0
  329. package/dist/state/job-output.d.ts +116 -0
  330. package/dist/state/job-output.d.ts.map +1 -0
  331. package/dist/state/job-output.js +218 -0
  332. package/dist/state/job-output.js.map +1 -0
  333. package/dist/state/schemas/__tests__/job-output.test.d.ts +2 -0
  334. package/dist/state/schemas/__tests__/job-output.test.d.ts.map +1 -0
  335. package/dist/state/schemas/__tests__/job-output.test.js +279 -0
  336. package/dist/state/schemas/__tests__/job-output.test.js.map +1 -0
  337. package/dist/state/schemas/fleet-state.d.ts +249 -0
  338. package/dist/state/schemas/fleet-state.d.ts.map +1 -0
  339. package/dist/state/schemas/fleet-state.js +97 -0
  340. package/dist/state/schemas/fleet-state.js.map +1 -0
  341. package/dist/state/schemas/index.d.ts +10 -0
  342. package/dist/state/schemas/index.d.ts.map +1 -0
  343. package/dist/state/schemas/index.js +10 -0
  344. package/dist/state/schemas/index.js.map +1 -0
  345. package/dist/state/schemas/job-metadata.d.ts +118 -0
  346. package/dist/state/schemas/job-metadata.d.ts.map +1 -0
  347. package/dist/state/schemas/job-metadata.js +123 -0
  348. package/dist/state/schemas/job-metadata.js.map +1 -0
  349. package/dist/state/schemas/job-output.d.ts +291 -0
  350. package/dist/state/schemas/job-output.d.ts.map +1 -0
  351. package/dist/state/schemas/job-output.js +132 -0
  352. package/dist/state/schemas/job-output.js.map +1 -0
  353. package/dist/state/schemas/session-info.d.ts +65 -0
  354. package/dist/state/schemas/session-info.d.ts.map +1 -0
  355. package/dist/state/schemas/session-info.js +58 -0
  356. package/dist/state/schemas/session-info.js.map +1 -0
  357. package/dist/state/session.d.ts +92 -0
  358. package/dist/state/session.d.ts.map +1 -0
  359. package/dist/state/session.js +173 -0
  360. package/dist/state/session.js.map +1 -0
  361. package/dist/state/types.d.ts +54 -0
  362. package/dist/state/types.d.ts.map +1 -0
  363. package/dist/state/types.js +18 -0
  364. package/dist/state/types.js.map +1 -0
  365. package/dist/state/utils/__tests__/atomic.test.d.ts +2 -0
  366. package/dist/state/utils/__tests__/atomic.test.d.ts.map +1 -0
  367. package/dist/state/utils/__tests__/atomic.test.js +537 -0
  368. package/dist/state/utils/__tests__/atomic.test.js.map +1 -0
  369. package/dist/state/utils/__tests__/reads.test.d.ts +2 -0
  370. package/dist/state/utils/__tests__/reads.test.d.ts.map +1 -0
  371. package/dist/state/utils/__tests__/reads.test.js +792 -0
  372. package/dist/state/utils/__tests__/reads.test.js.map +1 -0
  373. package/dist/state/utils/atomic.d.ts +89 -0
  374. package/dist/state/utils/atomic.d.ts.map +1 -0
  375. package/dist/state/utils/atomic.js +157 -0
  376. package/dist/state/utils/atomic.js.map +1 -0
  377. package/dist/state/utils/index.d.ts +6 -0
  378. package/dist/state/utils/index.d.ts.map +1 -0
  379. package/dist/state/utils/index.js +6 -0
  380. package/dist/state/utils/index.js.map +1 -0
  381. package/dist/state/utils/reads.d.ts +196 -0
  382. package/dist/state/utils/reads.d.ts.map +1 -0
  383. package/dist/state/utils/reads.js +346 -0
  384. package/dist/state/utils/reads.js.map +1 -0
  385. package/dist/work-sources/__tests__/github.test.d.ts +2 -0
  386. package/dist/work-sources/__tests__/github.test.d.ts.map +1 -0
  387. package/dist/work-sources/__tests__/github.test.js +1334 -0
  388. package/dist/work-sources/__tests__/github.test.js.map +1 -0
  389. package/dist/work-sources/__tests__/manager.test.d.ts +2 -0
  390. package/dist/work-sources/__tests__/manager.test.d.ts.map +1 -0
  391. package/dist/work-sources/__tests__/manager.test.js +424 -0
  392. package/dist/work-sources/__tests__/manager.test.js.map +1 -0
  393. package/dist/work-sources/__tests__/registry.test.d.ts +2 -0
  394. package/dist/work-sources/__tests__/registry.test.d.ts.map +1 -0
  395. package/dist/work-sources/__tests__/registry.test.js +381 -0
  396. package/dist/work-sources/__tests__/registry.test.js.map +1 -0
  397. package/dist/work-sources/__tests__/types.test.d.ts +2 -0
  398. package/dist/work-sources/__tests__/types.test.d.ts.map +1 -0
  399. package/dist/work-sources/__tests__/types.test.js +406 -0
  400. package/dist/work-sources/__tests__/types.test.js.map +1 -0
  401. package/dist/work-sources/adapters/github.d.ts +290 -0
  402. package/dist/work-sources/adapters/github.d.ts.map +1 -0
  403. package/dist/work-sources/adapters/github.js +803 -0
  404. package/dist/work-sources/adapters/github.js.map +1 -0
  405. package/dist/work-sources/adapters/index.d.ts +10 -0
  406. package/dist/work-sources/adapters/index.d.ts.map +1 -0
  407. package/dist/work-sources/adapters/index.js +31 -0
  408. package/dist/work-sources/adapters/index.js.map +1 -0
  409. package/dist/work-sources/errors.d.ts +40 -0
  410. package/dist/work-sources/errors.d.ts.map +1 -0
  411. package/dist/work-sources/errors.js +54 -0
  412. package/dist/work-sources/errors.js.map +1 -0
  413. package/dist/work-sources/index.d.ts +105 -0
  414. package/dist/work-sources/index.d.ts.map +1 -0
  415. package/dist/work-sources/index.js +24 -0
  416. package/dist/work-sources/index.js.map +1 -0
  417. package/dist/work-sources/manager.d.ts +370 -0
  418. package/dist/work-sources/manager.d.ts.map +1 -0
  419. package/dist/work-sources/manager.js +61 -0
  420. package/dist/work-sources/manager.js.map +1 -0
  421. package/dist/work-sources/registry.d.ts +128 -0
  422. package/dist/work-sources/registry.d.ts.map +1 -0
  423. package/dist/work-sources/registry.js +132 -0
  424. package/dist/work-sources/registry.js.map +1 -0
  425. package/dist/work-sources/types.d.ts +127 -0
  426. package/dist/work-sources/types.d.ts.map +1 -0
  427. package/dist/work-sources/types.js +8 -0
  428. package/dist/work-sources/types.js.map +1 -0
  429. package/package.json +23 -0
  430. package/src/config/__tests__/agent.test.ts +864 -0
  431. package/src/config/__tests__/interpolate.test.ts +644 -0
  432. package/src/config/__tests__/loader.test.ts +784 -0
  433. package/src/config/__tests__/merge.test.ts +751 -0
  434. package/src/config/__tests__/parser.test.ts +533 -0
  435. package/src/config/__tests__/schema.test.ts +873 -0
  436. package/src/config/index.ts +119 -0
  437. package/src/config/interpolate.ts +189 -0
  438. package/src/config/loader.ts +472 -0
  439. package/src/config/merge.ts +246 -0
  440. package/src/config/parser.ts +376 -0
  441. package/src/config/schema.ts +346 -0
  442. package/src/fleet-manager/__tests__/coverage.test.ts +2869 -0
  443. package/src/fleet-manager/__tests__/errors.test.ts +660 -0
  444. package/src/fleet-manager/__tests__/event-helpers.test.ts +448 -0
  445. package/src/fleet-manager/__tests__/integration.test.ts +1209 -0
  446. package/src/fleet-manager/__tests__/job-control.test.ts +283 -0
  447. package/src/fleet-manager/__tests__/job-manager.test.ts +869 -0
  448. package/src/fleet-manager/__tests__/job-queue.test.ts +401 -0
  449. package/src/fleet-manager/__tests__/reload.test.ts +751 -0
  450. package/src/fleet-manager/__tests__/status-queries.test.ts +595 -0
  451. package/src/fleet-manager/__tests__/trigger.test.ts +601 -0
  452. package/src/fleet-manager/errors.ts +747 -0
  453. package/src/fleet-manager/event-types.ts +378 -0
  454. package/src/fleet-manager/fleet-manager.ts +2315 -0
  455. package/src/fleet-manager/index.ts +128 -0
  456. package/src/fleet-manager/job-manager.ts +663 -0
  457. package/src/fleet-manager/job-queue.ts +798 -0
  458. package/src/fleet-manager/types.ts +839 -0
  459. package/src/index.ts +32 -0
  460. package/src/runner/__tests__/errors.test.ts +382 -0
  461. package/src/runner/__tests__/job-executor.test.ts +1708 -0
  462. package/src/runner/__tests__/message-processor.test.ts +960 -0
  463. package/src/runner/__tests__/sdk-adapter.test.ts +626 -0
  464. package/src/runner/errors.ts +307 -0
  465. package/src/runner/index.ts +57 -0
  466. package/src/runner/job-executor.ts +448 -0
  467. package/src/runner/message-processor.ts +355 -0
  468. package/src/runner/sdk-adapter.ts +191 -0
  469. package/src/runner/types.ts +158 -0
  470. package/src/scheduler/__tests__/errors.test.ts +159 -0
  471. package/src/scheduler/__tests__/interval.test.ts +515 -0
  472. package/src/scheduler/__tests__/schedule-runner.test.ts +798 -0
  473. package/src/scheduler/__tests__/schedule-state.test.ts +671 -0
  474. package/src/scheduler/__tests__/scheduler.test.ts +1280 -0
  475. package/src/scheduler/errors.ts +101 -0
  476. package/src/scheduler/index.ts +53 -0
  477. package/src/scheduler/interval.ts +189 -0
  478. package/src/scheduler/schedule-runner.ts +442 -0
  479. package/src/scheduler/schedule-state.ts +211 -0
  480. package/src/scheduler/scheduler.ts +570 -0
  481. package/src/scheduler/types.ts +216 -0
  482. package/src/state/__tests__/directory.test.ts +595 -0
  483. package/src/state/__tests__/fleet-state.test.ts +868 -0
  484. package/src/state/__tests__/job-metadata-schema.test.ts +414 -0
  485. package/src/state/__tests__/job-metadata.test.ts +831 -0
  486. package/src/state/__tests__/job-output.test.ts +856 -0
  487. package/src/state/__tests__/session-schema.test.ts +378 -0
  488. package/src/state/__tests__/session.test.ts +604 -0
  489. package/src/state/directory.ts +217 -0
  490. package/src/state/errors.ts +97 -0
  491. package/src/state/fleet-state.ts +284 -0
  492. package/src/state/index.ts +79 -0
  493. package/src/state/job-metadata.ts +445 -0
  494. package/src/state/job-output.ts +316 -0
  495. package/src/state/schemas/__tests__/job-output.test.ts +338 -0
  496. package/src/state/schemas/fleet-state.ts +120 -0
  497. package/src/state/schemas/index.ts +67 -0
  498. package/src/state/schemas/job-metadata.ts +181 -0
  499. package/src/state/schemas/job-output.ts +177 -0
  500. package/src/state/schemas/session-info.ts +92 -0
  501. package/src/state/session.ts +253 -0
  502. package/src/state/types.ts +59 -0
  503. package/src/state/utils/__tests__/atomic.test.ts +723 -0
  504. package/src/state/utils/__tests__/reads.test.ts +1071 -0
  505. package/src/state/utils/atomic.ts +221 -0
  506. package/src/state/utils/index.ts +6 -0
  507. package/src/state/utils/reads.ts +512 -0
  508. package/src/work-sources/__tests__/github.test.ts +1800 -0
  509. package/src/work-sources/__tests__/manager.test.ts +529 -0
  510. package/src/work-sources/__tests__/registry.test.ts +477 -0
  511. package/src/work-sources/__tests__/types.test.ts +479 -0
  512. package/src/work-sources/adapters/github.ts +1166 -0
  513. package/src/work-sources/adapters/index.ts +64 -0
  514. package/src/work-sources/errors.ts +71 -0
  515. package/src/work-sources/index.ts +148 -0
  516. package/src/work-sources/manager.ts +413 -0
  517. package/src/work-sources/registry.ts +178 -0
  518. package/src/work-sources/types.ts +161 -0
  519. package/tsconfig.json +9 -0
  520. package/vitest.config.ts +19 -0
@@ -0,0 +1,798 @@
1
+ /**
2
+ * Job Queue module for concurrency control
3
+ *
4
+ * Provides a job queue with per-agent and fleet-wide concurrency limits.
5
+ * Jobs queue when limits are reached and are processed FIFO within priority levels.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const queue = new JobQueue({
10
+ * defaultAgentConcurrency: 1,
11
+ * fleetConcurrency: 10,
12
+ * });
13
+ *
14
+ * // Enqueue a job
15
+ * const result = queue.enqueue({
16
+ * agentName: 'my-agent',
17
+ * scheduleName: 'hourly',
18
+ * priority: 5,
19
+ * });
20
+ *
21
+ * if (result.queued) {
22
+ * console.log(`Job queued at position ${result.position}`);
23
+ * } else {
24
+ * console.log(`Job ready to run: ${result.jobId}`);
25
+ * }
26
+ *
27
+ * // Dequeue when ready
28
+ * const job = queue.dequeue('my-agent');
29
+ * ```
30
+ */
31
+
32
+ import { EventEmitter } from "node:events";
33
+ import { randomUUID } from "node:crypto";
34
+
35
+ // =============================================================================
36
+ // Types
37
+ // =============================================================================
38
+
39
+ /**
40
+ * Priority level for queued jobs
41
+ * Lower numbers = higher priority
42
+ * Default priority is 5 (normal)
43
+ */
44
+ export type JobPriority = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
45
+
46
+ /**
47
+ * Configuration options for the JobQueue
48
+ */
49
+ export interface JobQueueOptions {
50
+ /**
51
+ * Default concurrency limit per agent
52
+ * Can be overridden per-agent via setAgentConcurrency()
53
+ * Default: 1
54
+ */
55
+ defaultAgentConcurrency?: number;
56
+
57
+ /**
58
+ * Fleet-wide concurrency limit (optional)
59
+ * When set, limits total concurrent jobs across all agents
60
+ * Default: undefined (no fleet-wide limit)
61
+ */
62
+ fleetConcurrency?: number;
63
+
64
+ /**
65
+ * Logger for queue operations
66
+ */
67
+ logger?: JobQueueLogger;
68
+ }
69
+
70
+ /**
71
+ * Logger interface for job queue operations
72
+ */
73
+ export interface JobQueueLogger {
74
+ debug: (message: string) => void;
75
+ info: (message: string) => void;
76
+ warn: (message: string) => void;
77
+ error: (message: string) => void;
78
+ }
79
+
80
+ /**
81
+ * A queued job entry
82
+ */
83
+ export interface QueuedJob {
84
+ /**
85
+ * Unique ID for this queued job
86
+ */
87
+ id: string;
88
+
89
+ /**
90
+ * Name of the agent this job is for
91
+ */
92
+ agentName: string;
93
+
94
+ /**
95
+ * Name of the schedule that triggered this job (optional)
96
+ */
97
+ scheduleName?: string;
98
+
99
+ /**
100
+ * Job priority (1-10, lower = higher priority)
101
+ * Default: 5 (normal)
102
+ */
103
+ priority: JobPriority;
104
+
105
+ /**
106
+ * ISO timestamp when the job was queued
107
+ */
108
+ queuedAt: string;
109
+
110
+ /**
111
+ * Prompt override for this job (optional)
112
+ */
113
+ prompt?: string;
114
+
115
+ /**
116
+ * Whether this is from a scheduled trigger
117
+ */
118
+ isScheduled: boolean;
119
+ }
120
+
121
+ /**
122
+ * Options for enqueueing a job
123
+ */
124
+ export interface EnqueueOptions {
125
+ /**
126
+ * Name of the agent to run
127
+ */
128
+ agentName: string;
129
+
130
+ /**
131
+ * Name of the schedule (optional)
132
+ */
133
+ scheduleName?: string;
134
+
135
+ /**
136
+ * Job priority (1-10, lower = higher priority)
137
+ * Default: 5
138
+ */
139
+ priority?: JobPriority;
140
+
141
+ /**
142
+ * Prompt override (optional)
143
+ */
144
+ prompt?: string;
145
+
146
+ /**
147
+ * Whether this is from a scheduled trigger
148
+ * Scheduled triggers are NOT queued - they emit schedule:skipped instead
149
+ * Default: false
150
+ */
151
+ isScheduled?: boolean;
152
+ }
153
+
154
+ /**
155
+ * Result of enqueueing a job
156
+ */
157
+ export interface EnqueueResult {
158
+ /**
159
+ * The queued job ID
160
+ */
161
+ jobId: string;
162
+
163
+ /**
164
+ * Whether the job was actually queued (vs ready to run immediately)
165
+ */
166
+ queued: boolean;
167
+
168
+ /**
169
+ * Position in the queue (1-based) if queued
170
+ * Undefined if not queued (ready to run)
171
+ */
172
+ position?: number;
173
+
174
+ /**
175
+ * Reason the job was queued, if applicable
176
+ */
177
+ reason?: "agent_at_capacity" | "fleet_at_capacity";
178
+ }
179
+
180
+ /**
181
+ * Result when a scheduled job is skipped due to concurrency
182
+ */
183
+ export interface ScheduleSkipResult {
184
+ /**
185
+ * The agent that was at capacity
186
+ */
187
+ agentName: string;
188
+
189
+ /**
190
+ * The schedule that was skipped
191
+ */
192
+ scheduleName?: string;
193
+
194
+ /**
195
+ * Reason for skipping
196
+ */
197
+ reason: "agent_at_capacity" | "fleet_at_capacity";
198
+
199
+ /**
200
+ * Current running count
201
+ */
202
+ currentRunning: number;
203
+
204
+ /**
205
+ * The limit that was hit
206
+ */
207
+ limit: number;
208
+ }
209
+
210
+ /**
211
+ * Status of the job queue for a specific agent
212
+ */
213
+ export interface AgentQueueStatus {
214
+ /**
215
+ * Name of the agent
216
+ */
217
+ agentName: string;
218
+
219
+ /**
220
+ * Number of jobs currently running for this agent
221
+ */
222
+ runningCount: number;
223
+
224
+ /**
225
+ * Maximum concurrent jobs allowed for this agent
226
+ */
227
+ maxConcurrent: number;
228
+
229
+ /**
230
+ * Number of jobs queued for this agent
231
+ */
232
+ queuedCount: number;
233
+
234
+ /**
235
+ * The queued jobs for this agent (in order)
236
+ */
237
+ queuedJobs: QueuedJob[];
238
+ }
239
+
240
+ /**
241
+ * Overall queue status
242
+ */
243
+ export interface QueueStatus {
244
+ /**
245
+ * Total jobs currently running across all agents
246
+ */
247
+ totalRunning: number;
248
+
249
+ /**
250
+ * Fleet-wide concurrency limit (if set)
251
+ */
252
+ fleetConcurrency: number | null;
253
+
254
+ /**
255
+ * Default per-agent concurrency limit
256
+ */
257
+ defaultAgentConcurrency: number;
258
+
259
+ /**
260
+ * Total jobs queued across all agents
261
+ */
262
+ totalQueued: number;
263
+
264
+ /**
265
+ * Per-agent queue status
266
+ */
267
+ agents: Map<string, AgentQueueStatus>;
268
+ }
269
+
270
+ /**
271
+ * Events emitted by the JobQueue
272
+ */
273
+ export interface JobQueueEventMap {
274
+ /**
275
+ * Emitted when a job is enqueued
276
+ */
277
+ "job:queued": [job: QueuedJob, position: number];
278
+
279
+ /**
280
+ * Emitted when a job is dequeued and ready to run
281
+ */
282
+ "job:dequeued": [job: QueuedJob];
283
+
284
+ /**
285
+ * Emitted when a scheduled trigger is skipped due to concurrency
286
+ */
287
+ "schedule:skipped": [result: ScheduleSkipResult];
288
+
289
+ /**
290
+ * Emitted when a job completes and capacity becomes available
291
+ */
292
+ "capacity:available": [agentName: string, available: number];
293
+ }
294
+
295
+ // =============================================================================
296
+ // Default Logger
297
+ // =============================================================================
298
+
299
+ function createDefaultLogger(): JobQueueLogger {
300
+ return {
301
+ debug: (message: string) => console.debug(`[job-queue] ${message}`),
302
+ info: (message: string) => console.info(`[job-queue] ${message}`),
303
+ warn: (message: string) => console.warn(`[job-queue] ${message}`),
304
+ error: (message: string) => console.error(`[job-queue] ${message}`),
305
+ };
306
+ }
307
+
308
+ // =============================================================================
309
+ // JobQueue Class
310
+ // =============================================================================
311
+
312
+ /**
313
+ * Job queue with concurrency control
314
+ *
315
+ * Manages a FIFO queue (within priority levels) with:
316
+ * - Per-agent concurrency limits
317
+ * - Optional fleet-wide concurrency limit
318
+ * - Priority-based ordering (lower number = higher priority)
319
+ *
320
+ * Scheduled triggers are NOT queued - instead, a schedule:skipped event
321
+ * is emitted when the agent or fleet is at capacity.
322
+ */
323
+ export class JobQueue extends EventEmitter {
324
+ private readonly defaultAgentConcurrency: number;
325
+ private readonly fleetConcurrency: number | null;
326
+ private readonly logger: JobQueueLogger;
327
+
328
+ // Per-agent concurrency limits (overrides default)
329
+ private readonly agentConcurrencyLimits: Map<string, number> = new Map();
330
+
331
+ // Currently running jobs per agent
332
+ private readonly runningJobs: Map<string, Set<string>> = new Map();
333
+
334
+ // Queued jobs per agent (ordered by priority then FIFO)
335
+ private readonly queuedJobs: Map<string, QueuedJob[]> = new Map();
336
+
337
+ // Total running jobs across fleet
338
+ private totalRunningCount = 0;
339
+
340
+ constructor(options: JobQueueOptions = {}) {
341
+ super();
342
+ this.defaultAgentConcurrency = options.defaultAgentConcurrency ?? 1;
343
+ this.fleetConcurrency = options.fleetConcurrency ?? null;
344
+ this.logger = options.logger ?? createDefaultLogger();
345
+ }
346
+
347
+ // ===========================================================================
348
+ // Configuration Methods
349
+ // ===========================================================================
350
+
351
+ /**
352
+ * Set the concurrency limit for a specific agent
353
+ *
354
+ * @param agentName - The agent name
355
+ * @param limit - The concurrency limit (must be >= 1)
356
+ */
357
+ setAgentConcurrency(agentName: string, limit: number): void {
358
+ if (limit < 1) {
359
+ throw new Error(`Concurrency limit must be >= 1, got ${limit}`);
360
+ }
361
+ this.agentConcurrencyLimits.set(agentName, limit);
362
+ this.logger.debug(
363
+ `Set concurrency limit for agent "${agentName}" to ${limit}`
364
+ );
365
+ }
366
+
367
+ /**
368
+ * Get the concurrency limit for an agent
369
+ *
370
+ * @param agentName - The agent name
371
+ * @returns The concurrency limit (agent-specific or default)
372
+ */
373
+ getAgentConcurrency(agentName: string): number {
374
+ return (
375
+ this.agentConcurrencyLimits.get(agentName) ?? this.defaultAgentConcurrency
376
+ );
377
+ }
378
+
379
+ /**
380
+ * Get the fleet-wide concurrency limit
381
+ *
382
+ * @returns The fleet concurrency limit or null if not set
383
+ */
384
+ getFleetConcurrency(): number | null {
385
+ return this.fleetConcurrency;
386
+ }
387
+
388
+ /**
389
+ * Get the default agent concurrency limit
390
+ *
391
+ * @returns The default agent concurrency limit
392
+ */
393
+ getDefaultAgentConcurrency(): number {
394
+ return this.defaultAgentConcurrency;
395
+ }
396
+
397
+ // ===========================================================================
398
+ // Queue Operations
399
+ // ===========================================================================
400
+
401
+ /**
402
+ * Check if there's capacity to run a job for an agent
403
+ *
404
+ * @param agentName - The agent name
405
+ * @returns Object with canRun boolean and reason if false
406
+ */
407
+ checkCapacity(agentName: string): {
408
+ canRun: boolean;
409
+ reason?: "agent_at_capacity" | "fleet_at_capacity";
410
+ currentRunning: number;
411
+ limit: number;
412
+ } {
413
+ const agentLimit = this.getAgentConcurrency(agentName);
414
+ const agentRunning = this.getRunningCount(agentName);
415
+
416
+ // Check agent-level capacity
417
+ if (agentRunning >= agentLimit) {
418
+ return {
419
+ canRun: false,
420
+ reason: "agent_at_capacity",
421
+ currentRunning: agentRunning,
422
+ limit: agentLimit,
423
+ };
424
+ }
425
+
426
+ // Check fleet-level capacity
427
+ if (
428
+ this.fleetConcurrency !== null &&
429
+ this.totalRunningCount >= this.fleetConcurrency
430
+ ) {
431
+ return {
432
+ canRun: false,
433
+ reason: "fleet_at_capacity",
434
+ currentRunning: this.totalRunningCount,
435
+ limit: this.fleetConcurrency,
436
+ };
437
+ }
438
+
439
+ return {
440
+ canRun: true,
441
+ currentRunning: agentRunning,
442
+ limit: agentLimit,
443
+ };
444
+ }
445
+
446
+ /**
447
+ * Enqueue a job or return immediately if capacity is available
448
+ *
449
+ * For scheduled triggers (isScheduled: true), jobs are NOT queued.
450
+ * Instead, a schedule:skipped event is emitted and null is returned.
451
+ *
452
+ * @param options - Enqueue options
453
+ * @returns EnqueueResult if job is queued/ready, or null if scheduled and at capacity
454
+ */
455
+ enqueue(options: EnqueueOptions): EnqueueResult | null {
456
+ const {
457
+ agentName,
458
+ scheduleName,
459
+ priority = 5,
460
+ prompt,
461
+ isScheduled = false,
462
+ } = options;
463
+
464
+ const capacity = this.checkCapacity(agentName);
465
+
466
+ // If we have capacity, the job can run immediately
467
+ if (capacity.canRun) {
468
+ const jobId = this.generateJobId();
469
+ this.logger.debug(
470
+ `Job ${jobId} for agent "${agentName}" can run immediately`
471
+ );
472
+ return {
473
+ jobId,
474
+ queued: false,
475
+ };
476
+ }
477
+
478
+ // At capacity - handle scheduled vs manual triggers differently
479
+ if (isScheduled) {
480
+ // Scheduled triggers are NOT queued - emit skip event
481
+ const skipResult: ScheduleSkipResult = {
482
+ agentName,
483
+ scheduleName,
484
+ reason: capacity.reason!,
485
+ currentRunning: capacity.currentRunning,
486
+ limit: capacity.limit,
487
+ };
488
+
489
+ this.logger.info(
490
+ `Schedule "${scheduleName}" for agent "${agentName}" skipped: ${capacity.reason} (${capacity.currentRunning}/${capacity.limit})`
491
+ );
492
+
493
+ this.emit("schedule:skipped", skipResult);
494
+ return null;
495
+ }
496
+
497
+ // Manual triggers get queued
498
+ const job: QueuedJob = {
499
+ id: this.generateJobId(),
500
+ agentName,
501
+ scheduleName,
502
+ priority: priority as JobPriority,
503
+ queuedAt: new Date().toISOString(),
504
+ prompt,
505
+ isScheduled: false,
506
+ };
507
+
508
+ // Get or create the agent's queue
509
+ if (!this.queuedJobs.has(agentName)) {
510
+ this.queuedJobs.set(agentName, []);
511
+ }
512
+ const agentQueue = this.queuedJobs.get(agentName)!;
513
+
514
+ // Insert job in priority order (lower priority number = higher priority)
515
+ // Within same priority, FIFO order is maintained
516
+ let insertIndex = agentQueue.length;
517
+ for (let i = 0; i < agentQueue.length; i++) {
518
+ if (agentQueue[i].priority > job.priority) {
519
+ insertIndex = i;
520
+ break;
521
+ }
522
+ }
523
+ agentQueue.splice(insertIndex, 0, job);
524
+
525
+ const position = insertIndex + 1;
526
+ this.logger.info(
527
+ `Job ${job.id} for agent "${agentName}" queued at position ${position} (${capacity.reason})`
528
+ );
529
+
530
+ this.emit("job:queued", job, position);
531
+
532
+ return {
533
+ jobId: job.id,
534
+ queued: true,
535
+ position,
536
+ reason: capacity.reason,
537
+ };
538
+ }
539
+
540
+ /**
541
+ * Dequeue the next job for an agent
542
+ *
543
+ * Returns the next queued job if one exists, otherwise null.
544
+ * Does NOT check capacity - caller should check capacity first.
545
+ *
546
+ * @param agentName - The agent name
547
+ * @returns The next queued job or null
548
+ */
549
+ dequeue(agentName: string): QueuedJob | null {
550
+ const agentQueue = this.queuedJobs.get(agentName);
551
+ if (!agentQueue || agentQueue.length === 0) {
552
+ return null;
553
+ }
554
+
555
+ const job = agentQueue.shift()!;
556
+ this.logger.debug(
557
+ `Dequeued job ${job.id} for agent "${agentName}" (${agentQueue.length} remaining)`
558
+ );
559
+
560
+ this.emit("job:dequeued", job);
561
+ return job;
562
+ }
563
+
564
+ /**
565
+ * Peek at the next job in the queue without removing it
566
+ *
567
+ * @param agentName - The agent name
568
+ * @returns The next queued job or null
569
+ */
570
+ peek(agentName: string): QueuedJob | null {
571
+ const agentQueue = this.queuedJobs.get(agentName);
572
+ if (!agentQueue || agentQueue.length === 0) {
573
+ return null;
574
+ }
575
+ return agentQueue[0];
576
+ }
577
+
578
+ /**
579
+ * Remove a specific job from the queue
580
+ *
581
+ * @param jobId - The job ID to remove
582
+ * @returns true if the job was found and removed
583
+ */
584
+ remove(jobId: string): boolean {
585
+ for (const [agentName, queue] of this.queuedJobs) {
586
+ const index = queue.findIndex((job) => job.id === jobId);
587
+ if (index !== -1) {
588
+ queue.splice(index, 1);
589
+ this.logger.debug(
590
+ `Removed job ${jobId} from agent "${agentName}" queue`
591
+ );
592
+ return true;
593
+ }
594
+ }
595
+ return false;
596
+ }
597
+
598
+ // ===========================================================================
599
+ // Running Job Tracking
600
+ // ===========================================================================
601
+
602
+ /**
603
+ * Mark a job as running for an agent
604
+ *
605
+ * @param agentName - The agent name
606
+ * @param jobId - The job ID
607
+ */
608
+ markRunning(agentName: string, jobId: string): void {
609
+ if (!this.runningJobs.has(agentName)) {
610
+ this.runningJobs.set(agentName, new Set());
611
+ }
612
+ this.runningJobs.get(agentName)!.add(jobId);
613
+ this.totalRunningCount++;
614
+
615
+ this.logger.debug(
616
+ `Marked job ${jobId} as running for agent "${agentName}" (total: ${this.totalRunningCount})`
617
+ );
618
+ }
619
+
620
+ /**
621
+ * Mark a job as completed for an agent
622
+ *
623
+ * This frees up capacity and may allow queued jobs to run.
624
+ *
625
+ * @param agentName - The agent name
626
+ * @param jobId - The job ID
627
+ */
628
+ markCompleted(agentName: string, jobId: string): void {
629
+ const agentJobs = this.runningJobs.get(agentName);
630
+ if (agentJobs?.has(jobId)) {
631
+ agentJobs.delete(jobId);
632
+ this.totalRunningCount--;
633
+
634
+ const available = this.getAgentConcurrency(agentName) - agentJobs.size;
635
+ this.logger.debug(
636
+ `Marked job ${jobId} as completed for agent "${agentName}" (${available} slots available)`
637
+ );
638
+
639
+ this.emit("capacity:available", agentName, available);
640
+ }
641
+ }
642
+
643
+ /**
644
+ * Get the number of running jobs for an agent
645
+ *
646
+ * @param agentName - The agent name
647
+ * @returns Number of currently running jobs
648
+ */
649
+ getRunningCount(agentName: string): number {
650
+ return this.runningJobs.get(agentName)?.size ?? 0;
651
+ }
652
+
653
+ /**
654
+ * Get the total number of running jobs across all agents
655
+ *
656
+ * @returns Total running job count
657
+ */
658
+ getTotalRunningCount(): number {
659
+ return this.totalRunningCount;
660
+ }
661
+
662
+ /**
663
+ * Get the IDs of running jobs for an agent
664
+ *
665
+ * @param agentName - The agent name
666
+ * @returns Set of running job IDs
667
+ */
668
+ getRunningJobIds(agentName: string): Set<string> {
669
+ return this.runningJobs.get(agentName) ?? new Set();
670
+ }
671
+
672
+ // ===========================================================================
673
+ // Status Queries
674
+ // ===========================================================================
675
+
676
+ /**
677
+ * Get the queue status for a specific agent
678
+ *
679
+ * @param agentName - The agent name
680
+ * @returns Agent queue status
681
+ */
682
+ getAgentQueueStatus(agentName: string): AgentQueueStatus {
683
+ const queuedJobs = this.queuedJobs.get(agentName) ?? [];
684
+ return {
685
+ agentName,
686
+ runningCount: this.getRunningCount(agentName),
687
+ maxConcurrent: this.getAgentConcurrency(agentName),
688
+ queuedCount: queuedJobs.length,
689
+ queuedJobs: [...queuedJobs], // Return a copy
690
+ };
691
+ }
692
+
693
+ /**
694
+ * Get the overall queue status
695
+ *
696
+ * @returns Overall queue status with per-agent details
697
+ */
698
+ getQueueStatus(): QueueStatus {
699
+ const agents = new Map<string, AgentQueueStatus>();
700
+
701
+ // Collect all known agent names from both running and queued
702
+ const allAgentNames = new Set<string>([
703
+ ...this.runningJobs.keys(),
704
+ ...this.queuedJobs.keys(),
705
+ ]);
706
+
707
+ let totalQueued = 0;
708
+ for (const agentName of allAgentNames) {
709
+ const status = this.getAgentQueueStatus(agentName);
710
+ agents.set(agentName, status);
711
+ totalQueued += status.queuedCount;
712
+ }
713
+
714
+ return {
715
+ totalRunning: this.totalRunningCount,
716
+ fleetConcurrency: this.fleetConcurrency,
717
+ defaultAgentConcurrency: this.defaultAgentConcurrency,
718
+ totalQueued,
719
+ agents,
720
+ };
721
+ }
722
+
723
+ /**
724
+ * Get the queue depth (number of queued jobs) for an agent
725
+ *
726
+ * @param agentName - The agent name
727
+ * @returns Number of queued jobs
728
+ */
729
+ getQueueDepth(agentName: string): number {
730
+ return this.queuedJobs.get(agentName)?.length ?? 0;
731
+ }
732
+
733
+ /**
734
+ * Get the total queue depth across all agents
735
+ *
736
+ * @returns Total number of queued jobs
737
+ */
738
+ getTotalQueueDepth(): number {
739
+ let total = 0;
740
+ for (const queue of this.queuedJobs.values()) {
741
+ total += queue.length;
742
+ }
743
+ return total;
744
+ }
745
+
746
+ // ===========================================================================
747
+ // Utility Methods
748
+ // ===========================================================================
749
+
750
+ /**
751
+ * Clear all queued jobs (does not affect running jobs)
752
+ */
753
+ clearQueue(): void {
754
+ const totalCleared = this.getTotalQueueDepth();
755
+ this.queuedJobs.clear();
756
+ this.logger.info(`Cleared ${totalCleared} queued jobs`);
757
+ }
758
+
759
+ /**
760
+ * Clear queued jobs for a specific agent
761
+ *
762
+ * @param agentName - The agent name
763
+ * @returns Number of jobs cleared
764
+ */
765
+ clearAgentQueue(agentName: string): number {
766
+ const queue = this.queuedJobs.get(agentName);
767
+ if (!queue) return 0;
768
+
769
+ const count = queue.length;
770
+ this.queuedJobs.delete(agentName);
771
+ this.logger.debug(`Cleared ${count} queued jobs for agent "${agentName}"`);
772
+ return count;
773
+ }
774
+
775
+ /**
776
+ * Reset all state (running jobs, queued jobs, concurrency limits)
777
+ */
778
+ reset(): void {
779
+ this.runningJobs.clear();
780
+ this.queuedJobs.clear();
781
+ this.agentConcurrencyLimits.clear();
782
+ this.totalRunningCount = 0;
783
+ this.logger.info("Job queue reset");
784
+ }
785
+
786
+ // ===========================================================================
787
+ // Private Methods
788
+ // ===========================================================================
789
+
790
+ /**
791
+ * Generate a unique job ID
792
+ */
793
+ private generateJobId(): string {
794
+ const date = new Date().toISOString().slice(0, 10);
795
+ const uuid = randomUUID().slice(0, 8);
796
+ return `queued-${date}-${uuid}`;
797
+ }
798
+ }