steroids-api 0.2.7

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 (328) hide show
  1. package/dist/API/src/index.d.ts +10 -0
  2. package/dist/API/src/index.d.ts.map +1 -0
  3. package/dist/API/src/index.js +130 -0
  4. package/dist/API/src/index.js.map +1 -0
  5. package/dist/API/src/routes/activity.d.ts +7 -0
  6. package/dist/API/src/routes/activity.d.ts.map +1 -0
  7. package/dist/API/src/routes/activity.js +252 -0
  8. package/dist/API/src/routes/activity.js.map +1 -0
  9. package/dist/API/src/routes/config.d.ts +7 -0
  10. package/dist/API/src/routes/config.d.ts.map +1 -0
  11. package/dist/API/src/routes/config.js +521 -0
  12. package/dist/API/src/routes/config.js.map +1 -0
  13. package/dist/API/src/routes/health.d.ts +7 -0
  14. package/dist/API/src/routes/health.d.ts.map +1 -0
  15. package/dist/API/src/routes/health.js +172 -0
  16. package/dist/API/src/routes/health.js.map +1 -0
  17. package/dist/API/src/routes/incidents.d.ts +7 -0
  18. package/dist/API/src/routes/incidents.d.ts.map +1 -0
  19. package/dist/API/src/routes/incidents.js +117 -0
  20. package/dist/API/src/routes/incidents.js.map +1 -0
  21. package/dist/API/src/routes/projects.d.ts +7 -0
  22. package/dist/API/src/routes/projects.d.ts.map +1 -0
  23. package/dist/API/src/routes/projects.js +398 -0
  24. package/dist/API/src/routes/projects.js.map +1 -0
  25. package/dist/API/src/routes/runners.d.ts +7 -0
  26. package/dist/API/src/routes/runners.d.ts.map +1 -0
  27. package/dist/API/src/routes/runners.js +242 -0
  28. package/dist/API/src/routes/runners.js.map +1 -0
  29. package/dist/API/src/routes/tasks.d.ts +7 -0
  30. package/dist/API/src/routes/tasks.d.ts.map +1 -0
  31. package/dist/API/src/routes/tasks.js +1007 -0
  32. package/dist/API/src/routes/tasks.js.map +1 -0
  33. package/dist/API/src/utils/validation.d.ts +22 -0
  34. package/dist/API/src/utils/validation.d.ts.map +1 -0
  35. package/dist/API/src/utils/validation.js +50 -0
  36. package/dist/API/src/utils/validation.js.map +1 -0
  37. package/dist/index.d.ts +10 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +184 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/routes/activity.d.ts +7 -0
  42. package/dist/routes/activity.d.ts.map +1 -0
  43. package/dist/routes/activity.js +252 -0
  44. package/dist/routes/activity.js.map +1 -0
  45. package/dist/routes/config.d.ts +7 -0
  46. package/dist/routes/config.d.ts.map +1 -0
  47. package/dist/routes/config.js +647 -0
  48. package/dist/routes/config.js.map +1 -0
  49. package/dist/routes/credit-alerts.d.ts +2 -0
  50. package/dist/routes/credit-alerts.d.ts.map +1 -0
  51. package/dist/routes/credit-alerts.js +97 -0
  52. package/dist/routes/credit-alerts.js.map +1 -0
  53. package/dist/routes/health.d.ts +7 -0
  54. package/dist/routes/health.d.ts.map +1 -0
  55. package/dist/routes/health.js +200 -0
  56. package/dist/routes/health.js.map +1 -0
  57. package/dist/routes/incidents.d.ts +7 -0
  58. package/dist/routes/incidents.d.ts.map +1 -0
  59. package/dist/routes/incidents.js +117 -0
  60. package/dist/routes/incidents.js.map +1 -0
  61. package/dist/routes/projects.d.ts +7 -0
  62. package/dist/routes/projects.d.ts.map +1 -0
  63. package/dist/routes/projects.js +643 -0
  64. package/dist/routes/projects.js.map +1 -0
  65. package/dist/routes/runners.d.ts +7 -0
  66. package/dist/routes/runners.d.ts.map +1 -0
  67. package/dist/routes/runners.js +299 -0
  68. package/dist/routes/runners.js.map +1 -0
  69. package/dist/routes/skills.d.ts +3 -0
  70. package/dist/routes/skills.d.ts.map +1 -0
  71. package/dist/routes/skills.js +109 -0
  72. package/dist/routes/skills.js.map +1 -0
  73. package/dist/routes/storage.d.ts +7 -0
  74. package/dist/routes/storage.d.ts.map +1 -0
  75. package/dist/routes/storage.js +93 -0
  76. package/dist/routes/storage.js.map +1 -0
  77. package/dist/routes/tasks.d.ts +7 -0
  78. package/dist/routes/tasks.d.ts.map +1 -0
  79. package/dist/routes/tasks.js +1145 -0
  80. package/dist/routes/tasks.js.map +1 -0
  81. package/dist/src/cleanup/invocation-logs.d.ts +30 -0
  82. package/dist/src/cleanup/invocation-logs.d.ts.map +1 -0
  83. package/dist/src/cleanup/invocation-logs.js +66 -0
  84. package/dist/src/cleanup/invocation-logs.js.map +1 -0
  85. package/dist/src/commands/loop-phases.d.ts +11 -0
  86. package/dist/src/commands/loop-phases.d.ts.map +1 -0
  87. package/dist/src/commands/loop-phases.js +304 -0
  88. package/dist/src/commands/loop-phases.js.map +1 -0
  89. package/dist/src/config/loader.d.ts +160 -0
  90. package/dist/src/config/loader.d.ts.map +1 -0
  91. package/dist/src/config/loader.js +276 -0
  92. package/dist/src/config/loader.js.map +1 -0
  93. package/dist/src/database/connection.d.ts +35 -0
  94. package/dist/src/database/connection.d.ts.map +1 -0
  95. package/dist/src/database/connection.js +197 -0
  96. package/dist/src/database/connection.js.map +1 -0
  97. package/dist/src/database/queries.d.ts +220 -0
  98. package/dist/src/database/queries.d.ts.map +1 -0
  99. package/dist/src/database/queries.js +589 -0
  100. package/dist/src/database/queries.js.map +1 -0
  101. package/dist/src/database/schema.d.ts +8 -0
  102. package/dist/src/database/schema.d.ts.map +1 -0
  103. package/dist/src/database/schema.js +184 -0
  104. package/dist/src/database/schema.js.map +1 -0
  105. package/dist/src/git/push.d.ts +26 -0
  106. package/dist/src/git/push.d.ts.map +1 -0
  107. package/dist/src/git/push.js +91 -0
  108. package/dist/src/git/push.js.map +1 -0
  109. package/dist/src/git/status.d.ts +83 -0
  110. package/dist/src/git/status.d.ts.map +1 -0
  111. package/dist/src/git/status.js +315 -0
  112. package/dist/src/git/status.js.map +1 -0
  113. package/dist/src/health/stuck-task-detector.d.ts +131 -0
  114. package/dist/src/health/stuck-task-detector.d.ts.map +1 -0
  115. package/dist/src/health/stuck-task-detector.js +233 -0
  116. package/dist/src/health/stuck-task-detector.js.map +1 -0
  117. package/dist/src/health/stuck-task-recovery.d.ts +45 -0
  118. package/dist/src/health/stuck-task-recovery.d.ts.map +1 -0
  119. package/dist/src/health/stuck-task-recovery.js +309 -0
  120. package/dist/src/health/stuck-task-recovery.js.map +1 -0
  121. package/dist/src/index.d.ts +10 -0
  122. package/dist/src/index.d.ts.map +1 -0
  123. package/dist/src/index.js +130 -0
  124. package/dist/src/index.js.map +1 -0
  125. package/dist/src/locking/queries.d.ts +116 -0
  126. package/dist/src/locking/queries.d.ts.map +1 -0
  127. package/dist/src/locking/queries.js +232 -0
  128. package/dist/src/locking/queries.js.map +1 -0
  129. package/dist/src/locking/section-lock.d.ts +74 -0
  130. package/dist/src/locking/section-lock.d.ts.map +1 -0
  131. package/dist/src/locking/section-lock.js +196 -0
  132. package/dist/src/locking/section-lock.js.map +1 -0
  133. package/dist/src/locking/task-lock.d.ts +92 -0
  134. package/dist/src/locking/task-lock.d.ts.map +1 -0
  135. package/dist/src/locking/task-lock.js +233 -0
  136. package/dist/src/locking/task-lock.js.map +1 -0
  137. package/dist/src/migrations/index.d.ts +7 -0
  138. package/dist/src/migrations/index.d.ts.map +1 -0
  139. package/dist/src/migrations/index.js +9 -0
  140. package/dist/src/migrations/index.js.map +1 -0
  141. package/dist/src/migrations/manifest.d.ts +92 -0
  142. package/dist/src/migrations/manifest.d.ts.map +1 -0
  143. package/dist/src/migrations/manifest.js +255 -0
  144. package/dist/src/migrations/manifest.js.map +1 -0
  145. package/dist/src/migrations/runner.d.ts +84 -0
  146. package/dist/src/migrations/runner.d.ts.map +1 -0
  147. package/dist/src/migrations/runner.js +338 -0
  148. package/dist/src/migrations/runner.js.map +1 -0
  149. package/dist/src/orchestrator/coder.d.ts +32 -0
  150. package/dist/src/orchestrator/coder.d.ts.map +1 -0
  151. package/dist/src/orchestrator/coder.js +170 -0
  152. package/dist/src/orchestrator/coder.js.map +1 -0
  153. package/dist/src/orchestrator/coordinator.d.ts +28 -0
  154. package/dist/src/orchestrator/coordinator.d.ts.map +1 -0
  155. package/dist/src/orchestrator/coordinator.js +252 -0
  156. package/dist/src/orchestrator/coordinator.js.map +1 -0
  157. package/dist/src/orchestrator/fallback-handler.d.ts +24 -0
  158. package/dist/src/orchestrator/fallback-handler.d.ts.map +1 -0
  159. package/dist/src/orchestrator/fallback-handler.js +280 -0
  160. package/dist/src/orchestrator/fallback-handler.js.map +1 -0
  161. package/dist/src/orchestrator/invoke.d.ts +14 -0
  162. package/dist/src/orchestrator/invoke.d.ts.map +1 -0
  163. package/dist/src/orchestrator/invoke.js +76 -0
  164. package/dist/src/orchestrator/invoke.js.map +1 -0
  165. package/dist/src/orchestrator/post-coder.d.ts +10 -0
  166. package/dist/src/orchestrator/post-coder.d.ts.map +1 -0
  167. package/dist/src/orchestrator/post-coder.js +198 -0
  168. package/dist/src/orchestrator/post-coder.js.map +1 -0
  169. package/dist/src/orchestrator/post-reviewer.d.ts +10 -0
  170. package/dist/src/orchestrator/post-reviewer.d.ts.map +1 -0
  171. package/dist/src/orchestrator/post-reviewer.js +199 -0
  172. package/dist/src/orchestrator/post-reviewer.js.map +1 -0
  173. package/dist/src/orchestrator/reviewer.d.ts +35 -0
  174. package/dist/src/orchestrator/reviewer.d.ts.map +1 -0
  175. package/dist/src/orchestrator/reviewer.js +237 -0
  176. package/dist/src/orchestrator/reviewer.js.map +1 -0
  177. package/dist/src/orchestrator/schemas.d.ts +10 -0
  178. package/dist/src/orchestrator/schemas.d.ts.map +1 -0
  179. package/dist/src/orchestrator/schemas.js +81 -0
  180. package/dist/src/orchestrator/schemas.js.map +1 -0
  181. package/dist/src/orchestrator/task-selector.d.ts +102 -0
  182. package/dist/src/orchestrator/task-selector.d.ts.map +1 -0
  183. package/dist/src/orchestrator/task-selector.js +326 -0
  184. package/dist/src/orchestrator/task-selector.js.map +1 -0
  185. package/dist/src/orchestrator/types.d.ts +74 -0
  186. package/dist/src/orchestrator/types.d.ts.map +1 -0
  187. package/dist/src/orchestrator/types.js +5 -0
  188. package/dist/src/orchestrator/types.js.map +1 -0
  189. package/dist/src/prompts/coder.d.ts +36 -0
  190. package/dist/src/prompts/coder.d.ts.map +1 -0
  191. package/dist/src/prompts/coder.js +303 -0
  192. package/dist/src/prompts/coder.js.map +1 -0
  193. package/dist/src/prompts/prompt-helpers.d.ts +51 -0
  194. package/dist/src/prompts/prompt-helpers.d.ts.map +1 -0
  195. package/dist/src/prompts/prompt-helpers.js +299 -0
  196. package/dist/src/prompts/prompt-helpers.js.map +1 -0
  197. package/dist/src/prompts/reviewer.d.ts +40 -0
  198. package/dist/src/prompts/reviewer.d.ts.map +1 -0
  199. package/dist/src/prompts/reviewer.js +416 -0
  200. package/dist/src/prompts/reviewer.js.map +1 -0
  201. package/dist/src/providers/claude.d.ts +53 -0
  202. package/dist/src/providers/claude.d.ts.map +1 -0
  203. package/dist/src/providers/claude.js +227 -0
  204. package/dist/src/providers/claude.js.map +1 -0
  205. package/dist/src/providers/codex.d.ts +53 -0
  206. package/dist/src/providers/codex.d.ts.map +1 -0
  207. package/dist/src/providers/codex.js +253 -0
  208. package/dist/src/providers/codex.js.map +1 -0
  209. package/dist/src/providers/gemini.d.ts +58 -0
  210. package/dist/src/providers/gemini.d.ts.map +1 -0
  211. package/dist/src/providers/gemini.js +240 -0
  212. package/dist/src/providers/gemini.js.map +1 -0
  213. package/dist/src/providers/interface.d.ts +185 -0
  214. package/dist/src/providers/interface.d.ts.map +1 -0
  215. package/dist/src/providers/interface.js +92 -0
  216. package/dist/src/providers/interface.js.map +1 -0
  217. package/dist/src/providers/invocation-logger.d.ts +97 -0
  218. package/dist/src/providers/invocation-logger.d.ts.map +1 -0
  219. package/dist/src/providers/invocation-logger.js +378 -0
  220. package/dist/src/providers/invocation-logger.js.map +1 -0
  221. package/dist/src/providers/openai.d.ts +53 -0
  222. package/dist/src/providers/openai.d.ts.map +1 -0
  223. package/dist/src/providers/openai.js +230 -0
  224. package/dist/src/providers/openai.js.map +1 -0
  225. package/dist/src/providers/registry.d.ts +100 -0
  226. package/dist/src/providers/registry.d.ts.map +1 -0
  227. package/dist/src/providers/registry.js +170 -0
  228. package/dist/src/providers/registry.js.map +1 -0
  229. package/dist/src/routes/activity.d.ts +7 -0
  230. package/dist/src/routes/activity.d.ts.map +1 -0
  231. package/dist/src/routes/activity.js +252 -0
  232. package/dist/src/routes/activity.js.map +1 -0
  233. package/dist/src/routes/config.d.ts +7 -0
  234. package/dist/src/routes/config.d.ts.map +1 -0
  235. package/dist/src/routes/config.js +521 -0
  236. package/dist/src/routes/config.js.map +1 -0
  237. package/dist/src/routes/health.d.ts +7 -0
  238. package/dist/src/routes/health.d.ts.map +1 -0
  239. package/dist/src/routes/health.js +172 -0
  240. package/dist/src/routes/health.js.map +1 -0
  241. package/dist/src/routes/incidents.d.ts +7 -0
  242. package/dist/src/routes/incidents.d.ts.map +1 -0
  243. package/dist/src/routes/incidents.js +117 -0
  244. package/dist/src/routes/incidents.js.map +1 -0
  245. package/dist/src/routes/projects.d.ts +7 -0
  246. package/dist/src/routes/projects.d.ts.map +1 -0
  247. package/dist/src/routes/projects.js +398 -0
  248. package/dist/src/routes/projects.js.map +1 -0
  249. package/dist/src/routes/runners.d.ts +7 -0
  250. package/dist/src/routes/runners.d.ts.map +1 -0
  251. package/dist/src/routes/runners.js +242 -0
  252. package/dist/src/routes/runners.js.map +1 -0
  253. package/dist/src/routes/tasks.d.ts +7 -0
  254. package/dist/src/routes/tasks.d.ts.map +1 -0
  255. package/dist/src/routes/tasks.js +1007 -0
  256. package/dist/src/routes/tasks.js.map +1 -0
  257. package/dist/src/runners/activity-log.d.ts +65 -0
  258. package/dist/src/runners/activity-log.d.ts.map +1 -0
  259. package/dist/src/runners/activity-log.js +140 -0
  260. package/dist/src/runners/activity-log.js.map +1 -0
  261. package/dist/src/runners/cron.d.ts +30 -0
  262. package/dist/src/runners/cron.d.ts.map +1 -0
  263. package/dist/src/runners/cron.js +333 -0
  264. package/dist/src/runners/cron.js.map +1 -0
  265. package/dist/src/runners/daemon.d.ts +71 -0
  266. package/dist/src/runners/daemon.d.ts.map +1 -0
  267. package/dist/src/runners/daemon.js +233 -0
  268. package/dist/src/runners/daemon.js.map +1 -0
  269. package/dist/src/runners/global-db.d.ts +31 -0
  270. package/dist/src/runners/global-db.d.ts.map +1 -0
  271. package/dist/src/runners/global-db.js +220 -0
  272. package/dist/src/runners/global-db.js.map +1 -0
  273. package/dist/src/runners/hang-detector.d.ts +38 -0
  274. package/dist/src/runners/hang-detector.d.ts.map +1 -0
  275. package/dist/src/runners/hang-detector.js +130 -0
  276. package/dist/src/runners/hang-detector.js.map +1 -0
  277. package/dist/src/runners/heartbeat.d.ts +39 -0
  278. package/dist/src/runners/heartbeat.d.ts.map +1 -0
  279. package/dist/src/runners/heartbeat.js +71 -0
  280. package/dist/src/runners/heartbeat.js.map +1 -0
  281. package/dist/src/runners/lock.d.ts +47 -0
  282. package/dist/src/runners/lock.d.ts.map +1 -0
  283. package/dist/src/runners/lock.js +140 -0
  284. package/dist/src/runners/lock.js.map +1 -0
  285. package/dist/src/runners/orchestrator-loop.d.ts +20 -0
  286. package/dist/src/runners/orchestrator-loop.d.ts.map +1 -0
  287. package/dist/src/runners/orchestrator-loop.js +208 -0
  288. package/dist/src/runners/orchestrator-loop.js.map +1 -0
  289. package/dist/src/runners/projects.d.ts +96 -0
  290. package/dist/src/runners/projects.d.ts.map +1 -0
  291. package/dist/src/runners/projects.js +243 -0
  292. package/dist/src/runners/projects.js.map +1 -0
  293. package/dist/src/runners/wakeup.d.ts +37 -0
  294. package/dist/src/runners/wakeup.d.ts.map +1 -0
  295. package/dist/src/runners/wakeup.js +355 -0
  296. package/dist/src/runners/wakeup.js.map +1 -0
  297. package/dist/src/utils/validation.d.ts +22 -0
  298. package/dist/src/utils/validation.d.ts.map +1 -0
  299. package/dist/src/utils/validation.js +50 -0
  300. package/dist/src/utils/validation.js.map +1 -0
  301. package/dist/utils/sqlite.d.ts +17 -0
  302. package/dist/utils/sqlite.d.ts.map +1 -0
  303. package/dist/utils/sqlite.js +27 -0
  304. package/dist/utils/sqlite.js.map +1 -0
  305. package/dist/utils/storage-cache.d.ts +33 -0
  306. package/dist/utils/storage-cache.d.ts.map +1 -0
  307. package/dist/utils/storage-cache.js +81 -0
  308. package/dist/utils/storage-cache.js.map +1 -0
  309. package/dist/utils/validation.d.ts +22 -0
  310. package/dist/utils/validation.d.ts.map +1 -0
  311. package/dist/utils/validation.js +51 -0
  312. package/dist/utils/validation.js.map +1 -0
  313. package/package.json +39 -0
  314. package/src/index.ts +199 -0
  315. package/src/routes/activity.ts +302 -0
  316. package/src/routes/config.ts +723 -0
  317. package/src/routes/credit-alerts.ts +73 -0
  318. package/src/routes/health.ts +219 -0
  319. package/src/routes/incidents.ts +131 -0
  320. package/src/routes/projects.ts +854 -0
  321. package/src/routes/runners.ts +357 -0
  322. package/src/routes/skills.ts +127 -0
  323. package/src/routes/storage.ts +108 -0
  324. package/src/routes/tasks.ts +1372 -0
  325. package/src/utils/sqlite.ts +36 -0
  326. package/src/utils/storage-cache.ts +107 -0
  327. package/src/utils/validation.ts +61 -0
  328. package/tsconfig.json +20 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Subprocess hang detection
