hungry-ghost-hive 0.3.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 (467) hide show
  1. package/LICENSE +111 -0
  2. package/README.md +352 -0
  3. package/dist/agents/base-agent.d.ts +63 -0
  4. package/dist/agents/base-agent.d.ts.map +1 -0
  5. package/dist/agents/base-agent.js +189 -0
  6. package/dist/agents/base-agent.js.map +1 -0
  7. package/dist/agents/index.d.ts +7 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/index.js +7 -0
  10. package/dist/agents/index.js.map +1 -0
  11. package/dist/agents/intermediate.d.ts +15 -0
  12. package/dist/agents/intermediate.d.ts.map +1 -0
  13. package/dist/agents/intermediate.js +142 -0
  14. package/dist/agents/intermediate.js.map +1 -0
  15. package/dist/agents/junior.d.ts +15 -0
  16. package/dist/agents/junior.d.ts.map +1 -0
  17. package/dist/agents/junior.js +147 -0
  18. package/dist/agents/junior.js.map +1 -0
  19. package/dist/agents/qa.d.ts +23 -0
  20. package/dist/agents/qa.d.ts.map +1 -0
  21. package/dist/agents/qa.js +238 -0
  22. package/dist/agents/qa.js.map +1 -0
  23. package/dist/agents/senior.d.ts +18 -0
  24. package/dist/agents/senior.d.ts.map +1 -0
  25. package/dist/agents/senior.js +267 -0
  26. package/dist/agents/senior.js.map +1 -0
  27. package/dist/agents/tech-lead.d.ts +17 -0
  28. package/dist/agents/tech-lead.d.ts.map +1 -0
  29. package/dist/agents/tech-lead.js +274 -0
  30. package/dist/agents/tech-lead.js.map +1 -0
  31. package/dist/cli/commands/add-repo.d.ts +3 -0
  32. package/dist/cli/commands/add-repo.d.ts.map +1 -0
  33. package/dist/cli/commands/add-repo.js +84 -0
  34. package/dist/cli/commands/add-repo.js.map +1 -0
  35. package/dist/cli/commands/agents.d.ts +3 -0
  36. package/dist/cli/commands/agents.d.ts.map +1 -0
  37. package/dist/cli/commands/agents.js +214 -0
  38. package/dist/cli/commands/agents.js.map +1 -0
  39. package/dist/cli/commands/assign.d.ts +3 -0
  40. package/dist/cli/commands/assign.d.ts.map +1 -0
  41. package/dist/cli/commands/assign.js +81 -0
  42. package/dist/cli/commands/assign.js.map +1 -0
  43. package/dist/cli/commands/config.d.ts +3 -0
  44. package/dist/cli/commands/config.d.ts.map +1 -0
  45. package/dist/cli/commands/config.js +118 -0
  46. package/dist/cli/commands/config.js.map +1 -0
  47. package/dist/cli/commands/escalations.d.ts +3 -0
  48. package/dist/cli/commands/escalations.d.ts.map +1 -0
  49. package/dist/cli/commands/escalations.js +157 -0
  50. package/dist/cli/commands/escalations.js.map +1 -0
  51. package/dist/cli/commands/index.d.ts +17 -0
  52. package/dist/cli/commands/index.d.ts.map +1 -0
  53. package/dist/cli/commands/index.js +17 -0
  54. package/dist/cli/commands/index.js.map +1 -0
  55. package/dist/cli/commands/init.d.ts +3 -0
  56. package/dist/cli/commands/init.d.ts.map +1 -0
  57. package/dist/cli/commands/init.js +59 -0
  58. package/dist/cli/commands/init.js.map +1 -0
  59. package/dist/cli/commands/manager.d.ts +3 -0
  60. package/dist/cli/commands/manager.d.ts.map +1 -0
  61. package/dist/cli/commands/manager.js +775 -0
  62. package/dist/cli/commands/manager.js.map +1 -0
  63. package/dist/cli/commands/manager.test.d.ts +2 -0
  64. package/dist/cli/commands/manager.test.d.ts.map +1 -0
  65. package/dist/cli/commands/manager.test.js +45 -0
  66. package/dist/cli/commands/manager.test.js.map +1 -0
  67. package/dist/cli/commands/msg.d.ts +3 -0
  68. package/dist/cli/commands/msg.d.ts.map +1 -0
  69. package/dist/cli/commands/msg.js +190 -0
  70. package/dist/cli/commands/msg.js.map +1 -0
  71. package/dist/cli/commands/my-stories.d.ts +3 -0
  72. package/dist/cli/commands/my-stories.d.ts.map +1 -0
  73. package/dist/cli/commands/my-stories.js +174 -0
  74. package/dist/cli/commands/my-stories.js.map +1 -0
  75. package/dist/cli/commands/nuke.d.ts +3 -0
  76. package/dist/cli/commands/nuke.d.ts.map +1 -0
  77. package/dist/cli/commands/nuke.js +189 -0
  78. package/dist/cli/commands/nuke.js.map +1 -0
  79. package/dist/cli/commands/pr.d.ts +3 -0
  80. package/dist/cli/commands/pr.d.ts.map +1 -0
  81. package/dist/cli/commands/pr.js +488 -0
  82. package/dist/cli/commands/pr.js.map +1 -0
  83. package/dist/cli/commands/req.d.ts +3 -0
  84. package/dist/cli/commands/req.d.ts.map +1 -0
  85. package/dist/cli/commands/req.js +212 -0
  86. package/dist/cli/commands/req.js.map +1 -0
  87. package/dist/cli/commands/resume.d.ts +3 -0
  88. package/dist/cli/commands/resume.d.ts.map +1 -0
  89. package/dist/cli/commands/resume.js +114 -0
  90. package/dist/cli/commands/resume.js.map +1 -0
  91. package/dist/cli/commands/status.d.ts +3 -0
  92. package/dist/cli/commands/status.d.ts.map +1 -0
  93. package/dist/cli/commands/status.js +259 -0
  94. package/dist/cli/commands/status.js.map +1 -0
  95. package/dist/cli/commands/stories.d.ts +3 -0
  96. package/dist/cli/commands/stories.d.ts.map +1 -0
  97. package/dist/cli/commands/stories.js +111 -0
  98. package/dist/cli/commands/stories.js.map +1 -0
  99. package/dist/cli/commands/teams.d.ts +3 -0
  100. package/dist/cli/commands/teams.d.ts.map +1 -0
  101. package/dist/cli/commands/teams.js +137 -0
  102. package/dist/cli/commands/teams.js.map +1 -0
  103. package/dist/cli/dashboard/index.d.ts +5 -0
  104. package/dist/cli/dashboard/index.d.ts.map +1 -0
  105. package/dist/cli/dashboard/index.js +128 -0
  106. package/dist/cli/dashboard/index.js.map +1 -0
  107. package/dist/cli/dashboard/panels/activity.d.ts +5 -0
  108. package/dist/cli/dashboard/panels/activity.d.ts.map +1 -0
  109. package/dist/cli/dashboard/panels/activity.js +64 -0
  110. package/dist/cli/dashboard/panels/activity.js.map +1 -0
  111. package/dist/cli/dashboard/panels/agents.d.ts +5 -0
  112. package/dist/cli/dashboard/panels/agents.d.ts.map +1 -0
  113. package/dist/cli/dashboard/panels/agents.js +196 -0
  114. package/dist/cli/dashboard/panels/agents.js.map +1 -0
  115. package/dist/cli/dashboard/panels/escalations.d.ts +5 -0
  116. package/dist/cli/dashboard/panels/escalations.d.ts.map +1 -0
  117. package/dist/cli/dashboard/panels/escalations.js +93 -0
  118. package/dist/cli/dashboard/panels/escalations.js.map +1 -0
  119. package/dist/cli/dashboard/panels/merge-queue.d.ts +5 -0
  120. package/dist/cli/dashboard/panels/merge-queue.d.ts.map +1 -0
  121. package/dist/cli/dashboard/panels/merge-queue.js +57 -0
  122. package/dist/cli/dashboard/panels/merge-queue.js.map +1 -0
  123. package/dist/cli/dashboard/panels/pipeline.d.ts +5 -0
  124. package/dist/cli/dashboard/panels/pipeline.d.ts.map +1 -0
  125. package/dist/cli/dashboard/panels/pipeline.js +54 -0
  126. package/dist/cli/dashboard/panels/pipeline.js.map +1 -0
  127. package/dist/cli/dashboard/panels/stories.d.ts +5 -0
  128. package/dist/cli/dashboard/panels/stories.d.ts.map +1 -0
  129. package/dist/cli/dashboard/panels/stories.js +79 -0
  130. package/dist/cli/dashboard/panels/stories.js.map +1 -0
  131. package/dist/cli-runtimes/claude.d.ts +8 -0
  132. package/dist/cli-runtimes/claude.d.ts.map +1 -0
  133. package/dist/cli-runtimes/claude.js +27 -0
  134. package/dist/cli-runtimes/claude.js.map +1 -0
  135. package/dist/cli-runtimes/codex.d.ts +8 -0
  136. package/dist/cli-runtimes/codex.d.ts.map +1 -0
  137. package/dist/cli-runtimes/codex.js +27 -0
  138. package/dist/cli-runtimes/codex.js.map +1 -0
  139. package/dist/cli-runtimes/gemini.d.ts +8 -0
  140. package/dist/cli-runtimes/gemini.d.ts.map +1 -0
  141. package/dist/cli-runtimes/gemini.js +29 -0
  142. package/dist/cli-runtimes/gemini.js.map +1 -0
  143. package/dist/cli-runtimes/index.d.ts +25 -0
  144. package/dist/cli-runtimes/index.d.ts.map +1 -0
  145. package/dist/cli-runtimes/index.js +48 -0
  146. package/dist/cli-runtimes/index.js.map +1 -0
  147. package/dist/cli-runtimes/index.test.d.ts +2 -0
  148. package/dist/cli-runtimes/index.test.d.ts.map +1 -0
  149. package/dist/cli-runtimes/index.test.js +216 -0
  150. package/dist/cli-runtimes/index.test.js.map +1 -0
  151. package/dist/cli-runtimes/types.d.ts +27 -0
  152. package/dist/cli-runtimes/types.d.ts.map +1 -0
  153. package/dist/cli-runtimes/types.js +2 -0
  154. package/dist/cli-runtimes/types.js.map +1 -0
  155. package/dist/config/index.d.ts +3 -0
  156. package/dist/config/index.d.ts.map +1 -0
  157. package/dist/config/index.js +3 -0
  158. package/dist/config/index.js.map +1 -0
  159. package/dist/config/loader.d.ts +11 -0
  160. package/dist/config/loader.d.ts.map +1 -0
  161. package/dist/config/loader.js +72 -0
  162. package/dist/config/loader.js.map +1 -0
  163. package/dist/config/schema.d.ts +660 -0
  164. package/dist/config/schema.d.ts.map +1 -0
  165. package/dist/config/schema.js +217 -0
  166. package/dist/config/schema.js.map +1 -0
  167. package/dist/config/schema.test.d.ts +2 -0
  168. package/dist/config/schema.test.d.ts.map +1 -0
  169. package/dist/config/schema.test.js +123 -0
  170. package/dist/config/schema.test.js.map +1 -0
  171. package/dist/context-files/generator.d.ts +32 -0
  172. package/dist/context-files/generator.d.ts.map +1 -0
  173. package/dist/context-files/generator.js +120 -0
  174. package/dist/context-files/generator.js.map +1 -0
  175. package/dist/context-files/index.d.ts +38 -0
  176. package/dist/context-files/index.d.ts.map +1 -0
  177. package/dist/context-files/index.js +76 -0
  178. package/dist/context-files/index.js.map +1 -0
  179. package/dist/context-files/index.test.d.ts +2 -0
  180. package/dist/context-files/index.test.d.ts.map +1 -0
  181. package/dist/context-files/index.test.js +265 -0
  182. package/dist/context-files/index.test.js.map +1 -0
  183. package/dist/context-files/templates.d.ts +19 -0
  184. package/dist/context-files/templates.d.ts.map +1 -0
  185. package/dist/context-files/templates.js +266 -0
  186. package/dist/context-files/templates.js.map +1 -0
  187. package/dist/db/client.d.ts +95 -0
  188. package/dist/db/client.d.ts.map +1 -0
  189. package/dist/db/client.js +343 -0
  190. package/dist/db/client.js.map +1 -0
  191. package/dist/db/lock.d.ts +25 -0
  192. package/dist/db/lock.d.ts.map +1 -0
  193. package/dist/db/lock.js +56 -0
  194. package/dist/db/lock.js.map +1 -0
  195. package/dist/db/lock.test.d.ts +2 -0
  196. package/dist/db/lock.test.d.ts.map +1 -0
  197. package/dist/db/lock.test.js +73 -0
  198. package/dist/db/lock.test.js.map +1 -0
  199. package/dist/db/queries/agents.d.ts +31 -0
  200. package/dist/db/queries/agents.d.ts.map +1 -0
  201. package/dist/db/queries/agents.js +76 -0
  202. package/dist/db/queries/agents.js.map +1 -0
  203. package/dist/db/queries/escalations.d.ts +29 -0
  204. package/dist/db/queries/escalations.d.ts.map +1 -0
  205. package/dist/db/queries/escalations.js +105 -0
  206. package/dist/db/queries/escalations.js.map +1 -0
  207. package/dist/db/queries/heartbeat.d.ts +20 -0
  208. package/dist/db/queries/heartbeat.d.ts.map +1 -0
  209. package/dist/db/queries/heartbeat.js +61 -0
  210. package/dist/db/queries/heartbeat.js.map +1 -0
  211. package/dist/db/queries/index.d.ts +8 -0
  212. package/dist/db/queries/index.d.ts.map +1 -0
  213. package/dist/db/queries/index.js +8 -0
  214. package/dist/db/queries/index.js.map +1 -0
  215. package/dist/db/queries/logs.d.ts +21 -0
  216. package/dist/db/queries/logs.d.ts.map +1 -0
  217. package/dist/db/queries/logs.js +72 -0
  218. package/dist/db/queries/logs.js.map +1 -0
  219. package/dist/db/queries/messages.d.ts +17 -0
  220. package/dist/db/queries/messages.d.ts.map +1 -0
  221. package/dist/db/queries/messages.js +22 -0
  222. package/dist/db/queries/messages.js.map +1 -0
  223. package/dist/db/queries/pull-requests.d.ts +33 -0
  224. package/dist/db/queries/pull-requests.d.ts.map +1 -0
  225. package/dist/db/queries/pull-requests.js +130 -0
  226. package/dist/db/queries/pull-requests.js.map +1 -0
  227. package/dist/db/queries/requirements.d.ts +22 -0
  228. package/dist/db/queries/requirements.d.ts.map +1 -0
  229. package/dist/db/queries/requirements.js +53 -0
  230. package/dist/db/queries/requirements.js.map +1 -0
  231. package/dist/db/queries/stories.d.ts +42 -0
  232. package/dist/db/queries/stories.d.ts.map +1 -0
  233. package/dist/db/queries/stories.js +163 -0
  234. package/dist/db/queries/stories.js.map +1 -0
  235. package/dist/db/queries/teams.d.ts +14 -0
  236. package/dist/db/queries/teams.d.ts.map +1 -0
  237. package/dist/db/queries/teams.js +24 -0
  238. package/dist/db/queries/teams.js.map +1 -0
  239. package/dist/git/branches.d.ts +52 -0
  240. package/dist/git/branches.d.ts.map +1 -0
  241. package/dist/git/branches.js +133 -0
  242. package/dist/git/branches.js.map +1 -0
  243. package/dist/git/github.d.ts +75 -0
  244. package/dist/git/github.d.ts.map +1 -0
  245. package/dist/git/github.js +162 -0
  246. package/dist/git/github.js.map +1 -0
  247. package/dist/git/index.d.ts +4 -0
  248. package/dist/git/index.d.ts.map +1 -0
  249. package/dist/git/index.js +4 -0
  250. package/dist/git/index.js.map +1 -0
  251. package/dist/git/submodules.d.ts +47 -0
  252. package/dist/git/submodules.d.ts.map +1 -0
  253. package/dist/git/submodules.js +115 -0
  254. package/dist/git/submodules.js.map +1 -0
  255. package/dist/index.d.ts +3 -0
  256. package/dist/index.d.ts.map +1 -0
  257. package/dist/index.js +62 -0
  258. package/dist/index.js.map +1 -0
  259. package/dist/llm/anthropic.d.ts +18 -0
  260. package/dist/llm/anthropic.d.ts.map +1 -0
  261. package/dist/llm/anthropic.js +111 -0
  262. package/dist/llm/anthropic.js.map +1 -0
  263. package/dist/llm/index.d.ts +6 -0
  264. package/dist/llm/index.d.ts.map +1 -0
  265. package/dist/llm/index.js +24 -0
  266. package/dist/llm/index.js.map +1 -0
  267. package/dist/llm/openai.d.ts +18 -0
  268. package/dist/llm/openai.d.ts.map +1 -0
  269. package/dist/llm/openai.js +103 -0
  270. package/dist/llm/openai.js.map +1 -0
  271. package/dist/llm/provider.d.ts +38 -0
  272. package/dist/llm/provider.d.ts.map +1 -0
  273. package/dist/llm/provider.js +17 -0
  274. package/dist/llm/provider.js.map +1 -0
  275. package/dist/orchestrator/index.d.ts +4 -0
  276. package/dist/orchestrator/index.d.ts.map +1 -0
  277. package/dist/orchestrator/index.js +4 -0
  278. package/dist/orchestrator/index.js.map +1 -0
  279. package/dist/orchestrator/scaler.d.ts +42 -0
  280. package/dist/orchestrator/scaler.d.ts.map +1 -0
  281. package/dist/orchestrator/scaler.js +154 -0
  282. package/dist/orchestrator/scaler.js.map +1 -0
  283. package/dist/orchestrator/scheduler.d.ts +90 -0
  284. package/dist/orchestrator/scheduler.d.ts.map +1 -0
  285. package/dist/orchestrator/scheduler.js +1003 -0
  286. package/dist/orchestrator/scheduler.js.map +1 -0
  287. package/dist/orchestrator/scheduler.test.d.ts +2 -0
  288. package/dist/orchestrator/scheduler.test.d.ts.map +1 -0
  289. package/dist/orchestrator/scheduler.test.js +242 -0
  290. package/dist/orchestrator/scheduler.test.js.map +1 -0
  291. package/dist/orchestrator/workflow.d.ts +18 -0
  292. package/dist/orchestrator/workflow.d.ts.map +1 -0
  293. package/dist/orchestrator/workflow.js +106 -0
  294. package/dist/orchestrator/workflow.js.map +1 -0
  295. package/dist/state-detectors/claude.d.ts +33 -0
  296. package/dist/state-detectors/claude.d.ts.map +1 -0
  297. package/dist/state-detectors/claude.js +237 -0
  298. package/dist/state-detectors/claude.js.map +1 -0
  299. package/dist/state-detectors/claude.test.d.ts +2 -0
  300. package/dist/state-detectors/claude.test.d.ts.map +1 -0
  301. package/dist/state-detectors/claude.test.js +127 -0
  302. package/dist/state-detectors/claude.test.js.map +1 -0
  303. package/dist/state-detectors/codex.d.ts +34 -0
  304. package/dist/state-detectors/codex.d.ts.map +1 -0
  305. package/dist/state-detectors/codex.js +233 -0
  306. package/dist/state-detectors/codex.js.map +1 -0
  307. package/dist/state-detectors/codex.test.d.ts +2 -0
  308. package/dist/state-detectors/codex.test.d.ts.map +1 -0
  309. package/dist/state-detectors/codex.test.js +85 -0
  310. package/dist/state-detectors/codex.test.js.map +1 -0
  311. package/dist/state-detectors/factory.d.ts +22 -0
  312. package/dist/state-detectors/factory.d.ts.map +1 -0
  313. package/dist/state-detectors/factory.js +37 -0
  314. package/dist/state-detectors/factory.js.map +1 -0
  315. package/dist/state-detectors/factory.test.d.ts +2 -0
  316. package/dist/state-detectors/factory.test.d.ts.map +1 -0
  317. package/dist/state-detectors/factory.test.js +44 -0
  318. package/dist/state-detectors/factory.test.js.map +1 -0
  319. package/dist/state-detectors/gemini.d.ts +34 -0
  320. package/dist/state-detectors/gemini.d.ts.map +1 -0
  321. package/dist/state-detectors/gemini.js +236 -0
  322. package/dist/state-detectors/gemini.js.map +1 -0
  323. package/dist/state-detectors/gemini.test.d.ts +2 -0
  324. package/dist/state-detectors/gemini.test.d.ts.map +1 -0
  325. package/dist/state-detectors/gemini.test.js +93 -0
  326. package/dist/state-detectors/gemini.test.js.map +1 -0
  327. package/dist/state-detectors/index.d.ts +20 -0
  328. package/dist/state-detectors/index.d.ts.map +1 -0
  329. package/dist/state-detectors/index.js +21 -0
  330. package/dist/state-detectors/index.js.map +1 -0
  331. package/dist/state-detectors/types.d.ts +67 -0
  332. package/dist/state-detectors/types.d.ts.map +1 -0
  333. package/dist/state-detectors/types.js +28 -0
  334. package/dist/state-detectors/types.js.map +1 -0
  335. package/dist/tmux/index.d.ts +2 -0
  336. package/dist/tmux/index.d.ts.map +1 -0
  337. package/dist/tmux/index.js +2 -0
  338. package/dist/tmux/index.js.map +1 -0
  339. package/dist/tmux/manager.d.ts +45 -0
  340. package/dist/tmux/manager.d.ts.map +1 -0
  341. package/dist/tmux/manager.js +252 -0
  342. package/dist/tmux/manager.js.map +1 -0
  343. package/dist/utils/claude-code-state.d.ts +46 -0
  344. package/dist/utils/claude-code-state.d.ts.map +1 -0
  345. package/dist/utils/claude-code-state.js +252 -0
  346. package/dist/utils/claude-code-state.js.map +1 -0
  347. package/dist/utils/cli-builder.d.ts +19 -0
  348. package/dist/utils/cli-builder.d.ts.map +1 -0
  349. package/dist/utils/cli-builder.js +58 -0
  350. package/dist/utils/cli-builder.js.map +1 -0
  351. package/dist/utils/cli-commands.d.ts +27 -0
  352. package/dist/utils/cli-commands.d.ts.map +1 -0
  353. package/dist/utils/cli-commands.js +69 -0
  354. package/dist/utils/cli-commands.js.map +1 -0
  355. package/dist/utils/index.d.ts +3 -0
  356. package/dist/utils/index.d.ts.map +1 -0
  357. package/dist/utils/index.js +3 -0
  358. package/dist/utils/index.js.map +1 -0
  359. package/dist/utils/logger.d.ts +13 -0
  360. package/dist/utils/logger.d.ts.map +1 -0
  361. package/dist/utils/logger.js +77 -0
  362. package/dist/utils/logger.js.map +1 -0
  363. package/dist/utils/paths.d.ts +17 -0
  364. package/dist/utils/paths.d.ts.map +1 -0
  365. package/dist/utils/paths.js +33 -0
  366. package/dist/utils/paths.js.map +1 -0
  367. package/dist/utils/timeout.d.ts +25 -0
  368. package/dist/utils/timeout.d.ts.map +1 -0
  369. package/dist/utils/timeout.js +57 -0
  370. package/dist/utils/timeout.js.map +1 -0
  371. package/package.json +78 -0
  372. package/src/agents/base-agent.ts +255 -0
  373. package/src/agents/index.ts +6 -0
  374. package/src/agents/intermediate.ts +161 -0
  375. package/src/agents/junior.ts +166 -0
  376. package/src/agents/qa.ts +272 -0
  377. package/src/agents/senior.ts +307 -0
  378. package/src/agents/tech-lead.ts +324 -0
  379. package/src/cli/commands/add-repo.ts +89 -0
  380. package/src/cli/commands/agents.ts +247 -0
  381. package/src/cli/commands/assign.ts +86 -0
  382. package/src/cli/commands/config.ts +121 -0
  383. package/src/cli/commands/escalations.ts +179 -0
  384. package/src/cli/commands/index.ts +16 -0
  385. package/src/cli/commands/init.ts +66 -0
  386. package/src/cli/commands/manager.test.ts +52 -0
  387. package/src/cli/commands/manager.ts +916 -0
  388. package/src/cli/commands/msg.ts +232 -0
  389. package/src/cli/commands/my-stories.ts +198 -0
  390. package/src/cli/commands/nuke.ts +223 -0
  391. package/src/cli/commands/pr.ts +559 -0
  392. package/src/cli/commands/req.ts +231 -0
  393. package/src/cli/commands/resume.ts +129 -0
  394. package/src/cli/commands/status.ts +284 -0
  395. package/src/cli/commands/stories.ts +131 -0
  396. package/src/cli/commands/teams.ts +158 -0
  397. package/src/cli/dashboard/index.ts +141 -0
  398. package/src/cli/dashboard/panels/activity.ts +77 -0
  399. package/src/cli/dashboard/panels/agents.ts +244 -0
  400. package/src/cli/dashboard/panels/escalations.ts +109 -0
  401. package/src/cli/dashboard/panels/merge-queue.ts +65 -0
  402. package/src/cli/dashboard/panels/pipeline.ts +65 -0
  403. package/src/cli/dashboard/panels/stories.ts +87 -0
  404. package/src/cli-runtimes/claude.ts +31 -0
  405. package/src/cli-runtimes/codex.ts +31 -0
  406. package/src/cli-runtimes/gemini.ts +33 -0
  407. package/src/cli-runtimes/index.test.ts +261 -0
  408. package/src/cli-runtimes/index.ts +52 -0
  409. package/src/cli-runtimes/types.ts +30 -0
  410. package/src/config/index.ts +2 -0
  411. package/src/config/loader.ts +89 -0
  412. package/src/config/schema.test.ts +135 -0
  413. package/src/config/schema.ts +238 -0
  414. package/src/context-files/generator.ts +132 -0
  415. package/src/context-files/index.test.ts +323 -0
  416. package/src/context-files/index.ts +102 -0
  417. package/src/context-files/templates.ts +279 -0
  418. package/src/db/client.ts +475 -0
  419. package/src/db/lock.test.ts +93 -0
  420. package/src/db/lock.ts +74 -0
  421. package/src/db/migrations/001-initial.sql +121 -0
  422. package/src/db/migrations/005-add-agent-heartbeat.sql +4 -0
  423. package/src/db/queries/agents.ts +113 -0
  424. package/src/db/queries/escalations.ts +140 -0
  425. package/src/db/queries/heartbeat.ts +92 -0
  426. package/src/db/queries/index.ts +7 -0
  427. package/src/db/queries/logs.ts +136 -0
  428. package/src/db/queries/messages.ts +38 -0
  429. package/src/db/queries/pull-requests.ts +170 -0
  430. package/src/db/queries/requirements.ts +81 -0
  431. package/src/db/queries/stories.ts +223 -0
  432. package/src/db/queries/teams.ts +39 -0
  433. package/src/git/branches.ts +186 -0
  434. package/src/git/github.ts +247 -0
  435. package/src/git/index.ts +3 -0
  436. package/src/git/submodules.ts +141 -0
  437. package/src/index.ts +93 -0
  438. package/src/llm/anthropic.ts +134 -0
  439. package/src/llm/index.ts +26 -0
  440. package/src/llm/openai.ts +125 -0
  441. package/src/llm/provider.ts +60 -0
  442. package/src/orchestrator/index.ts +3 -0
  443. package/src/orchestrator/scaler.ts +201 -0
  444. package/src/orchestrator/scheduler.test.ts +288 -0
  445. package/src/orchestrator/scheduler.ts +1130 -0
  446. package/src/orchestrator/workflow.ts +137 -0
  447. package/src/state-detectors/claude.test.ts +149 -0
  448. package/src/state-detectors/claude.ts +256 -0
  449. package/src/state-detectors/codex.test.ts +100 -0
  450. package/src/state-detectors/codex.ts +252 -0
  451. package/src/state-detectors/factory.test.ts +51 -0
  452. package/src/state-detectors/factory.ts +40 -0
  453. package/src/state-detectors/gemini.test.ts +110 -0
  454. package/src/state-detectors/gemini.ts +255 -0
  455. package/src/state-detectors/index.ts +25 -0
  456. package/src/state-detectors/types.ts +80 -0
  457. package/src/tmux/index.ts +1 -0
  458. package/src/tmux/manager.ts +310 -0
  459. package/src/types/sql.js.d.ts +34 -0
  460. package/src/utils/claude-code-state.ts +281 -0
  461. package/src/utils/cli-builder.ts +78 -0
  462. package/src/utils/cli-commands.ts +84 -0
  463. package/src/utils/index.ts +2 -0
  464. package/src/utils/logger.ts +93 -0
  465. package/src/utils/paths.ts +49 -0
  466. package/src/utils/timeout.ts +84 -0
  467. package/tsconfig.json +25 -0
