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,261 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import {
3
+ getCliRuntimeBuilder,
4
+ validateCliBinary,
5
+ validateCliRuntime,
6
+ ClaudeRuntimeBuilder,
7
+ CodexRuntimeBuilder,
8
+ GeminiRuntimeBuilder,
9
+ } from './index.js';
10
+
11
+ vi.mock('execa');
12
+
13
+ describe('CLI Runtime Builders', () => {
14
+ describe('ClaudeRuntimeBuilder', () => {
15
+ it('should build spawn command with correct flags', () => {
16
+ const builder = new ClaudeRuntimeBuilder();
17
+ const command = builder.buildSpawnCommand('claude-sonnet-4-20250514');
18
+
19
+ expect(command).toEqual([
20
+ 'claude',
21
+ '--dangerously-skip-permissions',
22
+ '--model',
23
+ 'claude-sonnet-4-20250514',
24
+ ]);
25
+ });
26
+
27
+ it('should build resume command with session ID', () => {
28
+ const builder = new ClaudeRuntimeBuilder();
29
+ const command = builder.buildResumeCommand('claude-sonnet-4-20250514', 'session-123');
30
+
31
+ expect(command).toEqual([
32
+ 'claude',
33
+ '--dangerously-skip-permissions',
34
+ '--model',
35
+ 'claude-sonnet-4-20250514',
36
+ '--resume',
37
+ 'session-123',
38
+ ]);
39
+ });
40
+
41
+ it('should return correct auto-approval flag', () => {
42
+ const builder = new ClaudeRuntimeBuilder();
43
+ expect(builder.getAutoApprovalFlag()).toBe('--dangerously-skip-permissions');
44
+ });
45
+
46
+ it('should return correct model flag', () => {
47
+ const builder = new ClaudeRuntimeBuilder();
48
+ expect(builder.getModelFlag()).toBe('--model');
49
+ });
50
+ });
51
+
52
+ describe('CodexRuntimeBuilder', () => {
53
+ it('should build spawn command with correct flags', () => {
54
+ const builder = new CodexRuntimeBuilder();
55
+ const command = builder.buildSpawnCommand('gpt-4o-mini');
56
+
57
+ expect(command).toEqual([
58
+ 'codex',
59
+ '--full-auto',
60
+ '--model',
61
+ 'gpt-4o-mini',
62
+ ]);
63
+ });
64
+
65
+ it('should build resume command with session ID', () => {
66
+ const builder = new CodexRuntimeBuilder();
67
+ const command = builder.buildResumeCommand('gpt-4o-mini', 'session-456');
68
+
69
+ expect(command).toEqual([
70
+ 'codex',
71
+ '--full-auto',
72
+ '--model',
73
+ 'gpt-4o-mini',
74
+ '--resume',
75
+ 'session-456',
76
+ ]);
77
+ });
78
+
79
+ it('should return correct auto-approval flag', () => {
80
+ const builder = new CodexRuntimeBuilder();
81
+ expect(builder.getAutoApprovalFlag()).toBe('--full-auto');
82
+ });
83
+
84
+ it('should return correct model flag', () => {
85
+ const builder = new CodexRuntimeBuilder();
86
+ expect(builder.getModelFlag()).toBe('--model');
87
+ });
88
+ });
89
+
90
+ describe('GeminiRuntimeBuilder', () => {
91
+ it('should build spawn command with correct flags', () => {
92
+ const builder = new GeminiRuntimeBuilder();
93
+ const command = builder.buildSpawnCommand('gemini-2.0-flash-exp');
94
+
95
+ expect(command).toEqual([
96
+ 'gemini',
97
+ '--model',
98
+ 'gemini-2.0-flash-exp',
99
+ '--sandbox',
100
+ 'none',
101
+ ]);
102
+ });
103
+
104
+ it('should build resume command with session ID', () => {
105
+ const builder = new GeminiRuntimeBuilder();
106
+ const command = builder.buildResumeCommand('gemini-2.0-flash-exp', 'session-789');
107
+
108
+ expect(command).toEqual([
109
+ 'gemini',
110
+ '--model',
111
+ 'gemini-2.0-flash-exp',
112
+ '--sandbox',
113
+ 'none',
114
+ '--resume',
115
+ 'session-789',
116
+ ]);
117
+ });
118
+
119
+ it('should return correct auto-approval flag', () => {
120
+ const builder = new GeminiRuntimeBuilder();
121
+ expect(builder.getAutoApprovalFlag()).toBe('--sandbox');
122
+ });
123
+
124
+ it('should return correct model flag', () => {
125
+ const builder = new GeminiRuntimeBuilder();
126
+ expect(builder.getModelFlag()).toBe('--model');
127
+ });
128
+ });
129
+
130
+ describe('getCliRuntimeBuilder', () => {
131
+ it('should return ClaudeRuntimeBuilder for claude type', () => {
132
+ const builder = getCliRuntimeBuilder('claude');
133
+ expect(builder).toBeInstanceOf(ClaudeRuntimeBuilder);
134
+ });
135
+
136
+ it('should return CodexRuntimeBuilder for codex type', () => {
137
+ const builder = getCliRuntimeBuilder('codex');
138
+ expect(builder).toBeInstanceOf(CodexRuntimeBuilder);
139
+ });
140
+
141
+ it('should return GeminiRuntimeBuilder for gemini type', () => {
142
+ const builder = getCliRuntimeBuilder('gemini');
143
+ expect(builder).toBeInstanceOf(GeminiRuntimeBuilder);
144
+ });
145
+
146
+ it('should throw error for unknown runtime type', () => {
147
+ expect(() => {
148
+ // @ts-expect-error Testing invalid input
149
+ getCliRuntimeBuilder('unknown');
150
+ }).toThrow('Unknown CLI runtime type: unknown');
151
+ });
152
+ });
153
+
154
+ describe('validateCliBinary', () => {
155
+ beforeEach(() => {
156
+ vi.clearAllMocks();
157
+ });
158
+
159
+ afterEach(() => {
160
+ vi.restoreAllMocks();
161
+ });
162
+
163
+ it('should return true when binary exists', async () => {
164
+ const { execa } = await import('execa');
165
+ vi.mocked(execa).mockResolvedValue({
166
+ stdout: '/usr/local/bin/claude',
167
+ stderr: '',
168
+ exitCode: 0,
169
+ command: 'which claude',
170
+ escapedCommand: 'which claude',
171
+ failed: false,
172
+ timedOut: false,
173
+ isCanceled: false,
174
+ killed: false,
175
+ } as any);
176
+
177
+ const result = await validateCliBinary('claude');
178
+ expect(result).toBe(true);
179
+ });
180
+
181
+ it('should return false when binary does not exist', async () => {
182
+ const { execa } = await import('execa');
183
+ vi.mocked(execa).mockRejectedValue(new Error('Command failed'));
184
+
185
+ const result = await validateCliBinary('nonexistent');
186
+ expect(result).toBe(false);
187
+ });
188
+ });
189
+
190
+ describe('validateCliRuntime', () => {
191
+ beforeEach(() => {
192
+ vi.clearAllMocks();
193
+ });
194
+
195
+ afterEach(() => {
196
+ vi.restoreAllMocks();
197
+ });
198
+
199
+ it('should validate claude runtime', async () => {
200
+ const { execa } = await import('execa');
201
+ vi.mocked(execa).mockResolvedValue({
202
+ stdout: '/usr/local/bin/claude',
203
+ stderr: '',
204
+ exitCode: 0,
205
+ command: 'which claude',
206
+ escapedCommand: 'which claude',
207
+ failed: false,
208
+ timedOut: false,
209
+ isCanceled: false,
210
+ killed: false,
211
+ } as any);
212
+
213
+ const result = await validateCliRuntime('claude');
214
+ expect(result).toBe(true);
215
+ });
216
+
217
+ it('should validate codex runtime', async () => {
218
+ const { execa } = await import('execa');
219
+ vi.mocked(execa).mockResolvedValue({
220
+ stdout: '/usr/local/bin/codex',
221
+ stderr: '',
222
+ exitCode: 0,
223
+ command: 'which codex',
224
+ escapedCommand: 'which codex',
225
+ failed: false,
226
+ timedOut: false,
227
+ isCanceled: false,
228
+ killed: false,
229
+ } as any);
230
+
231
+ const result = await validateCliRuntime('codex');
232
+ expect(result).toBe(true);
233
+ });
234
+
235
+ it('should validate gemini runtime', async () => {
236
+ const { execa } = await import('execa');
237
+ vi.mocked(execa).mockResolvedValue({
238
+ stdout: '/usr/local/bin/gemini',
239
+ stderr: '',
240
+ exitCode: 0,
241
+ command: 'which gemini',
242
+ escapedCommand: 'which gemini',
243
+ failed: false,
244
+ timedOut: false,
245
+ isCanceled: false,
246
+ killed: false,
247
+ } as any);
248
+
249
+ const result = await validateCliRuntime('gemini');
250
+ expect(result).toBe(true);
251
+ });
252
+
253
+ it('should return false for missing runtime binary', async () => {
254
+ const { execa } = await import('execa');
255
+ vi.mocked(execa).mockRejectedValue(new Error('Command failed'));
256
+
257
+ const result = await validateCliRuntime('claude');
258
+ expect(result).toBe(false);
259
+ });
260
+ });
261
+ });
@@ -0,0 +1,52 @@
1
+ import { execa } from 'execa';
2
+ import { CliRuntimeType, CliRuntimeBuilder } from './types.js';
3
+ import { ClaudeRuntimeBuilder } from './claude.js';
4
+ import { CodexRuntimeBuilder } from './codex.js';
5
+ import { GeminiRuntimeBuilder } from './gemini.js';
6
+
7
+ /**
8
+ * Factory function to get the appropriate CLI runtime builder
9
+ * @param runtimeType - The type of CLI runtime to use
10
+ * @returns The corresponding runtime builder instance
11
+ * @throws Error if the runtime type is unknown
12
+ */
13
+ export function getCliRuntimeBuilder(runtimeType: CliRuntimeType): CliRuntimeBuilder {
14
+ switch (runtimeType) {
15
+ case 'claude':
16
+ return new ClaudeRuntimeBuilder();
17
+ case 'codex':
18
+ return new CodexRuntimeBuilder();
19
+ case 'gemini':
20
+ return new GeminiRuntimeBuilder();
21
+ default:
22
+ throw new Error(`Unknown CLI runtime type: ${runtimeType}`);
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Validate that a CLI binary is available in the system PATH
28
+ * @param binary - The name of the binary to check
29
+ * @returns Promise that resolves to true if binary exists, false otherwise
30
+ */
31
+ export async function validateCliBinary(binary: string): Promise<boolean> {
32
+ try {
33
+ await execa('which', [binary]);
34
+ return true;
35
+ } catch {
36
+ return false;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Validate that the CLI runtime binary is available
42
+ * @param runtimeType - The type of CLI runtime to validate
43
+ * @returns Promise that resolves to true if binary exists, false otherwise
44
+ */
45
+ export async function validateCliRuntime(runtimeType: CliRuntimeType): Promise<boolean> {
46
+ return validateCliBinary(runtimeType);
47
+ }
48
+
49
+ export type { CliRuntimeType, CliRuntimeBuilder };
50
+ export { ClaudeRuntimeBuilder } from './claude.js';
51
+ export { CodexRuntimeBuilder } from './codex.js';
52
+ export { GeminiRuntimeBuilder } from './gemini.js';
@@ -0,0 +1,30 @@
1
+ export type CliRuntimeType = 'claude' | 'codex' | 'gemini';
2
+
3
+ export interface CliRuntimeBuilder {
4
+ /**
5
+ * Build command array for spawning a new agent session
6
+ * @param model - The model identifier to use
7
+ * @returns Array of command and arguments suitable for spawn
8
+ */
9
+ buildSpawnCommand(model: string): string[];
10
+
11
+ /**
12
+ * Build command array for resuming an existing agent session
13
+ * @param model - The model identifier to use
14
+ * @param sessionId - The session ID to resume
15
+ * @returns Array of command and arguments suitable for spawn
16
+ */
17
+ buildResumeCommand(model: string, sessionId: string): string[];
18
+
19
+ /**
20
+ * Get the auto-approval flag for this CLI runtime
21
+ * @returns The flag string that enables auto-approval mode
22
+ */
23
+ getAutoApprovalFlag(): string;
24
+
25
+ /**
26
+ * Get the model flag for this CLI runtime
27
+ * @returns The flag string used to specify the model
28
+ */
29
+ getModelFlag(): string;
30
+ }
@@ -0,0 +1,2 @@
1
+ export * from './schema.js';
2
+ export * from './loader.js';
@@ -0,0 +1,89 @@
1
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { parse, stringify } from 'yaml';
4
+ import { HiveConfigSchema, type HiveConfig, generateDefaultConfigYaml } from './schema.js';
5
+
6
+ export class ConfigError extends Error {
7
+ constructor(message: string) {
8
+ super(message);
9
+ this.name = 'ConfigError';
10
+ }
11
+ }
12
+
13
+ export function loadConfig(hiveDir: string): HiveConfig {
14
+ const configPath = join(hiveDir, 'hive.config.yaml');
15
+
16
+ if (!existsSync(configPath)) {
17
+ throw new ConfigError(`Config file not found: ${configPath}`);
18
+ }
19
+
20
+ const content = readFileSync(configPath, 'utf-8');
21
+ const rawConfig = parse(content);
22
+
23
+ const result = HiveConfigSchema.safeParse(rawConfig);
24
+
25
+ if (!result.success) {
26
+ const errors = result.error.errors.map(e => ` - ${e.path.join('.')}: ${e.message}`).join('\n');
27
+ throw new ConfigError(`Invalid configuration:\n${errors}`);
28
+ }
29
+
30
+ return result.data;
31
+ }
32
+
33
+ export function saveConfig(hiveDir: string, config: HiveConfig): void {
34
+ const configPath = join(hiveDir, 'hive.config.yaml');
35
+ const content = stringify(config, { indent: 2 });
36
+ writeFileSync(configPath, content, 'utf-8');
37
+ }
38
+
39
+ export function createDefaultConfig(hiveDir: string): HiveConfig {
40
+ const configPath = join(hiveDir, 'hive.config.yaml');
41
+ const content = generateDefaultConfigYaml();
42
+ writeFileSync(configPath, content, 'utf-8');
43
+ return loadConfig(hiveDir);
44
+ }
45
+
46
+ export function configExists(hiveDir: string): boolean {
47
+ const configPath = join(hiveDir, 'hive.config.yaml');
48
+ return existsSync(configPath);
49
+ }
50
+
51
+ export function getConfigValue(config: HiveConfig, path: string): unknown {
52
+ const parts = path.split('.');
53
+ let current: unknown = config;
54
+
55
+ for (const part of parts) {
56
+ if (current === null || current === undefined || typeof current !== 'object') {
57
+ return undefined;
58
+ }
59
+ current = (current as Record<string, unknown>)[part];
60
+ }
61
+
62
+ return current;
63
+ }
64
+
65
+ export function setConfigValue(config: HiveConfig, path: string, value: unknown): HiveConfig {
66
+ const parts = path.split('.');
67
+ const newConfig = JSON.parse(JSON.stringify(config)) as HiveConfig;
68
+
69
+ let current = newConfig as Record<string, unknown>;
70
+ for (let i = 0; i < parts.length - 1; i++) {
71
+ const part = parts[i];
72
+ if (current[part] === undefined || typeof current[part] !== 'object') {
73
+ current[part] = {};
74
+ }
75
+ current = current[part] as Record<string, unknown>;
76
+ }
77
+
78
+ const lastPart = parts[parts.length - 1];
79
+ current[lastPart] = value;
80
+
81
+ // Validate the new config
82
+ const result = HiveConfigSchema.safeParse(newConfig);
83
+ if (!result.success) {
84
+ const errors = result.error.errors.map(e => ` - ${e.path.join('.')}: ${e.message}`).join('\n');
85
+ throw new ConfigError(`Invalid configuration after update:\n${errors}`);
86
+ }
87
+
88
+ return result.data;
89
+ }
@@ -0,0 +1,135 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { HiveConfigSchema, DEFAULT_CONFIG } from './schema.js';
3
+
4
+ describe('HiveConfigSchema', () => {
5
+ it('should validate default config', () => {
6
+ const result = HiveConfigSchema.safeParse(DEFAULT_CONFIG);
7
+ expect(result.success).toBe(true);
8
+ });
9
+
10
+ it('should accept valid config with cli_tool', () => {
11
+ const config = {
12
+ version: '1.0',
13
+ models: {
14
+ tech_lead: {
15
+ provider: 'anthropic',
16
+ model: 'claude-opus-4-20250514',
17
+ max_tokens: 16000,
18
+ temperature: 0.7,
19
+ cli_tool: 'claude',
20
+ },
21
+ senior: {
22
+ provider: 'anthropic',
23
+ model: 'claude-sonnet-4-20250514',
24
+ max_tokens: 8000,
25
+ temperature: 0.5,
26
+ cli_tool: 'claude',
27
+ },
28
+ intermediate: {
29
+ provider: 'anthropic',
30
+ model: 'claude-haiku-3-5-20241022',
31
+ max_tokens: 4000,
32
+ temperature: 0.3,
33
+ cli_tool: 'claude',
34
+ },
35
+ junior: {
36
+ provider: 'openai',
37
+ model: 'gpt-4o-mini',
38
+ max_tokens: 4000,
39
+ temperature: 0.2,
40
+ cli_tool: 'codex',
41
+ },
42
+ qa: {
43
+ provider: 'anthropic',
44
+ model: 'claude-sonnet-4-20250514',
45
+ max_tokens: 8000,
46
+ temperature: 0.2,
47
+ cli_tool: 'claude',
48
+ },
49
+ },
50
+ scaling: {
51
+ senior_capacity: 20,
52
+ junior_max_complexity: 3,
53
+ intermediate_max_complexity: 5,
54
+ },
55
+ github: {
56
+ base_branch: 'main',
57
+ },
58
+ };
59
+
60
+ const result = HiveConfigSchema.safeParse(config);
61
+ expect(result.success).toBe(true);
62
+ });
63
+
64
+ it('should apply defaults for empty config', () => {
65
+ const result = HiveConfigSchema.safeParse({});
66
+ expect(result.success).toBe(true);
67
+ if (result.success) {
68
+ expect(result.data.version).toBe('1.0');
69
+ expect(result.data.scaling.senior_capacity).toBe(20);
70
+ }
71
+ });
72
+
73
+ it('should reject invalid scaling values', () => {
74
+ const config = {
75
+ scaling: {
76
+ junior_max_complexity: 15, // Invalid: max is 13
77
+ },
78
+ };
79
+
80
+ const result = HiveConfigSchema.safeParse(config);
81
+ expect(result.success).toBe(false);
82
+ });
83
+
84
+ it('should accept all valid cli_tool values (claude, codex, gemini)', () => {
85
+ const tools = ['claude', 'codex', 'gemini'];
86
+
87
+ for (const tool of tools) {
88
+ const config = {
89
+ models: {
90
+ junior: {
91
+ provider: 'openai',
92
+ model: 'gpt-4o-mini',
93
+ cli_tool: tool,
94
+ },
95
+ },
96
+ };
97
+
98
+ const result = HiveConfigSchema.safeParse(config);
99
+ expect(result.success).toBe(true);
100
+ }
101
+ });
102
+
103
+ it('should reject invalid cli_tool values', () => {
104
+ const config = {
105
+ models: {
106
+ junior: {
107
+ provider: 'openai',
108
+ model: 'gpt-4o-mini',
109
+ max_tokens: 4000,
110
+ temperature: 0.2,
111
+ cli_tool: 'invalid_tool',
112
+ },
113
+ },
114
+ };
115
+
116
+ const result = HiveConfigSchema.safeParse(config);
117
+ expect(result.success).toBe(false);
118
+ });
119
+
120
+ it('should apply cli_tool default to all tiers', () => {
121
+ const config = HiveConfigSchema.parse({});
122
+ expect(config.models.tech_lead.cli_tool).toBe('claude');
123
+ expect(config.models.senior.cli_tool).toBe('claude');
124
+ expect(config.models.intermediate.cli_tool).toBe('claude');
125
+ expect(config.models.junior.cli_tool).toBe('claude');
126
+ expect(config.models.qa.cli_tool).toBe('claude');
127
+ });
128
+
129
+ it('should export ModelConfig type with cli_tool', () => {
130
+ const config = DEFAULT_CONFIG;
131
+ expect(config.models).toBeDefined();
132
+ expect(config.models.junior.cli_tool).toBe('claude');
133
+ expect(typeof config.models.junior.cli_tool).toBe('string');
134
+ });
135
+ });