3
+ * Monitors log output and kills processes that appear stuck
4
+ */
5
+ const DEFAULT_HANG_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
6
+ /**
7
+ * Create a hang detector for a subprocess
8
+ * Monitors output activity and detects when a process appears stuck
9
+ */
10
+ export function createHangDetector(options = {}) {
11
+ const { timeoutMs = DEFAULT_HANG_TIMEOUT_MS, onHang, onOutput } = options;
12
+ let lastOutputTime = new Date();
13
+ let checkInterval = null;
14
+ let hasNotifiedHang = false;
15
+ const recordOutput = () => {
16
+ lastOutputTime = new Date();
17
+ hasNotifiedHang = false;
18
+ if (onOutput) {
19
+ onOutput();
20
+ }
21
+ };
22
+ const getElapsedSinceOutput = () => {
23
+ return Date.now() - lastOutputTime.getTime();
24
+ };
25
+ const isHung = () => {
26
+ return getElapsedSinceOutput() > timeoutMs;
27
+ };
28
+ const getLastOutputTime = () => {
29
+ return lastOutputTime;
30
+ };
31
+ // Start periodic check
32
+ checkInterval = setInterval(() => {
33
+ if (isHung() && !hasNotifiedHang) {
34
+ hasNotifiedHang = true;
35
+ if (onHang) {
36
+ onHang(lastOutputTime, getElapsedSinceOutput());
37
+ }
38
+ }
39
+ }, 60 * 1000); // Check every minute
40
+ const stop = () => {
41
+ if (checkInterval) {
42
+ clearInterval(checkInterval);
43
+ checkInterval = null;
44
+ }
45
+ };
46
+ return {
47
+ recordOutput,
48
+ isHung,
49
+ getLastOutputTime,
50
+ getElapsedSinceOutput,
51
+ stop,
52
+ };
53
+ }
54
+ /**
55
+ * Attach hang detection to a child process
56
+ * Monitors stdout/stderr for output activity
57
+ */
58
+ export function attachHangDetector(child, options = {}) {
59
+ const { killOnHang = true, ...detectorOptions } = options;
60
+ const detector = createHangDetector({
61
+ ...detectorOptions,
62
+ onHang: (lastOutput, elapsed) => {
63
+ const minutes = Math.floor(elapsed / 60000);
64
+ console.error(`Process appears hung (no output for ${minutes} minutes)`);
65
+ if (killOnHang && child.pid) {
66
+ console.error(`Killing hung process (PID: ${child.pid})`);
67
+ try {
68
+ child.kill('SIGTERM');
69
+ // Force kill after 10 seconds if still alive
70
+ setTimeout(() => {
71
+ try {
72
+ child.kill('SIGKILL');
73
+ }
74
+ catch {
75
+ // Process already dead
76
+ }
77
+ }, 10000);
78
+ }
79
+ catch {
80
+ // Process already dead
81
+ }
82
+ }
83
+ if (detectorOptions.onHang) {
84
+ detectorOptions.onHang(lastOutput, elapsed);
85
+ }
86
+ },
87
+ });
88
+ // Monitor stdout
89
+ if (child.stdout) {
90
+ child.stdout.on('data', () => {
91
+ detector.recordOutput();
92
+ });
93
+ }
94
+ // Monitor stderr
95
+ if (child.stderr) {
96
+ child.stderr.on('data', () => {
97
+ detector.recordOutput();
98
+ });
99
+ }
100
+ // Clean up on process exit
101
+ child.on('exit', () => {
102
+ detector.stop();
103
+ });
104
+ child.on('error', () => {
105
+ detector.stop();
106
+ });
107
+ return detector;
108
+ }
109
+ /**
110
+ * Get default hang timeout in milliseconds
111
+ */
112
+ export function getDefaultHangTimeout() {
113
+ return DEFAULT_HANG_TIMEOUT_MS;
114
+ }
115
+ /**
116
+ * Format elapsed time for display
117
+ */
118
+ export function formatElapsed(ms) {
119
+ const seconds = Math.floor(ms / 1000);
120
+ const minutes = Math.floor(seconds / 60);
121
+ const hours = Math.floor(minutes / 60);
122
+ if (hours > 0) {
123
+ return `${hours}h ${minutes % 60}m`;
124
+ }
125
+ if (minutes > 0) {
126
+ return `${minutes}m ${seconds % 60}s`;
127
+ }
128
+ return `${seconds}s`;
129
+ }
130
+ //# sourceMappingURL=hang-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hang-detector.js","sourceRoot":"","sources":["../../../../src/runners/hang-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Heartbeat system for runner liveness detection
3
+ */
4
+ import type Database from 'better-sqlite3';
5
+ export interface HeartbeatManager {
6
+ start: () => void;
7
+ stop: () => void;
8
+ beat: () => void;
9
+ }
10
+ /**
11
+ * Update heartbeat timestamp for a runner
12
+ */
13
+ export declare function updateHeartbeat(db: Database.Database, runnerId: string): void;
14
+ /**
15
+ * Check if a runner's heartbeat is stale
16
+ */
17
+ export declare function isHeartbeatStale(db: Database.Database, runnerId: string): boolean;
18
+ /**
19
+ * Find stale runners (no heartbeat for > 5 minutes)
20
+ */
21
+ export declare function findStaleRunners(db: Database.Database): Array<{
22
+ id: string;
23
+ pid: number | null;
24
+ heartbeat_at: string;
25
+ }>;
26
+ /**
27
+ * Create a heartbeat manager for a runner
28
+ * Automatically updates heartbeat at regular intervals
29
+ */
30
+ export declare function createHeartbeatManager(db: Database.Database, runnerId: string): HeartbeatManager;
31
+ /**
32
+ * Get heartbeat interval in milliseconds
33
+ */
34
+ export declare function getHeartbeatInterval(): number;
35
+ /**
36
+ * Get stale timeout in milliseconds
37
+ */
38
+ export declare function getStaleTimeout(): number;
39
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../../../src/runners/heartbeat.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI7E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAWT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,GACpB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAUjE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAuBlB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Heartbeat system for runner liveness detection
3
+ */
4
+ const HEARTBEAT_INTERVAL_MS = 30 * 1000; // 30 seconds
5
+ const STALE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
6
+ /**
7
+ * Update heartbeat timestamp for a runner
8
+ */
9
+ export function updateHeartbeat(db, runnerId) {
10
+ db.prepare(`UPDATE runners SET heartbeat_at = datetime('now') WHERE id = ?`).run(runnerId);
11
+ }
12
+ /**
13
+ * Check if a runner's heartbeat is stale
14
+ */
15
+ export function isHeartbeatStale(db, runnerId) {
16
+ // Use SQLite's datetime comparison to avoid JavaScript/SQLite format issues
17
+ const result = db
18
+ .prepare(`SELECT 1 FROM runners
19
+ WHERE id = ? AND heartbeat_at >= datetime('now', '-5 minutes')`)
20
+ .get(runnerId);
21
+ // If no row returned, either runner doesn't exist or heartbeat is stale
22
+ return result === undefined;
23
+ }
24
+ /**
25
+ * Find stale runners (no heartbeat for > 5 minutes)
26
+ */
27
+ export function findStaleRunners(db) {
28
+ // Use SQLite's datetime function to avoid timestamp format mismatches
29
+ // JavaScript ISO format ("2026-02-08T22:28:49.000Z") differs from
30
+ // SQLite datetime format ("2026-02-08 22:33:49"), breaking string comparison
31
+ return db
32
+ .prepare(`SELECT id, pid, heartbeat_at FROM runners
33
+ WHERE heartbeat_at < datetime('now', '-5 minutes') AND status != 'idle'`)
34
+ .all();
35
+ }
36
+ /**
37
+ * Create a heartbeat manager for a runner
38
+ * Automatically updates heartbeat at regular intervals
39
+ */
40
+ export function createHeartbeatManager(db, runnerId) {
41
+ let intervalId = null;
42
+ const beat = () => {
43
+ updateHeartbeat(db, runnerId);
44
+ };
45
+ const start = () => {
46
+ // Update immediately
47
+ beat();
48
+ // Then update every 30 seconds
49
+ intervalId = setInterval(beat, HEARTBEAT_INTERVAL_MS);
50
+ };
51
+ const stop = () => {
52
+ if (intervalId) {
53
+ clearInterval(intervalId);
54
+ intervalId = null;
55
+ }
56
+ };
57
+ return { start, stop, beat };
58
+ }
59
+ /**
60
+ * Get heartbeat interval in milliseconds
61
+ */
62
+ export function getHeartbeatInterval() {
63
+ return HEARTBEAT_INTERVAL_MS;
64
+ }
65
+ /**
66
+ * Get stale timeout in milliseconds
67
+ */
68
+ export function getStaleTimeout() {
69
+ return STALE_TIMEOUT_MS;
70
+ }
71
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../../../src/runners/heartbeat.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AACtD,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAQpD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,EAAqB,EAAE,QAAgB;IACrE,EAAE,CAAC,OAAO,CACR,gEAAgE,CACjE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAqB,EACrB,QAAgB;IAEhB,4EAA4E;IAC5E,MAAM,MAAM,GAAG,EAAE;SACd,OAAO,CACN;sEACgE,CACjE;SACA,GAAG,CAAC,QAAQ,CAA8B,CAAC;IAE9C,wEAAwE;IACxE,OAAO,MAAM,KAAK,SAAS,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAqB;IAErB,sEAAsE;IACtE,kEAAkE;IAClE,6EAA6E;IAC7E,OAAO,EAAE;SACN,OAAO,CACN;+EACyE,CAC1E;SACA,GAAG,EAAqE,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,QAAgB;IAEhB,IAAI,UAAU,GAA0B,IAAI,CAAC;IAE7C,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,qBAAqB;QACrB,IAAI,EAAE,CAAC;QAEP,+BAA+B;QAC/B,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,UAAU,EAAE,CAAC;YACf,aAAa,CAAC,UAAU,CAAC,CAAC;YAC1B,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Singleton lock for runner daemon
3
+ * Uses directory-based locking with PID file
4
+ */
5
+ export interface LockResult {
6
+ acquired: boolean;
7
+ existingPid?: number;
8
+ isZombie?: boolean;
9
+ }
10
+ /**
11
+ * Get the lock directory path
12
+ */
13
+ export declare function getLockDir(): string;
14
+ /**
15
+ * Get the PID file path
16
+ */
17
+ export declare function getPidFilePath(): string;
18
+ /**
19
+ * Check if a process with given PID is running
20
+ */
21
+ export declare function isProcessAlive(pid: number): boolean;
22
+ /**
23
+ * Read the PID from lock file
24
+ */
25
+ export declare function readLockPid(): number | null;
26
+ /**
27
+ * Remove the lock directory
28
+ */
29
+ export declare function removeLock(): void;
30
+ /**
31
+ * Attempt to acquire the singleton lock
32
+ * Returns result indicating success or existing lock holder
33
+ */
34
+ export declare function acquireLock(): LockResult;
35
+ /**
36
+ * Release the lock (should be called on shutdown)
37
+ */
38
+ export declare function releaseLock(): void;
39
+ /**
40
+ * Check lock status without acquiring
41
+ */
42
+ export declare function checkLockStatus(): {
43
+ locked: boolean;
44
+ pid: number | null;
45
+ isZombie: boolean;
46
+ };
47
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../../src/runners/lock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAa3C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,UAAU,CAiDxC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAOlC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAkBA"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Singleton lock for runner daemon
3
+ * Uses directory-based locking with PID file
4
+ */
5
+ import { existsSync, mkdirSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { getGlobalSteroidsDir } from './global-db.js';
8
+ const LOCK_DIR = 'runners/lock';
9
+ const PID_FILE = 'pid';
10
+ /**
11
+ * Get the lock directory path
12
+ */
13
+ export function getLockDir() {
14
+ return join(getGlobalSteroidsDir(), LOCK_DIR);
15
+ }
16
+ /**
17
+ * Get the PID file path
18
+ */
19
+ export function getPidFilePath() {
20
+ return join(getLockDir(), PID_FILE);
21
+ }
22
+ /**
23
+ * Check if a process with given PID is running
24
+ */
25
+ export function isProcessAlive(pid) {
26
+ try {
27
+ // Sending signal 0 checks if process exists without killing it
28
+ process.kill(pid, 0);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Read the PID from lock file
37
+ */
38
+ export function readLockPid() {
39
+ const pidPath = getPidFilePath();
40
+ if (!existsSync(pidPath)) {
41
+ return null;
42
+ }
43
+ try {
44
+ const content = readFileSync(pidPath, 'utf-8').trim();
45
+ const pid = parseInt(content, 10);
46
+ return isNaN(pid) ? null : pid;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * Remove the lock directory
54
+ */
55
+ export function removeLock() {
56
+ const lockDir = getLockDir();
57
+ if (existsSync(lockDir)) {
58
+ rmSync(lockDir, { recursive: true, force: true });
59
+ }
60
+ }
61
+ /**
62
+ * Attempt to acquire the singleton lock
63
+ * Returns result indicating success or existing lock holder
64
+ */
65
+ export function acquireLock() {
66
+ const lockDir = getLockDir();
67
+ const pidPath = getPidFilePath();
68
+ // Check if lock exists
69
+ if (existsSync(lockDir)) {
70
+ const existingPid = readLockPid();
71
+ if (existingPid !== null) {
72
+ if (isProcessAlive(existingPid)) {
73
+ // Another runner is active
74
+ return {
75
+ acquired: false,
76
+ existingPid,
77
+ isZombie: false,
78
+ };
79
+ }
80
+ // Zombie lock - process is dead
81
+ removeLock();
82
+ // Fall through to acquire
83
+ }
84
+ else {
85
+ // Lock dir exists but no valid PID - clean up
86
+ removeLock();
87
+ }
88
+ }
89
+ // Create lock directory
90
+ try {
91
+ mkdirSync(lockDir, { recursive: true });
92
+ }
93
+ catch (err) {
94
+ // Race condition - another process may have created it
95
+ if (existsSync(lockDir)) {
96
+ const existingPid = readLockPid();
97
+ if (existingPid !== null && isProcessAlive(existingPid)) {
98
+ return {
99
+ acquired: false,
100
+ existingPid,
101
+ isZombie: false,
102
+ };
103
+ }
104
+ }
105
+ throw err;
106
+ }
107
+ // Write our PID
108
+ writeFileSync(pidPath, String(process.pid));
109
+ return { acquired: true };
110
+ }
111
+ /**
112
+ * Release the lock (should be called on shutdown)
113
+ */
114
+ export function releaseLock() {
115
+ const existingPid = readLockPid();
116
+ // Only release if we own the lock
117
+ if (existingPid === process.pid) {
118
+ removeLock();
119
+ }
120
+ }
121
+ /**
122
+ * Check lock status without acquiring
123
+ */
124
+ export function checkLockStatus() {
125
+ const lockDir = getLockDir();
126
+ if (!existsSync(lockDir)) {
127
+ return { locked: false, pid: null, isZombie: false };
128
+ }
129
+ const pid = readLockPid();
130
+ if (pid === null) {
131
+ return { locked: false, pid: null, isZombie: false };
132
+ }
133
+ const alive = isProcessAlive(pid);
134
+ return {
135
+ locked: alive,
136
+ pid,
137
+ isZombie: !alive,
138
+ };
139
+ }
140
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../../src/runners/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Orchestrator loop - core task processing logic
3
+ * Used by both the daemon and the loop command
4
+ */
5
+ export interface LoopOptions {
6
+ projectPath: string;
7
+ once?: boolean;
8
+ sectionId?: string;
9
+ runnerId?: string;
10
+ onIteration?: (iteration: number) => void;
11
+ onTaskStart?: (taskId: string, action: string) => void;
12
+ onTaskComplete?: (taskId: string) => void;
13
+ shouldStop?: () => boolean;
14
+ }
15
+ /**
16
+ * Run the orchestrator loop
17
+ * Processes tasks until all are complete or shouldStop returns true
18
+ */
19
+ export declare function runOrchestratorLoop(options: LoopOptions): Promise<void>;
20
+ //# sourceMappingURL=orchestrator-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-loop.d.ts","sourceRoot":"","sources":["../../../../src/runners/orchestrator-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwBH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmP7E"}