steroids-cli 0.4.47

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 (395) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +640 -0
  3. package/dist/cli/colors.d.ts +110 -0
  4. package/dist/cli/colors.d.ts.map +1 -0
  5. package/dist/cli/colors.js +228 -0
  6. package/dist/cli/colors.js.map +1 -0
  7. package/dist/cli/env.d.ts +159 -0
  8. package/dist/cli/env.d.ts.map +1 -0
  9. package/dist/cli/env.js +227 -0
  10. package/dist/cli/env.js.map +1 -0
  11. package/dist/cli/errors.d.ts +166 -0
  12. package/dist/cli/errors.d.ts.map +1 -0
  13. package/dist/cli/errors.js +244 -0
  14. package/dist/cli/errors.js.map +1 -0
  15. package/dist/cli/flags.d.ts +75 -0
  16. package/dist/cli/flags.d.ts.map +1 -0
  17. package/dist/cli/flags.js +232 -0
  18. package/dist/cli/flags.js.map +1 -0
  19. package/dist/cli/help.d.ts +97 -0
  20. package/dist/cli/help.d.ts.map +1 -0
  21. package/dist/cli/help.js +275 -0
  22. package/dist/cli/help.js.map +1 -0
  23. package/dist/cli/index.d.ts +13 -0
  24. package/dist/cli/index.d.ts.map +1 -0
  25. package/dist/cli/index.js +29 -0
  26. package/dist/cli/index.js.map +1 -0
  27. package/dist/cli/interactive.d.ts +58 -0
  28. package/dist/cli/interactive.d.ts.map +1 -0
  29. package/dist/cli/interactive.js +127 -0
  30. package/dist/cli/interactive.js.map +1 -0
  31. package/dist/cli/output.d.ts +116 -0
  32. package/dist/cli/output.d.ts.map +1 -0
  33. package/dist/cli/output.js +178 -0
  34. package/dist/cli/output.js.map +1 -0
  35. package/dist/commands/about.d.ts +7 -0
  36. package/dist/commands/about.d.ts.map +1 -0
  37. package/dist/commands/about.js +259 -0
  38. package/dist/commands/about.js.map +1 -0
  39. package/dist/commands/ai.d.ts +6 -0
  40. package/dist/commands/ai.d.ts.map +1 -0
  41. package/dist/commands/ai.js +382 -0
  42. package/dist/commands/ai.js.map +1 -0
  43. package/dist/commands/backup.d.ts +3 -0
  44. package/dist/commands/backup.d.ts.map +1 -0
  45. package/dist/commands/backup.js +528 -0
  46. package/dist/commands/backup.js.map +1 -0
  47. package/dist/commands/completion.d.ts +3 -0
  48. package/dist/commands/completion.d.ts.map +1 -0
  49. package/dist/commands/completion.js +405 -0
  50. package/dist/commands/completion.js.map +1 -0
  51. package/dist/commands/config.d.ts +3 -0
  52. package/dist/commands/config.d.ts.map +1 -0
  53. package/dist/commands/config.js +665 -0
  54. package/dist/commands/config.js.map +1 -0
  55. package/dist/commands/disputes.d.ts +3 -0
  56. package/dist/commands/disputes.d.ts.map +1 -0
  57. package/dist/commands/disputes.js +499 -0
  58. package/dist/commands/disputes.js.map +1 -0
  59. package/dist/commands/gc.d.ts +3 -0
  60. package/dist/commands/gc.d.ts.map +1 -0
  61. package/dist/commands/gc.js +300 -0
  62. package/dist/commands/gc.js.map +1 -0
  63. package/dist/commands/git.d.ts +3 -0
  64. package/dist/commands/git.d.ts.map +1 -0
  65. package/dist/commands/git.js +458 -0
  66. package/dist/commands/git.js.map +1 -0
  67. package/dist/commands/health.d.ts +3 -0
  68. package/dist/commands/health.d.ts.map +1 -0
  69. package/dist/commands/health.js +604 -0
  70. package/dist/commands/health.js.map +1 -0
  71. package/dist/commands/hooks.d.ts +6 -0
  72. package/dist/commands/hooks.d.ts.map +1 -0
  73. package/dist/commands/hooks.js +529 -0
  74. package/dist/commands/hooks.js.map +1 -0
  75. package/dist/commands/init.d.ts +6 -0
  76. package/dist/commands/init.d.ts.map +1 -0
  77. package/dist/commands/init.js +200 -0
  78. package/dist/commands/init.js.map +1 -0
  79. package/dist/commands/llm.d.ts +7 -0
  80. package/dist/commands/llm.d.ts.map +1 -0
  81. package/dist/commands/llm.js +285 -0
  82. package/dist/commands/llm.js.map +1 -0
  83. package/dist/commands/locks.d.ts +3 -0
  84. package/dist/commands/locks.d.ts.map +1 -0
  85. package/dist/commands/locks.js +431 -0
  86. package/dist/commands/locks.js.map +1 -0
  87. package/dist/commands/logs.d.ts +3 -0
  88. package/dist/commands/logs.d.ts.map +1 -0
  89. package/dist/commands/logs.js +487 -0
  90. package/dist/commands/logs.js.map +1 -0
  91. package/dist/commands/loop-phases.d.ts +11 -0
  92. package/dist/commands/loop-phases.d.ts.map +1 -0
  93. package/dist/commands/loop-phases.js +204 -0
  94. package/dist/commands/loop-phases.js.map +1 -0
  95. package/dist/commands/loop.d.ts +3 -0
  96. package/dist/commands/loop.d.ts.map +1 -0
  97. package/dist/commands/loop.js +396 -0
  98. package/dist/commands/loop.js.map +1 -0
  99. package/dist/commands/projects.d.ts +6 -0
  100. package/dist/commands/projects.d.ts.map +1 -0
  101. package/dist/commands/projects.js +362 -0
  102. package/dist/commands/projects.js.map +1 -0
  103. package/dist/commands/purge.d.ts +3 -0
  104. package/dist/commands/purge.d.ts.map +1 -0
  105. package/dist/commands/purge.js +516 -0
  106. package/dist/commands/purge.js.map +1 -0
  107. package/dist/commands/runners.d.ts +3 -0
  108. package/dist/commands/runners.d.ts.map +1 -0
  109. package/dist/commands/runners.js +1076 -0
  110. package/dist/commands/runners.js.map +1 -0
  111. package/dist/commands/scan.d.ts +3 -0
  112. package/dist/commands/scan.d.ts.map +1 -0
  113. package/dist/commands/scan.js +291 -0
  114. package/dist/commands/scan.js.map +1 -0
  115. package/dist/commands/sections-commands.d.ts +9 -0
  116. package/dist/commands/sections-commands.d.ts.map +1 -0
  117. package/dist/commands/sections-commands.js +282 -0
  118. package/dist/commands/sections-commands.js.map +1 -0
  119. package/dist/commands/sections-graph.d.ts +25 -0
  120. package/dist/commands/sections-graph.d.ts.map +1 -0
  121. package/dist/commands/sections-graph.js +180 -0
  122. package/dist/commands/sections-graph.js.map +1 -0
  123. package/dist/commands/sections.d.ts +3 -0
  124. package/dist/commands/sections.d.ts.map +1 -0
  125. package/dist/commands/sections.js +376 -0
  126. package/dist/commands/sections.js.map +1 -0
  127. package/dist/commands/stats.d.ts +6 -0
  128. package/dist/commands/stats.d.ts.map +1 -0
  129. package/dist/commands/stats.js +324 -0
  130. package/dist/commands/stats.js.map +1 -0
  131. package/dist/commands/tasks.d.ts +3 -0
  132. package/dist/commands/tasks.d.ts.map +1 -0
  133. package/dist/commands/tasks.js +1115 -0
  134. package/dist/commands/tasks.js.map +1 -0
  135. package/dist/commands/web.d.ts +7 -0
  136. package/dist/commands/web.d.ts.map +1 -0
  137. package/dist/commands/web.js +204 -0
  138. package/dist/commands/web.js.map +1 -0
  139. package/dist/config/ai-setup.d.ts +27 -0
  140. package/dist/config/ai-setup.d.ts.map +1 -0
  141. package/dist/config/ai-setup.js +432 -0
  142. package/dist/config/ai-setup.js.map +1 -0
  143. package/dist/config/browser.d.ts +9 -0
  144. package/dist/config/browser.d.ts.map +1 -0
  145. package/dist/config/browser.js +200 -0
  146. package/dist/config/browser.js.map +1 -0
  147. package/dist/config/json-schema.d.ts +28 -0
  148. package/dist/config/json-schema.d.ts.map +1 -0
  149. package/dist/config/json-schema.js +84 -0
  150. package/dist/config/json-schema.js.map +1 -0
  151. package/dist/config/loader.d.ts +152 -0
  152. package/dist/config/loader.d.ts.map +1 -0
  153. package/dist/config/loader.js +270 -0
  154. package/dist/config/loader.js.map +1 -0
  155. package/dist/config/schema.d.ts +34 -0
  156. package/dist/config/schema.d.ts.map +1 -0
  157. package/dist/config/schema.js +437 -0
  158. package/dist/config/schema.js.map +1 -0
  159. package/dist/config/validator.d.ts +32 -0
  160. package/dist/config/validator.d.ts.map +1 -0
  161. package/dist/config/validator.js +187 -0
  162. package/dist/config/validator.js.map +1 -0
  163. package/dist/database/connection.d.ts +35 -0
  164. package/dist/database/connection.d.ts.map +1 -0
  165. package/dist/database/connection.js +208 -0
  166. package/dist/database/connection.js.map +1 -0
  167. package/dist/database/queries.d.ts +218 -0
  168. package/dist/database/queries.d.ts.map +1 -0
  169. package/dist/database/queries.js +613 -0
  170. package/dist/database/queries.js.map +1 -0
  171. package/dist/database/schema.d.ts +8 -0
  172. package/dist/database/schema.d.ts.map +1 -0
  173. package/dist/database/schema.js +160 -0
  174. package/dist/database/schema.js.map +1 -0
  175. package/dist/disputes/behavior.d.ts +106 -0
  176. package/dist/disputes/behavior.d.ts.map +1 -0
  177. package/dist/disputes/behavior.js +150 -0
  178. package/dist/disputes/behavior.js.map +1 -0
  179. package/dist/disputes/create.d.ts +59 -0
  180. package/dist/disputes/create.d.ts.map +1 -0
  181. package/dist/disputes/create.js +222 -0
  182. package/dist/disputes/create.js.map +1 -0
  183. package/dist/disputes/index.d.ts +21 -0
  184. package/dist/disputes/index.d.ts.map +1 -0
  185. package/dist/disputes/index.js +76 -0
  186. package/dist/disputes/index.js.map +1 -0
  187. package/dist/disputes/markdown.d.ts +41 -0
  188. package/dist/disputes/markdown.d.ts.map +1 -0
  189. package/dist/disputes/markdown.js +261 -0
  190. package/dist/disputes/markdown.js.map +1 -0
  191. package/dist/disputes/queries.d.ts +83 -0
  192. package/dist/disputes/queries.d.ts.map +1 -0
  193. package/dist/disputes/queries.js +180 -0
  194. package/dist/disputes/queries.js.map +1 -0
  195. package/dist/disputes/resolve.d.ts +57 -0
  196. package/dist/disputes/resolve.d.ts.map +1 -0
  197. package/dist/disputes/resolve.js +171 -0
  198. package/dist/disputes/resolve.js.map +1 -0
  199. package/dist/disputes/stale.d.ts +98 -0
  200. package/dist/disputes/stale.d.ts.map +1 -0
  201. package/dist/disputes/stale.js +205 -0
  202. package/dist/disputes/stale.js.map +1 -0
  203. package/dist/disputes/types.d.ts +92 -0
  204. package/dist/disputes/types.d.ts.map +1 -0
  205. package/dist/disputes/types.js +100 -0
  206. package/dist/disputes/types.js.map +1 -0
  207. package/dist/git/push.d.ts +26 -0
  208. package/dist/git/push.d.ts.map +1 -0
  209. package/dist/git/push.js +97 -0
  210. package/dist/git/push.js.map +1 -0
  211. package/dist/git/status.d.ts +61 -0
  212. package/dist/git/status.d.ts.map +1 -0
  213. package/dist/git/status.js +251 -0
  214. package/dist/git/status.js.map +1 -0
  215. package/dist/hooks/events.d.ts +72 -0
  216. package/dist/hooks/events.d.ts.map +1 -0
  217. package/dist/hooks/events.js +120 -0
  218. package/dist/hooks/events.js.map +1 -0
  219. package/dist/hooks/index.d.ts +19 -0
  220. package/dist/hooks/index.d.ts.map +1 -0
  221. package/dist/hooks/index.js +48 -0
  222. package/dist/hooks/index.js.map +1 -0
  223. package/dist/hooks/integration.d.ts +69 -0
  224. package/dist/hooks/integration.d.ts.map +1 -0
  225. package/dist/hooks/integration.js +179 -0
  226. package/dist/hooks/integration.js.map +1 -0
  227. package/dist/hooks/merge.d.ts +115 -0
  228. package/dist/hooks/merge.d.ts.map +1 -0
  229. package/dist/hooks/merge.js +161 -0
  230. package/dist/hooks/merge.js.map +1 -0
  231. package/dist/hooks/orchestrator.d.ts +115 -0
  232. package/dist/hooks/orchestrator.d.ts.map +1 -0
  233. package/dist/hooks/orchestrator.js +226 -0
  234. package/dist/hooks/orchestrator.js.map +1 -0
  235. package/dist/hooks/payload.d.ts +294 -0
  236. package/dist/hooks/payload.d.ts.map +1 -0
  237. package/dist/hooks/payload.js +267 -0
  238. package/dist/hooks/payload.js.map +1 -0
  239. package/dist/hooks/script-runner.d.ts +63 -0
  240. package/dist/hooks/script-runner.d.ts.map +1 -0
  241. package/dist/hooks/script-runner.js +221 -0
  242. package/dist/hooks/script-runner.js.map +1 -0
  243. package/dist/hooks/templates.d.ts +104 -0
  244. package/dist/hooks/templates.d.ts.map +1 -0
  245. package/dist/hooks/templates.js +327 -0
  246. package/dist/hooks/templates.js.map +1 -0
  247. package/dist/hooks/webhook-runner.d.ts +69 -0
  248. package/dist/hooks/webhook-runner.d.ts.map +1 -0
  249. package/dist/hooks/webhook-runner.js +208 -0
  250. package/dist/hooks/webhook-runner.js.map +1 -0
  251. package/dist/index.d.ts +7 -0
  252. package/dist/index.d.ts.map +1 -0
  253. package/dist/index.js +281 -0
  254. package/dist/index.js.map +1 -0
  255. package/dist/locking/cleanup.d.ts +70 -0
  256. package/dist/locking/cleanup.d.ts.map +1 -0
  257. package/dist/locking/cleanup.js +157 -0
  258. package/dist/locking/cleanup.js.map +1 -0
  259. package/dist/locking/queries.d.ts +116 -0
  260. package/dist/locking/queries.d.ts.map +1 -0
  261. package/dist/locking/queries.js +255 -0
  262. package/dist/locking/queries.js.map +1 -0
  263. package/dist/locking/section-lock.d.ts +74 -0
  264. package/dist/locking/section-lock.d.ts.map +1 -0
  265. package/dist/locking/section-lock.js +207 -0
  266. package/dist/locking/section-lock.js.map +1 -0
  267. package/dist/locking/task-lock.d.ts +92 -0
  268. package/dist/locking/task-lock.d.ts.map +1 -0
  269. package/dist/locking/task-lock.js +246 -0
  270. package/dist/locking/task-lock.js.map +1 -0
  271. package/dist/migrations/index.d.ts +7 -0
  272. package/dist/migrations/index.d.ts.map +1 -0
  273. package/dist/migrations/index.js +37 -0
  274. package/dist/migrations/index.js.map +1 -0
  275. package/dist/migrations/manifest.d.ts +92 -0
  276. package/dist/migrations/manifest.d.ts.map +1 -0
  277. package/dist/migrations/manifest.js +270 -0
  278. package/dist/migrations/manifest.js.map +1 -0
  279. package/dist/migrations/runner.d.ts +84 -0
  280. package/dist/migrations/runner.d.ts.map +1 -0
  281. package/dist/migrations/runner.js +351 -0
  282. package/dist/migrations/runner.js.map +1 -0
  283. package/dist/orchestrator/coder.d.ts +32 -0
  284. package/dist/orchestrator/coder.d.ts.map +1 -0
  285. package/dist/orchestrator/coder.js +174 -0
  286. package/dist/orchestrator/coder.js.map +1 -0
  287. package/dist/orchestrator/coordinator.d.ts +28 -0
  288. package/dist/orchestrator/coordinator.d.ts.map +1 -0
  289. package/dist/orchestrator/coordinator.js +256 -0
  290. package/dist/orchestrator/coordinator.js.map +1 -0
  291. package/dist/orchestrator/reviewer.d.ts +35 -0
  292. package/dist/orchestrator/reviewer.d.ts.map +1 -0
  293. package/dist/orchestrator/reviewer.js +241 -0
  294. package/dist/orchestrator/reviewer.js.map +1 -0
  295. package/dist/orchestrator/task-selector.d.ts +102 -0
  296. package/dist/orchestrator/task-selector.d.ts.map +1 -0
  297. package/dist/orchestrator/task-selector.js +341 -0
  298. package/dist/orchestrator/task-selector.js.map +1 -0
  299. package/dist/prompts/coder.d.ts +36 -0
  300. package/dist/prompts/coder.d.ts.map +1 -0
  301. package/dist/prompts/coder.js +315 -0
  302. package/dist/prompts/coder.js.map +1 -0
  303. package/dist/prompts/prompt-helpers.d.ts +51 -0
  304. package/dist/prompts/prompt-helpers.d.ts.map +1 -0
  305. package/dist/prompts/prompt-helpers.js +312 -0
  306. package/dist/prompts/prompt-helpers.js.map +1 -0
  307. package/dist/prompts/reviewer.d.ts +40 -0
  308. package/dist/prompts/reviewer.d.ts.map +1 -0
  309. package/dist/prompts/reviewer.js +438 -0
  310. package/dist/prompts/reviewer.js.map +1 -0
  311. package/dist/providers/api-models.d.ts +65 -0
  312. package/dist/providers/api-models.d.ts.map +1 -0
  313. package/dist/providers/api-models.js +323 -0
  314. package/dist/providers/api-models.js.map +1 -0
  315. package/dist/providers/claude.d.ts +53 -0
  316. package/dist/providers/claude.d.ts.map +1 -0
  317. package/dist/providers/claude.js +229 -0
  318. package/dist/providers/claude.js.map +1 -0
  319. package/dist/providers/codex.d.ts +53 -0
  320. package/dist/providers/codex.d.ts.map +1 -0
  321. package/dist/providers/codex.js +214 -0
  322. package/dist/providers/codex.js.map +1 -0
  323. package/dist/providers/gemini.d.ts +58 -0
  324. package/dist/providers/gemini.d.ts.map +1 -0
  325. package/dist/providers/gemini.js +242 -0
  326. package/dist/providers/gemini.js.map +1 -0
  327. package/dist/providers/index.d.ts +13 -0
  328. package/dist/providers/index.d.ts.map +1 -0
  329. package/dist/providers/index.js +49 -0
  330. package/dist/providers/index.js.map +1 -0
  331. package/dist/providers/interface.d.ts +173 -0
  332. package/dist/providers/interface.d.ts.map +1 -0
  333. package/dist/providers/interface.js +96 -0
  334. package/dist/providers/interface.js.map +1 -0
  335. package/dist/providers/invocation-logger.d.ts +114 -0
  336. package/dist/providers/invocation-logger.d.ts.map +1 -0
  337. package/dist/providers/invocation-logger.js +298 -0
  338. package/dist/providers/invocation-logger.js.map +1 -0
  339. package/dist/providers/openai.d.ts +53 -0
  340. package/dist/providers/openai.d.ts.map +1 -0
  341. package/dist/providers/openai.js +232 -0
  342. package/dist/providers/openai.js.map +1 -0
  343. package/dist/providers/registry.d.ts +100 -0
  344. package/dist/providers/registry.d.ts.map +1 -0
  345. package/dist/providers/registry.js +178 -0
  346. package/dist/providers/registry.js.map +1 -0
  347. package/dist/runners/activity-log.d.ts +65 -0
  348. package/dist/runners/activity-log.d.ts.map +1 -0
  349. package/dist/runners/activity-log.js +148 -0
  350. package/dist/runners/activity-log.js.map +1 -0
  351. package/dist/runners/cron.d.ts +26 -0
  352. package/dist/runners/cron.d.ts.map +1 -0
  353. package/dist/runners/cron.js +176 -0
  354. package/dist/runners/cron.js.map +1 -0
  355. package/dist/runners/daemon.d.ts +71 -0
  356. package/dist/runners/daemon.d.ts.map +1 -0
  357. package/dist/runners/daemon.js +245 -0
  358. package/dist/runners/daemon.js.map +1 -0
  359. package/dist/runners/global-db.d.ts +31 -0
  360. package/dist/runners/global-db.d.ts.map +1 -0
  361. package/dist/runners/global-db.js +230 -0
  362. package/dist/runners/global-db.js.map +1 -0
  363. package/dist/runners/hang-detector.d.ts +38 -0
  364. package/dist/runners/hang-detector.d.ts.map +1 -0
  365. package/dist/runners/hang-detector.js +136 -0
  366. package/dist/runners/hang-detector.js.map +1 -0
  367. package/dist/runners/heartbeat.d.ts +39 -0
  368. package/dist/runners/heartbeat.d.ts.map +1 -0
  369. package/dist/runners/heartbeat.js +79 -0
  370. package/dist/runners/heartbeat.js.map +1 -0
  371. package/dist/runners/lock.d.ts +47 -0
  372. package/dist/runners/lock.d.ts.map +1 -0
  373. package/dist/runners/lock.js +150 -0
  374. package/dist/runners/lock.js.map +1 -0
  375. package/dist/runners/orchestrator-loop.d.ts +20 -0
  376. package/dist/runners/orchestrator-loop.d.ts.map +1 -0
  377. package/dist/runners/orchestrator-loop.js +285 -0
  378. package/dist/runners/orchestrator-loop.js.map +1 -0
  379. package/dist/runners/projects.d.ts +96 -0
  380. package/dist/runners/projects.d.ts.map +1 -0
  381. package/dist/runners/projects.js +255 -0
  382. package/dist/runners/projects.js.map +1 -0
  383. package/dist/runners/wakeup.d.ts +34 -0
  384. package/dist/runners/wakeup.d.ts.map +1 -0
  385. package/dist/runners/wakeup.js +291 -0
  386. package/dist/runners/wakeup.js.map +1 -0
  387. package/migrations/001_initial_schema.sql +106 -0
  388. package/migrations/002_add_commit_sha.sql +12 -0
  389. package/migrations/003_add_section_priority.sql +13 -0
  390. package/migrations/004_add_section_dependencies.sql +18 -0
  391. package/migrations/005_add_audit_actor_model.sql +10 -0
  392. package/migrations/006_add_task_invocations.sql +33 -0
  393. package/migrations/007_add_file_anchor.sql +14 -0
  394. package/migrations/manifest.json +62 -0
  395. package/package.json +49 -0
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ /**
3
+ * Global project registry management
4
+ * Tracks all registered steroids projects across the system
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.registerProject = registerProject;
8
+ exports.getRegisteredProjects = getRegisteredProjects;
9
+ exports.getRegisteredProject = getRegisteredProject;
10
+ exports.unregisterProject = unregisterProject;
11
+ exports.disableProject = disableProject;
12
+ exports.enableProject = enableProject;
13
+ exports.pruneProjects = pruneProjects;
14
+ exports.updateProjectLastSeen = updateProjectLastSeen;
15
+ exports.isProjectRegistered = isProjectRegistered;
16
+ exports.updateProjectStats = updateProjectStats;
17
+ const node_fs_1 = require("node:fs");
18
+ const node_path_1 = require("node:path");
19
+ const global_db_js_1 = require("./global-db.js");
20
+ /**
21
+ * Normalize a project path to its canonical form
22
+ * - Resolves symlinks
23
+ * - Removes trailing slashes
24
+ * - Returns absolute path
25
+ */
26
+ function normalizePath(p) {
27
+ try {
28
+ const resolved = (0, node_path_1.resolve)(p);
29
+ const realPath = (0, node_fs_1.realpathSync)(resolved);
30
+ return realPath.replace(/\/+$/, '');
31
+ }
32
+ catch (error) {
33
+ // If path doesn't exist or can't be resolved, just clean up the input
34
+ return (0, node_path_1.resolve)(p).replace(/\/+$/, '');
35
+ }
36
+ }
37
+ /**
38
+ * Register a project in the global registry
39
+ * Idempotent - updates last_seen_at if project already exists
40
+ *
41
+ * @param path - Absolute path to project directory
42
+ * @param name - Optional project name
43
+ */
44
+ function registerProject(path, name) {
45
+ const normalizedPath = normalizePath(path);
46
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
47
+ try {
48
+ db.prepare(`
49
+ INSERT INTO projects (path, name, registered_at, last_seen_at, enabled)
50
+ VALUES (?, ?, datetime('now'), datetime('now'), 1)
51
+ ON CONFLICT(path) DO UPDATE SET
52
+ name = COALESCE(excluded.name, name),
53
+ last_seen_at = datetime('now')
54
+ `).run(normalizedPath, name ?? null);
55
+ }
56
+ finally {
57
+ close();
58
+ }
59
+ }
60
+ /**
61
+ * Get all registered projects (enabled only by default)
62
+ *
63
+ * @param includeDisabled - If true, includes disabled projects
64
+ * @returns Array of registered projects
65
+ */
66
+ function getRegisteredProjects(includeDisabled = false) {
67
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
68
+ try {
69
+ const query = includeDisabled
70
+ ? 'SELECT * FROM projects'
71
+ : 'SELECT * FROM projects WHERE enabled = 1';
72
+ const rows = db.prepare(query).all();
73
+ return rows.map((row) => ({
74
+ path: row.path,
75
+ name: row.name,
76
+ registered_at: row.registered_at,
77
+ last_seen_at: row.last_seen_at,
78
+ enabled: row.enabled === 1,
79
+ pending_count: row.pending_count,
80
+ in_progress_count: row.in_progress_count,
81
+ review_count: row.review_count,
82
+ completed_count: row.completed_count,
83
+ stats_updated_at: row.stats_updated_at,
84
+ }));
85
+ }
86
+ finally {
87
+ close();
88
+ }
89
+ }
90
+ /**
91
+ * Get a single registered project by path
92
+ *
93
+ * @param path - Project path to look up
94
+ * @returns Project if found, null otherwise
95
+ */
96
+ function getRegisteredProject(path) {
97
+ const normalizedPath = normalizePath(path);
98
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
99
+ try {
100
+ const row = db
101
+ .prepare('SELECT * FROM projects WHERE path = ?')
102
+ .get(normalizedPath);
103
+ if (!row) {
104
+ return null;
105
+ }
106
+ return {
107
+ path: row.path,
108
+ name: row.name,
109
+ registered_at: row.registered_at,
110
+ last_seen_at: row.last_seen_at,
111
+ enabled: row.enabled === 1,
112
+ pending_count: row.pending_count,
113
+ in_progress_count: row.in_progress_count,
114
+ review_count: row.review_count,
115
+ completed_count: row.completed_count,
116
+ stats_updated_at: row.stats_updated_at,
117
+ };
118
+ }
119
+ finally {
120
+ close();
121
+ }
122
+ }
123
+ /**
124
+ * Unregister a project from the global registry
125
+ * Removes it completely from the database
126
+ *
127
+ * @param path - Project path to unregister
128
+ */
129
+ function unregisterProject(path) {
130
+ const normalizedPath = normalizePath(path);
131
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
132
+ try {
133
+ db.prepare('DELETE FROM projects WHERE path = ?').run(normalizedPath);
134
+ }
135
+ finally {
136
+ close();
137
+ }
138
+ }
139
+ /**
140
+ * Disable a project (skip in wakeup, but keep in registry)
141
+ *
142
+ * @param path - Project path to disable
143
+ */
144
+ function disableProject(path) {
145
+ const normalizedPath = normalizePath(path);
146
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
147
+ try {
148
+ db.prepare('UPDATE projects SET enabled = 0 WHERE path = ?').run(normalizedPath);
149
+ }
150
+ finally {
151
+ close();
152
+ }
153
+ }
154
+ /**
155
+ * Enable a project (include in wakeup)
156
+ *
157
+ * @param path - Project path to enable
158
+ */
159
+ function enableProject(path) {
160
+ const normalizedPath = normalizePath(path);
161
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
162
+ try {
163
+ db.prepare('UPDATE projects SET enabled = 1 WHERE path = ?').run(normalizedPath);
164
+ }
165
+ finally {
166
+ close();
167
+ }
168
+ }
169
+ /**
170
+ * Remove projects that no longer exist on disk
171
+ * Returns the number of projects removed
172
+ *
173
+ * @returns Number of projects pruned
174
+ */
175
+ function pruneProjects() {
176
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
177
+ try {
178
+ const projects = db.prepare('SELECT path FROM projects').all();
179
+ let removed = 0;
180
+ for (const project of projects) {
181
+ const steroidsDir = (0, node_path_1.join)(project.path, '.steroids');
182
+ const steroidsDb = (0, node_path_1.join)(steroidsDir, 'steroids.db');
183
+ // Remove if project directory or .steroids directory doesn't exist
184
+ if (!(0, node_fs_1.existsSync)(project.path) || !(0, node_fs_1.existsSync)(steroidsDir) || !(0, node_fs_1.existsSync)(steroidsDb)) {
185
+ db.prepare('DELETE FROM projects WHERE path = ?').run(project.path);
186
+ removed++;
187
+ }
188
+ }
189
+ return removed;
190
+ }
191
+ finally {
192
+ close();
193
+ }
194
+ }
195
+ /**
196
+ * Update last_seen_at timestamp for a project
197
+ * Used by runners to track when project was last active
198
+ *
199
+ * @param path - Project path to update
200
+ */
201
+ function updateProjectLastSeen(path) {
202
+ const normalizedPath = normalizePath(path);
203
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
204
+ try {
205
+ db.prepare("UPDATE projects SET last_seen_at = datetime('now') WHERE path = ?").run(normalizedPath);
206
+ }
207
+ finally {
208
+ close();
209
+ }
210
+ }
211
+ /**
212
+ * Check if a project is registered
213
+ *
214
+ * @param path - Project path to check
215
+ * @returns True if project is registered
216
+ */
217
+ function isProjectRegistered(path) {
218
+ const normalizedPath = normalizePath(path);
219
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
220
+ try {
221
+ const row = db
222
+ .prepare('SELECT 1 FROM projects WHERE path = ?')
223
+ .get(normalizedPath);
224
+ return row !== undefined;
225
+ }
226
+ finally {
227
+ close();
228
+ }
229
+ }
230
+ /**
231
+ * Update project stats in global database
232
+ * Called by runner heartbeat to cache stats for API/WebUI access
233
+ *
234
+ * @param path - Project path
235
+ * @param stats - Task counts by status
236
+ */
237
+ function updateProjectStats(path, stats) {
238
+ const normalizedPath = normalizePath(path);
239
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
240
+ try {
241
+ db.prepare(`
242
+ UPDATE projects SET
243
+ pending_count = ?,
244
+ in_progress_count = ?,
245
+ review_count = ?,
246
+ completed_count = ?,
247
+ stats_updated_at = datetime('now')
248
+ WHERE path = ?
249
+ `).run(stats.pending, stats.in_progress, stats.review, stats.completed, normalizedPath);
250
+ }
251
+ finally {
252
+ close();
253
+ }
254
+ }
255
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/runners/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Cron wake-up command for restarting stale/dead runners
3
+ */
4
+ export interface WakeupOptions {
5
+ quiet?: boolean;
6
+ dryRun?: boolean;
7
+ }
8
+ export interface WakeupResult {
9
+ action: 'none' | 'started' | 'restarted' | 'cleaned' | 'would_start';
10
+ reason: string;
11
+ runnerId?: string;
12
+ pid?: number;
13
+ staleRunners?: number;
14
+ pendingTasks?: number;
15
+ projectPath?: string;
16
+ }
17
+ /**
18
+ * Check if there's an active runner for a specific project
19
+ * Exported for use in daemon startup checks
20
+ */
21
+ export declare function hasActiveRunnerForProject(projectPath: string): boolean;
22
+ /**
23
+ * Get the last wakeup invocation time
24
+ */
25
+ export declare function getLastWakeupTime(): string | null;
26
+ export declare function wakeup(options?: WakeupOptions): Promise<WakeupResult[]>;
27
+ /**
28
+ * Check if wake-up is needed without taking action
29
+ */
30
+ export declare function checkWakeupNeeded(): Promise<{
31
+ needed: boolean;
32
+ reason: string;
33
+ }>;
34
+ //# sourceMappingURL=wakeup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA8BD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAgBtE;AA2DD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAUjD;AAED,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAuIjF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAyCD"}
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ /**
3
+ * Cron wake-up command for restarting stale/dead runners
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.hasActiveRunnerForProject = hasActiveRunnerForProject;
7
+ exports.getLastWakeupTime = getLastWakeupTime;
8
+ exports.wakeup = wakeup;
9
+ exports.checkWakeupNeeded = checkWakeupNeeded;
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = require("node:path");
12
+ const node_child_process_1 = require("node:child_process");
13
+ const lock_js_1 = require("./lock.js");
14
+ const global_db_js_1 = require("./global-db.js");
15
+ const heartbeat_js_1 = require("./heartbeat.js");
16
+ const projects_js_1 = require("./projects.js");
17
+ /**
18
+ * Check if a project has pending work
19
+ */
20
+ async function projectHasPendingWork(projectPath) {
21
+ const dbPath = (0, node_path_1.join)(projectPath, '.steroids', 'steroids.db');
22
+ if (!(0, node_fs_1.existsSync)(dbPath)) {
23
+ return false;
24
+ }
25
+ try {
26
+ // Use dynamic import for ESM compatibility
27
+ const { default: Database } = await import('better-sqlite3');
28
+ const db = new Database(dbPath, { readonly: true });
29
+ const result = db
30
+ .prepare(`SELECT COUNT(*) as count FROM tasks
31
+ WHERE status IN ('pending', 'in_progress', 'review')`)
32
+ .get();
33
+ db.close();
34
+ return result.count > 0;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ /**
41
+ * Check if there's an active runner for a specific project
42
+ * Exported for use in daemon startup checks
43
+ */
44
+ function hasActiveRunnerForProject(projectPath) {
45
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
46
+ try {
47
+ const row = db
48
+ .prepare(`SELECT 1 FROM runners
49
+ WHERE project_path = ?
50
+ AND status != 'stopped'
51
+ AND heartbeat_at > datetime('now', '-5 minutes')`)
52
+ .get(projectPath);
53
+ return row !== undefined;
54
+ }
55
+ finally {
56
+ close();
57
+ }
58
+ }
59
+ /**
60
+ * Kill a process by PID
61
+ */
62
+ function killProcess(pid) {
63
+ try {
64
+ process.kill(pid, 'SIGTERM');
65
+ return true;
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ /**
72
+ * Start a new runner daemon
73
+ * Uses 'steroids runners start --detach' so the runner registers in the global DB
74
+ * and updates heartbeat, allowing hasActiveRunnerForProject() to detect it
75
+ */
76
+ function startRunner(projectPath) {
77
+ try {
78
+ // Use runners start --detach so the daemon registers itself in the global DB
79
+ // This is critical: hasActiveRunnerForProject() checks the runners table,
80
+ // and only the daemon (not loop directly) writes to that table
81
+ const args = ['runners', 'start', '--detach', '--project', projectPath];
82
+ const child = (0, node_child_process_1.spawn)('steroids', args, {
83
+ detached: true,
84
+ stdio: 'ignore',
85
+ });
86
+ child.unref();
87
+ return { pid: child.pid ?? 0 };
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ }
93
+ /**
94
+ * Main wake-up function
95
+ * Called by cron every minute to ensure runners are healthy
96
+ * Iterates over ALL registered projects and starts runners as needed
97
+ * Returns per-project results
98
+ */
99
+ /**
100
+ * Record the last wakeup invocation time
101
+ */
102
+ function recordWakeupTime() {
103
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
104
+ try {
105
+ db.prepare(`INSERT INTO _global_schema (key, value) VALUES ('last_wakeup_at', datetime('now'))
106
+ ON CONFLICT(key) DO UPDATE SET value = datetime('now')`).run();
107
+ }
108
+ finally {
109
+ close();
110
+ }
111
+ }
112
+ /**
113
+ * Get the last wakeup invocation time
114
+ */
115
+ function getLastWakeupTime() {
116
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
117
+ try {
118
+ const row = db
119
+ .prepare("SELECT value FROM _global_schema WHERE key = 'last_wakeup_at'")
120
+ .get();
121
+ return row?.value ?? null;
122
+ }
123
+ finally {
124
+ close();
125
+ }
126
+ }
127
+ async function wakeup(options = {}) {
128
+ const { quiet = false, dryRun = false } = options;
129
+ const results = [];
130
+ const log = (msg) => {
131
+ if (!quiet)
132
+ console.log(msg);
133
+ };
134
+ // Record wakeup invocation time (even for dry runs)
135
+ if (!dryRun) {
136
+ recordWakeupTime();
137
+ }
138
+ // Step 1: Clean up stale runners first
139
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
140
+ try {
141
+ const staleRunners = (0, heartbeat_js_1.findStaleRunners)(db);
142
+ if (staleRunners.length > 0) {
143
+ log(`Found ${staleRunners.length} stale runner(s), cleaning up...`);
144
+ if (!dryRun) {
145
+ for (const runner of staleRunners) {
146
+ if (runner.pid) {
147
+ killProcess(runner.pid);
148
+ }
149
+ db.prepare('DELETE FROM runners WHERE id = ?').run(runner.id);
150
+ }
151
+ }
152
+ results.push({
153
+ action: 'cleaned',
154
+ reason: `Cleaned ${staleRunners.length} stale runner(s)`,
155
+ staleRunners: staleRunners.length,
156
+ });
157
+ }
158
+ }
159
+ finally {
160
+ close();
161
+ }
162
+ // Step 2: Clean zombie lock if present
163
+ const lockStatus = (0, lock_js_1.checkLockStatus)();
164
+ if (lockStatus.isZombie && lockStatus.pid) {
165
+ log(`Found zombie lock (PID: ${lockStatus.pid}), cleaning...`);
166
+ if (!dryRun) {
167
+ (0, lock_js_1.removeLock)();
168
+ }
169
+ }
170
+ // Step 3: Get all registered projects from global registry
171
+ const registeredProjects = (0, projects_js_1.getRegisteredProjects)(false); // enabled only
172
+ if (registeredProjects.length === 0) {
173
+ log('No registered projects found');
174
+ log('Run "steroids projects add <path>" to register a project');
175
+ results.push({
176
+ action: 'none',
177
+ reason: 'No registered projects',
178
+ pendingTasks: 0,
179
+ });
180
+ return results;
181
+ }
182
+ log(`Checking ${registeredProjects.length} registered project(s)...`);
183
+ // Step 4: Check each project and start runners as needed
184
+ for (const project of registeredProjects) {
185
+ // Skip if project directory doesn't exist
186
+ if (!(0, node_fs_1.existsSync)(project.path)) {
187
+ log(`Skipping ${project.path}: directory not found`);
188
+ results.push({
189
+ action: 'none',
190
+ reason: 'Directory not found',
191
+ projectPath: project.path,
192
+ });
193
+ continue;
194
+ }
195
+ // Skip if project already has an active runner
196
+ if (hasActiveRunnerForProject(project.path)) {
197
+ log(`Skipping ${project.path}: runner already active`);
198
+ results.push({
199
+ action: 'none',
200
+ reason: 'Runner already active',
201
+ projectPath: project.path,
202
+ });
203
+ continue;
204
+ }
205
+ // Check for pending work
206
+ if (!(await projectHasPendingWork(project.path))) {
207
+ log(`Skipping ${project.path}: no pending tasks`);
208
+ results.push({
209
+ action: 'none',
210
+ reason: 'No pending tasks',
211
+ projectPath: project.path,
212
+ });
213
+ continue;
214
+ }
215
+ // Start runner for this project
216
+ log(`Starting runner for: ${project.path}`);
217
+ if (dryRun) {
218
+ results.push({
219
+ action: 'would_start',
220
+ reason: `Would start runner (dry-run)`,
221
+ projectPath: project.path,
222
+ });
223
+ continue;
224
+ }
225
+ const startResult = startRunner(project.path);
226
+ if (startResult) {
227
+ results.push({
228
+ action: 'started',
229
+ reason: `Started runner`,
230
+ pid: startResult.pid,
231
+ projectPath: project.path,
232
+ });
233
+ }
234
+ else {
235
+ results.push({
236
+ action: 'none',
237
+ reason: 'Failed to start runner',
238
+ projectPath: project.path,
239
+ });
240
+ }
241
+ }
242
+ // If no specific results, add a summary
243
+ if (results.length === 0) {
244
+ results.push({
245
+ action: 'none',
246
+ reason: 'No action needed',
247
+ });
248
+ }
249
+ return results;
250
+ }
251
+ /**
252
+ * Check if wake-up is needed without taking action
253
+ */
254
+ async function checkWakeupNeeded() {
255
+ const lockStatus = (0, lock_js_1.checkLockStatus)();
256
+ if (lockStatus.locked && lockStatus.pid) {
257
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
258
+ try {
259
+ const staleRunners = (0, heartbeat_js_1.findStaleRunners)(db);
260
+ if (staleRunners.length > 0) {
261
+ return {
262
+ needed: true,
263
+ reason: `${staleRunners.length} stale runner(s) need cleanup`,
264
+ };
265
+ }
266
+ return { needed: false, reason: 'Runner is healthy' };
267
+ }
268
+ finally {
269
+ close();
270
+ }
271
+ }
272
+ if (lockStatus.isZombie) {
273
+ return { needed: true, reason: 'Zombie lock needs cleanup' };
274
+ }
275
+ // Check registered projects
276
+ const registeredProjects = (0, projects_js_1.getRegisteredProjects)(false);
277
+ let projectsWithWork = 0;
278
+ for (const project of registeredProjects) {
279
+ if ((0, node_fs_1.existsSync)(project.path) && (await projectHasPendingWork(project.path))) {
280
+ projectsWithWork++;
281
+ }
282
+ }
283
+ if (projectsWithWork > 0) {
284
+ return {
285
+ needed: true,
286
+ reason: `${projectsWithWork} project(s) have pending tasks`,
287
+ };
288
+ }
289
+ return { needed: false, reason: 'No pending tasks' };
290
+ }
291
+ //# sourceMappingURL=wakeup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup.js","sourceRoot":"","sources":["../../src/runners/wakeup.ts"],"names":[],"mappings":"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"}