hungry-ghost-hive 0.48.0 → 0.49.0

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 (472) hide show
  1. package/dist/agents/base-agent.d.ts +11 -11
  2. package/dist/agents/base-agent.d.ts.map +1 -1
  3. package/dist/agents/base-agent.js +25 -25
  4. package/dist/agents/base-agent.js.map +1 -1
  5. package/dist/agents/base-agent.test.js +2 -1
  6. package/dist/agents/base-agent.test.js.map +1 -1
  7. package/dist/agents/intermediate.d.ts +2 -0
  8. package/dist/agents/intermediate.d.ts.map +1 -1
  9. package/dist/agents/intermediate.js +25 -18
  10. package/dist/agents/intermediate.js.map +1 -1
  11. package/dist/agents/junior.d.ts +2 -0
  12. package/dist/agents/junior.d.ts.map +1 -1
  13. package/dist/agents/junior.js +25 -18
  14. package/dist/agents/junior.js.map +1 -1
  15. package/dist/agents/qa.d.ts +2 -0
  16. package/dist/agents/qa.d.ts.map +1 -1
  17. package/dist/agents/qa.js +47 -38
  18. package/dist/agents/qa.js.map +1 -1
  19. package/dist/agents/senior.d.ts +2 -0
  20. package/dist/agents/senior.d.ts.map +1 -1
  21. package/dist/agents/senior.js +40 -27
  22. package/dist/agents/senior.js.map +1 -1
  23. package/dist/agents/tech-lead.d.ts +2 -0
  24. package/dist/agents/tech-lead.d.ts.map +1 -1
  25. package/dist/agents/tech-lead.js +37 -31
  26. package/dist/agents/tech-lead.js.map +1 -1
  27. package/dist/cli/commands/add-repo.js +2 -2
  28. package/dist/cli/commands/add-repo.js.map +1 -1
  29. package/dist/cli/commands/add-repo.test.js +1 -1
  30. package/dist/cli/commands/add-repo.test.js.map +1 -1
  31. package/dist/cli/commands/agents.d.ts.map +1 -1
  32. package/dist/cli/commands/agents.js +12 -10
  33. package/dist/cli/commands/agents.js.map +1 -1
  34. package/dist/cli/commands/agents.test.js +7 -7
  35. package/dist/cli/commands/agents.test.js.map +1 -1
  36. package/dist/cli/commands/approach.js +2 -2
  37. package/dist/cli/commands/approach.js.map +1 -1
  38. package/dist/cli/commands/approvals.js +7 -7
  39. package/dist/cli/commands/approvals.js.map +1 -1
  40. package/dist/cli/commands/approvals.test.js +8 -8
  41. package/dist/cli/commands/approvals.test.js.map +1 -1
  42. package/dist/cli/commands/assign.js +4 -4
  43. package/dist/cli/commands/assign.js.map +1 -1
  44. package/dist/cli/commands/assign.test.js +18 -16
  45. package/dist/cli/commands/assign.test.js.map +1 -1
  46. package/dist/cli/commands/cleanup.d.ts.map +1 -1
  47. package/dist/cli/commands/cleanup.js +8 -8
  48. package/dist/cli/commands/cleanup.js.map +1 -1
  49. package/dist/cli/commands/cleanup.test.js +5 -1
  50. package/dist/cli/commands/cleanup.test.js.map +1 -1
  51. package/dist/cli/commands/escalations.js +9 -7
  52. package/dist/cli/commands/escalations.js.map +1 -1
  53. package/dist/cli/commands/escalations.test.js +2 -2
  54. package/dist/cli/commands/escalations.test.js.map +1 -1
  55. package/dist/cli/commands/init.d.ts.map +1 -1
  56. package/dist/cli/commands/init.js +48 -5
  57. package/dist/cli/commands/init.js.map +1 -1
  58. package/dist/cli/commands/init.test.js +4 -0
  59. package/dist/cli/commands/init.test.js.map +1 -1
  60. package/dist/cli/commands/manager/agent-monitoring.d.ts +2 -2
  61. package/dist/cli/commands/manager/agent-monitoring.d.ts.map +1 -1
  62. package/dist/cli/commands/manager/agent-monitoring.js +1 -1
  63. package/dist/cli/commands/manager/agent-monitoring.js.map +1 -1
  64. package/dist/cli/commands/manager/auditor-lifecycle.js +3 -3
  65. package/dist/cli/commands/manager/auditor-lifecycle.js.map +1 -1
  66. package/dist/cli/commands/manager/auditor-lifecycle.test.js +21 -14
  67. package/dist/cli/commands/manager/auditor-lifecycle.test.js.map +1 -1
  68. package/dist/cli/commands/manager/auto-reject-comment-only-reviews.test.js +28 -23
  69. package/dist/cli/commands/manager/auto-reject-comment-only-reviews.test.js.map +1 -1
  70. package/dist/cli/commands/manager/escalation-handler.d.ts +2 -2
  71. package/dist/cli/commands/manager/escalation-handler.d.ts.map +1 -1
  72. package/dist/cli/commands/manager/escalation-handler.js +11 -10
  73. package/dist/cli/commands/manager/escalation-handler.js.map +1 -1
  74. package/dist/cli/commands/manager/escalation-handler.test.js +8 -8
  75. package/dist/cli/commands/manager/escalation-handler.test.js.map +1 -1
  76. package/dist/cli/commands/manager/feature-sign-off.js +7 -7
  77. package/dist/cli/commands/manager/feature-sign-off.js.map +1 -1
  78. package/dist/cli/commands/manager/feature-sign-off.test.js +40 -31
  79. package/dist/cli/commands/manager/feature-sign-off.test.js.map +1 -1
  80. package/dist/cli/commands/manager/feature-test-result.d.ts.map +1 -1
  81. package/dist/cli/commands/manager/feature-test-result.js +12 -13
  82. package/dist/cli/commands/manager/feature-test-result.js.map +1 -1
  83. package/dist/cli/commands/manager/handoff-recovery.d.ts.map +1 -1
  84. package/dist/cli/commands/manager/handoff-recovery.js +14 -15
  85. package/dist/cli/commands/manager/handoff-recovery.js.map +1 -1
  86. package/dist/cli/commands/manager/index.d.ts.map +1 -1
  87. package/dist/cli/commands/manager/index.js +26 -26
  88. package/dist/cli/commands/manager/index.js.map +1 -1
  89. package/dist/cli/commands/manager/index.test.js +3 -3
  90. package/dist/cli/commands/manager/index.test.js.map +1 -1
  91. package/dist/cli/commands/manager/merged-story-cleanup.d.ts +2 -2
  92. package/dist/cli/commands/manager/merged-story-cleanup.d.ts.map +1 -1
  93. package/dist/cli/commands/manager/merged-story-cleanup.js +6 -7
  94. package/dist/cli/commands/manager/merged-story-cleanup.js.map +1 -1
  95. package/dist/cli/commands/manager/merged-story-cleanup.test.js +27 -18
  96. package/dist/cli/commands/manager/merged-story-cleanup.test.js.map +1 -1
  97. package/dist/cli/commands/manager/pr-sync-orchestrator.d.ts.map +1 -1
  98. package/dist/cli/commands/manager/pr-sync-orchestrator.js +46 -38
  99. package/dist/cli/commands/manager/pr-sync-orchestrator.js.map +1 -1
  100. package/dist/cli/commands/manager/qa-review-handler.d.ts.map +1 -1
  101. package/dist/cli/commands/manager/qa-review-handler.js +25 -22
  102. package/dist/cli/commands/manager/qa-review-handler.js.map +1 -1
  103. package/dist/cli/commands/manager/spin-down.d.ts.map +1 -1
  104. package/dist/cli/commands/manager/spin-down.js +23 -19
  105. package/dist/cli/commands/manager/spin-down.js.map +1 -1
  106. package/dist/cli/commands/manager/stale-escalations.d.ts +2 -3
  107. package/dist/cli/commands/manager/stale-escalations.d.ts.map +1 -1
  108. package/dist/cli/commands/manager/stale-escalations.js.map +1 -1
  109. package/dist/cli/commands/manager/stuck-story-helpers.js +8 -8
  110. package/dist/cli/commands/manager/stuck-story-helpers.js.map +1 -1
  111. package/dist/cli/commands/manager/stuck-story-processor.d.ts +2 -2
  112. package/dist/cli/commands/manager/stuck-story-processor.d.ts.map +1 -1
  113. package/dist/cli/commands/manager/stuck-story-processor.js +23 -22
  114. package/dist/cli/commands/manager/stuck-story-processor.js.map +1 -1
  115. package/dist/cli/commands/manager/tech-lead-lifecycle.js +6 -6
  116. package/dist/cli/commands/manager/tech-lead-lifecycle.js.map +1 -1
  117. package/dist/cli/commands/manager/types.d.ts +2 -3
  118. package/dist/cli/commands/manager/types.d.ts.map +1 -1
  119. package/dist/cli/commands/manager/types.js.map +1 -1
  120. package/dist/cli/commands/msg.test.js +2 -2
  121. package/dist/cli/commands/msg.test.js.map +1 -1
  122. package/dist/cli/commands/my-stories.d.ts.map +1 -1
  123. package/dist/cli/commands/my-stories.js +17 -18
  124. package/dist/cli/commands/my-stories.js.map +1 -1
  125. package/dist/cli/commands/my-stories.test.js +2 -2
  126. package/dist/cli/commands/my-stories.test.js.map +1 -1
  127. package/dist/cli/commands/nuke.test.js +1 -1
  128. package/dist/cli/commands/nuke.test.js.map +1 -1
  129. package/dist/cli/commands/pr.js +32 -32
  130. package/dist/cli/commands/pr.js.map +1 -1
  131. package/dist/cli/commands/pr.test.js +10 -6
  132. package/dist/cli/commands/pr.test.js.map +1 -1
  133. package/dist/cli/commands/progress.d.ts.map +1 -1
  134. package/dist/cli/commands/progress.js +4 -5
  135. package/dist/cli/commands/progress.js.map +1 -1
  136. package/dist/cli/commands/progress.test.js +1 -1
  137. package/dist/cli/commands/progress.test.js.map +1 -1
  138. package/dist/cli/commands/req-headless.test.d.ts +2 -0
  139. package/dist/cli/commands/req-headless.test.d.ts.map +1 -0
  140. package/dist/cli/commands/req-headless.test.js +128 -0
  141. package/dist/cli/commands/req-headless.test.js.map +1 -0
  142. package/dist/cli/commands/req-spawn.test.js +5 -1
  143. package/dist/cli/commands/req-spawn.test.js.map +1 -1
  144. package/dist/cli/commands/req.d.ts.map +1 -1
  145. package/dist/cli/commands/req.js +13 -14
  146. package/dist/cli/commands/req.js.map +1 -1
  147. package/dist/cli/commands/resume.d.ts.map +1 -1
  148. package/dist/cli/commands/resume.js +7 -8
  149. package/dist/cli/commands/resume.js.map +1 -1
  150. package/dist/cli/commands/resume.test.js +1 -1
  151. package/dist/cli/commands/resume.test.js.map +1 -1
  152. package/dist/cli/commands/status.d.ts.map +1 -1
  153. package/dist/cli/commands/status.js +42 -40
  154. package/dist/cli/commands/status.js.map +1 -1
  155. package/dist/cli/commands/status.test.js +1 -1
  156. package/dist/cli/commands/status.test.js.map +1 -1
  157. package/dist/cli/commands/stories.js +9 -9
  158. package/dist/cli/commands/stories.js.map +1 -1
  159. package/dist/cli/commands/stories.test.js +2 -2
  160. package/dist/cli/commands/stories.test.js.map +1 -1
  161. package/dist/cli/commands/teams.js +11 -11
  162. package/dist/cli/commands/teams.js.map +1 -1
  163. package/dist/cli/commands/teams.test.js +2 -2
  164. package/dist/cli/commands/teams.test.js.map +1 -1
  165. package/dist/cli/dashboard/index.d.ts +2 -2
  166. package/dist/cli/dashboard/index.d.ts.map +1 -1
  167. package/dist/cli/dashboard/index.js +29 -20
  168. package/dist/cli/dashboard/index.js.map +1 -1
  169. package/dist/cli/dashboard/index.test.js +34 -32
  170. package/dist/cli/dashboard/index.test.js.map +1 -1
  171. package/dist/cli/dashboard/panels/activity.d.ts +3 -3
  172. package/dist/cli/dashboard/panels/activity.d.ts.map +1 -1
  173. package/dist/cli/dashboard/panels/activity.js +1 -1
  174. package/dist/cli/dashboard/panels/activity.js.map +1 -1
  175. package/dist/cli/dashboard/panels/agents.d.ts +3 -3
  176. package/dist/cli/dashboard/panels/agents.d.ts.map +1 -1
  177. package/dist/cli/dashboard/panels/agents.js +2 -2
  178. package/dist/cli/dashboard/panels/agents.js.map +1 -1
  179. package/dist/cli/dashboard/panels/escalations.d.ts +3 -3
  180. package/dist/cli/dashboard/panels/escalations.d.ts.map +1 -1
  181. package/dist/cli/dashboard/panels/escalations.js +1 -1
  182. package/dist/cli/dashboard/panels/escalations.js.map +1 -1
  183. package/dist/cli/dashboard/panels/merge-queue.d.ts +3 -3
  184. package/dist/cli/dashboard/panels/merge-queue.d.ts.map +1 -1
  185. package/dist/cli/dashboard/panels/merge-queue.js +1 -1
  186. package/dist/cli/dashboard/panels/merge-queue.js.map +1 -1
  187. package/dist/cli/dashboard/panels/pipeline.d.ts +3 -3
  188. package/dist/cli/dashboard/panels/pipeline.d.ts.map +1 -1
  189. package/dist/cli/dashboard/panels/pipeline.js +1 -1
  190. package/dist/cli/dashboard/panels/pipeline.js.map +1 -1
  191. package/dist/config/schema.d.ts +85 -82
  192. package/dist/config/schema.d.ts.map +1 -1
  193. package/dist/config/schema.js +1 -0
  194. package/dist/config/schema.js.map +1 -1
  195. package/dist/connectors/project-management/operations.d.ts +7 -7
  196. package/dist/connectors/project-management/operations.d.ts.map +1 -1
  197. package/dist/connectors/project-management/operations.js +2 -3
  198. package/dist/connectors/project-management/operations.js.map +1 -1
  199. package/dist/context-files/index.test.js +1 -0
  200. package/dist/context-files/index.test.js.map +1 -1
  201. package/dist/db/client.d.ts +6 -0
  202. package/dist/db/client.d.ts.map +1 -1
  203. package/dist/db/client.js +7 -0
  204. package/dist/db/client.js.map +1 -1
  205. package/dist/db/postgres-provider.d.ts +43 -0
  206. package/dist/db/postgres-provider.d.ts.map +1 -0
  207. package/dist/db/postgres-provider.integration.test.d.ts +2 -0
  208. package/dist/db/postgres-provider.integration.test.d.ts.map +1 -0
  209. package/dist/db/postgres-provider.integration.test.js +399 -0
  210. package/dist/db/postgres-provider.integration.test.js.map +1 -0
  211. package/dist/db/postgres-provider.js +315 -0
  212. package/dist/db/postgres-provider.js.map +1 -0
  213. package/dist/db/postgres-provider.test.d.ts +2 -0
  214. package/dist/db/postgres-provider.test.d.ts.map +1 -0
  215. package/dist/db/postgres-provider.test.js +72 -0
  216. package/dist/db/postgres-provider.test.js.map +1 -0
  217. package/dist/db/provider.d.ts +59 -0
  218. package/dist/db/provider.d.ts.map +1 -0
  219. package/dist/db/provider.js +121 -0
  220. package/dist/db/provider.js.map +1 -0
  221. package/dist/db/provider.test.d.ts +2 -0
  222. package/dist/db/provider.test.d.ts.map +1 -0
  223. package/dist/db/provider.test.js +226 -0
  224. package/dist/db/provider.test.js.map +1 -0
  225. package/dist/db/queries/agents.d.ts +13 -13
  226. package/dist/db/queries/agents.d.ts.map +1 -1
  227. package/dist/db/queries/agents.js +27 -28
  228. package/dist/db/queries/agents.js.map +1 -1
  229. package/dist/db/queries/agents.test.js +113 -111
  230. package/dist/db/queries/agents.test.js.map +1 -1
  231. package/dist/db/queries/escalations.d.ts +16 -16
  232. package/dist/db/queries/escalations.d.ts.map +1 -1
  233. package/dist/db/queries/escalations.js +34 -35
  234. package/dist/db/queries/escalations.js.map +1 -1
  235. package/dist/db/queries/escalations.test.js +133 -131
  236. package/dist/db/queries/escalations.test.js.map +1 -1
  237. package/dist/db/queries/heartbeat.d.ts +5 -5
  238. package/dist/db/queries/heartbeat.d.ts.map +1 -1
  239. package/dist/db/queries/heartbeat.js +7 -23
  240. package/dist/db/queries/heartbeat.js.map +1 -1
  241. package/dist/db/queries/heartbeat.test.js +76 -76
  242. package/dist/db/queries/heartbeat.test.js.map +1 -1
  243. package/dist/db/queries/integration-sync.d.ts +7 -7
  244. package/dist/db/queries/integration-sync.d.ts.map +1 -1
  245. package/dist/db/queries/integration-sync.js +13 -14
  246. package/dist/db/queries/integration-sync.js.map +1 -1
  247. package/dist/db/queries/logs.d.ts +10 -10
  248. package/dist/db/queries/logs.d.ts.map +1 -1
  249. package/dist/db/queries/logs.js +44 -42
  250. package/dist/db/queries/logs.js.map +1 -1
  251. package/dist/db/queries/logs.test.js +149 -146
  252. package/dist/db/queries/logs.test.js.map +1 -1
  253. package/dist/db/queries/messages.d.ts +6 -6
  254. package/dist/db/queries/messages.d.ts.map +1 -1
  255. package/dist/db/queries/messages.js +12 -11
  256. package/dist/db/queries/messages.js.map +1 -1
  257. package/dist/db/queries/messages.test.js +47 -46
  258. package/dist/db/queries/messages.test.js.map +1 -1
  259. package/dist/db/queries/pull-requests.d.ts +18 -18
  260. package/dist/db/queries/pull-requests.d.ts.map +1 -1
  261. package/dist/db/queries/pull-requests.js +50 -48
  262. package/dist/db/queries/pull-requests.js.map +1 -1
  263. package/dist/db/queries/pull-requests.test.js +195 -198
  264. package/dist/db/queries/pull-requests.test.js.map +1 -1
  265. package/dist/db/queries/requirements.d.ts +8 -8
  266. package/dist/db/queries/requirements.d.ts.map +1 -1
  267. package/dist/db/queries/requirements.js +17 -18
  268. package/dist/db/queries/requirements.js.map +1 -1
  269. package/dist/db/queries/requirements.test.js +83 -81
  270. package/dist/db/queries/requirements.test.js.map +1 -1
  271. package/dist/db/queries/stories.d.ts +29 -29
  272. package/dist/db/queries/stories.d.ts.map +1 -1
  273. package/dist/db/queries/stories.js +58 -64
  274. package/dist/db/queries/stories.js.map +1 -1
  275. package/dist/db/queries/stories.test.js +172 -170
  276. package/dist/db/queries/stories.test.js.map +1 -1
  277. package/dist/db/queries/teams.d.ts +6 -6
  278. package/dist/db/queries/teams.d.ts.map +1 -1
  279. package/dist/db/queries/teams.js +11 -12
  280. package/dist/db/queries/teams.js.map +1 -1
  281. package/dist/db/queries/teams.test.js +36 -34
  282. package/dist/db/queries/teams.test.js.map +1 -1
  283. package/dist/integrations/jira/repair.test.js +26 -24
  284. package/dist/integrations/jira/repair.test.js.map +1 -1
  285. package/dist/integrations/jira/stories.d.ts +3 -3
  286. package/dist/integrations/jira/stories.d.ts.map +1 -1
  287. package/dist/integrations/jira/stories.js +12 -12
  288. package/dist/integrations/jira/stories.js.map +1 -1
  289. package/dist/integrations/jira/stories.test.js +10 -8
  290. package/dist/integrations/jira/stories.test.js.map +1 -1
  291. package/dist/integrations/jira/sync.d.ts +7 -7
  292. package/dist/integrations/jira/sync.d.ts.map +1 -1
  293. package/dist/integrations/jira/sync.js +17 -20
  294. package/dist/integrations/jira/sync.js.map +1 -1
  295. package/dist/integrations/jira/sync.test.js +63 -62
  296. package/dist/integrations/jira/sync.test.js.map +1 -1
  297. package/dist/integrations/jira/transitions.d.ts +3 -3
  298. package/dist/integrations/jira/transitions.d.ts.map +1 -1
  299. package/dist/integrations/jira/transitions.js +3 -3
  300. package/dist/integrations/jira/transitions.js.map +1 -1
  301. package/dist/orchestrator/agent-selector.d.ts +3 -3
  302. package/dist/orchestrator/agent-selector.d.ts.map +1 -1
  303. package/dist/orchestrator/agent-selector.js +5 -6
  304. package/dist/orchestrator/agent-selector.js.map +1 -1
  305. package/dist/orchestrator/dependency-resolver.d.ts +4 -4
  306. package/dist/orchestrator/dependency-resolver.d.ts.map +1 -1
  307. package/dist/orchestrator/dependency-resolver.js +6 -6
  308. package/dist/orchestrator/dependency-resolver.js.map +1 -1
  309. package/dist/orchestrator/feature-branch.d.ts +3 -3
  310. package/dist/orchestrator/feature-branch.d.ts.map +1 -1
  311. package/dist/orchestrator/feature-branch.js +9 -10
  312. package/dist/orchestrator/feature-branch.js.map +1 -1
  313. package/dist/orchestrator/feature-branch.test.js +80 -78
  314. package/dist/orchestrator/feature-branch.test.js.map +1 -1
  315. package/dist/orchestrator/orphan-recovery.d.ts +2 -2
  316. package/dist/orchestrator/orphan-recovery.d.ts.map +1 -1
  317. package/dist/orchestrator/orphan-recovery.js +10 -10
  318. package/dist/orchestrator/orphan-recovery.js.map +1 -1
  319. package/dist/orchestrator/scheduler.d.ts +4 -4
  320. package/dist/orchestrator/scheduler.d.ts.map +1 -1
  321. package/dist/orchestrator/scheduler.js +90 -76
  322. package/dist/orchestrator/scheduler.js.map +1 -1
  323. package/dist/orchestrator/scheduler.test.js +496 -374
  324. package/dist/orchestrator/scheduler.test.js.map +1 -1
  325. package/dist/utils/auto-merge.d.ts.map +1 -1
  326. package/dist/utils/auto-merge.js +74 -56
  327. package/dist/utils/auto-merge.js.map +1 -1
  328. package/dist/utils/auto-merge.test.js +101 -66
  329. package/dist/utils/auto-merge.test.js.map +1 -1
  330. package/dist/utils/cli-helpers.d.ts +5 -5
  331. package/dist/utils/cli-helpers.d.ts.map +1 -1
  332. package/dist/utils/cli-helpers.js +8 -9
  333. package/dist/utils/cli-helpers.js.map +1 -1
  334. package/dist/utils/cli-helpers.test.js +28 -30
  335. package/dist/utils/cli-helpers.test.js.map +1 -1
  336. package/dist/utils/paths.d.ts +6 -0
  337. package/dist/utils/paths.d.ts.map +1 -1
  338. package/dist/utils/paths.js +12 -1
  339. package/dist/utils/paths.js.map +1 -1
  340. package/dist/utils/paths.test.js +1 -0
  341. package/dist/utils/paths.test.js.map +1 -1
  342. package/dist/utils/pr-sync.d.ts +10 -10
  343. package/dist/utils/pr-sync.d.ts.map +1 -1
  344. package/dist/utils/pr-sync.js +20 -21
  345. package/dist/utils/pr-sync.js.map +1 -1
  346. package/dist/utils/pr-sync.test.js +52 -50
  347. package/dist/utils/pr-sync.test.js.map +1 -1
  348. package/dist/utils/with-hive-context.d.ts.map +1 -1
  349. package/dist/utils/with-hive-context.js +70 -1
  350. package/dist/utils/with-hive-context.js.map +1 -1
  351. package/package.json +3 -1
  352. package/src/agents/base-agent.test.ts +2 -1
  353. package/src/agents/base-agent.ts +32 -28
  354. package/src/agents/intermediate.ts +27 -18
  355. package/src/agents/junior.ts +27 -18
  356. package/src/agents/qa.ts +54 -40
  357. package/src/agents/senior.ts +42 -27
  358. package/src/agents/tech-lead.ts +42 -32
  359. package/src/cli/commands/add-repo.test.ts +1 -1
  360. package/src/cli/commands/add-repo.ts +2 -2
  361. package/src/cli/commands/agents.test.ts +7 -7
  362. package/src/cli/commands/agents.ts +12 -10
  363. package/src/cli/commands/approach.ts +2 -2
  364. package/src/cli/commands/approvals.test.ts +8 -8
  365. package/src/cli/commands/approvals.ts +9 -7
  366. package/src/cli/commands/assign.test.ts +19 -18
  367. package/src/cli/commands/assign.ts +4 -4
  368. package/src/cli/commands/cleanup.test.ts +5 -1
  369. package/src/cli/commands/cleanup.ts +11 -9
  370. package/src/cli/commands/escalations.test.ts +2 -2
  371. package/src/cli/commands/escalations.ts +9 -7
  372. package/src/cli/commands/init.test.ts +5 -0
  373. package/src/cli/commands/init.ts +53 -5
  374. package/src/cli/commands/manager/agent-monitoring.ts +3 -3
  375. package/src/cli/commands/manager/auditor-lifecycle.test.ts +21 -14
  376. package/src/cli/commands/manager/auditor-lifecycle.ts +3 -3
  377. package/src/cli/commands/manager/auto-reject-comment-only-reviews.test.ts +28 -23
  378. package/src/cli/commands/manager/escalation-handler.test.ts +13 -13
  379. package/src/cli/commands/manager/escalation-handler.ts +19 -12
  380. package/src/cli/commands/manager/feature-sign-off.test.ts +40 -31
  381. package/src/cli/commands/manager/feature-sign-off.ts +7 -7
  382. package/src/cli/commands/manager/feature-test-result.ts +13 -16
  383. package/src/cli/commands/manager/handoff-recovery.ts +20 -20
  384. package/src/cli/commands/manager/index.test.ts +4 -4
  385. package/src/cli/commands/manager/index.ts +58 -59
  386. package/src/cli/commands/manager/merged-story-cleanup.test.ts +28 -19
  387. package/src/cli/commands/manager/merged-story-cleanup.ts +11 -14
  388. package/src/cli/commands/manager/pr-sync-orchestrator.ts +115 -110
  389. package/src/cli/commands/manager/qa-review-handler.ts +50 -63
  390. package/src/cli/commands/manager/spin-down.ts +27 -25
  391. package/src/cli/commands/manager/stale-escalations.ts +2 -3
  392. package/src/cli/commands/manager/stuck-story-helpers.ts +10 -10
  393. package/src/cli/commands/manager/stuck-story-processor.ts +56 -62
  394. package/src/cli/commands/manager/tech-lead-lifecycle.ts +6 -6
  395. package/src/cli/commands/manager/types.ts +2 -3
  396. package/src/cli/commands/msg.test.ts +2 -2
  397. package/src/cli/commands/my-stories.test.ts +4 -2
  398. package/src/cli/commands/my-stories.ts +22 -27
  399. package/src/cli/commands/nuke.test.ts +1 -1
  400. package/src/cli/commands/pr.test.ts +10 -6
  401. package/src/cli/commands/pr.ts +41 -32
  402. package/src/cli/commands/progress.test.ts +1 -1
  403. package/src/cli/commands/progress.ts +11 -6
  404. package/src/cli/commands/req-headless.test.ts +170 -0
  405. package/src/cli/commands/req-spawn.test.ts +12 -2
  406. package/src/cli/commands/req.ts +13 -14
  407. package/src/cli/commands/resume.test.ts +1 -1
  408. package/src/cli/commands/resume.ts +7 -8
  409. package/src/cli/commands/status.test.ts +1 -1
  410. package/src/cli/commands/status.ts +52 -40
  411. package/src/cli/commands/stories.test.ts +4 -2
  412. package/src/cli/commands/stories.ts +11 -11
  413. package/src/cli/commands/teams.test.ts +2 -2
  414. package/src/cli/commands/teams.ts +11 -11
  415. package/src/cli/dashboard/index.test.ts +35 -34
  416. package/src/cli/dashboard/index.ts +34 -23
  417. package/src/cli/dashboard/panels/activity.ts +10 -4
  418. package/src/cli/dashboard/panels/agents.ts +8 -5
  419. package/src/cli/dashboard/panels/escalations.ts +4 -4
  420. package/src/cli/dashboard/panels/merge-queue.ts +4 -4
  421. package/src/cli/dashboard/panels/pipeline.ts +10 -4
  422. package/src/config/schema.ts +1 -0
  423. package/src/connectors/project-management/operations.ts +9 -10
  424. package/src/context-files/index.test.ts +1 -0
  425. package/src/db/client.ts +17 -0
  426. package/src/db/pg-migrations/001-full-schema.sql +209 -0
  427. package/src/db/postgres-provider.integration.test.ts +574 -0
  428. package/src/db/postgres-provider.test.ts +97 -0
  429. package/src/db/postgres-provider.ts +364 -0
  430. package/src/db/provider.test.ts +283 -0
  431. package/src/db/provider.ts +161 -0
  432. package/src/db/queries/agents.test.ts +114 -113
  433. package/src/db/queries/agents.ts +50 -36
  434. package/src/db/queries/escalations.test.ts +134 -133
  435. package/src/db/queries/escalations.ts +72 -57
  436. package/src/db/queries/heartbeat.test.ts +77 -78
  437. package/src/db/queries/heartbeat.ts +24 -46
  438. package/src/db/queries/integration-sync.ts +26 -26
  439. package/src/db/queries/logs.test.ts +151 -148
  440. package/src/db/queries/logs.ts +78 -53
  441. package/src/db/queries/messages.test.ts +48 -50
  442. package/src/db/queries/messages.ts +26 -18
  443. package/src/db/queries/pull-requests.test.ts +194 -199
  444. package/src/db/queries/pull-requests.ts +117 -88
  445. package/src/db/queries/requirements.test.ts +84 -83
  446. package/src/db/queries/requirements.ts +33 -28
  447. package/src/db/queries/stories.test.ts +173 -172
  448. package/src/db/queries/stories.ts +141 -110
  449. package/src/db/queries/teams.test.ts +37 -36
  450. package/src/db/queries/teams.ts +22 -14
  451. package/src/integrations/jira/repair.test.ts +27 -26
  452. package/src/integrations/jira/stories.test.ts +15 -16
  453. package/src/integrations/jira/stories.ts +15 -15
  454. package/src/integrations/jira/sync.test.ts +68 -68
  455. package/src/integrations/jira/sync.ts +29 -39
  456. package/src/integrations/jira/transitions.ts +6 -6
  457. package/src/orchestrator/agent-selector.ts +9 -8
  458. package/src/orchestrator/dependency-resolver.ts +16 -7
  459. package/src/orchestrator/feature-branch.test.ts +85 -80
  460. package/src/orchestrator/feature-branch.ts +13 -14
  461. package/src/orchestrator/orphan-recovery.ts +14 -13
  462. package/src/orchestrator/scheduler.test.ts +536 -394
  463. package/src/orchestrator/scheduler.ts +129 -115
  464. package/src/utils/auto-merge.test.ts +102 -68
  465. package/src/utils/auto-merge.ts +161 -168
  466. package/src/utils/cli-helpers.test.ts +30 -32
  467. package/src/utils/cli-helpers.ts +15 -11
  468. package/src/utils/paths.test.ts +1 -0
  469. package/src/utils/paths.ts +14 -1
  470. package/src/utils/pr-sync.test.ts +55 -52
  471. package/src/utils/pr-sync.ts +27 -32
  472. package/src/utils/with-hive-context.ts +89 -1
