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,315 @@
1
+ /**
2
+ * Git status and diff utilities
3
+ */
4
+ import { execSync, execFileSync } from 'node:child_process';
5
+ /**
6
+ * Get the current HEAD commit SHA
7
+ */
8
+ export function getCurrentCommitSha(projectPath = process.cwd()) {
9
+ try {
10
+ return execSync('git rev-parse HEAD', {
11
+ cwd: projectPath,
12
+ encoding: 'utf-8',
13
+ stdio: ['pipe', 'pipe', 'pipe'],
14
+ }).trim();
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ /**
21
+ * Get short (7 char) commit SHA
22
+ */
23
+ export function getShortCommitSha(projectPath = process.cwd()) {
24
+ try {
25
+ return execSync('git rev-parse --short HEAD', {
26
+ cwd: projectPath,
27
+ encoding: 'utf-8',
28
+ stdio: ['pipe', 'pipe', 'pipe'],
29
+ }).trim();
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Get git status output
37
+ */
38
+ export function getGitStatus(projectPath = process.cwd()) {
39
+ try {
40
+ return execSync('git status --porcelain', {
41
+ cwd: projectPath,
42
+ encoding: 'utf-8',
43
+ stdio: ['pipe', 'pipe', 'pipe'],
44
+ });
45
+ }
46
+ catch {
47
+ return '';
48
+ }
49
+ }
50
+ /**
51
+ * Get git diff output
52
+ */
53
+ export function getGitDiff(projectPath = process.cwd(), ref) {
54
+ try {
55
+ const cmd = ref ? `git diff ${ref}` : 'git diff';
56
+ return execSync(cmd, {
57
+ cwd: projectPath,
58
+ encoding: 'utf-8',
59
+ stdio: ['pipe', 'pipe', 'pipe'],
60
+ maxBuffer: 10 * 1024 * 1024, // 10MB
61
+ });
62
+ }
63
+ catch {
64
+ return '';
65
+ }
66
+ }
67
+ /**
68
+ * Get list of modified files
69
+ */
70
+ export function getModifiedFiles(projectPath = process.cwd(), ref) {
71
+ try {
72
+ const cmd = ref ? `git diff --name-only ${ref}` : 'git diff --name-only HEAD~1';
73
+ const output = execSync(cmd, {
74
+ cwd: projectPath,
75
+ encoding: 'utf-8',
76
+ stdio: ['pipe', 'pipe', 'pipe'],
77
+ });
78
+ return output.trim().split('\n').filter(Boolean);
79
+ }
80
+ catch {
81
+ return [];
82
+ }
83
+ }
84
+ /**
85
+ * Check if there are uncommitted changes
86
+ */
87
+ export function hasUncommittedChanges(projectPath = process.cwd()) {
88
+ const status = getGitStatus(projectPath);
89
+ return status.trim().length > 0;
90
+ }
91
+ /**
92
+ * Check if we're in a git repository
93
+ */
94
+ export function isGitRepo(projectPath = process.cwd()) {
95
+ try {
96
+ execSync('git rev-parse --git-dir', {
97
+ cwd: projectPath,
98
+ encoding: 'utf-8',
99
+ stdio: ['pipe', 'pipe', 'pipe'],
100
+ });
101
+ return true;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
107
+ /**
108
+ * Find the commit hash for a task by searching commit messages
109
+ * Returns the most recent commit that mentions the task title
110
+ */
111
+ export function findTaskCommit(projectPath, taskTitle) {
112
+ try {
113
+ // Search last 20 commits for one mentioning the task
114
+ const log = execSync('git log --oneline -20', {
115
+ cwd: projectPath,
116
+ encoding: 'utf-8',
117
+ stdio: ['pipe', 'pipe', 'pipe'],
118
+ });
119
+ // Look for commit message containing key words from task title
120
+ const titleWords = taskTitle.toLowerCase().split(/\s+/).filter(w => w.length > 3);
121
+ const lines = log.trim().split('\n');
122
+ for (const line of lines) {
123
+ const [hash, ...messageParts] = line.split(' ');
124
+ const message = messageParts.join(' ').toLowerCase();
125
+ // Check if at least 2 significant words match
126
+ let matches = 0;
127
+ for (const word of titleWords) {
128
+ if (message.includes(word))
129
+ matches++;
130
+ }
131
+ if (matches >= 2 || (titleWords.length <= 2 && matches >= 1)) {
132
+ return hash;
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+ catch {
138
+ return null;
139
+ }
140
+ }
141
+ /**
142
+ * Get the diff of a specific commit
143
+ */
144
+ export function getCommitDiff(projectPath, commitHash) {
145
+ try {
146
+ return execSync(`git show ${commitHash} --stat --patch`, {
147
+ cwd: projectPath,
148
+ encoding: 'utf-8',
149
+ stdio: ['pipe', 'pipe', 'pipe'],
150
+ maxBuffer: 10 * 1024 * 1024,
151
+ });
152
+ }
153
+ catch {
154
+ return '';
155
+ }
156
+ }
157
+ /**
158
+ * Get files changed in a specific commit
159
+ */
160
+ export function getCommitFiles(projectPath, commitHash) {
161
+ try {
162
+ const output = execSync(`git show --name-only --pretty=format: ${commitHash}`, {
163
+ cwd: projectPath,
164
+ encoding: 'utf-8',
165
+ stdio: ['pipe', 'pipe', 'pipe'],
166
+ });
167
+ return output.trim().split('\n').filter(Boolean);
168
+ }
169
+ catch {
170
+ return [];
171
+ }
172
+ }
173
+ /**
174
+ * Check if a specific file is tracked by git
175
+ */
176
+ export function isFileTracked(filePath, projectPath = process.cwd()) {
177
+ try {
178
+ execFileSync('git', ['ls-files', '--error-unmatch', filePath], {
179
+ cwd: projectPath,
180
+ encoding: 'utf-8',
181
+ stdio: ['pipe', 'pipe', 'pipe'],
182
+ });
183
+ return true;
184
+ }
185
+ catch {
186
+ return false;
187
+ }
188
+ }
189
+ /**
190
+ * Check if a specific file has uncommitted changes (staged or unstaged)
191
+ */
192
+ export function isFileDirty(filePath, projectPath = process.cwd()) {
193
+ try {
194
+ const status = execFileSync('git', ['status', '--porcelain', '--', filePath], {
195
+ cwd: projectPath,
196
+ encoding: 'utf-8',
197
+ stdio: ['pipe', 'pipe', 'pipe'],
198
+ }).trim();
199
+ return status.length > 0;
200
+ }
201
+ catch {
202
+ return true;
203
+ }
204
+ }
205
+ /**
206
+ * Get the SHA of the most recent commit that modified a file
207
+ */
208
+ export function getFileLastCommit(filePath, projectPath = process.cwd()) {
209
+ try {
210
+ return execFileSync('git', ['log', '-1', '--format=%H', '--', filePath], {
211
+ cwd: projectPath,
212
+ encoding: 'utf-8',
213
+ stdio: ['pipe', 'pipe', 'pipe'],
214
+ }).trim() || null;
215
+ }
216
+ catch {
217
+ return null;
218
+ }
219
+ }
220
+ /**
221
+ * Get the git blob hash of a file at HEAD (content-addressable hash)
222
+ */
223
+ export function getFileContentHash(filePath, projectPath = process.cwd()) {
224
+ try {
225
+ return execFileSync('git', ['rev-parse', `HEAD:${filePath}`], {
226
+ cwd: projectPath,
227
+ encoding: 'utf-8',
228
+ stdio: ['pipe', 'pipe', 'pipe'],
229
+ }).trim() || null;
230
+ }
231
+ catch {
232
+ return null;
233
+ }
234
+ }
235
+ /**
236
+ * Get recent commits with SHA and message
237
+ */
238
+ export function getRecentCommits(projectPath = process.cwd(), count = 5) {
239
+ try {
240
+ const log = execSync(`git log -${count} --format=%H||%s`, {
241
+ cwd: projectPath,
242
+ encoding: 'utf-8',
243
+ stdio: ['pipe', 'pipe', 'pipe'],
244
+ });
245
+ return log.trim().split('\n').filter(Boolean).map(line => {
246
+ const [sha, ...messageParts] = line.split('||');
247
+ return { sha, message: messageParts.join('||') };
248
+ });
249
+ }
250
+ catch {
251
+ return [];
252
+ }
253
+ }
254
+ /**
255
+ * Get changed files since last commit
256
+ */
257
+ export function getChangedFiles(projectPath = process.cwd()) {
258
+ try {
259
+ // Get both staged and unstaged files
260
+ const output = execSync('git diff --name-only HEAD', {
261
+ cwd: projectPath,
262
+ encoding: 'utf-8',
263
+ stdio: ['pipe', 'pipe', 'pipe'],
264
+ });
265
+ return output.trim().split('\n').filter(Boolean);
266
+ }
267
+ catch {
268
+ return [];
269
+ }
270
+ }
271
+ /**
272
+ * Get diff summary (additions/deletions)
273
+ */
274
+ export function getDiffSummary(projectPath = process.cwd()) {
275
+ try {
276
+ const output = execSync('git diff --stat HEAD', {
277
+ cwd: projectPath,
278
+ encoding: 'utf-8',
279
+ stdio: ['pipe', 'pipe', 'pipe'],
280
+ });
281
+ return output.trim();
282
+ }
283
+ catch {
284
+ return '';
285
+ }
286
+ }
287
+ /**
288
+ * Get diff additions and deletions count
289
+ */
290
+ export function getDiffStats(projectPath = process.cwd(), ref) {
291
+ try {
292
+ const cmd = ref
293
+ ? `git diff --numstat ${ref}`
294
+ : 'git diff --numstat HEAD~1';
295
+ const output = execSync(cmd, {
296
+ cwd: projectPath,
297
+ encoding: 'utf-8',
298
+ stdio: ['pipe', 'pipe', 'pipe'],
299
+ });
300
+ let additions = 0;
301
+ let deletions = 0;
302
+ for (const line of output.trim().split('\n')) {
303
+ if (!line)
304
+ continue;
305
+ const [add, del] = line.split(/\s+/);
306
+ additions += parseInt(add) || 0;
307
+ deletions += parseInt(del) || 0;
308
+ }
309
+ return { additions, deletions };
310
+ }
311
+ catch {
312
+ return { additions: 0, deletions: 0 };
313
+ }
314
+ }
315
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/git/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Core stuck-task detection logic (detection only, no recovery).
3
+ *
4
+ * This implementation intentionally uses the project's current schemas:
5
+ * - Project DB: tasks, audit, task_invocations
6
+ * - Global DB: runners
7
+ *
8
+ * The design doc (docs/stuck-task-detection.md) describes additional fields/tables
9
+ * (incidents, invocation started/completed timestamps, last_tool_execution, etc.).
10
+ * Those are not present in the current repo schema, so we derive signals from
11
+ * existing timestamps (tasks.updated_at, task_invocations.created_at, runners.heartbeat_at).
12
+ */
13
+ import type Database from 'better-sqlite3';
14
+ export type FailureMode = 'orphaned_task' | 'hanging_invocation' | 'zombie_runner' | 'dead_runner' | 'db_inconsistency';
15
+ export interface StuckTaskDetectionConfig {
16
+ /**
17
+ * How long a task may remain `in_progress` without a recent invocation and without
18
+ * an active runner assigned before being considered orphaned.
19
+ */
20
+ orphanedTaskTimeoutSec?: number;
21
+ /**
22
+ * Maximum allowed time a task may remain `in_progress` while an active runner is
23
+ * actively working on it (approximates "hanging coder invocation" without
24
+ * started/completed timestamps).
25
+ */
26
+ maxCoderDurationSec?: number;
27
+ /**
28
+ * Maximum allowed time a task may remain `review` while an active runner is
29
+ * actively working on it (approximates "hanging reviewer invocation").
30
+ */
31
+ maxReviewerDurationSec?: number;
32
+ /** Runner heartbeat staleness threshold. */
33
+ runnerHeartbeatTimeoutSec?: number;
34
+ /**
35
+ * How long since last task invocation to consider a task "inactive" for orphan checks.
36
+ * This is compared against task_invocations.created_at.
37
+ */
38
+ invocationStalenessSec?: number;
39
+ /** Recent-update window used for "DB inconsistency" transient detection. */
40
+ dbInconsistencyRecentUpdateSec?: number;
41
+ }
42
+ export interface OrphanedTaskSignal {
43
+ failureMode: 'orphaned_task';
44
+ taskId: string;
45
+ title: string;
46
+ status: 'in_progress';
47
+ updatedAt: Date;
48
+ secondsSinceUpdate: number;
49
+ invocationCount: number;
50
+ lastInvocationAt: Date | null;
51
+ hasActiveRunner: boolean;
52
+ }
53
+ export interface HangingTaskSignal {
54
+ failureMode: 'hanging_invocation';
55
+ phase: 'coder' | 'reviewer';
56
+ taskId: string;
57
+ title: string;
58
+ status: 'in_progress' | 'review';
59
+ updatedAt: Date;
60
+ secondsSinceUpdate: number;
61
+ runnerId: string;
62
+ runnerPid: number | null;
63
+ runnerHeartbeatAt: Date;
64
+ }
65
+ export interface ZombieRunnerSignal {
66
+ failureMode: 'zombie_runner';
67
+ runnerId: string;
68
+ pid: number | null;
69
+ status: string;
70
+ projectPath: string | null;
71
+ currentTaskId: string | null;
72
+ heartbeatAt: Date;
73
+ secondsSinceHeartbeat: number;
74
+ }
75
+ export interface DeadRunnerSignal {
76
+ failureMode: 'dead_runner';
77
+ runnerId: string;
78
+ pid: number | null;
79
+ status: string;
80
+ projectPath: string | null;
81
+ currentTaskId: string | null;
82
+ heartbeatAt: Date;
83
+ secondsSinceHeartbeat: number;
84
+ }
85
+ export interface DbInconsistencySignal {
86
+ failureMode: 'db_inconsistency';
87
+ taskId: string;
88
+ title: string;
89
+ status: 'in_progress';
90
+ updatedAt: Date;
91
+ secondsSinceUpdate: number;
92
+ invocationCount: 0;
93
+ }
94
+ export interface StuckTaskDetectionReport {
95
+ timestamp: Date;
96
+ orphanedTasks: OrphanedTaskSignal[];
97
+ hangingInvocations: HangingTaskSignal[];
98
+ zombieRunners: ZombieRunnerSignal[];
99
+ deadRunners: DeadRunnerSignal[];
100
+ dbInconsistencies: DbInconsistencySignal[];
101
+ }
102
+ export interface DetectStuckTasksOptions {
103
+ /** Absolute project path as stored in global runners DB. */
104
+ projectPath: string;
105
+ /** Project-local database connection (tasks, task_invocations). */
106
+ projectDb: Database.Database;
107
+ /** Global database connection (runners). */
108
+ globalDb: Database.Database;
109
+ /** Optional config overrides. */
110
+ config?: StuckTaskDetectionConfig;
111
+ /**
112
+ * PID liveness check override for testing.
113
+ * If omitted, a best-effort `process.kill(pid, 0)` check is used.
114
+ */
115
+ isPidAlive?: (pid: number) => boolean;
116
+ /** Override current time for deterministic tests. */
117
+ now?: Date;
118
+ }
119
+ /**
120
+ * Parse SQLite datetime('now') strings (YYYY-MM-DD HH:MM:SS) as UTC.
121
+ * Node's Date parser can treat "YYYY-MM-DD HH:MM:SS" as local time depending on runtime,
122
+ * so we normalize to ISO 8601 Zulu.
123
+ */
124
+ export declare function parseSqliteDateTimeUtc(value: string): Date;
125
+ /**
126
+ * Format a Date as SQLite datetime('now')-compatible UTC string: YYYY-MM-DD HH:MM:SS
127
+ * This keeps comparisons lexicographically safe against stored SQLite timestamps.
128
+ */
129
+ export declare function formatSqliteDateTimeUtc(date: Date): string;
130
+ export declare function detectStuckTasks(options: DetectStuckTasksOptions): StuckTaskDetectionReport;
131
+ //# sourceMappingURL=stuck-task-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stuck-task-detector.d.ts","sourceRoot":"","sources":["../../../../src/health/stuck-task-detector.ts"],"names":[],"mappings":"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"}