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
@@ -1,7 +1,7 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
 
3
- import type { Database } from 'sql.js';
4
- import { queryAll, queryOne, run, type AgentLogRow } from '../client.js';
3
+ import { type AgentLogRow } from '../client.js';
4
+ import type { DatabaseProvider } from '../provider.js';
5
5
 
6
6
  export type { AgentLogRow };
7
7
 
@@ -91,23 +91,22 @@ function inferAgentType(
91
91
  return 'tech_lead';
92
92
  }
93
93
 
94
- function getAgentColumnNames(db: Database): Set<string> {
95
- const result = db.exec('PRAGMA table_info(agents)');
96
- if (result.length === 0) return new Set<string>();
97
-
94
+ async function getAgentColumnNames(provider: DatabaseProvider): Promise<Set<string>> {
95
+ const rows = await provider.queryAll<{ name: string }>('PRAGMA table_info(agents)');
98
96
  const columnNames = new Set<string>();
99
- for (const row of result[0].values) {
100
- // PRAGMA table_info columns: cid, name, type, notnull, dflt_value, pk
101
- columnNames.add(String(row[1]));
97
+ for (const row of rows) {
98
+ columnNames.add(row.name);
102
99
  }
103
100
  return columnNames;
104
101
  }
105
102
 
106
- function ensureLogAgentExists(db: Database, agentId: string): void {
107
- const existing = queryOne<{ id: string }>(db, 'SELECT id FROM agents WHERE id = ?', [agentId]);
103
+ async function ensureLogAgentExists(provider: DatabaseProvider, agentId: string): Promise<void> {
104
+ const existing = await provider.queryOne<{ id: string }>('SELECT id FROM agents WHERE id = ?', [
105
+ agentId,
106
+ ]);
108
107
  if (existing?.id) return;
109
108
 
110
- const columns = getAgentColumnNames(db);
109
+ const columns = await getAgentColumnNames(provider);
111
110
  const now = new Date().toISOString();
112
111
  const insertColumns: string[] = ['id'];
113
112
  const insertValues: (string | null)[] = [agentId];
@@ -134,8 +133,7 @@ function ensureLogAgentExists(db: Database, agentId: string): void {
134
133
  }
135
134
 
136
135
  const placeholders = insertColumns.map(() => '?').join(', ');
137
- run(
138
- db,
136
+ await provider.run(
139
137
  `
140
138
  INSERT OR IGNORE INTO agents (${insertColumns.join(', ')})
141
139
  VALUES (${placeholders})
@@ -144,17 +142,18 @@ function ensureLogAgentExists(db: Database, agentId: string): void {
144
142
  );
145
143
  }
146
144
 
147
- function resolveLogAgentId(db: Database, rawAgentId: string): string {
148
- const direct = queryOne<{ id: string }>(db, 'SELECT id FROM agents WHERE id = ?', [rawAgentId]);
145
+ async function resolveLogAgentId(provider: DatabaseProvider, rawAgentId: string): Promise<string> {
146
+ const direct = await provider.queryOne<{ id: string }>('SELECT id FROM agents WHERE id = ?', [
147
+ rawAgentId,
148
+ ]);
149
149
  if (direct?.id) return direct.id;
150
150
 
151
- const columns = getAgentColumnNames(db);
151
+ const columns = await getAgentColumnNames(provider);
152
152
 
153
153
  // Many call-sites provide tmux session names (for example: "hive-qa-team-1").
154
154
  // Prefer resolving those back to canonical agent IDs so logs remain linked.
155
155
  if (columns.has('tmux_session')) {
156
- const bySession = queryOne<{ id: string }>(
157
- db,
156
+ const bySession = await provider.queryOne<{ id: string }>(
158
157
  `SELECT id FROM agents WHERE tmux_session = ?${
159
158
  columns.has('updated_at') ? ' ORDER BY updated_at DESC' : ''
160
159
  } LIMIT 1`,
@@ -165,24 +164,31 @@ function resolveLogAgentId(db: Database, rawAgentId: string): string {
165
164
 
166
165
  // Last resort: create a lightweight synthetic agent row for system/session actors
167
166
  // like "manager" or "scheduler" so FK constraints cannot fail logging.
168
- ensureLogAgentExists(db, rawAgentId);
167
+ await ensureLogAgentExists(provider, rawAgentId);
169
168
  return rawAgentId;
170
169
  }
171
170
 
172
- function resolveLogStoryId(db: Database, storyId?: string | null): string | null {
171
+ async function resolveLogStoryId(
172
+ provider: DatabaseProvider,
173
+ storyId?: string | null
174
+ ): Promise<string | null> {
173
175
  if (!storyId) return null;
174
- const story = queryOne<{ id: string }>(db, 'SELECT id FROM stories WHERE id = ?', [storyId]);
176
+ const story = await provider.queryOne<{ id: string }>('SELECT id FROM stories WHERE id = ?', [
177
+ storyId,
178
+ ]);
175
179
  return story?.id || null;
176
180
  }
177
181
 
178
- export function createLog(db: Database, input: CreateLogInput): AgentLogRow {
182
+ export async function createLog(
183
+ provider: DatabaseProvider,
184
+ input: CreateLogInput
185
+ ): Promise<AgentLogRow> {
179
186
  const metadata = input.metadata ? JSON.stringify(input.metadata) : null;
180
187
  const now = new Date().toISOString();
181
- const resolvedAgentId = resolveLogAgentId(db, input.agentId);
182
- const resolvedStoryId = resolveLogStoryId(db, input.storyId);
188
+ const resolvedAgentId = await resolveLogAgentId(provider, input.agentId);
189
+ const resolvedStoryId = await resolveLogStoryId(provider, input.storyId);
183
190
 
184
- run(
185
- db,
191
+ await provider.run(
186
192
  `
187
193
  INSERT INTO agent_logs (agent_id, story_id, event_type, status, message, metadata, timestamp)
188
194
  VALUES (?, ?, ?, ?, ?, ?, ?)
@@ -199,17 +205,23 @@ export function createLog(db: Database, input: CreateLogInput): AgentLogRow {
199
205
  );
200
206
 
201
207
  // Get the last inserted row
202
- const result = queryOne<{ id: number }>(db, 'SELECT last_insert_rowid() as id');
203
- return getLogById(db, result?.id || 0)!;
208
+ const result = await provider.queryOne<{ id: number }>('SELECT last_insert_rowid() as id');
209
+ return (await getLogById(provider, result?.id || 0))!;
204
210
  }
205
211
 
206
- export function getLogById(db: Database, id: number): AgentLogRow | undefined {
207
- return queryOne<AgentLogRow>(db, 'SELECT * FROM agent_logs WHERE id = ?', [id]);
212
+ export async function getLogById(
213
+ provider: DatabaseProvider,
214
+ id: number
215
+ ): Promise<AgentLogRow | undefined> {
216
+ return await provider.queryOne<AgentLogRow>('SELECT * FROM agent_logs WHERE id = ?', [id]);
208
217
  }
209
218
 
210
- export function getLogsByAgent(db: Database, agentId: string, limit = 100): AgentLogRow[] {
211
- return queryAll<AgentLogRow>(
212
- db,
219
+ export async function getLogsByAgent(
220
+ provider: DatabaseProvider,
221
+ agentId: string,
222
+ limit = 100
223
+ ): Promise<AgentLogRow[]> {
224
+ return await provider.queryAll<AgentLogRow>(
213
225
  `
214
226
  SELECT * FROM agent_logs
215
227
  WHERE agent_id = ?
@@ -220,9 +232,11 @@ export function getLogsByAgent(db: Database, agentId: string, limit = 100): Agen
220
232
  );
221
233
  }
222
234
 
223
- export function getLogsByStory(db: Database, storyId: string): AgentLogRow[] {
224
- return queryAll<AgentLogRow>(
225
- db,
235
+ export async function getLogsByStory(
236
+ provider: DatabaseProvider,
237
+ storyId: string
238
+ ): Promise<AgentLogRow[]> {
239
+ return await provider.queryAll<AgentLogRow>(
226
240
  `
227
241
  SELECT * FROM agent_logs
228
242
  WHERE story_id = ?
@@ -232,9 +246,12 @@ export function getLogsByStory(db: Database, storyId: string): AgentLogRow[] {
232
246
  );
233
247
  }
234
248
 
235
- export function getLogsByEventType(db: Database, eventType: EventType, limit = 100): AgentLogRow[] {
236
- return queryAll<AgentLogRow>(
237
- db,
249
+ export async function getLogsByEventType(
250
+ provider: DatabaseProvider,
251
+ eventType: EventType,
252
+ limit = 100
253
+ ): Promise<AgentLogRow[]> {
254
+ return await provider.queryAll<AgentLogRow>(
238
255
  `
239
256
  SELECT * FROM agent_logs
240
257
  WHERE event_type = ?
@@ -245,9 +262,11 @@ export function getLogsByEventType(db: Database, eventType: EventType, limit = 1
245
262
  );
246
263
  }
247
264
 
248
- export function getRecentLogs(db: Database, limit = 50): AgentLogRow[] {
249
- return queryAll<AgentLogRow>(
250
- db,
265
+ export async function getRecentLogs(
266
+ provider: DatabaseProvider,
267
+ limit = 50
268
+ ): Promise<AgentLogRow[]> {
269
+ return await provider.queryAll<AgentLogRow>(
251
270
  `
252
271
  SELECT * FROM agent_logs
253
272
  ORDER BY timestamp DESC
@@ -257,9 +276,11 @@ export function getRecentLogs(db: Database, limit = 50): AgentLogRow[] {
257
276
  );
258
277
  }
259
278
 
260
- export function getLogsSince(db: Database, since: string): AgentLogRow[] {
261
- return queryAll<AgentLogRow>(
262
- db,
279
+ export async function getLogsSince(
280
+ provider: DatabaseProvider,
281
+ since: string
282
+ ): Promise<AgentLogRow[]> {
283
+ return await provider.queryAll<AgentLogRow>(
263
284
  `
264
285
  SELECT * FROM agent_logs
265
286
  WHERE timestamp > ?
@@ -269,9 +290,11 @@ export function getLogsSince(db: Database, since: string): AgentLogRow[] {
269
290
  );
270
291
  }
271
292
 
272
- export function countQaFailuresByStory(db: Database, storyId: string): number {
273
- const result = queryOne<{ count: number }>(
274
- db,
293
+ export async function countQaFailuresByStory(
294
+ provider: DatabaseProvider,
295
+ storyId: string
296
+ ): Promise<number> {
297
+ const result = await provider.queryOne<{ count: number }>(
275
298
  `
276
299
  SELECT COUNT(*) as count
277
300
  FROM agent_logs
@@ -282,21 +305,23 @@ export function countQaFailuresByStory(db: Database, storyId: string): number {
282
305
  return result?.count || 0;
283
306
  }
284
307
 
285
- export function pruneOldLogs(db: Database, retentionDays: number): number {
308
+ export async function pruneOldLogs(
309
+ provider: DatabaseProvider,
310
+ retentionDays: number
311
+ ): Promise<number> {
286
312
  const cutoffDate = new Date();
287
313
  cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
288
314
  const cutoff = cutoffDate.toISOString();
289
315
 
290
316
  // Get count before delete
291
- const before = queryOne<{ count: number }>(
292
- db,
317
+ const before = await provider.queryOne<{ count: number }>(
293
318
  `
294
319
  SELECT COUNT(*) as count FROM agent_logs WHERE timestamp < ?
295
320
  `,
296
321
  [cutoff]
297
322
  );
298
323
 
299
- run(db, `DELETE FROM agent_logs WHERE timestamp < ?`, [cutoff]);
324
+ await provider.run(`DELETE FROM agent_logs WHERE timestamp < ?`, [cutoff]);
300
325
 
301
326
  return before?.count || 0;
302
327
  }
@@ -1,8 +1,7 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
 
3
- import type { Database } from 'sql.js';
4
3
  import { beforeEach, describe, expect, it } from 'vitest';
5
- import { run } from '../client.js';
4
+ import { SqliteProvider } from '../provider.js';
6
5
  import {
7
6
  getAllPendingMessages,
8
7
  getMessageById,
@@ -12,10 +11,11 @@ import {
12
11
  import { createTestDatabase } from './test-helpers.js';
13
12
 
14
13
  describe('messages queries', () => {
15
- let db: Database;
14
+ let db: SqliteProvider;
16
15
 
17
16
  beforeEach(async () => {
18
- db = await createTestDatabase();
17
+ const rawDb = await createTestDatabase();
18
+ db = new SqliteProvider(rawDb);
19
19
  });
20
20
 
21
21
  // Helper function to create a test message
@@ -28,8 +28,7 @@ describe('messages queries', () => {
28
28
  subject?: string | null
29
29
  ): void {
30
30
  const now = new Date().toISOString();
31
- run(
32
- db,
31
+ db.db.run(
33
32
  `
34
33
  INSERT INTO messages (id, from_session, to_session, subject, body, status, created_at)
35
34
  VALUES (?, ?, ?, ?, ?, ?, ?)
@@ -39,12 +38,12 @@ describe('messages queries', () => {
39
38
  }
40
39
 
41
40
  describe('getUnreadMessages', () => {
42
- it('should return unread messages for a session', () => {
41
+ it('should return unread messages for a session', async () => {
43
42
  createMessage('msg1', 'session-a', 'session-b', 'Message 1', 'pending');
44
43
  createMessage('msg2', 'session-a', 'session-b', 'Message 2', 'pending');
45
44
  createMessage('msg3', 'session-a', 'session-b', 'Message 3', 'read');
46
45
 
47
- const unread = getUnreadMessages(db, 'session-b');
46
+ const unread = await getUnreadMessages(db, 'session-b');
48
47
 
49
48
  expect(unread).toHaveLength(2);
50
49
  expect(unread.map(m => m.id)).toContain('msg1');
@@ -52,21 +51,21 @@ describe('messages queries', () => {
52
51
  expect(unread.map(m => m.id)).not.toContain('msg3');
53
52
  });
54
53
 
55
- it('should return empty array when no unread messages', () => {
54
+ it('should return empty array when no unread messages', async () => {
56
55
  createMessage('msg1', 'session-a', 'session-b', 'Message 1', 'read');
57
56
 
58
- const unread = getUnreadMessages(db, 'session-b');
57
+ const unread = await getUnreadMessages(db, 'session-b');
59
58
 
60
59
  expect(unread).toEqual([]);
61
60
  });
62
61
 
63
- it('should order messages by created_at ASC', () => {
62
+ it('should order messages by created_at ASC', async () => {
64
63
  // Create messages with slight delays to ensure ordering
65
64
  createMessage('msg1', 'session-a', 'session-b', 'First', 'pending');
66
65
  createMessage('msg2', 'session-a', 'session-b', 'Second', 'pending');
67
66
  createMessage('msg3', 'session-a', 'session-b', 'Third', 'pending');
68
67
 
69
- const unread = getUnreadMessages(db, 'session-b');
68
+ const unread = await getUnreadMessages(db, 'session-b');
70
69
 
71
70
  expect(unread).toHaveLength(3);
72
71
  expect(unread[0].id).toBe('msg1');
@@ -74,12 +73,12 @@ describe('messages queries', () => {
74
73
  expect(unread[2].id).toBe('msg3');
75
74
  });
76
75
 
77
- it('should filter by recipient session', () => {
76
+ it('should filter by recipient session', async () => {
78
77
  createMessage('msg1', 'session-a', 'session-b', 'For B', 'pending');
79
78
  createMessage('msg2', 'session-a', 'session-c', 'For C', 'pending');
80
79
 
81
- const unreadB = getUnreadMessages(db, 'session-b');
82
- const unreadC = getUnreadMessages(db, 'session-c');
80
+ const unreadB = await getUnreadMessages(db, 'session-b');
81
+ const unreadC = await getUnreadMessages(db, 'session-c');
83
82
 
84
83
  expect(unreadB).toHaveLength(1);
85
84
  expect(unreadB[0].id).toBe('msg1');
@@ -89,43 +88,43 @@ describe('messages queries', () => {
89
88
  });
90
89
 
91
90
  describe('markMessageRead', () => {
92
- it('should mark a pending message as read', () => {
91
+ it('should mark a pending message as read', async () => {
93
92
  createMessage('msg1', 'session-a', 'session-b', 'Message', 'pending');
94
93
 
95
- markMessageRead(db, 'msg1');
94
+ await markMessageRead(db, 'msg1');
96
95
 
97
- const message = getMessageById(db, 'msg1');
96
+ const message = await getMessageById(db, 'msg1');
98
97
  expect(message?.status).toBe('read');
99
98
  });
100
99
 
101
- it('should not affect already read messages', () => {
100
+ it('should not affect already read messages', async () => {
102
101
  createMessage('msg1', 'session-a', 'session-b', 'Message', 'read');
103
102
 
104
- markMessageRead(db, 'msg1');
103
+ await markMessageRead(db, 'msg1');
105
104
 
106
- const message = getMessageById(db, 'msg1');
105
+ const message = await getMessageById(db, 'msg1');
107
106
  expect(message?.status).toBe('read');
108
107
  });
109
108
 
110
- it('should not affect replied messages', () => {
109
+ it('should not affect replied messages', async () => {
111
110
  createMessage('msg1', 'session-a', 'session-b', 'Message', 'replied');
112
111
 
113
- markMessageRead(db, 'msg1');
112
+ await markMessageRead(db, 'msg1');
114
113
 
115
- const message = getMessageById(db, 'msg1');
114
+ const message = await getMessageById(db, 'msg1');
116
115
  expect(message?.status).toBe('replied');
117
116
  });
118
117
 
119
- it('should not throw for non-existent message', () => {
120
- expect(() => markMessageRead(db, 'non-existent-id')).not.toThrow();
118
+ it('should not throw for non-existent message', async () => {
119
+ await expect(markMessageRead(db, 'non-existent-id')).resolves.not.toThrow();
121
120
  });
122
121
  });
123
122
 
124
123
  describe('getMessageById', () => {
125
- it('should retrieve a message by ID', () => {
124
+ it('should retrieve a message by ID', async () => {
126
125
  createMessage('msg1', 'session-a', 'session-b', 'Test message', 'pending', 'Test subject');
127
126
 
128
- const message = getMessageById(db, 'msg1');
127
+ const message = await getMessageById(db, 'msg1');
129
128
 
130
129
  expect(message).toBeDefined();
131
130
  expect(message?.id).toBe('msg1');
@@ -136,15 +135,15 @@ describe('messages queries', () => {
136
135
  expect(message?.status).toBe('pending');
137
136
  });
138
137
 
139
- it('should return undefined for non-existent message', () => {
140
- const message = getMessageById(db, 'non-existent-id');
138
+ it('should return undefined for non-existent message', async () => {
139
+ const message = await getMessageById(db, 'non-existent-id');
141
140
  expect(message).toBeUndefined();
142
141
  });
143
142
 
144
- it('should handle messages without subject', () => {
143
+ it('should handle messages without subject', async () => {
145
144
  createMessage('msg1', 'session-a', 'session-b', 'Message without subject', 'pending');
146
145
 
147
- const message = getMessageById(db, 'msg1');
146
+ const message = await getMessageById(db, 'msg1');
148
147
 
149
148
  expect(message?.subject).toBeNull();
150
149
  expect(message?.body).toBe('Message without subject');
@@ -152,32 +151,32 @@ describe('messages queries', () => {
152
151
  });
153
152
 
154
153
  describe('getAllPendingMessages', () => {
155
- it('should return all pending messages across all sessions', () => {
154
+ it('should return all pending messages across all sessions', async () => {
156
155
  createMessage('msg1', 'session-a', 'session-b', 'Message 1', 'pending');
157
156
  createMessage('msg2', 'session-b', 'session-c', 'Message 2', 'pending');
158
157
  createMessage('msg3', 'session-c', 'session-a', 'Message 3', 'read');
159
158
  createMessage('msg4', 'session-a', 'session-d', 'Message 4', 'replied');
160
159
 
161
- const pending = getAllPendingMessages(db);
160
+ const pending = await getAllPendingMessages(db);
162
161
 
163
162
  expect(pending).toHaveLength(2);
164
163
  expect(pending.map(m => m.id)).toContain('msg1');
165
164
  expect(pending.map(m => m.id)).toContain('msg2');
166
165
  });
167
166
 
168
- it('should return empty array when no pending messages', () => {
167
+ it('should return empty array when no pending messages', async () => {
169
168
  createMessage('msg1', 'session-a', 'session-b', 'Message', 'read');
170
169
 
171
- const pending = getAllPendingMessages(db);
170
+ const pending = await getAllPendingMessages(db);
172
171
 
173
172
  expect(pending).toEqual([]);
174
173
  });
175
174
 
176
- it('should order by created_at ASC', () => {
175
+ it('should order by created_at ASC', async () => {
177
176
  createMessage('msg1', 'session-a', 'session-b', 'First', 'pending');
178
177
  createMessage('msg2', 'session-a', 'session-b', 'Second', 'pending');
179
178
 
180
- const pending = getAllPendingMessages(db);
179
+ const pending = await getAllPendingMessages(db);
181
180
 
182
181
  expect(pending[0].id).toBe('msg1');
183
182
  expect(pending[1].id).toBe('msg2');
@@ -185,31 +184,31 @@ describe('messages queries', () => {
185
184
  });
186
185
 
187
186
  describe('edge cases', () => {
188
- it('should handle messages with null subject', () => {
187
+ it('should handle messages with null subject', async () => {
189
188
  createMessage('msg1', 'session-a', 'session-b', 'Body text', 'pending', null);
190
189
 
191
- const message = getMessageById(db, 'msg1');
190
+ const message = await getMessageById(db, 'msg1');
192
191
  expect(message?.subject).toBeNull();
193
192
  expect(message?.body).toBe('Body text');
194
193
  });
195
194
 
196
- it('should handle messages with very long body text', () => {
195
+ it('should handle messages with very long body text', async () => {
197
196
  const longBody = 'A'.repeat(50000);
198
197
  createMessage('msg1', 'session-a', 'session-b', longBody, 'pending');
199
198
 
200
- const message = getMessageById(db, 'msg1');
199
+ const message = await getMessageById(db, 'msg1');
201
200
  expect(message?.body).toBe(longBody);
202
201
  });
203
202
 
204
- it('should handle special characters in message content', () => {
203
+ it('should handle special characters in message content', async () => {
205
204
  const specialBody = 'Message with \'quotes\' "double" and\nnewlines\ttabs';
206
205
  createMessage('msg1', 'session-a', 'session-b', specialBody, 'pending', 'Special chars');
207
206
 
208
- const message = getMessageById(db, 'msg1');
207
+ const message = await getMessageById(db, 'msg1');
209
208
  expect(message?.body).toBe(specialBody);
210
209
  });
211
210
 
212
- it('should handle session names with special characters', () => {
211
+ it('should handle session names with special characters', async () => {
213
212
  createMessage(
214
213
  'msg1',
215
214
  'session-with-dashes',
@@ -218,15 +217,14 @@ describe('messages queries', () => {
218
217
  'pending'
219
218
  );
220
219
 
221
- const unread = getUnreadMessages(db, 'session_with_underscores');
220
+ const unread = await getUnreadMessages(db, 'session_with_underscores');
222
221
  expect(unread).toHaveLength(1);
223
222
  expect(unread[0].from_session).toBe('session-with-dashes');
224
223
  });
225
224
 
226
- it('should handle reply and replied_at fields', () => {
225
+ it('should handle reply and replied_at fields', async () => {
227
226
  const now = new Date().toISOString();
228
- run(
229
- db,
227
+ db.db.run(
230
228
  `
231
229
  INSERT INTO messages (id, from_session, to_session, body, status, reply, replied_at, created_at)
232
230
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
@@ -234,7 +232,7 @@ describe('messages queries', () => {
234
232
  ['msg1', 'session-a', 'session-b', 'Original message', 'replied', 'Reply text', now, now]
235
233
  );
236
234
 
237
- const message = getMessageById(db, 'msg1');
235
+ const message = await getMessageById(db, 'msg1');
238
236
  expect(message?.status).toBe('replied');
239
237
  expect(message?.reply).toBe('Reply text');
240
238
  expect(message?.replied_at).toBeDefined();
@@ -1,7 +1,6 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
 
3
- import type { Database } from 'sql.js';
4
- import { queryAll, queryOne, run } from '../client.js';
3
+ import type { DatabaseProvider } from '../provider.js';
5
4
 
6
5
  export interface MessageRow {
7
6
  id: string;
@@ -15,9 +14,11 @@ export interface MessageRow {
15
14
  replied_at: string | null;
16
15
  }
17
16
 
18
- export function getUnreadMessages(db: Database, toSession: string): MessageRow[] {
19
- return queryAll<MessageRow>(
20
- db,
17
+ export async function getUnreadMessages(
18
+ provider: DatabaseProvider,
19
+ toSession: string
20
+ ): Promise<MessageRow[]> {
21
+ return await provider.queryAll<MessageRow>(
21
22
  `
22
23
  SELECT * FROM messages
23
24
  WHERE to_session = ? AND status = 'pending'
@@ -27,31 +28,38 @@ export function getUnreadMessages(db: Database, toSession: string): MessageRow[]
27
28
  );
28
29
  }
29
30
 
30
- export function markMessageRead(db: Database, messageId: string): void {
31
- run(db, `UPDATE messages SET status = 'read' WHERE id = ? AND status = 'pending'`, [messageId]);
31
+ export async function markMessageRead(
32
+ provider: DatabaseProvider,
33
+ messageId: string
34
+ ): Promise<void> {
35
+ await provider.run(`UPDATE messages SET status = 'read' WHERE id = ? AND status = 'pending'`, [
36
+ messageId,
37
+ ]);
32
38
  }
33
39
 
34
- export function markMessagesRead(db: Database, messageIds: string[]): void {
40
+ export async function markMessagesRead(
41
+ provider: DatabaseProvider,
42
+ messageIds: string[]
43
+ ): Promise<void> {
35
44
  if (messageIds.length === 0) return;
36
45
  const placeholders = messageIds.map(() => '?').join(',');
37
- run(
38
- db,
46
+ await provider.run(
39
47
  `UPDATE messages SET status = 'read' WHERE id IN (${placeholders}) AND status = 'pending'`,
40
48
  messageIds
41
49
  );
42
50
  }
43
51
 
44
- export function getMessageById(db: Database, id: string): MessageRow | undefined {
45
- return queryOne<MessageRow>(db, 'SELECT * FROM messages WHERE id = ?', [id]);
52
+ export async function getMessageById(
53
+ provider: DatabaseProvider,
54
+ id: string
55
+ ): Promise<MessageRow | undefined> {
56
+ return await provider.queryOne<MessageRow>('SELECT * FROM messages WHERE id = ?', [id]);
46
57
  }
47
58
 
48
- export function getAllPendingMessages(db: Database): MessageRow[] {
49
- return queryAll<MessageRow>(
50
- db,
51
- `
59
+ export async function getAllPendingMessages(provider: DatabaseProvider): Promise<MessageRow[]> {
60
+ return await provider.queryAll<MessageRow>(`
52
61
  SELECT * FROM messages
53
62
  WHERE status = 'pending'
54
63
  ORDER BY created_at ASC
55
- `
56
- );
64
+ `);
57
65
  }