@@ -7,7 +7,6 @@ import {
7
7
  syncStatusForStory,
8
8
  } from '../connectors/project-management/operations.js';
9
9
  import type { DatabaseClient } from '../db/client.js';
10
- import { queryOne, withTransaction } from '../db/client.js';
11
10
  import { getAgentById, updateAgent } from '../db/queries/agents.js';
12
11
  import { createLog } from '../db/queries/logs.js';
13
12
  import {
@@ -153,7 +152,7 @@ export async function autoMergeApprovedPRs(
153
152
  const claimedPRs: ClaimedPR[] = [];
154
153
 
155
154
  const claimPhase = async (phaseDb: DatabaseClient) => {
156
- const approvedPRs = getApprovedPullRequests(phaseDb.db).filter(
155
+ const approvedPRs = (await getApprovedPullRequests(phaseDb.provider)).filter(
157
156
  pr => !isManualMergeRequired(pr.review_notes)
158
157
  );
159
158
 
@@ -161,21 +160,17 @@ export async function autoMergeApprovedPRs(
161
160
  if (!pr.github_pr_number) continue;
162
161
 
163
162
  let claimed = false;
164
- await withTransaction(
165
- phaseDb.db,
166
- () => {
167
- const currentPR = queryOne<{ status: string }>(
168
- phaseDb.db,
169
- `SELECT status FROM pull_requests WHERE id = ?`,
170
- [pr.id]
171
- );
172
- if (currentPR?.status === 'approved') {
173
- updatePullRequest(phaseDb.db, pr.id, { status: 'queued' });
174
- claimed = true;
175
- }
176
- },
177
- () => phaseDb.save()
178
- );
163
+ await phaseDb.provider.withTransaction(async () => {
164
+ const currentPR = await phaseDb.provider.queryOne<{ status: string }>(
165
+ `SELECT status FROM pull_requests WHERE id = ?`,
166
+ [pr.id]
167
+ );
168
+ if (currentPR?.status === 'approved') {
169
+ await updatePullRequest(phaseDb.provider, pr.id, { status: 'queued' });
170
+ claimed = true;
171
+ }
172
+ });
173
+ phaseDb.save();
179
174
 
180
175
  if (!claimed) continue;
181
176
 
@@ -185,11 +180,11 @@ export async function autoMergeApprovedPRs(
185
180
  let repoSlug: string | null = null;
186
181
 
187
182
  if (teamId) {
188
- const team = getAllTeams(phaseDb.db).find(t => t.id === teamId);
183
+ const team = (await getAllTeams(phaseDb.provider)).find(t => t.id === teamId);
189
184
  if (team?.repo_path) repoCwd = join(root, team.repo_path);
190
185
  if (team?.repo_url) repoSlug = ghRepoSlug(team.repo_url);
191
186
  } else if (pr.branch_name) {
192
- const teams = getAllTeams(phaseDb.db);
187
+ const teams = await getAllTeams(phaseDb.provider);
193
188
  for (const team of teams) {
194
189
  if (team.repo_path) {
195
190
  repoCwd = join(root, team.repo_path);
@@ -379,7 +374,7 @@ export async function autoMergeApprovedPRs(
379
374
 
380
375
  switch (result.outcome.type) {
381
376
  case 'unknown_state': {
382
- createLog(phaseDb.db, {
377
+ await createLog(phaseDb.provider, {
383
378
  agentId: 'manager',
384
379
  storyId: pr.story_id || undefined,
385
380
  eventType: 'PR_MERGE_SKIPPED',
@@ -393,55 +388,58 @@ export async function autoMergeApprovedPRs(
393
388
  case 'already_closed': {
394
389
  const prState = result.outcome.prState;
395
390
  const newStatus = prState.state === 'MERGED' ? 'merged' : 'closed';
396
- await withTransaction(
397
- phaseDb.db,
398
- () => {
399
- updatePullRequest(phaseDb.db, pr.id, { status: newStatus });
400
- if (pr.story_id && prState.state === 'MERGED') {
401
- const story = getStoryById(phaseDb.db, pr.story_id);
402
- if (story?.assigned_agent_id) {
403
- const agent = getAgentById(phaseDb.db, story.assigned_agent_id);
404
- if (agent && agent.current_story_id === pr.story_id) {
405
- updateAgent(phaseDb.db, agent.id, { currentStoryId: null, status: 'idle' });
406
- }
391
+ await phaseDb.provider.withTransaction(async () => {
392
+ await updatePullRequest(phaseDb.provider, pr.id, { status: newStatus });
393
+ if (pr.story_id && prState.state === 'MERGED') {
394
+ const story = await getStoryById(phaseDb.provider, pr.story_id);
395
+ if (story?.assigned_agent_id) {
396
+ const agent = await getAgentById(phaseDb.provider, story.assigned_agent_id);
397
+ if (agent && agent.current_story_id === pr.story_id) {
398
+ await updateAgent(phaseDb.provider, agent.id, {
399
+ currentStoryId: null,
400
+ status: 'idle',
401
+ });
407
402
  }
408
- updateStory(phaseDb.db, pr.story_id, { status: 'merged', assignedAgentId: null });
409
- createLog(phaseDb.db, {
410
- agentId: 'manager',
411
- storyId: pr.story_id,
412
- eventType: 'STORY_MERGED',
413
- message: `Story merged (PR #${pr.github_pr_number} was already merged on GitHub)`,
414
- metadata: { pr_id: pr.id },
415
- });
416
- postLifecycleComment(
417
- phaseDb.db,
418
- paths.hiveDir,
419
- config,
420
- pr.story_id,
421
- 'merged'
422
- ).catch(() => {
423
- /* non-fatal */
424
- });
425
403
  }
426
- createLog(phaseDb.db, {
404
+ await updateStory(phaseDb.provider, pr.story_id, {
405
+ status: 'merged',
406
+ assignedAgentId: null,
407
+ });
408
+ await createLog(phaseDb.provider, {
427
409
  agentId: 'manager',
428
- storyId: pr.story_id || undefined,
429
- eventType: 'PR_MERGE_SKIPPED',
430
- message: `PR #${pr.github_pr_number} is already ${prState.state.toLowerCase()}, skipping merge`,
431
- metadata: { pr_id: pr.id, github_state: prState.state },
410
+ storyId: pr.story_id,
411
+ eventType: 'STORY_MERGED',
412
+ message: `Story merged (PR #${pr.github_pr_number} was already merged on GitHub)`,
413
+ metadata: { pr_id: pr.id },
432
414
  });
433
- },
434
- () => phaseDb.save()
435
- );
415
+ postLifecycleComment(
416
+ phaseDb.provider,
417
+ paths.hiveDir,
418
+ config,
419
+ pr.story_id,
420
+ 'merged'
421
+ ).catch(() => {
422
+ /* non-fatal */
423
+ });
424
+ }
425
+ await createLog(phaseDb.provider, {
426
+ agentId: 'manager',
427
+ storyId: pr.story_id || undefined,
428
+ eventType: 'PR_MERGE_SKIPPED',
429
+ message: `PR #${pr.github_pr_number} is already ${prState.state.toLowerCase()}, skipping merge`,
430
+ metadata: { pr_id: pr.id, github_state: prState.state },
431
+ });
432
+ });
433
+ phaseDb.save();
436
434
 
437
435
  if (pr.story_id && prState.state === 'MERGED') {
438
- syncStatusForStory(root, phaseDb.db, pr.story_id, 'merged');
436
+ syncStatusForStory(root, phaseDb.provider, pr.story_id, 'merged');
439
437
  }
440
438
  break;
441
439
  }
442
440
 
443
441
  case 'conflicts': {
444
- createLog(phaseDb.db, {
442
+ await createLog(phaseDb.provider, {
445
443
  agentId: 'manager',
446
444
  storyId: pr.story_id || undefined,
447
445
  eventType: 'PR_MERGE_SKIPPED',
@@ -453,115 +451,116 @@ export async function autoMergeApprovedPRs(
453
451
  }
454
452
 
455
453
  case 'ci_blocked': {
456
- await withTransaction(
457
- phaseDb.db,
458
- () => {
459
- updatePullRequest(phaseDb.db, pr.id, { status: 'approved' });
460
- createLog(phaseDb.db, {
461
- agentId: 'manager',
462
- storyId: pr.story_id || undefined,
463
- eventType: 'PR_MERGE_SKIPPED',
464
- status: 'warn',
465
- message: `Skipped auto-merge of PR #${pr.github_pr_number}: CI checks are failing (not pre-existing on base branch)`,
466
- metadata: { pr_id: pr.id },
467
- });
468
- },
469
- () => phaseDb.save()
470
- );
454
+ await phaseDb.provider.withTransaction(async () => {
455
+ await updatePullRequest(phaseDb.provider, pr.id, { status: 'approved' });
456
+ await createLog(phaseDb.provider, {
457
+ agentId: 'manager',
458
+ storyId: pr.story_id || undefined,
459
+ eventType: 'PR_MERGE_SKIPPED',
460
+ status: 'warn',
461
+ message: `Skipped auto-merge of PR #${pr.github_pr_number}: CI checks are failing (not pre-existing on base branch)`,
462
+ metadata: { pr_id: pr.id },
463
+ });
464
+ });
465
+ phaseDb.save();
471
466
  break;
472
467
  }
473
468
 
474
469
  case 'ci_bypassed': {
475
470
  const storyId = pr.story_id;
476
471
  const bypassedChecks = result.outcome.bypassedChecks;
477
- await withTransaction(
478
- phaseDb.db,
479
- () => {
480
- updatePullRequest(phaseDb.db, pr.id, { status: 'merged' });
481
- if (storyId) {
482
- updateStory(phaseDb.db, storyId, { status: 'merged' });
483
- const story = getStoryById(phaseDb.db, storyId);
484
- if (story?.assigned_agent_id) {
485
- const agent = getAgentById(phaseDb.db, story.assigned_agent_id);
486
- if (agent && agent.current_story_id === storyId) {
487
- updateAgent(phaseDb.db, agent.id, { currentStoryId: null, status: 'idle' });
488
- }
472
+ await phaseDb.provider.withTransaction(async () => {
473
+ await updatePullRequest(phaseDb.provider, pr.id, { status: 'merged' });
474
+ if (storyId) {
475
+ await updateStory(phaseDb.provider, storyId, { status: 'merged' });
476
+ const story = await getStoryById(phaseDb.provider, storyId);
477
+ if (story?.assigned_agent_id) {
478
+ const agent = await getAgentById(phaseDb.provider, story.assigned_agent_id);
479
+ if (agent && agent.current_story_id === storyId) {
480
+ await updateAgent(phaseDb.provider, agent.id, {
481
+ currentStoryId: null,
482
+ status: 'idle',
483
+ });
489
484
  }
490
- createLog(phaseDb.db, {
491
- agentId: 'manager',
492
- storyId,
493
- eventType: 'STORY_MERGED',
494
- message: `Story auto-merged from GitHub PR #${pr.github_pr_number} (bypassed pre-existing CI failures: ${bypassedChecks.join(', ')})`,
495
- });
496
- } else {
497
- createLog(phaseDb.db, {
498
- agentId: 'manager',
499
- eventType: 'PR_MERGED',
500
- message: `PR ${pr.id} auto-merged (GitHub PR #${pr.github_pr_number}, bypassed pre-existing CI failures: ${bypassedChecks.join(', ')})`,
501
- metadata: { pr_id: pr.id },
502
- });
503
485
  }
504
- },
505
- () => phaseDb.save()
506
- );
486
+ await createLog(phaseDb.provider, {
487
+ agentId: 'manager',
488
+ storyId,
489
+ eventType: 'STORY_MERGED',
490
+ message: `Story auto-merged from GitHub PR #${pr.github_pr_number} (bypassed pre-existing CI failures: ${bypassedChecks.join(', ')})`,
491
+ });
492
+ } else {
493
+ await createLog(phaseDb.provider, {
494
+ agentId: 'manager',
495
+ eventType: 'PR_MERGED',
496
+ message: `PR ${pr.id} auto-merged (GitHub PR #${pr.github_pr_number}, bypassed pre-existing CI failures: ${bypassedChecks.join(', ')})`,
497
+ metadata: { pr_id: pr.id },
498
+ });
499
+ }
500
+ });
501
+ phaseDb.save();
507
502
 
508
503
  mergedCount++;
509
504
 
510
505
  if (storyId) {
511
- postLifecycleComment(phaseDb.db, paths.hiveDir, config, storyId, 'merged').catch(() => {
512
- /* non-fatal */
513
- });
514
- syncStatusForStory(root, phaseDb.db, storyId, 'merged');
506
+ postLifecycleComment(phaseDb.provider, paths.hiveDir, config, storyId, 'merged').catch(
507
+ () => {
508
+ /* non-fatal */
509
+ }
510
+ );
511
+ syncStatusForStory(root, phaseDb.provider, storyId, 'merged');
515
512
  }
516
513
  break;
517
514
  }
518
515
 
519
516
  case 'merged': {
520
517
  const storyId = pr.story_id;
521
- await withTransaction(
522
- phaseDb.db,
523
- () => {
524
- updatePullRequest(phaseDb.db, pr.id, { status: 'merged' });
525
- if (storyId) {
526
- updateStory(phaseDb.db, storyId, { status: 'merged' });
527
- const story = getStoryById(phaseDb.db, storyId);
528
- if (story?.assigned_agent_id) {
529
- const agent = getAgentById(phaseDb.db, story.assigned_agent_id);
530
- if (agent && agent.current_story_id === storyId) {
531
- updateAgent(phaseDb.db, agent.id, { currentStoryId: null, status: 'idle' });
532
- }
518
+ await phaseDb.provider.withTransaction(async () => {
519
+ await updatePullRequest(phaseDb.provider, pr.id, { status: 'merged' });
520
+ if (storyId) {
521
+ await updateStory(phaseDb.provider, storyId, { status: 'merged' });
522
+ const story = await getStoryById(phaseDb.provider, storyId);
523
+ if (story?.assigned_agent_id) {
524
+ const agent = await getAgentById(phaseDb.provider, story.assigned_agent_id);
525
+ if (agent && agent.current_story_id === storyId) {
526
+ await updateAgent(phaseDb.provider, agent.id, {
527
+ currentStoryId: null,
528
+ status: 'idle',
529
+ });
533
530
  }
534
- createLog(phaseDb.db, {
535
- agentId: 'manager',
536
- storyId,
537
- eventType: 'STORY_MERGED',
538
- message: `Story auto-merged from GitHub PR #${pr.github_pr_number}`,
539
- });
540
- } else {
541
- createLog(phaseDb.db, {
542
- agentId: 'manager',
543
- eventType: 'PR_MERGED',
544
- message: `PR ${pr.id} auto-merged (GitHub PR #${pr.github_pr_number})`,
545
- metadata: { pr_id: pr.id },
546
- });
547
531
  }
548
- },
549
- () => phaseDb.save()
550
- );
532
+ await createLog(phaseDb.provider, {
533
+ agentId: 'manager',
534
+ storyId,
535
+ eventType: 'STORY_MERGED',
536
+ message: `Story auto-merged from GitHub PR #${pr.github_pr_number}`,
537
+ });
538
+ } else {
539
+ await createLog(phaseDb.provider, {
540
+ agentId: 'manager',
541
+ eventType: 'PR_MERGED',
542
+ message: `PR ${pr.id} auto-merged (GitHub PR #${pr.github_pr_number})`,
543
+ metadata: { pr_id: pr.id },
544
+ });
545
+ }
546
+ });
547
+ phaseDb.save();
551
548
 
552
549
  mergedCount++;
553
550
 
554
551
  if (storyId) {
555
- postLifecycleComment(phaseDb.db, paths.hiveDir, config, storyId, 'merged').catch(() => {
556
- /* non-fatal */
557
- });
558
- syncStatusForStory(root, phaseDb.db, storyId, 'merged');
552
+ postLifecycleComment(phaseDb.provider, paths.hiveDir, config, storyId, 'merged').catch(
553
+ () => {
554
+ /* non-fatal */
555
+ }
556
+ );
557
+ syncStatusForStory(root, phaseDb.provider, storyId, 'merged');
559
558
  }
560
559
  break;
561
560
  }
562
561
 
563
562
  case 'auto_merge_pending': {
564
- createLog(phaseDb.db, {
563
+ await createLog(phaseDb.provider, {
565
564
  agentId: 'manager',
566
565
  storyId: pr.story_id || undefined,
567
566
  eventType: 'PR_MERGE_SKIPPED',
@@ -574,40 +573,34 @@ export async function autoMergeApprovedPRs(
574
573
 
575
574
  case 'branch_updated': {
576
575
  // Reset to 'approved' so the PR is retried on the next cycle once CI passes
577
- await withTransaction(
578
- phaseDb.db,
579
- () => {
580
- updatePullRequest(phaseDb.db, pr.id, { status: 'approved' });
581
- createLog(phaseDb.db, {
582
- agentId: 'manager',
583
- storyId: pr.story_id || undefined,
584
- eventType: 'PR_MERGE_SKIPPED',
585
- status: 'info',
586
- message: `Updated stale branch for PR #${pr.github_pr_number} (was behind base branch), will retry merge`,
587
- metadata: { pr_id: pr.id },
588
- });
589
- },
590
- () => phaseDb.save()
591
- );
576
+ await phaseDb.provider.withTransaction(async () => {
577
+ await updatePullRequest(phaseDb.provider, pr.id, { status: 'approved' });
578
+ await createLog(phaseDb.provider, {
579
+ agentId: 'manager',
580
+ storyId: pr.story_id || undefined,
581
+ eventType: 'PR_MERGE_SKIPPED',
582
+ status: 'info',
583
+ message: `Updated stale branch for PR #${pr.github_pr_number} (was behind base branch), will retry merge`,
584
+ metadata: { pr_id: pr.id },
585
+ });
586
+ });
587
+ phaseDb.save();
592
588
  break;
593
589
  }
594
590
 
595
591
  case 'merge_failed': {
596
- await withTransaction(
597
- phaseDb.db,
598
- () => {
599
- updatePullRequest(phaseDb.db, pr.id, { status: 'approved' });
600
- createLog(phaseDb.db, {
601
- agentId: 'manager',
602
- storyId: pr.story_id || undefined,
603
- eventType: 'PR_MERGE_FAILED',
604
- status: 'error',
605
- message: `Failed to auto-merge PR ${pr.id} (GitHub PR #${pr.github_pr_number}): ${result.outcome.type === 'merge_failed' ? result.outcome.error.message : 'Unknown error'}`,
606
- metadata: { pr_id: pr.id },
607
- });
608
- },
609
- () => phaseDb.save()
610
- );
592
+ await phaseDb.provider.withTransaction(async () => {
593
+ await updatePullRequest(phaseDb.provider, pr.id, { status: 'approved' });
594
+ await createLog(phaseDb.provider, {
595
+ agentId: 'manager',
596
+ storyId: pr.story_id || undefined,
597
+ eventType: 'PR_MERGE_FAILED',
598
+ status: 'error',
599
+ message: `Failed to auto-merge PR ${pr.id} (GitHub PR #${pr.github_pr_number}): ${result.outcome.type === 'merge_failed' ? result.outcome.error.message : 'Unknown error'}`,
600
+ metadata: { pr_id: pr.id },
601
+ });
602
+ });
603
+ phaseDb.save();
611
604
  break;
612
605
  }
613
606
  }
@@ -2,10 +2,6 @@
2
2
 
3
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
4
4
 
5
- vi.mock('../db/client.js', () => ({
6
- queryOne: vi.fn(),
7
- }));
8
-
9
5
  vi.mock('../db/queries/agents.js', () => ({
10
6
  getAgentById: vi.fn(),
11
7
  }));
@@ -18,7 +14,6 @@ vi.mock('../db/queries/stories.js', () => ({
18
14
  getStoryById: vi.fn(),
19
15
  }));
20
16
 
21
- import { queryOne } from '../db/client.js';
22
17
  import { getAgentById } from '../db/queries/agents.js';
23
18
  import { getPullRequestById } from '../db/queries/pull-requests.js';
24
19
  import { getStoryById } from '../db/queries/stories.js';
@@ -29,83 +24,86 @@ import {
29
24
  requireStory,
30
25
  } from './cli-helpers.js';
31
26
 
32
- const mockDb = {} as any;
27
+ const mockDb = {
28
+ queryOne: vi.fn(),
29
+ } as any;
33
30
 
34
31
  beforeEach(() => {
35
32
  vi.clearAllMocks();
36
33
  });
37
34
 
38
35
  describe('requireStory', () => {
39
- it('returns the story when found', () => {
36
+ it('returns the story when found', async () => {
40
37
  const story = { id: 'STORY-1', title: 'Test' };
41
- vi.mocked(getStoryById).mockReturnValue(story as any);
38
+ vi.mocked(getStoryById).mockResolvedValue(story as any);
42
39
 
43
- const result = requireStory(mockDb, 'STORY-1');
40
+ const result = await requireStory(mockDb, 'STORY-1');
44
41
 
45
42
  expect(result).toBe(story);
46
43
  expect(getStoryById).toHaveBeenCalledWith(mockDb, 'STORY-1');
47
44
  });
48
45
 
49
- it('exits with error when story not found', () => {
50
- vi.mocked(getStoryById).mockReturnValue(undefined);
46
+ it('exits with error when story not found', async () => {
47
+ vi.mocked(getStoryById).mockResolvedValue(undefined);
51
48
  const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
52
49
  const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
53
50
  throw new Error('process.exit called');
54
51
  }) as any);
55
52
 
56
- expect(() => requireStory(mockDb, 'STORY-99')).toThrow('process.exit called');
53
+ await expect(requireStory(mockDb, 'STORY-99')).rejects.toThrow('process.exit called');
57
54
  expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Story not found: STORY-99'));
58
55
  expect(exitSpy).toHaveBeenCalledWith(1);
59
56
  });
60
57
  });
61
58
 
62
59
  describe('requireAgent', () => {
63
- it('returns the agent when found', () => {
60
+ it('returns the agent when found', async () => {
64
61
  const agent = { id: 'agent-1', type: 'senior' };
65
- vi.mocked(getAgentById).mockReturnValue(agent as any);
62
+ vi.mocked(getAgentById).mockResolvedValue(agent as any);
66
63
 
67
- const result = requireAgent(mockDb, 'agent-1');
64
+ const result = await requireAgent(mockDb, 'agent-1');
68
65
 
69
66
  expect(result).toBe(agent);
70
67
  expect(getAgentById).toHaveBeenCalledWith(mockDb, 'agent-1');
71
68
  });
72
69
 
73
- it('exits with error when agent not found', () => {
74
- vi.mocked(getAgentById).mockReturnValue(undefined);
70
+ it('exits with error when agent not found', async () => {
71
+ vi.mocked(getAgentById).mockResolvedValue(undefined);
75
72
  const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
76
73
  const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
77
74
  throw new Error('process.exit called');
78
75
  }) as any);
79
76
 
80
- expect(() => requireAgent(mockDb, 'agent-99')).toThrow('process.exit called');
77
+ await expect(requireAgent(mockDb, 'agent-99')).rejects.toThrow('process.exit called');
81
78
  expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Agent not found: agent-99'));
82
79
  expect(exitSpy).toHaveBeenCalledWith(1);
83
80
  });
84
81
  });
85
82
 
86
83
  describe('requireAgentBySession', () => {
87
- it('returns the agent when session matches', () => {
84
+ it('returns the agent when session matches', async () => {
88
85
  const agent = { id: 'agent-1', tmux_session: 'hive-senior-team' };
89
- vi.mocked(queryOne).mockReturnValue(agent as any);
86
+ mockDb.queryOne.mockResolvedValue(agent as any);
90
87
 
91
- const result = requireAgentBySession(mockDb, 'hive-senior-team');
88
+ const result = await requireAgentBySession(mockDb, 'hive-senior-team');
92
89
 
93
90
  expect(result).toBe(agent);
94
- expect(queryOne).toHaveBeenCalledWith(
95
- mockDb,
91
+ expect(mockDb.queryOne).toHaveBeenCalledWith(
96
92
  expect.stringContaining("status != 'terminated'"),
97
93
  ['hive-senior-team']
98
94
  );
99
95
  });
100
96
 
101
- it('exits with error when session not found', () => {
102
- vi.mocked(queryOne).mockReturnValue(undefined);
97
+ it('exits with error when session not found', async () => {
98
+ mockDb.queryOne.mockResolvedValue(undefined);
103
99
  const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
104
100
  const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
105
101
  throw new Error('process.exit called');
106
102
  }) as any);
107
103
 
108
- expect(() => requireAgentBySession(mockDb, 'unknown-session')).toThrow('process.exit called');
104
+ await expect(requireAgentBySession(mockDb, 'unknown-session')).rejects.toThrow(
105
+ 'process.exit called'
106
+ );
109
107
  expect(errorSpy).toHaveBeenCalledWith(
110
108
  expect.stringContaining('No agent found with session: unknown-session')
111
109
  );
@@ -114,24 +112,24 @@ describe('requireAgentBySession', () => {
114
112
  });
115
113
 
116
114
  describe('requirePullRequest', () => {
117
- it('returns the PR when found', () => {
115
+ it('returns the PR when found', async () => {
118
116
  const pr = { id: 'pr-1', branch_name: 'feature/test' };
119
- vi.mocked(getPullRequestById).mockReturnValue(pr as any);
117
+ vi.mocked(getPullRequestById).mockResolvedValue(pr as any);
120
118
 
121
- const result = requirePullRequest(mockDb, 'pr-1');
119
+ const result = await requirePullRequest(mockDb, 'pr-1');
122
120
 
123
121
  expect(result).toBe(pr);
124
122
  expect(getPullRequestById).toHaveBeenCalledWith(mockDb, 'pr-1');
125
123
  });
126
124
 
127
- it('exits with error when PR not found', () => {
128
- vi.mocked(getPullRequestById).mockReturnValue(undefined);
125
+ it('exits with error when PR not found', async () => {
126
+ vi.mocked(getPullRequestById).mockResolvedValue(undefined);
129
127
  const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
130
128
  const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
131
129
  throw new Error('process.exit called');
132
130
  }) as any);
133
131
 
134
- expect(() => requirePullRequest(mockDb, 'pr-99')).toThrow('process.exit called');
132
+ await expect(requirePullRequest(mockDb, 'pr-99')).rejects.toThrow('process.exit called');
135
133
  expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('PR not found: pr-99'));
136
134
  expect(exitSpy).toHaveBeenCalledWith(1);
137
135
  });
@@ -1,9 +1,8 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
 
3
3
  import chalk from 'chalk';
4
- import type { Database } from 'sql.js';
5
4
  import type { AgentRow, PullRequestRow, StoryRow } from '../db/client.js';
6
- import { queryOne } from '../db/client.js';
5
+ import type { DatabaseProvider } from '../db/provider.js';
7
6
  import { getAgentById } from '../db/queries/agents.js';
8
7
  import { getPullRequestById } from '../db/queries/pull-requests.js';
9
8
  import { getStoryById } from '../db/queries/stories.js';
@@ -12,8 +11,8 @@ import { normalizeStoryId } from './story-id.js';
12
11
  /**
13
12
  * Require a story by ID, exit with error if not found.
14
13
  */
15
- export function requireStory(db: Database, storyId: string): StoryRow {
16
- const story = getStoryById(db, normalizeStoryId(storyId));
14
+ export async function requireStory(db: DatabaseProvider, storyId: string): Promise<StoryRow> {
15
+ const story = await getStoryById(db, normalizeStoryId(storyId));
17
16
  if (!story) {
18
17
  console.error(chalk.red(`Story not found: ${storyId}`));
19
18
  process.exit(1);
@@ -24,8 +23,8 @@ export function requireStory(db: Database, storyId: string): StoryRow {
24
23
  /**
25
24
  * Require an agent by ID, exit with error if not found.
26
25
  */
27
- export function requireAgent(db: Database, agentId: string): AgentRow {
28
- const agent = getAgentById(db, agentId);
26
+ export async function requireAgent(db: DatabaseProvider, agentId: string): Promise<AgentRow> {
27
+ const agent = await getAgentById(db, agentId);
29
28
  if (!agent) {
30
29
  console.error(chalk.red(`Agent not found: ${agentId}`));
31
30
  process.exit(1);
@@ -36,9 +35,11 @@ export function requireAgent(db: Database, agentId: string): AgentRow {
36
35
  /**
37
36
  * Require an active agent by tmux session name, exit with error if not found or terminated.
38
37
  */
39
- export function requireAgentBySession(db: Database, session: string): AgentRow {
40
- const agent = queryOne<AgentRow>(
41
- db,
38
+ export async function requireAgentBySession(
39
+ db: DatabaseProvider,
40
+ session: string
41
+ ): Promise<AgentRow> {
42
+ const agent = await db.queryOne<AgentRow>(
42
43
  "SELECT * FROM agents WHERE tmux_session = ? AND status != 'terminated'",
43
44
  [session]
44
45
  );
@@ -52,8 +53,11 @@ export function requireAgentBySession(db: Database, session: string): AgentRow {
52
53
  /**
53
54
  * Require a pull request by ID, exit with error if not found.
54
55
  */
55
- export function requirePullRequest(db: Database, prId: string): PullRequestRow {
56
- const pr = getPullRequestById(db, prId);
56
+ export async function requirePullRequest(
57
+ db: DatabaseProvider,
58
+ prId: string
59
+ ): Promise<PullRequestRow> {
60
+ const pr = await getPullRequestById(db, prId);
57
61
  if (!pr) {
58
62
  console.error(chalk.red(`PR not found: ${prId}`));
59
63
  process.exit(1);
@@ -99,6 +99,7 @@ describe('paths utility', () => {
99
99
  hiveDir: join(rootDir, '.hive'),
100
100
  dbPath: join(rootDir, '.hive', 'hive.db'),
101
101
  configPath: join(rootDir, '.hive', 'hive.config.yaml'),
102
+ workspaceIdPath: join(rootDir, '.hive', 'workspace.id'),
102
103
  agentsDir: join(rootDir, '.hive', 'agents'),
103
104
  logsDir: join(rootDir, '.hive', 'logs'),
104
105
  reposDir: join(rootDir, 'repos'),