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,170 @@
1
+ import type { Database } from 'sql.js';
2
+ import { nanoid } from 'nanoid';
3
+ import { queryAll, queryOne, run, type PullRequestRow } from '../client.js';
4
+
5
+ export type { PullRequestRow };
6
+
7
+ export type PullRequestStatus = 'queued' | 'reviewing' | 'approved' | 'merged' | 'rejected' | 'closed';
8
+
9
+ export interface CreatePullRequestInput {
10
+ storyId?: string | null;
11
+ teamId?: string | null;
12
+ branchName: string;
13
+ githubPrNumber?: number | null;
14
+ githubPrUrl?: string | null;
15
+ submittedBy?: string | null;
16
+ }
17
+
18
+ export interface UpdatePullRequestInput {
19
+ status?: PullRequestStatus;
20
+ reviewedBy?: string | null;
21
+ reviewNotes?: string | null;
22
+ githubPrNumber?: number | null;
23
+ githubPrUrl?: string | null;
24
+ }
25
+
26
+ export function createPullRequest(db: Database, input: CreatePullRequestInput): PullRequestRow {
27
+ const id = `pr-${nanoid(8)}`;
28
+ const now = new Date().toISOString();
29
+
30
+ run(db, `
31
+ INSERT INTO pull_requests (id, story_id, team_id, branch_name, github_pr_number, github_pr_url, submitted_by, status, created_at, updated_at)
32
+ VALUES (?, ?, ?, ?, ?, ?, ?, 'queued', ?, ?)
33
+ `, [
34
+ id,
35
+ input.storyId || null,
36
+ input.teamId || null,
37
+ input.branchName,
38
+ input.githubPrNumber || null,
39
+ input.githubPrUrl || null,
40
+ input.submittedBy || null,
41
+ now,
42
+ now,
43
+ ]);
44
+
45
+ return getPullRequestById(db, id)!;
46
+ }
47
+
48
+ export function getPullRequestById(db: Database, id: string): PullRequestRow | undefined {
49
+ return queryOne<PullRequestRow>(db, 'SELECT * FROM pull_requests WHERE id = ?', [id]);
50
+ }
51
+
52
+ export function getPullRequestByStory(db: Database, storyId: string): PullRequestRow | undefined {
53
+ return queryOne<PullRequestRow>(db, 'SELECT * FROM pull_requests WHERE story_id = ?', [storyId]);
54
+ }
55
+
56
+ export function getPullRequestByGithubNumber(db: Database, prNumber: number): PullRequestRow | undefined {
57
+ return queryOne<PullRequestRow>(db, 'SELECT * FROM pull_requests WHERE github_pr_number = ?', [prNumber]);
58
+ }
59
+
60
+ // Merge Queue functions
61
+
62
+ export function getMergeQueue(db: Database, teamId?: string): PullRequestRow[] {
63
+ if (teamId) {
64
+ return queryAll<PullRequestRow>(db, `
65
+ SELECT * FROM pull_requests
66
+ WHERE team_id = ? AND status IN ('queued', 'reviewing')
67
+ ORDER BY created_at ASC
68
+ `, [teamId]);
69
+ }
70
+ return queryAll<PullRequestRow>(db, `
71
+ SELECT * FROM pull_requests
72
+ WHERE status IN ('queued', 'reviewing')
73
+ ORDER BY created_at ASC
74
+ `);
75
+ }
76
+
77
+ export function getNextInQueue(db: Database, teamId?: string): PullRequestRow | undefined {
78
+ if (teamId) {
79
+ return queryOne<PullRequestRow>(db, `
80
+ SELECT * FROM pull_requests
81
+ WHERE team_id = ? AND status = 'queued'
82
+ ORDER BY created_at ASC
83
+ LIMIT 1
84
+ `, [teamId]);
85
+ }
86
+ return queryOne<PullRequestRow>(db, `
87
+ SELECT * FROM pull_requests
88
+ WHERE status = 'queued'
89
+ ORDER BY created_at ASC
90
+ LIMIT 1
91
+ `);
92
+ }
93
+
94
+ export function getQueuePosition(db: Database, prId: string): number {
95
+ const pr = getPullRequestById(db, prId);
96
+ if (!pr || !['queued', 'reviewing'].includes(pr.status)) return -1;
97
+
98
+ const queue = getMergeQueue(db, pr.team_id || undefined);
99
+ return queue.findIndex(p => p.id === prId) + 1;
100
+ }
101
+
102
+ export function getPullRequestsByStatus(db: Database, status: PullRequestStatus): PullRequestRow[] {
103
+ return queryAll<PullRequestRow>(db, `
104
+ SELECT * FROM pull_requests
105
+ WHERE status = ?
106
+ ORDER BY created_at DESC
107
+ `, [status]);
108
+ }
109
+
110
+ export function getApprovedPullRequests(db: Database): PullRequestRow[] {
111
+ return queryAll<PullRequestRow>(db, `
112
+ SELECT * FROM pull_requests
113
+ WHERE status = 'approved'
114
+ ORDER BY created_at ASC
115
+ `);
116
+ }
117
+
118
+ export function getAllPullRequests(db: Database): PullRequestRow[] {
119
+ return queryAll<PullRequestRow>(db, 'SELECT * FROM pull_requests ORDER BY created_at DESC');
120
+ }
121
+
122
+ export function getPullRequestsByTeam(db: Database, teamId: string): PullRequestRow[] {
123
+ return queryAll<PullRequestRow>(db, `
124
+ SELECT * FROM pull_requests
125
+ WHERE team_id = ?
126
+ ORDER BY created_at DESC
127
+ `, [teamId]);
128
+ }
129
+
130
+ export function updatePullRequest(db: Database, id: string, input: UpdatePullRequestInput): PullRequestRow | undefined {
131
+ const updates: string[] = ['updated_at = ?'];
132
+ const values: (string | number | null)[] = [new Date().toISOString()];
133
+
134
+ if (input.status !== undefined) {
135
+ updates.push('status = ?');
136
+ values.push(input.status);
137
+ if (['reviewing', 'approved', 'rejected', 'merged'].includes(input.status)) {
138
+ updates.push('reviewed_at = ?');
139
+ values.push(new Date().toISOString());
140
+ }
141
+ }
142
+ if (input.reviewedBy !== undefined) {
143
+ updates.push('reviewed_by = ?');
144
+ values.push(input.reviewedBy);
145
+ }
146
+ if (input.reviewNotes !== undefined) {
147
+ updates.push('review_notes = ?');
148
+ values.push(input.reviewNotes);
149
+ }
150
+ if (input.githubPrNumber !== undefined) {
151
+ updates.push('github_pr_number = ?');
152
+ values.push(input.githubPrNumber);
153
+ }
154
+ if (input.githubPrUrl !== undefined) {
155
+ updates.push('github_pr_url = ?');
156
+ values.push(input.githubPrUrl);
157
+ }
158
+
159
+ if (updates.length === 1) {
160
+ return getPullRequestById(db, id);
161
+ }
162
+
163
+ values.push(id);
164
+ run(db, `UPDATE pull_requests SET ${updates.join(', ')} WHERE id = ?`, values);
165
+ return getPullRequestById(db, id);
166
+ }
167
+
168
+ export function deletePullRequest(db: Database, id: string): void {
169
+ run(db, 'DELETE FROM pull_requests WHERE id = ?', [id]);
170
+ }
@@ -0,0 +1,81 @@
1
+ import type { Database } from 'sql.js';
2
+ import { nanoid } from 'nanoid';
3
+ import { queryAll, queryOne, run, type RequirementRow } from '../client.js';
4
+
5
+ export type { RequirementRow };
6
+
7
+ export type RequirementStatus = 'pending' | 'planning' | 'planned' | 'in_progress' | 'completed';
8
+
9
+ export interface CreateRequirementInput {
10
+ title: string;
11
+ description: string;
12
+ submittedBy?: string;
13
+ }
14
+
15
+ export interface UpdateRequirementInput {
16
+ title?: string;
17
+ description?: string;
18
+ status?: RequirementStatus;
19
+ }
20
+
21
+ export function createRequirement(db: Database, input: CreateRequirementInput): RequirementRow {
22
+ const id = `REQ-${nanoid(8).toUpperCase()}`;
23
+ const now = new Date().toISOString();
24
+
25
+ run(db, `
26
+ INSERT INTO requirements (id, title, description, submitted_by, created_at)
27
+ VALUES (?, ?, ?, ?, ?)
28
+ `, [id, input.title, input.description, input.submittedBy || 'human', now]);
29
+
30
+ return getRequirementById(db, id)!;
31
+ }
32
+
33
+ export function getRequirementById(db: Database, id: string): RequirementRow | undefined {
34
+ return queryOne<RequirementRow>(db, 'SELECT * FROM requirements WHERE id = ?', [id]);
35
+ }
36
+
37
+ export function getAllRequirements(db: Database): RequirementRow[] {
38
+ return queryAll<RequirementRow>(db, 'SELECT * FROM requirements ORDER BY created_at DESC');
39
+ }
40
+
41
+ export function getRequirementsByStatus(db: Database, status: RequirementStatus): RequirementRow[] {
42
+ return queryAll<RequirementRow>(db, 'SELECT * FROM requirements WHERE status = ? ORDER BY created_at DESC', [status]);
43
+ }
44
+
45
+ export function getPendingRequirements(db: Database): RequirementRow[] {
46
+ return queryAll<RequirementRow>(db, `
47
+ SELECT * FROM requirements
48
+ WHERE status IN ('pending', 'planning', 'in_progress')
49
+ ORDER BY created_at
50
+ `);
51
+ }
52
+
53
+ export function updateRequirement(db: Database, id: string, input: UpdateRequirementInput): RequirementRow | undefined {
54
+ const updates: string[] = [];
55
+ const values: string[] = [];
56
+
57
+ if (input.title !== undefined) {
58
+ updates.push('title = ?');
59
+ values.push(input.title);
60
+ }
61
+ if (input.description !== undefined) {
62
+ updates.push('description = ?');
63
+ values.push(input.description);
64
+ }
65
+ if (input.status !== undefined) {
66
+ updates.push('status = ?');
67
+ values.push(input.status);
68
+ }
69
+
70
+ if (updates.length === 0) {
71
+ return getRequirementById(db, id);
72
+ }
73
+
74
+ values.push(id);
75
+ run(db, `UPDATE requirements SET ${updates.join(', ')} WHERE id = ?`, values);
76
+ return getRequirementById(db, id);
77
+ }
78
+
79
+ export function deleteRequirement(db: Database, id: string): void {
80
+ run(db, 'DELETE FROM requirements WHERE id = ?', [id]);
81
+ }
@@ -0,0 +1,223 @@
1
+ import type { Database } from 'sql.js';
2
+ import { nanoid } from 'nanoid';
3
+ import { queryAll, queryOne, run, type StoryRow } from '../client.js';
4
+
5
+ export type { StoryRow };
6
+
7
+ export type StoryStatus =
8
+ | 'draft'
9
+ | 'estimated'
10
+ | 'planned'
11
+ | 'in_progress'
12
+ | 'review'
13
+ | 'qa'
14
+ | 'qa_failed'
15
+ | 'pr_submitted'
16
+ | 'merged';
17
+
18
+ export interface CreateStoryInput {
19
+ requirementId?: string | null;
20
+ teamId?: string | null;
21
+ title: string;
22
+ description: string;
23
+ acceptanceCriteria?: string[] | null;
24
+ }
25
+
26
+ export interface UpdateStoryInput {
27
+ teamId?: string | null;
28
+ title?: string;
29
+ description?: string;
30
+ acceptanceCriteria?: string[] | null;
31
+ complexityScore?: number | null;
32
+ storyPoints?: number | null;
33
+ status?: StoryStatus;
34
+ assignedAgentId?: string | null;
35
+ branchName?: string | null;
36
+ prUrl?: string | null;
37
+ }
38
+
39
+ export function createStory(db: Database, input: CreateStoryInput): StoryRow {
40
+ const id = `STORY-${nanoid(6).toUpperCase()}`;
41
+ const acceptanceCriteria = input.acceptanceCriteria
42
+ ? JSON.stringify(input.acceptanceCriteria)
43
+ : null;
44
+ const now = new Date().toISOString();
45
+
46
+ run(db, `
47
+ INSERT INTO stories (id, requirement_id, team_id, title, description, acceptance_criteria, created_at, updated_at)
48
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
49
+ `, [id, input.requirementId || null, input.teamId || null, input.title, input.description, acceptanceCriteria, now, now]);
50
+
51
+ return getStoryById(db, id)!;
52
+ }
53
+
54
+ export function getStoryById(db: Database, id: string): StoryRow | undefined {
55
+ return queryOne<StoryRow>(db, 'SELECT * FROM stories WHERE id = ?', [id]);
56
+ }
57
+
58
+ export function getStoriesByRequirement(db: Database, requirementId: string): StoryRow[] {
59
+ return queryAll<StoryRow>(db, 'SELECT * FROM stories WHERE requirement_id = ? ORDER BY created_at', [requirementId]);
60
+ }
61
+
62
+ export function getStoriesByTeam(db: Database, teamId: string): StoryRow[] {
63
+ return queryAll<StoryRow>(db, 'SELECT * FROM stories WHERE team_id = ? ORDER BY created_at', [teamId]);
64
+ }
65
+
66
+ export function getStoriesByStatus(db: Database, status: StoryStatus): StoryRow[] {
67
+ return queryAll<StoryRow>(db, 'SELECT * FROM stories WHERE status = ? ORDER BY created_at', [status]);
68
+ }
69
+
70
+ export function getStoriesByAgent(db: Database, agentId: string): StoryRow[] {
71
+ return queryAll<StoryRow>(db, 'SELECT * FROM stories WHERE assigned_agent_id = ? ORDER BY created_at', [agentId]);
72
+ }
73
+
74
+ export function getActiveStoriesByAgent(db: Database, agentId: string): StoryRow[] {
75
+ return queryAll<StoryRow>(db, `
76
+ SELECT * FROM stories
77
+ WHERE assigned_agent_id = ?
78
+ AND status IN ('planned', 'in_progress', 'review', 'qa', 'qa_failed', 'pr_submitted')
79
+ ORDER BY created_at
80
+ `, [agentId]);
81
+ }
82
+
83
+ export function getAllStories(db: Database): StoryRow[] {
84
+ return queryAll<StoryRow>(db, 'SELECT * FROM stories ORDER BY created_at DESC');
85
+ }
86
+
87
+ export function getPlannedStories(db: Database): StoryRow[] {
88
+ return queryAll<StoryRow>(db, `
89
+ SELECT * FROM stories
90
+ WHERE status = 'planned'
91
+ ORDER BY story_points DESC, created_at
92
+ `);
93
+ }
94
+
95
+ export function getInProgressStories(db: Database): StoryRow[] {
96
+ return queryAll<StoryRow>(db, `
97
+ SELECT * FROM stories
98
+ WHERE status IN ('in_progress', 'review', 'qa', 'qa_failed')
99
+ ORDER BY created_at
100
+ `);
101
+ }
102
+
103
+ export function getStoryPointsByTeam(db: Database, teamId: string): number {
104
+ const result = queryOne<{ total: number }>(db, `
105
+ SELECT COALESCE(SUM(story_points), 0) as total
106
+ FROM stories
107
+ WHERE team_id = ? AND status IN ('planned', 'in_progress', 'review', 'qa')
108
+ `, [teamId]);
109
+ return result?.total || 0;
110
+ }
111
+
112
+ export function updateStory(db: Database, id: string, input: UpdateStoryInput): StoryRow | undefined {
113
+ const updates: string[] = ['updated_at = ?'];
114
+ const values: (string | number | null)[] = [new Date().toISOString()];
115
+
116
+ if (input.teamId !== undefined) {
117
+ updates.push('team_id = ?');
118
+ values.push(input.teamId);
119
+ }
120
+ if (input.title !== undefined) {
121
+ updates.push('title = ?');
122
+ values.push(input.title);
123
+ }
124
+ if (input.description !== undefined) {
125
+ updates.push('description = ?');
126
+ values.push(input.description);
127
+ }
128
+ if (input.acceptanceCriteria !== undefined) {
129
+ updates.push('acceptance_criteria = ?');
130
+ values.push(input.acceptanceCriteria ? JSON.stringify(input.acceptanceCriteria) : null);
131
+ }
132
+ if (input.complexityScore !== undefined) {
133
+ updates.push('complexity_score = ?');
134
+ values.push(input.complexityScore);
135
+ }
136
+ if (input.storyPoints !== undefined) {
137
+ updates.push('story_points = ?');
138
+ values.push(input.storyPoints);
139
+ }
140
+ if (input.status !== undefined) {
141
+ updates.push('status = ?');
142
+ values.push(input.status);
143
+ }
144
+ if (input.assignedAgentId !== undefined) {
145
+ updates.push('assigned_agent_id = ?');
146
+ values.push(input.assignedAgentId);
147
+ }
148
+ if (input.branchName !== undefined) {
149
+ updates.push('branch_name = ?');
150
+ values.push(input.branchName);
151
+ }
152
+ if (input.prUrl !== undefined) {
153
+ updates.push('pr_url = ?');
154
+ values.push(input.prUrl);
155
+ }
156
+
157
+ if (updates.length === 1) {
158
+ return getStoryById(db, id);
159
+ }
160
+
161
+ values.push(id);
162
+ run(db, `UPDATE stories SET ${updates.join(', ')} WHERE id = ?`, values);
163
+ return getStoryById(db, id);
164
+ }
165
+
166
+ export function deleteStory(db: Database, id: string): void {
167
+ run(db, 'DELETE FROM story_dependencies WHERE story_id = ? OR depends_on_story_id = ?', [id, id]);
168
+ run(db, 'DELETE FROM stories WHERE id = ?', [id]);
169
+ }
170
+
171
+ // Story dependencies
172
+ export function addStoryDependency(db: Database, storyId: string, dependsOnStoryId: string): void {
173
+ run(db, `
174
+ INSERT OR IGNORE INTO story_dependencies (story_id, depends_on_story_id)
175
+ VALUES (?, ?)
176
+ `, [storyId, dependsOnStoryId]);
177
+ }
178
+
179
+ export function removeStoryDependency(db: Database, storyId: string, dependsOnStoryId: string): void {
180
+ run(db, 'DELETE FROM story_dependencies WHERE story_id = ? AND depends_on_story_id = ?', [storyId, dependsOnStoryId]);
181
+ }
182
+
183
+ export function getStoryDependencies(db: Database, storyId: string): StoryRow[] {
184
+ return queryAll<StoryRow>(db, `
185
+ SELECT s.* FROM stories s
186
+ JOIN story_dependencies sd ON s.id = sd.depends_on_story_id
187
+ WHERE sd.story_id = ?
188
+ `, [storyId]);
189
+ }
190
+
191
+ export function getStoriesDependingOn(db: Database, storyId: string): StoryRow[] {
192
+ return queryAll<StoryRow>(db, `
193
+ SELECT s.* FROM stories s
194
+ JOIN story_dependencies sd ON s.id = sd.story_id
195
+ WHERE sd.depends_on_story_id = ?
196
+ `, [storyId]);
197
+ }
198
+
199
+ export function getStoryCounts(db: Database): Record<StoryStatus, number> {
200
+ const rows = queryAll<{ status: StoryStatus; count: number }>(db, `
201
+ SELECT status, COUNT(*) as count
202
+ FROM stories
203
+ GROUP BY status
204
+ `);
205
+
206
+ const counts: Record<StoryStatus, number> = {
207
+ draft: 0,
208
+ estimated: 0,
209
+ planned: 0,
210
+ in_progress: 0,
211
+ review: 0,
212
+ qa: 0,
213
+ qa_failed: 0,
214
+ pr_submitted: 0,
215
+ merged: 0,
216
+ };
217
+
218
+ for (const row of rows) {
219
+ counts[row.status] = row.count;
220
+ }
221
+
222
+ return counts;
223
+ }
@@ -0,0 +1,39 @@
1
+ import type { Database } from 'sql.js';
2
+ import { nanoid } from 'nanoid';
3
+ import { queryAll, queryOne, run, type TeamRow } from '../client.js';
4
+
5
+ export type { TeamRow };
6
+
7
+ export interface CreateTeamInput {
8
+ repoUrl: string;
9
+ repoPath: string;
10
+ name: string;
11
+ }
12
+
13
+ export function createTeam(db: Database, input: CreateTeamInput): TeamRow {
14
+ const id = `team-${nanoid(10)}`;
15
+ const now = new Date().toISOString();
16
+
17
+ run(db, `
18
+ INSERT INTO teams (id, repo_url, repo_path, name, created_at)
19
+ VALUES (?, ?, ?, ?, ?)
20
+ `, [id, input.repoUrl, input.repoPath, input.name, now]);
21
+
22
+ return getTeamById(db, id)!;
23
+ }
24
+
25
+ export function getTeamById(db: Database, id: string): TeamRow | undefined {
26
+ return queryOne<TeamRow>(db, 'SELECT * FROM teams WHERE id = ?', [id]);
27
+ }
28
+
29
+ export function getTeamByName(db: Database, name: string): TeamRow | undefined {
30
+ return queryOne<TeamRow>(db, 'SELECT * FROM teams WHERE name = ?', [name]);
31
+ }
32
+
33
+ export function getAllTeams(db: Database): TeamRow[] {
34
+ return queryAll<TeamRow>(db, 'SELECT * FROM teams ORDER BY created_at');
35
+ }
36
+
37
+ export function deleteTeam(db: Database, id: string): void {
38
+ run(db, 'DELETE FROM teams WHERE id = ?', [id]);
39
+ }
@@ -0,0 +1,186 @@
1
+ import { execa } from 'execa';
2
+
3
+ export interface BranchInfo {
4
+ name: string;
5
+ current: boolean;
6
+ remote?: string;
7
+ upstream?: string;
8
+ lastCommit: string;
9
+ }
10
+
11
+ /**
12
+ * Get current branch name
13
+ */
14
+ export async function getCurrentBranch(workDir: string): Promise<string> {
15
+ const { stdout } = await execa('git', ['branch', '--show-current'], {
16
+ cwd: workDir,
17
+ });
18
+ return stdout.trim();
19
+ }
20
+
21
+ /**
22
+ * List all local branches
23
+ */
24
+ export async function listBranches(workDir: string): Promise<BranchInfo[]> {
25
+ const { stdout } = await execa('git', [
26
+ 'branch', '-v', '--format=%(refname:short)|%(objectname:short)|%(HEAD)',
27
+ ], { cwd: workDir });
28
+
29
+ return stdout.split('\n').filter(Boolean).map(line => {
30
+ const [name, lastCommit, head] = line.split('|');
31
+ return {
32
+ name,
33
+ current: head === '*',
34
+ lastCommit,
35
+ };
36
+ });
37
+ }
38
+
39
+ /**
40
+ * Create a new branch
41
+ */
42
+ export async function createBranch(
43
+ workDir: string,
44
+ name: string,
45
+ startPoint?: string
46
+ ): Promise<void> {
47
+ const args = ['branch', name];
48
+ if (startPoint) {
49
+ args.push(startPoint);
50
+ }
51
+ await execa('git', args, { cwd: workDir });
52
+ }
53
+
54
+ /**
55
+ * Checkout a branch
56
+ */
57
+ export async function checkoutBranch(
58
+ workDir: string,
59
+ name: string,
60
+ create: boolean = false
61
+ ): Promise<void> {
62
+ const args = ['checkout'];
63
+ if (create) {
64
+ args.push('-b');
65
+ }
66
+ args.push(name);
67
+ await execa('git', args, { cwd: workDir });
68
+ }
69
+
70
+ /**
71
+ * Delete a branch
72
+ */
73
+ export async function deleteBranch(
74
+ workDir: string,
75
+ name: string,
76
+ force: boolean = false
77
+ ): Promise<void> {
78
+ const args = ['branch', force ? '-D' : '-d', name];
79
+ await execa('git', args, { cwd: workDir });
80
+ }
81
+
82
+ /**
83
+ * Check if branch exists
84
+ */
85
+ export async function branchExists(workDir: string, name: string): Promise<boolean> {
86
+ try {
87
+ await execa('git', ['rev-parse', '--verify', name], { cwd: workDir });
88
+ return true;
89
+ } catch {
90
+ return false;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Get branch tracking info
96
+ */
97
+ export async function getBranchTracking(workDir: string, branch: string): Promise<{
98
+ upstream: string | null;
99
+ ahead: number;
100
+ behind: number;
101
+ }> {
102
+ try {
103
+ const { stdout: upstream } = await execa('git', [
104
+ 'rev-parse', '--abbrev-ref', `${branch}@{upstream}`,
105
+ ], { cwd: workDir });
106
+
107
+ const { stdout: counts } = await execa('git', [
108
+ 'rev-list', '--left-right', '--count', `${upstream.trim()}...${branch}`,
109
+ ], { cwd: workDir });
110
+
111
+ const [behind, ahead] = counts.trim().split('\t').map(Number);
112
+
113
+ return {
114
+ upstream: upstream.trim(),
115
+ ahead,
116
+ behind,
117
+ };
118
+ } catch {
119
+ return { upstream: null, ahead: 0, behind: 0 };
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Push branch to remote
125
+ */
126
+ export async function pushBranch(
127
+ workDir: string,
128
+ branch: string,
129
+ remote: string = 'origin',
130
+ setUpstream: boolean = false
131
+ ): Promise<void> {
132
+ const args = ['push', remote, branch];
133
+ if (setUpstream) {
134
+ args.splice(1, 0, '-u');
135
+ }
136
+ await execa('git', args, { cwd: workDir });
137
+ }
138
+
139
+ /**
140
+ * Create and checkout a feature branch
141
+ */
142
+ export async function createFeatureBranch(
143
+ workDir: string,
144
+ storyId: string,
145
+ description: string,
146
+ baseBranch: string = 'main'
147
+ ): Promise<string> {
148
+ // Normalize the description for branch name
149
+ const slug = description
150
+ .toLowerCase()
151
+ .replace(/[^a-z0-9]+/g, '-')
152
+ .replace(/^-|-$/g, '')
153
+ .substring(0, 30);
154
+
155
+ const branchName = `feature/${storyId.toLowerCase()}-${slug}`;
156
+
157
+ // Make sure we're on the base branch and up to date
158
+ await checkoutBranch(workDir, baseBranch);
159
+
160
+ try {
161
+ await execa('git', ['pull', 'origin', baseBranch], { cwd: workDir });
162
+ } catch {
163
+ // Pull might fail if no remote tracking, continue anyway
164
+ }
165
+
166
+ // Create and checkout the feature branch
167
+ await checkoutBranch(workDir, branchName, true);
168
+
169
+ return branchName;
170
+ }
171
+
172
+ /**
173
+ * Merge a branch
174
+ */
175
+ export async function mergeBranch(
176
+ workDir: string,
177
+ branch: string,
178
+ noFf: boolean = true
179
+ ): Promise<void> {
180
+ const args = ['merge'];
181
+ if (noFf) {
182
+ args.push('--no-ff');
183
+ }
184
+ args.push(branch);
185
+ await execa('git', args, { cwd: workDir });
186
+ }