@@ -0,0 +1,559 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { execa } from 'execa';
4
+ import { findHiveRoot, getHivePaths } from '../../utils/paths.js';
5
+ import { getDatabase, queryAll } from '../../db/client.js';
6
+ import {
7
+ createPullRequest,
8
+ getMergeQueue,
9
+ getNextInQueue,
10
+ getPullRequestById,
11
+ updatePullRequest,
12
+ getQueuePosition,
13
+ type PullRequestRow,
14
+ } from '../../db/queries/pull-requests.js';
15
+ import { getStoryById, updateStory } from '../../db/queries/stories.js';
16
+ import { getTeamById } from '../../db/queries/teams.js';
17
+ import { createLog } from '../../db/queries/logs.js';
18
+ import { join } from 'path';
19
+ import { loadConfig } from '../../config/loader.js';
20
+ import { Scheduler } from '../../orchestrator/scheduler.js';
21
+ import { sendToTmuxSession, isTmuxSessionRunning } from '../../tmux/manager.js';
22
+
23
+ export const prCommand = new Command('pr')
24
+ .description('Manage pull requests and merge queue');
25
+
26
+ // Submit a PR to the merge queue
27
+ prCommand
28
+ .command('submit')
29
+ .description('Submit a PR to the merge queue')
30
+ .requiredOption('-b, --branch <branch>', 'Branch name')
31
+ .option('-s, --story <story-id>', 'Associated story ID')
32
+ .option('-t, --team <team-id>', 'Team ID')
33
+ .option('--pr-number <number>', 'GitHub PR number')
34
+ .option('--pr-url <url>', 'GitHub PR URL')
35
+ .option('--from <session>', 'Submitting agent session')
36
+ .action(async (options: {
37
+ branch: string;
38
+ story?: string;
39
+ team?: string;
40
+ prNumber?: string;
41
+ prUrl?: string;
42
+ from?: string;
43
+ }) => {
44
+ const root = findHiveRoot();
45
+ if (!root) {
46
+ console.error(chalk.red('Not in a Hive workspace.'));
47
+ process.exit(1);
48
+ }
49
+
50
+ const paths = getHivePaths(root);
51
+ const db = await getDatabase(paths.hiveDir);
52
+
53
+ try {
54
+ // If story ID provided, get team from story
55
+ let teamId = options.team || null;
56
+ const storyId = options.story || null;
57
+
58
+ if (storyId) {
59
+ const story = getStoryById(db.db, storyId);
60
+ if (story) {
61
+ teamId = story.team_id;
62
+ // Update story status
63
+ updateStory(db.db, storyId, { status: 'pr_submitted' });
64
+ }
65
+ }
66
+
67
+ const pr = createPullRequest(db.db, {
68
+ storyId,
69
+ teamId,
70
+ branchName: options.branch,
71
+ githubPrNumber: options.prNumber ? parseInt(options.prNumber, 10) : null,
72
+ githubPrUrl: options.prUrl || null,
73
+ submittedBy: options.from || null,
74
+ });
75
+
76
+ db.save();
77
+
78
+ const position = getQueuePosition(db.db, pr.id);
79
+
80
+ console.log(chalk.green(`PR submitted to merge queue`));
81
+ console.log(chalk.gray(` ID: ${pr.id}`));
82
+ console.log(chalk.gray(` Branch: ${pr.branch_name}`));
83
+ console.log(chalk.gray(` Queue position: ${position}`));
84
+ if (pr.github_pr_url) {
85
+ console.log(chalk.gray(` GitHub: ${pr.github_pr_url}`));
86
+ }
87
+
88
+ if (options.from) {
89
+ createLog(db.db, {
90
+ agentId: options.from,
91
+ storyId: storyId || undefined,
92
+ eventType: 'PR_SUBMITTED',
93
+ message: `Submitted PR for branch ${options.branch}`,
94
+ metadata: { pr_id: pr.id, queue_position: position },
95
+ });
96
+ db.save();
97
+ }
98
+
99
+ // Check if QA agents need to be spawned for the merge queue
100
+ try {
101
+ const config = loadConfig(paths.hiveDir);
102
+ const scheduler = new Scheduler(db.db, {
103
+ scaling: config.scaling,
104
+ models: config.models,
105
+ rootDir: root,
106
+ });
107
+ await scheduler.checkMergeQueue();
108
+ db.save();
109
+ console.log(chalk.gray(' QA agents notified'));
110
+ } catch {
111
+ // Non-fatal - QA can be triggered manually
112
+ }
113
+ } finally {
114
+ db.close();
115
+ }
116
+ });
117
+
118
+ // View merge queue
119
+ prCommand
120
+ .command('queue')
121
+ .description('View the merge queue')
122
+ .option('-t, --team <team-id>', 'Filter by team')
123
+ .option('--json', 'Output as JSON')
124
+ .action(async (options: { team?: string; json?: boolean }) => {
125
+ const root = findHiveRoot();
126
+ if (!root) {
127
+ console.error(chalk.red('Not in a Hive workspace.'));
128
+ process.exit(1);
129
+ }
130
+
131
+ const paths = getHivePaths(root);
132
+ const db = await getDatabase(paths.hiveDir);
133
+
134
+ try {
135
+ const queue = getMergeQueue(db.db, options.team);
136
+
137
+ if (options.json) {
138
+ console.log(JSON.stringify(queue, null, 2));
139
+ return;
140
+ }
141
+
142
+ if (queue.length === 0) {
143
+ console.log(chalk.yellow('Merge queue is empty.'));
144
+ return;
145
+ }
146
+
147
+ console.log(chalk.bold('\nMerge Queue:\n'));
148
+ console.log(chalk.gray(
149
+ `${'#'.padEnd(4)} ${'ID'.padEnd(15)} ${'Branch'.padEnd(30)} ${'Status'.padEnd(12)} ${'Story'}`
150
+ ));
151
+ console.log(chalk.gray('─'.repeat(80)));
152
+
153
+ queue.forEach((pr, index) => {
154
+ const statusColor = pr.status === 'reviewing' ? chalk.yellow : chalk.blue;
155
+ console.log(
156
+ `${String(index + 1).padEnd(4)} ` +
157
+ `${chalk.cyan(pr.id.padEnd(15))} ` +
158
+ `${pr.branch_name.padEnd(30)} ` +
159
+ `${statusColor(pr.status.toUpperCase().padEnd(12))} ` +
160
+ `${pr.story_id || '-'}`
161
+ );
162
+ });
163
+ console.log();
164
+ } finally {
165
+ db.close();
166
+ }
167
+ });
168
+
169
+ // Claim next PR for review (QA)
170
+ prCommand
171
+ .command('review')
172
+ .description('Claim the next PR in queue for review (QA)')
173
+ .option('-t, --team <team-id>', 'Filter by team')
174
+ .option('--from <session>', 'QA agent session')
175
+ .action(async (options: { team?: string; from?: string }) => {
176
+ const root = findHiveRoot();
177
+ if (!root) {
178
+ console.error(chalk.red('Not in a Hive workspace.'));
179
+ process.exit(1);
180
+ }
181
+
182
+ const paths = getHivePaths(root);
183
+ const db = await getDatabase(paths.hiveDir);
184
+
185
+ try {
186
+ const pr = getNextInQueue(db.db, options.team);
187
+
188
+ if (!pr) {
189
+ console.log(chalk.yellow('No PRs waiting for review.'));
190
+ return;
191
+ }
192
+
193
+ updatePullRequest(db.db, pr.id, {
194
+ status: 'reviewing',
195
+ reviewedBy: options.from || null,
196
+ });
197
+ db.save();
198
+
199
+ console.log(chalk.green(`Claimed PR for review: ${pr.id}`));
200
+ console.log(chalk.gray(` Branch: ${pr.branch_name}`));
201
+ console.log(chalk.gray(` Story: ${pr.story_id || '-'}`));
202
+ if (pr.github_pr_url) {
203
+ console.log(chalk.gray(` GitHub: ${pr.github_pr_url}`));
204
+ }
205
+ console.log();
206
+ console.log(chalk.cyan('To approve and merge:'));
207
+ console.log(chalk.gray(` hive pr approve ${pr.id}`));
208
+ console.log(chalk.cyan('To reject:'));
209
+ console.log(chalk.gray(` hive pr reject ${pr.id} --reason "..."`));
210
+
211
+ if (options.from) {
212
+ createLog(db.db, {
213
+ agentId: options.from,
214
+ storyId: pr.story_id || undefined,
215
+ eventType: 'PR_REVIEW_STARTED',
216
+ message: `Started reviewing PR ${pr.id}`,
217
+ metadata: { pr_id: pr.id, branch: pr.branch_name },
218
+ });
219
+ db.save();
220
+ }
221
+ } finally {
222
+ db.close();
223
+ }
224
+ });
225
+
226
+ // View specific PR
227
+ prCommand
228
+ .command('show <pr-id>')
229
+ .description('View details of a PR')
230
+ .action(async (prId: string) => {
231
+ const root = findHiveRoot();
232
+ if (!root) {
233
+ console.error(chalk.red('Not in a Hive workspace.'));
234
+ process.exit(1);
235
+ }
236
+
237
+ const paths = getHivePaths(root);
238
+ const db = await getDatabase(paths.hiveDir);
239
+
240
+ try {
241
+ const pr = getPullRequestById(db.db, prId);
242
+ if (!pr) {
243
+ console.error(chalk.red(`PR not found: ${prId}`));
244
+ process.exit(1);
245
+ }
246
+
247
+ console.log(chalk.bold(`\nPull Request: ${pr.id}\n`));
248
+ console.log(chalk.gray(`Branch: ${pr.branch_name}`));
249
+ console.log(chalk.gray(`Status: ${pr.status.toUpperCase()}`));
250
+ console.log(chalk.gray(`Story: ${pr.story_id || '-'}`));
251
+ console.log(chalk.gray(`Team: ${pr.team_id || '-'}`));
252
+ console.log(chalk.gray(`GitHub PR: ${pr.github_pr_url || '-'}`));
253
+ console.log(chalk.gray(`Submitted by: ${pr.submitted_by || '-'}`));
254
+ console.log(chalk.gray(`Reviewed by: ${pr.reviewed_by || '-'}`));
255
+ console.log(chalk.gray(`Created: ${pr.created_at}`));
256
+ if (pr.reviewed_at) {
257
+ console.log(chalk.gray(`Reviewed: ${pr.reviewed_at}`));
258
+ }
259
+ if (pr.review_notes) {
260
+ console.log(chalk.bold('\nReview Notes:'));
261
+ console.log(pr.review_notes);
262
+ }
263
+
264
+ const position = getQueuePosition(db.db, pr.id);
265
+ if (position > 0) {
266
+ console.log(chalk.cyan(`\nQueue Position: ${position}`));
267
+ }
268
+ console.log();
269
+ } finally {
270
+ db.close();
271
+ }
272
+ });
273
+
274
+ // Approve and merge PR
275
+ prCommand
276
+ .command('approve <pr-id>')
277
+ .description('Approve and merge a PR')
278
+ .option('--notes <notes>', 'Review notes')
279
+ .option('--from <session>', 'QA agent session')
280
+ .option('--no-merge', 'Approve without merging (manual merge needed)')
281
+ .action(async (prId: string, options: { notes?: string; from?: string; merge?: boolean }) => {
282
+ const root = findHiveRoot();
283
+ if (!root) {
284
+ console.error(chalk.red('Not in a Hive workspace.'));
285
+ process.exit(1);
286
+ }
287
+
288
+ const paths = getHivePaths(root);
289
+ const db = await getDatabase(paths.hiveDir);
290
+
291
+ try {
292
+ const pr = getPullRequestById(db.db, prId);
293
+ if (!pr) {
294
+ console.error(chalk.red(`PR not found: ${prId}`));
295
+ process.exit(1);
296
+ }
297
+
298
+ if (pr.status === 'merged') {
299
+ console.log(chalk.yellow('PR already merged.'));
300
+ return;
301
+ }
302
+
303
+ // Extract story ID from PR or branch name
304
+ let storyId = pr.story_id;
305
+ if (!storyId && pr.branch_name) {
306
+ const storyMatch = pr.branch_name.match(/STORY-[A-Z0-9-]+/i);
307
+ if (storyMatch) {
308
+ storyId = storyMatch[0].toUpperCase();
309
+ }
310
+ }
311
+
312
+ const shouldMerge = options.merge !== false;
313
+ let actuallyMerged = false;
314
+
315
+ if (shouldMerge && pr.github_pr_number) {
316
+ // Actually merge on GitHub via gh CLI
317
+ // Use the team's repo path as cwd so gh knows which repo to operate on
318
+ let repoCwd = root;
319
+ if (pr.team_id) {
320
+ const team = getTeamById(db.db, pr.team_id);
321
+ if (team?.repo_path) {
322
+ repoCwd = join(root, team.repo_path);
323
+ }
324
+ }
325
+ try {
326
+ const { execSync } = await import('child_process');
327
+ // First approve the PR on GitHub
328
+ try {
329
+ execSync(`gh pr review ${pr.github_pr_number} --approve`, { stdio: 'pipe', cwd: repoCwd });
330
+ } catch {
331
+ // May fail if already approved or if it's our own PR - continue
332
+ }
333
+ // Then merge
334
+ execSync(`gh pr merge ${pr.github_pr_number} --squash --delete-branch`, { stdio: 'pipe', cwd: repoCwd });
335
+ actuallyMerged = true;
336
+ console.log(chalk.green(`PR ${prId} approved and merged on GitHub!`));
337
+ } catch (mergeErr: unknown) {
338
+ const errMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
339
+ console.log(chalk.yellow(`GitHub merge failed: ${errMsg}`));
340
+ console.log(chalk.yellow('Marking as approved (manual merge needed).'));
341
+ }
342
+ } else if (shouldMerge && !pr.github_pr_number) {
343
+ console.log(chalk.yellow('No GitHub PR number linked - marking as approved only.'));
344
+ }
345
+
346
+ const newStatus = actuallyMerged ? 'merged' : 'approved';
347
+
348
+ updatePullRequest(db.db, prId, {
349
+ status: newStatus,
350
+ reviewedBy: options.from || pr.reviewed_by,
351
+ reviewNotes: options.notes || null,
352
+ });
353
+
354
+ if (storyId && newStatus === 'merged') {
355
+ updateStory(db.db, storyId, { status: 'merged' });
356
+ }
357
+
358
+ db.save();
359
+
360
+ if (!actuallyMerged && shouldMerge) {
361
+ console.log(chalk.green(`PR ${prId} approved.`));
362
+ console.log(chalk.gray('Manual merge is needed on GitHub.'));
363
+ } else if (!shouldMerge) {
364
+ console.log(chalk.green(`PR ${prId} approved.`));
365
+ console.log(chalk.gray('Manual merge is needed.'));
366
+ }
367
+
368
+ if (options.from) {
369
+ createLog(db.db, {
370
+ agentId: options.from,
371
+ storyId: storyId || undefined,
372
+ eventType: newStatus === 'merged' ? 'PR_MERGED' : 'PR_APPROVED',
373
+ message: `${newStatus === 'merged' ? 'Merged' : 'Approved'} PR ${prId}${storyId ? ` (${storyId})` : ''}`,
374
+ metadata: { pr_id: prId, branch: pr.branch_name, story_id: storyId },
375
+ });
376
+ db.save();
377
+ }
378
+ } finally {
379
+ db.close();
380
+ }
381
+ });
382
+
383
+ // Reject PR
384
+ prCommand
385
+ .command('reject <pr-id>')
386
+ .description('Reject a PR and send back for fixes')
387
+ .requiredOption('-r, --reason <reason>', 'Reason for rejection')
388
+ .option('--from <session>', 'QA agent session')
389
+ .action(async (prId: string, options: { reason: string; from?: string }) => {
390
+ const root = findHiveRoot();
391
+ if (!root) {
392
+ console.error(chalk.red('Not in a Hive workspace.'));
393
+ process.exit(1);
394
+ }
395
+
396
+ const paths = getHivePaths(root);
397
+ const db = await getDatabase(paths.hiveDir);
398
+
399
+ try {
400
+ const pr = getPullRequestById(db.db, prId);
401
+ if (!pr) {
402
+ console.error(chalk.red(`PR not found: ${prId}`));
403
+ process.exit(1);
404
+ }
405
+
406
+ updatePullRequest(db.db, prId, {
407
+ status: 'rejected',
408
+ reviewedBy: options.from || pr.reviewed_by,
409
+ reviewNotes: options.reason,
410
+ });
411
+
412
+ // Update story status - extract from branch name if not directly linked
413
+ let storyId = pr.story_id;
414
+ if (!storyId && pr.branch_name) {
415
+ const storyMatch = pr.branch_name.match(/STORY-\d+-[A-Z]+/i);
416
+ if (storyMatch) {
417
+ storyId = storyMatch[0].toUpperCase();
418
+ }
419
+ }
420
+ if (storyId) {
421
+ updateStory(db.db, storyId, { status: 'qa_failed' });
422
+ }
423
+
424
+ db.save();
425
+
426
+ console.log(chalk.yellow(`PR ${prId} rejected.`));
427
+ console.log(chalk.gray(`Reason: ${options.reason}`));
428
+
429
+ // Auto-notify the developer via tmux if their session is running
430
+ if (pr.submitted_by) {
431
+ try {
432
+ if (await isTmuxSessionRunning(pr.submitted_by)) {
433
+ await sendToTmuxSession(pr.submitted_by,
434
+ `# PR REJECTED: ${prId}\n# Reason: ${options.reason}\n# Please fix the issues and resubmit.`
435
+ );
436
+ console.log(chalk.green(`Developer ${pr.submitted_by} notified via tmux`));
437
+ } else {
438
+ console.log(chalk.cyan(`\nNotify the developer:`));
439
+ console.log(chalk.gray(` hive msg send ${pr.submitted_by} "PR rejected: ${options.reason}" --from ${options.from || 'qa'}`));
440
+ }
441
+ } catch {
442
+ console.log(chalk.cyan(`\nNotify the developer:`));
443
+ console.log(chalk.gray(` hive msg send ${pr.submitted_by} "PR rejected: ${options.reason}" --from ${options.from || 'qa'}`));
444
+ }
445
+ }
446
+
447
+ if (options.from) {
448
+ createLog(db.db, {
449
+ agentId: options.from,
450
+ storyId: storyId || undefined,
451
+ eventType: 'PR_REJECTED',
452
+ message: `Rejected PR ${prId}${storyId ? ` (${storyId})` : ''}: ${options.reason}`,
453
+ metadata: { pr_id: prId, branch: pr.branch_name, story_id: storyId },
454
+ });
455
+ db.save();
456
+ }
457
+ } finally {
458
+ db.close();
459
+ }
460
+ });
461
+
462
+ // Sync GitHub PRs into the merge queue
463
+ prCommand
464
+ .command('sync')
465
+ .description('Import open GitHub PRs into the merge queue')
466
+ .option('-r, --repo <path>', 'Repository path (relative to repos/)')
467
+ .action(async (options: { repo?: string }) => {
468
+ const root = findHiveRoot();
469
+ if (!root) {
470
+ console.error(chalk.red('Not in a Hive workspace.'));
471
+ process.exit(1);
472
+ }
473
+
474
+ const paths = getHivePaths(root);
475
+ const db = await getDatabase(paths.hiveDir);
476
+
477
+ try {
478
+ // Get ALL existing PRs (including merged/closed) to prevent duplicate imports
479
+ const existingPRs = queryAll<PullRequestRow>(db.db,
480
+ 'SELECT * FROM pull_requests'
481
+ );
482
+ const existingBranches = new Set(existingPRs.filter(pr => !['merged', 'closed'].includes(pr.status)).map(pr => pr.branch_name));
483
+ const existingPrNumbers = new Set(existingPRs.map(pr => pr.github_pr_number).filter(Boolean));
484
+
485
+ // Find repo directories
486
+ const repoDir = options.repo
487
+ ? `${root}/repos/${options.repo}`
488
+ : process.cwd();
489
+
490
+ console.log(chalk.cyan(`Checking for open PRs in ${repoDir}...`));
491
+
492
+ // Get open PRs from GitHub
493
+ let ghPRs: Array<{ number: number; headRefName: string; url: string; title: string }> = [];
494
+ try {
495
+ const result = await execa('gh', ['pr', 'list', '--json', 'number,headRefName,url,title', '--state', 'open'], {
496
+ cwd: repoDir,
497
+ });
498
+ ghPRs = JSON.parse(result.stdout);
499
+ } catch (err) {
500
+ console.error(chalk.red('Failed to list GitHub PRs. Is gh CLI authenticated?'), err);
501
+ process.exit(1);
502
+ }
503
+
504
+ if (ghPRs.length === 0) {
505
+ console.log(chalk.yellow('No open PRs found on GitHub.'));
506
+ return;
507
+ }
508
+
509
+ let imported = 0;
510
+ for (const ghPR of ghPRs) {
511
+ // Skip if already in queue
512
+ if (existingBranches.has(ghPR.headRefName) || existingPrNumbers.has(ghPR.number)) {
513
+ console.log(chalk.gray(` Skipping PR #${ghPR.number} (${ghPR.headRefName}) - already in queue`));
514
+ continue;
515
+ }
516
+
517
+ // Try to match to a story by parsing branch name (e.g., feature/STORY-001-description)
518
+ const storyMatch = ghPR.headRefName.match(/STORY-\d+/i);
519
+ const storyId = storyMatch ? storyMatch[0].toUpperCase() : null;
520
+
521
+ const pr = createPullRequest(db.db, {
522
+ storyId,
523
+ teamId: null,
524
+ branchName: ghPR.headRefName,
525
+ githubPrNumber: ghPR.number,
526
+ githubPrUrl: ghPR.url,
527
+ submittedBy: null,
528
+ });
529
+
530
+ console.log(chalk.green(` Imported: PR #${ghPR.number} (${ghPR.headRefName}) → ${pr.id}`));
531
+ imported++;
532
+ }
533
+
534
+ db.save();
535
+
536
+ if (imported > 0) {
537
+ console.log(chalk.green(`\nImported ${imported} PR(s) into merge queue.`));
538
+
539
+ // Trigger QA check
540
+ try {
541
+ const config = loadConfig(paths.hiveDir);
542
+ const scheduler = new Scheduler(db.db, {
543
+ scaling: config.scaling,
544
+ models: config.models,
545
+ rootDir: root,
546
+ });
547
+ await scheduler.checkMergeQueue();
548
+ db.save();
549
+ console.log(chalk.gray('QA agents notified.'));
550
+ } catch {
551
+ // Non-fatal
552
+ }
553
+ } else {
554
+ console.log(chalk.yellow('\nNo new PRs to import.'));
555
+ }
556
+ } finally {
557
+ db.close();
558
+ }
559
+ });