@recombine-ai/bosun 0.16.2 → 0.17.1

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 (524) hide show
  1. package/README.md +24 -0
  2. package/bin/bosun.js +153 -20
  3. package/bin/git-mode.js +1139 -0
  4. package/build/client/_app/immutable/assets/0.D9HpHezk.css +1 -0
  5. package/build/client/_app/immutable/assets/0.D9HpHezk.css.br +0 -0
  6. package/build/client/_app/immutable/assets/0.D9HpHezk.css.gz +0 -0
  7. package/build/client/_app/immutable/assets/{2.DtxQDOXx.css → 2.Bc0Sf3YD.css} +1 -1
  8. package/build/client/_app/immutable/assets/2.Bc0Sf3YD.css.br +0 -0
  9. package/build/client/_app/immutable/assets/2.Bc0Sf3YD.css.gz +0 -0
  10. package/build/client/_app/immutable/chunks/{DneQQ7D5.js → -3ZOIHDA.js} +1 -1
  11. package/build/client/_app/immutable/chunks/-3ZOIHDA.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/-3ZOIHDA.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/7hV1SZxK.js +1 -0
  14. package/build/client/_app/immutable/chunks/7hV1SZxK.js.br +2 -0
  15. package/build/client/_app/immutable/chunks/7hV1SZxK.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/B-dTD_wm.js +1 -0
  17. package/build/client/_app/immutable/chunks/B-dTD_wm.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/B-dTD_wm.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/{UqjCSZmA.js → B-iasAJv.js} +1 -1
  20. package/build/client/_app/immutable/chunks/B-iasAJv.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/B-iasAJv.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/BDijIo6D.js +33 -0
  23. package/build/client/_app/immutable/chunks/BDijIo6D.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/BDijIo6D.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/BHB0Pj1h.js +2 -0
  26. package/build/client/_app/immutable/chunks/BHB0Pj1h.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/BHB0Pj1h.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/{Bog028VR.js → BKfmN1Rj.js} +1 -1
  29. package/build/client/_app/immutable/chunks/BKfmN1Rj.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/BKfmN1Rj.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/{pPpIn6tB.js → BlFOg-Sd.js} +1 -1
  32. package/build/client/_app/immutable/chunks/BlFOg-Sd.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/BlFOg-Sd.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/{CJcZ2GVC.js → Byg3jr1u.js} +1 -1
  35. package/build/client/_app/immutable/chunks/Byg3jr1u.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/Byg3jr1u.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/{Bmd5zhWC.js → BzxxLgHi.js} +1 -1
  38. package/build/client/_app/immutable/chunks/BzxxLgHi.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/BzxxLgHi.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/{CEHsomMo.js → C4UC6AgE.js} +1 -1
  41. package/build/client/_app/immutable/chunks/C4UC6AgE.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/{CEHsomMo.js.gz → C4UC6AgE.js.gz} +0 -0
  43. package/build/client/_app/immutable/chunks/C60AG6QQ.js +1 -0
  44. package/build/client/_app/immutable/chunks/C60AG6QQ.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/C60AG6QQ.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/CAIfVN23.js +1 -0
  47. package/build/client/_app/immutable/chunks/CAIfVN23.js.br +0 -0
  48. package/build/client/_app/immutable/chunks/CAIfVN23.js.gz +0 -0
  49. package/build/client/_app/immutable/chunks/{JcG4w2gF.js → CB9iDxwI.js} +1 -1
  50. package/build/client/_app/immutable/chunks/CB9iDxwI.js.br +0 -0
  51. package/build/client/_app/immutable/chunks/CB9iDxwI.js.gz +0 -0
  52. package/build/client/_app/immutable/chunks/{DoD3q5w5.js → CD_KdWs9.js} +1 -1
  53. package/build/client/_app/immutable/chunks/CD_KdWs9.js.br +0 -0
  54. package/build/client/_app/immutable/chunks/CD_KdWs9.js.gz +0 -0
  55. package/build/client/_app/immutable/chunks/CDy1LBR5.js +1 -0
  56. package/build/client/_app/immutable/chunks/CDy1LBR5.js.br +0 -0
  57. package/build/client/_app/immutable/chunks/CDy1LBR5.js.gz +0 -0
  58. package/build/client/_app/immutable/chunks/{DCXjBDmY.js → CMFNmSvo.js} +1 -1
  59. package/build/client/_app/immutable/chunks/CMFNmSvo.js.br +0 -0
  60. package/build/client/_app/immutable/chunks/CMFNmSvo.js.gz +0 -0
  61. package/build/client/_app/immutable/chunks/{Bv1mNXs0.js → CNIn4L55.js} +1 -1
  62. package/build/client/_app/immutable/chunks/CNIn4L55.js.br +0 -0
  63. package/build/client/_app/immutable/chunks/CNIn4L55.js.gz +0 -0
  64. package/build/client/_app/immutable/chunks/CUKoVL36.js +1 -0
  65. package/build/client/_app/immutable/chunks/CUKoVL36.js.br +0 -0
  66. package/build/client/_app/immutable/chunks/CUKoVL36.js.gz +0 -0
  67. package/build/client/_app/immutable/chunks/CYGbCr1i.js +3 -0
  68. package/build/client/_app/immutable/chunks/CYGbCr1i.js.br +0 -0
  69. package/build/client/_app/immutable/chunks/CYGbCr1i.js.gz +0 -0
  70. package/build/client/_app/immutable/chunks/CYr0FGgn.js +1 -0
  71. package/build/client/_app/immutable/chunks/CYr0FGgn.js.br +0 -0
  72. package/build/client/_app/immutable/chunks/CYr0FGgn.js.gz +0 -0
  73. package/build/client/_app/immutable/chunks/{DtXXy94i.js → Ce6a22qU.js} +1 -1
  74. package/build/client/_app/immutable/chunks/Ce6a22qU.js.br +0 -0
  75. package/build/client/_app/immutable/chunks/Ce6a22qU.js.gz +0 -0
  76. package/build/client/_app/immutable/chunks/{DfcDjAv-.js → CeoQ-OhK.js} +1 -1
  77. package/build/client/_app/immutable/chunks/CeoQ-OhK.js.br +0 -0
  78. package/build/client/_app/immutable/chunks/CeoQ-OhK.js.gz +0 -0
  79. package/build/client/_app/immutable/chunks/{D8mA-uZ4.js → CupXtwVS.js} +1 -1
  80. package/build/client/_app/immutable/chunks/CupXtwVS.js.br +0 -0
  81. package/build/client/_app/immutable/chunks/CupXtwVS.js.gz +0 -0
  82. package/build/client/_app/immutable/chunks/{B5zf3x62.js → Cy2Uze-c.js} +1 -1
  83. package/build/client/_app/immutable/chunks/Cy2Uze-c.js.br +0 -0
  84. package/build/client/_app/immutable/chunks/Cy2Uze-c.js.gz +0 -0
  85. package/build/client/_app/immutable/chunks/{Dg0A8wPA.js → D8Lmn3S5.js} +1 -1
  86. package/build/client/_app/immutable/chunks/D8Lmn3S5.js.br +0 -0
  87. package/build/client/_app/immutable/chunks/D8Lmn3S5.js.gz +0 -0
  88. package/build/client/_app/immutable/chunks/D8doM1Y6.js +1 -0
  89. package/build/client/_app/immutable/chunks/D8doM1Y6.js.br +2 -0
  90. package/build/client/_app/immutable/chunks/D8doM1Y6.js.gz +0 -0
  91. package/build/client/_app/immutable/chunks/{BHHfrjbV.js → D9BWOD7V.js} +1 -1
  92. package/build/client/_app/immutable/chunks/D9BWOD7V.js.br +3 -0
  93. package/build/client/_app/immutable/chunks/D9BWOD7V.js.gz +0 -0
  94. package/build/client/_app/immutable/chunks/{Cp_st-64.js → DBB88ZB7.js} +1 -1
  95. package/build/client/_app/immutable/chunks/DBB88ZB7.js.br +2 -0
  96. package/build/client/_app/immutable/chunks/DBB88ZB7.js.gz +0 -0
  97. package/build/client/_app/immutable/chunks/{Dm49pcMm.js → DC7lPrn4.js} +1 -1
  98. package/build/client/_app/immutable/chunks/DC7lPrn4.js.br +0 -0
  99. package/build/client/_app/immutable/chunks/DC7lPrn4.js.gz +0 -0
  100. package/build/client/_app/immutable/chunks/DCwWNTpf.js +9 -0
  101. package/build/client/_app/immutable/chunks/DCwWNTpf.js.br +0 -0
  102. package/build/client/_app/immutable/chunks/DCwWNTpf.js.gz +0 -0
  103. package/build/client/_app/immutable/chunks/{wcTQUnZO.js → DEnUeQNt.js} +1 -1
  104. package/build/client/_app/immutable/chunks/DEnUeQNt.js.br +0 -0
  105. package/build/client/_app/immutable/chunks/DEnUeQNt.js.gz +0 -0
  106. package/build/client/_app/immutable/chunks/D_laxq3h.js +1 -0
  107. package/build/client/_app/immutable/chunks/D_laxq3h.js.br +0 -0
  108. package/build/client/_app/immutable/chunks/D_laxq3h.js.gz +0 -0
  109. package/build/client/_app/immutable/chunks/{Ddv5LgEc.js → DfkYlKBk.js} +1 -1
  110. package/build/client/_app/immutable/chunks/DfkYlKBk.js.br +0 -0
  111. package/build/client/_app/immutable/chunks/DfkYlKBk.js.gz +0 -0
  112. package/build/client/_app/immutable/chunks/DnMS2X6M.js +2 -0
  113. package/build/client/_app/immutable/chunks/DnMS2X6M.js.br +0 -0
  114. package/build/client/_app/immutable/chunks/DnMS2X6M.js.gz +0 -0
  115. package/build/client/_app/immutable/chunks/{B1HdnQRQ.js → DrE1ro9S.js} +1 -1
  116. package/build/client/_app/immutable/chunks/DrE1ro9S.js.br +0 -0
  117. package/build/client/_app/immutable/chunks/DrE1ro9S.js.gz +0 -0
  118. package/build/client/_app/immutable/chunks/DzY_RPb9.js +1 -0
  119. package/build/client/_app/immutable/chunks/DzY_RPb9.js.br +0 -0
  120. package/build/client/_app/immutable/chunks/DzY_RPb9.js.gz +0 -0
  121. package/build/client/_app/immutable/chunks/PrCSpCPg.js +1 -0
  122. package/build/client/_app/immutable/chunks/PrCSpCPg.js.br +0 -0
  123. package/build/client/_app/immutable/chunks/PrCSpCPg.js.gz +0 -0
  124. package/build/client/_app/immutable/chunks/{CN555stc.js → eMofpOrR.js} +1 -1
  125. package/build/client/_app/immutable/chunks/eMofpOrR.js.br +0 -0
  126. package/build/client/_app/immutable/chunks/eMofpOrR.js.gz +0 -0
  127. package/build/client/_app/immutable/entry/app.BQUuHkSR.js +2 -0
  128. package/build/client/_app/immutable/entry/app.BQUuHkSR.js.br +0 -0
  129. package/build/client/_app/immutable/entry/app.BQUuHkSR.js.gz +0 -0
  130. package/build/client/_app/immutable/entry/start.DoeTycdu.js +1 -0
  131. package/build/client/_app/immutable/entry/start.DoeTycdu.js.br +2 -0
  132. package/build/client/_app/immutable/entry/start.DoeTycdu.js.gz +0 -0
  133. package/build/client/_app/immutable/nodes/0.DBnFpwRM.js +4 -0
  134. package/build/client/_app/immutable/nodes/0.DBnFpwRM.js.br +0 -0
  135. package/build/client/_app/immutable/nodes/0.DBnFpwRM.js.gz +0 -0
  136. package/build/client/_app/immutable/nodes/1.D-kI-fLd.js +1 -0
  137. package/build/client/_app/immutable/nodes/1.D-kI-fLd.js.br +0 -0
  138. package/build/client/_app/immutable/nodes/1.D-kI-fLd.js.gz +0 -0
  139. package/build/client/_app/immutable/nodes/10.DWb5H7vX.js +28 -0
  140. package/build/client/_app/immutable/nodes/10.DWb5H7vX.js.br +0 -0
  141. package/build/client/_app/immutable/nodes/10.DWb5H7vX.js.gz +0 -0
  142. package/build/client/_app/immutable/nodes/{15.D2I0y3ys.js → 15.CGc3_07c.js} +1 -1
  143. package/build/client/_app/immutable/nodes/15.CGc3_07c.js.br +3 -0
  144. package/build/client/_app/immutable/nodes/15.CGc3_07c.js.gz +0 -0
  145. package/build/client/_app/immutable/nodes/17.BIba62hW.js +3 -0
  146. package/build/client/_app/immutable/nodes/17.BIba62hW.js.br +0 -0
  147. package/build/client/_app/immutable/nodes/17.BIba62hW.js.gz +0 -0
  148. package/build/client/_app/immutable/nodes/18.Clxr6FwI.js +11 -0
  149. package/build/client/_app/immutable/nodes/18.Clxr6FwI.js.br +0 -0
  150. package/build/client/_app/immutable/nodes/18.Clxr6FwI.js.gz +0 -0
  151. package/build/client/_app/immutable/nodes/2.cbpnR8be.js +35 -0
  152. package/build/client/_app/immutable/nodes/2.cbpnR8be.js.br +0 -0
  153. package/build/client/_app/immutable/nodes/2.cbpnR8be.js.gz +0 -0
  154. package/build/client/_app/immutable/nodes/3.DsP759xk.js +1 -0
  155. package/build/client/_app/immutable/nodes/3.DsP759xk.js.br +0 -0
  156. package/build/client/_app/immutable/nodes/3.DsP759xk.js.gz +0 -0
  157. package/build/client/_app/immutable/nodes/{4.C8VxVbVn.js → 4.BIGLAIDe.js} +1 -1
  158. package/build/client/_app/immutable/nodes/4.BIGLAIDe.js.br +0 -0
  159. package/build/client/_app/immutable/nodes/4.BIGLAIDe.js.gz +0 -0
  160. package/build/client/_app/immutable/nodes/{5.BjrnKYaA.js → 5.zMHOyhDv.js} +1 -1
  161. package/build/client/_app/immutable/nodes/5.zMHOyhDv.js.br +0 -0
  162. package/build/client/_app/immutable/nodes/5.zMHOyhDv.js.gz +0 -0
  163. package/build/client/_app/immutable/nodes/6.DFQ1IZsQ.js +1 -0
  164. package/build/client/_app/immutable/nodes/6.DFQ1IZsQ.js.br +0 -0
  165. package/build/client/_app/immutable/nodes/6.DFQ1IZsQ.js.gz +0 -0
  166. package/build/client/_app/immutable/nodes/8.CTgEdr7L.js +2 -0
  167. package/build/client/_app/immutable/nodes/8.CTgEdr7L.js.br +0 -0
  168. package/build/client/_app/immutable/nodes/8.CTgEdr7L.js.gz +0 -0
  169. package/build/client/_app/immutable/nodes/9.BidF5Uvq.js +2 -0
  170. package/build/client/_app/immutable/nodes/9.BidF5Uvq.js.br +0 -0
  171. package/build/client/_app/immutable/nodes/9.BidF5Uvq.js.gz +0 -0
  172. package/build/client/_app/version.json +1 -1
  173. package/build/client/_app/version.json.br +0 -0
  174. package/build/client/_app/version.json.gz +0 -0
  175. package/build/server/chunks/0-BZOFUIfF.js +9 -0
  176. package/build/server/chunks/0-BZOFUIfF.js.map +1 -0
  177. package/build/server/chunks/1-XwGU5VVN.js +9 -0
  178. package/build/server/chunks/{1-C0HdTvXW.js.map → 1-XwGU5VVN.js.map} +1 -1
  179. package/build/server/chunks/10-BgFSx4ib.js +9 -0
  180. package/build/server/chunks/10-BgFSx4ib.js.map +1 -0
  181. package/build/server/chunks/15-BjTTC1jf.js +9 -0
  182. package/build/server/chunks/{15-BQcb9C_y.js.map → 15-BjTTC1jf.js.map} +1 -1
  183. package/build/server/chunks/17-BEkWCfzc.js +9 -0
  184. package/build/server/chunks/17-BEkWCfzc.js.map +1 -0
  185. package/build/server/chunks/18-C-S0wKdp.js +9 -0
  186. package/build/server/chunks/18-C-S0wKdp.js.map +1 -0
  187. package/build/server/chunks/2-o-cIkIjs.js +9 -0
  188. package/build/server/chunks/2-o-cIkIjs.js.map +1 -0
  189. package/build/server/chunks/3-B-ABlyFO.js +9 -0
  190. package/build/server/chunks/3-B-ABlyFO.js.map +1 -0
  191. package/build/server/chunks/4-joAFA_Y8.js +9 -0
  192. package/build/server/chunks/4-joAFA_Y8.js.map +1 -0
  193. package/build/server/chunks/5-DIhC9k4l.js +9 -0
  194. package/build/server/chunks/5-DIhC9k4l.js.map +1 -0
  195. package/build/server/chunks/6-CMuAQIcW.js +9 -0
  196. package/build/server/chunks/6-CMuAQIcW.js.map +1 -0
  197. package/build/server/chunks/8-CbETTVRG.js +9 -0
  198. package/build/server/chunks/8-CbETTVRG.js.map +1 -0
  199. package/build/server/chunks/9-nMV90uVU.js +9 -0
  200. package/build/server/chunks/9-nMV90uVU.js.map +1 -0
  201. package/build/server/chunks/{AgentSidebar-BWBnqHnV.js → AgentSidebar-BEbSdZdN.js} +4 -4
  202. package/build/server/chunks/{AgentSidebar-BWBnqHnV.js.map → AgentSidebar-BEbSdZdN.js.map} +1 -1
  203. package/build/server/chunks/{Button-DH7gdU0s.js → Button-Dc9CR4Wh.js} +2 -2
  204. package/build/server/chunks/{Button-DH7gdU0s.js.map → Button-Dc9CR4Wh.js.map} +1 -1
  205. package/build/server/chunks/{ChatStepTrace-BivoNYOY.js → ChatStepTrace-OM96X4g8.js} +18 -7
  206. package/build/server/chunks/ChatStepTrace-OM96X4g8.js.map +1 -0
  207. package/build/server/chunks/{Dropdown-DnARl86Q.js → Dropdown-Cgd7pG-k.js} +2 -2
  208. package/build/server/chunks/{Dropdown-DnARl86Q.js.map → Dropdown-Cgd7pG-k.js.map} +1 -1
  209. package/build/server/chunks/GitControlsButton-BLcNzrDt.js +81 -0
  210. package/build/server/chunks/GitControlsButton-BLcNzrDt.js.map +1 -0
  211. package/build/server/chunks/{Icon-DP1YKCRV.js → Icon-Bogvl2n9.js} +2 -2
  212. package/build/server/chunks/{Icon-DP1YKCRV.js.map → Icon-Bogvl2n9.js.map} +1 -1
  213. package/build/server/chunks/{Input-CUJ9Cg7b.js → Input-7hpw1WLW.js} +2 -2
  214. package/build/server/chunks/{Input-CUJ9Cg7b.js.map → Input-7hpw1WLW.js.map} +1 -1
  215. package/build/server/chunks/{Modal-CGJuNpZ0.js → Modal-7IIIfFEG.js} +5 -5
  216. package/build/server/chunks/{Modal-CGJuNpZ0.js.map → Modal-7IIIfFEG.js.map} +1 -1
  217. package/build/server/chunks/{Panel-zvjxe036.js → Panel-Cj1mXx9-.js} +2 -2
  218. package/build/server/chunks/{Panel-zvjxe036.js.map → Panel-Cj1mXx9-.js.map} +1 -1
  219. package/build/server/chunks/{Tab-CUkyLqbN.js → Tab-bf4ZDs5y.js} +4 -4
  220. package/build/server/chunks/{Tab-CUkyLqbN.js.map → Tab-bf4ZDs5y.js.map} +1 -1
  221. package/build/server/chunks/{_layout.svelte-BnrWYuLv.js → _layout.svelte-C71luIwv.js} +10 -10
  222. package/build/server/chunks/{_layout.svelte-BnrWYuLv.js.map → _layout.svelte-C71luIwv.js.map} +1 -1
  223. package/build/server/chunks/{_layout.svelte-wi6o5Ecu.js → _layout.svelte-CFhHgXI_.js} +24 -18
  224. package/build/server/chunks/_layout.svelte-CFhHgXI_.js.map +1 -0
  225. package/build/server/chunks/_layout.svelte-CJd_pmkx.js +431 -0
  226. package/build/server/chunks/_layout.svelte-CJd_pmkx.js.map +1 -0
  227. package/build/server/chunks/{_layout.svelte-B88WMyk0.js → _layout.svelte-D6rhwm98.js} +445 -70
  228. package/build/server/chunks/_layout.svelte-D6rhwm98.js.map +1 -0
  229. package/build/server/chunks/{_page.svelte-CeS_21Ho.js → _page.svelte-BBvDMiTV.js} +25 -21
  230. package/build/server/chunks/_page.svelte-BBvDMiTV.js.map +1 -0
  231. package/build/server/chunks/{_page.svelte-h_J4lNT9.js → _page.svelte-BQs9dEuq.js} +8 -7
  232. package/build/server/chunks/{_page.svelte-h_J4lNT9.js.map → _page.svelte-BQs9dEuq.js.map} +1 -1
  233. package/build/server/chunks/{_page.svelte-DhFNFMnl.js → _page.svelte-BoO2LWVX.js} +34 -14
  234. package/build/server/chunks/_page.svelte-BoO2LWVX.js.map +1 -0
  235. package/build/server/chunks/{_page.svelte-CHgQjBQj.js → _page.svelte-DUCTSdv-.js} +2 -2
  236. package/build/server/chunks/{_page.svelte-CHgQjBQj.js.map → _page.svelte-DUCTSdv-.js.map} +1 -1
  237. package/build/server/chunks/_page.svelte-FXYLKyMw.js +110 -0
  238. package/build/server/chunks/_page.svelte-FXYLKyMw.js.map +1 -0
  239. package/build/server/chunks/{_page.svelte-57pyhszV.js → _page.svelte-KA1hqKj2.js} +20 -107
  240. package/build/server/chunks/_page.svelte-KA1hqKj2.js.map +1 -0
  241. package/build/server/chunks/{_page.svelte-BSVJ2d2G.js → _page.svelte-y8CZFL8a.js} +210 -106
  242. package/build/server/chunks/_page.svelte-y8CZFL8a.js.map +1 -0
  243. package/build/server/chunks/{_page.svelte-DHSYVLoj.js → _page.svelte-yIHSIEW6.js} +21 -15
  244. package/build/server/chunks/_page.svelte-yIHSIEW6.js.map +1 -0
  245. package/build/server/chunks/_server.ts-Cp9DgLcE.js +336 -0
  246. package/build/server/chunks/_server.ts-Cp9DgLcE.js.map +1 -0
  247. package/build/server/chunks/{agents-context-CbFsZmi5.js → agents-context-owgusUPR.js} +2 -2
  248. package/build/server/chunks/{agents-context-CbFsZmi5.js.map → agents-context-owgusUPR.js.map} +1 -1
  249. package/build/server/chunks/{client-DO-hqMbT.js → client-P-7bDULt.js} +4 -4
  250. package/build/server/chunks/{client-DO-hqMbT.js.map → client-P-7bDULt.js.map} +1 -1
  251. package/build/server/chunks/{conversation-view-memory-CtbUZd_L.js → conversation-view-memory-SdpdqTR7.js} +2 -2
  252. package/build/server/chunks/{conversation-view-memory-CtbUZd_L.js.map → conversation-view-memory-SdpdqTR7.js.map} +1 -1
  253. package/build/server/chunks/{edit-workspace-context-tyHBPujC.js → edit-workspace-context-hanFnXR3.js} +2 -2
  254. package/build/server/chunks/{edit-workspace-context-tyHBPujC.js.map → edit-workspace-context-hanFnXR3.js.map} +1 -1
  255. package/build/server/chunks/error.svelte-yI9RS6H4.js +15 -0
  256. package/build/server/chunks/{error.svelte-DmKKN1RU.js.map → error.svelte-yI9RS6H4.js.map} +1 -1
  257. package/build/server/chunks/git-mode-context-BpNsAUGF.js +18 -0
  258. package/build/server/chunks/git-mode-context-BpNsAUGF.js.map +1 -0
  259. package/build/server/chunks/{index-LMsd1ih2.js → index-DGtbUu8Y.js} +2 -2
  260. package/build/server/chunks/{index-LMsd1ih2.js.map → index-DGtbUu8Y.js.map} +1 -1
  261. package/build/server/chunks/{index-server-BRr5mZEq.js → index-server-l8-WsVn4.js} +2 -2
  262. package/build/server/chunks/{index-server-BRr5mZEq.js.map → index-server-l8-WsVn4.js.map} +1 -1
  263. package/build/server/chunks/{index2-ClgfzZ89.js → index2-CtgLiJVO.js} +3 -3
  264. package/build/server/chunks/{index2-ClgfzZ89.js.map → index2-CtgLiJVO.js.map} +1 -1
  265. package/build/server/chunks/{index3-BdRUAffj.js → index3-4hbbCqW0.js} +2 -2
  266. package/build/server/chunks/{index3-BdRUAffj.js.map → index3-4hbbCqW0.js.map} +1 -1
  267. package/build/server/chunks/{root-4q2Pr7ck.js → root-sWPnlpi3.js} +2 -2
  268. package/build/server/chunks/{root-4q2Pr7ck.js.map → root-sWPnlpi3.js.map} +1 -1
  269. package/build/server/chunks/{source-selection-CcN1cgXc.js → source-selection-DSkaPGfZ.js} +7 -2
  270. package/build/server/chunks/source-selection-DSkaPGfZ.js.map +1 -0
  271. package/build/server/chunks/{state.svelte-Bd1i-u49.js → state.svelte-BkvaElc6.js} +3 -3
  272. package/build/server/chunks/{state.svelte-Bd1i-u49.js.map → state.svelte-BkvaElc6.js.map} +1 -1
  273. package/build/server/chunks/trpc-client-Cr8RJ4UO.js +260 -0
  274. package/build/server/chunks/trpc-client-Cr8RJ4UO.js.map +1 -0
  275. package/build/server/index.js +4 -4
  276. package/build/server/index.js.map +1 -1
  277. package/build/server/manifest.js +15 -15
  278. package/build/server/manifest.js.map +1 -1
  279. package/package.json +1 -1
  280. package/src/backend/git-mode/command.spec.ts +172 -0
  281. package/src/backend/git-mode/command.ts +405 -0
  282. package/src/backend/git-mode/config.spec.ts +45 -0
  283. package/src/backend/git-mode/config.ts +90 -0
  284. package/src/backend/git-mode/index.ts +20 -0
  285. package/src/backend/git-mode/repository-write-gate.spec.ts +116 -0
  286. package/src/backend/git-mode/repository-write-gate.ts +260 -0
  287. package/src/backend/git-mode/router.ts +59 -0
  288. package/src/backend/git-mode/service.spec.ts +1653 -0
  289. package/src/backend/git-mode/service.ts +2183 -0
  290. package/src/backend/git-mode/types.ts +82 -0
  291. package/src/backend/git-mode/write-tracker.spec.ts +46 -0
  292. package/src/backend/git-mode/write-tracker.ts +39 -0
  293. package/src/backend/lib/backend-restart.spec.ts +27 -0
  294. package/src/backend/lib/backend-restart.ts +16 -2
  295. package/src/backend/lib/middleware/cors.spec.ts +67 -0
  296. package/src/backend/lib/middleware/cors.ts +40 -12
  297. package/src/backend/roleplay/agent-loader.ts +49 -0
  298. package/src/backend/roleplay/old-server.ts +106 -56
  299. package/src/backend/roleplay/prompt-edit-proposals.ts +38 -4
  300. package/src/backend/roleplay/prompt-file.ts +59 -0
  301. package/src/backend/roleplay/router.spec.ts +75 -0
  302. package/src/backend/roleplay/router.ts +123 -69
  303. package/src/backend/roleplay/suggest-file-edit.ts +160 -0
  304. package/src/backend/roleplay/suggest-prompt-edit.ts +9 -138
  305. package/src/backend/roleplay/suggest-test-fix.spec.ts +50 -0
  306. package/src/backend/roleplay/suggest-test-fix.ts +65 -0
  307. package/src/backend/roleplay/test-fix-proposal-acceptance.spec.ts +253 -0
  308. package/src/backend/server.ts +116 -13
  309. package/src/backend/tests/academy.ts +17 -3
  310. package/src/backend/tests/data.spec.ts +81 -2
  311. package/src/backend/tests/data.ts +74 -4
  312. package/src/backend/tests/router.ts +101 -36
  313. package/src/backend/tests/suggest-test-history-edit.spec.ts +20 -0
  314. package/src/backend/tests/suggest-test-history-edit.ts +52 -0
  315. package/src/backend/tests/test-edit-source.spec.ts +61 -0
  316. package/src/backend/tests/test-edit-source.ts +34 -0
  317. package/src/backend/tests/test-history-edit-proposals.ts +69 -0
  318. package/src/backend/tests/test-history-overrides.spec.ts +24 -0
  319. package/src/backend/tests/test-selection.ts +27 -0
  320. package/src/lib/api-telescope/source-selection.spec.ts +44 -0
  321. package/src/lib/api-telescope/source-selection.ts +28 -0
  322. package/src/lib/components/Modal.svelte +1 -1
  323. package/src/lib/edit/edit-workspace-context.ts +33 -3
  324. package/src/lib/edit/test-ai-edit.spec.ts +31 -0
  325. package/src/lib/edit/test-ai-edit.ts +52 -0
  326. package/src/lib/git-mode/BlockingGitDialog.svelte +118 -0
  327. package/src/lib/git-mode/GitControlsButton.svelte +96 -0
  328. package/src/lib/git-mode/client-admission.spec.ts +304 -0
  329. package/src/lib/git-mode/client-admission.ts +343 -0
  330. package/src/lib/git-mode/errors.ts +2 -0
  331. package/src/lib/git-mode/git-mode-context.ts +70 -0
  332. package/src/lib/git-mode/refresh-policy.spec.ts +95 -0
  333. package/src/lib/git-mode/refresh-policy.ts +39 -0
  334. package/src/lib/git-mode/status-recovery.spec.ts +86 -0
  335. package/src/lib/git-mode/status-recovery.ts +33 -0
  336. package/src/lib/monaco/bosun-theme.ts +6 -83
  337. package/src/lib/monaco/editor-appearance.spec.ts +84 -0
  338. package/src/lib/monaco/editor-appearance.ts +154 -0
  339. package/src/lib/monaco/editor-decorations.spec.ts +91 -0
  340. package/src/lib/monaco/editor-decorations.ts +133 -0
  341. package/src/lib/tests/assertion-types.ts +74 -0
  342. package/src/lib/trpc-client.ts +15 -1
  343. package/src/lib/ws-client.spec.ts +208 -0
  344. package/src/lib/ws-client.ts +196 -14
  345. package/src/lib/ws-message.ts +24 -0
  346. package/build/client/_app/immutable/assets/0.Rrc0O--C.css +0 -1
  347. package/build/client/_app/immutable/assets/0.Rrc0O--C.css.br +0 -0
  348. package/build/client/_app/immutable/assets/0.Rrc0O--C.css.gz +0 -0
  349. package/build/client/_app/immutable/assets/2.DtxQDOXx.css.br +0 -0
  350. package/build/client/_app/immutable/assets/2.DtxQDOXx.css.gz +0 -0
  351. package/build/client/_app/immutable/chunks/B1HdnQRQ.js.br +0 -0
  352. package/build/client/_app/immutable/chunks/B1HdnQRQ.js.gz +0 -0
  353. package/build/client/_app/immutable/chunks/B5zf3x62.js.br +0 -0
  354. package/build/client/_app/immutable/chunks/B5zf3x62.js.gz +0 -0
  355. package/build/client/_app/immutable/chunks/BHHfrjbV.js.br +0 -2
  356. package/build/client/_app/immutable/chunks/BHHfrjbV.js.gz +0 -0
  357. package/build/client/_app/immutable/chunks/BU7aeYn4.js +0 -1
  358. package/build/client/_app/immutable/chunks/BU7aeYn4.js.br +0 -0
  359. package/build/client/_app/immutable/chunks/BU7aeYn4.js.gz +0 -0
  360. package/build/client/_app/immutable/chunks/BbGYcfPY.js +0 -3
  361. package/build/client/_app/immutable/chunks/BbGYcfPY.js.br +0 -0
  362. package/build/client/_app/immutable/chunks/BbGYcfPY.js.gz +0 -0
  363. package/build/client/_app/immutable/chunks/Bmd5zhWC.js.br +0 -0
  364. package/build/client/_app/immutable/chunks/Bmd5zhWC.js.gz +0 -0
  365. package/build/client/_app/immutable/chunks/BnqH7p3U.js +0 -33
  366. package/build/client/_app/immutable/chunks/BnqH7p3U.js.br +0 -0
  367. package/build/client/_app/immutable/chunks/BnqH7p3U.js.gz +0 -0
  368. package/build/client/_app/immutable/chunks/Bog028VR.js.br +0 -0
  369. package/build/client/_app/immutable/chunks/Bog028VR.js.gz +0 -0
  370. package/build/client/_app/immutable/chunks/Bv1mNXs0.js.br +0 -0
  371. package/build/client/_app/immutable/chunks/Bv1mNXs0.js.gz +0 -0
  372. package/build/client/_app/immutable/chunks/BvjXTrOz.js +0 -1
  373. package/build/client/_app/immutable/chunks/BvjXTrOz.js.br +0 -0
  374. package/build/client/_app/immutable/chunks/BvjXTrOz.js.gz +0 -0
  375. package/build/client/_app/immutable/chunks/C1R-s4aD.js +0 -1
  376. package/build/client/_app/immutable/chunks/C1R-s4aD.js.br +0 -0
  377. package/build/client/_app/immutable/chunks/C1R-s4aD.js.gz +0 -0
  378. package/build/client/_app/immutable/chunks/CC1OcqhR.js +0 -1
  379. package/build/client/_app/immutable/chunks/CC1OcqhR.js.br +0 -0
  380. package/build/client/_app/immutable/chunks/CC1OcqhR.js.gz +0 -0
  381. package/build/client/_app/immutable/chunks/CEHsomMo.js.br +0 -0
  382. package/build/client/_app/immutable/chunks/CJcZ2GVC.js.br +0 -0
  383. package/build/client/_app/immutable/chunks/CJcZ2GVC.js.gz +0 -0
  384. package/build/client/_app/immutable/chunks/CN555stc.js.br +0 -0
  385. package/build/client/_app/immutable/chunks/CN555stc.js.gz +0 -0
  386. package/build/client/_app/immutable/chunks/CQg2Mme0.js +0 -9
  387. package/build/client/_app/immutable/chunks/CQg2Mme0.js.br +0 -0
  388. package/build/client/_app/immutable/chunks/CQg2Mme0.js.gz +0 -0
  389. package/build/client/_app/immutable/chunks/Cp_st-64.js.br +0 -0
  390. package/build/client/_app/immutable/chunks/Cp_st-64.js.gz +0 -0
  391. package/build/client/_app/immutable/chunks/D8mA-uZ4.js.br +0 -0
  392. package/build/client/_app/immutable/chunks/D8mA-uZ4.js.gz +0 -0
  393. package/build/client/_app/immutable/chunks/DCXjBDmY.js.br +0 -0
  394. package/build/client/_app/immutable/chunks/DCXjBDmY.js.gz +0 -0
  395. package/build/client/_app/immutable/chunks/DSLyVE1P.js +0 -1
  396. package/build/client/_app/immutable/chunks/DSLyVE1P.js.br +0 -0
  397. package/build/client/_app/immutable/chunks/DSLyVE1P.js.gz +0 -0
  398. package/build/client/_app/immutable/chunks/Ddv5LgEc.js.br +0 -0
  399. package/build/client/_app/immutable/chunks/Ddv5LgEc.js.gz +0 -0
  400. package/build/client/_app/immutable/chunks/DfcDjAv-.js.br +0 -0
  401. package/build/client/_app/immutable/chunks/DfcDjAv-.js.gz +0 -0
  402. package/build/client/_app/immutable/chunks/Dg0A8wPA.js.br +0 -0
  403. package/build/client/_app/immutable/chunks/Dg0A8wPA.js.gz +0 -0
  404. package/build/client/_app/immutable/chunks/Dm49pcMm.js.br +0 -0
  405. package/build/client/_app/immutable/chunks/Dm49pcMm.js.gz +0 -0
  406. package/build/client/_app/immutable/chunks/DneQQ7D5.js.br +0 -0
  407. package/build/client/_app/immutable/chunks/DneQQ7D5.js.gz +0 -0
  408. package/build/client/_app/immutable/chunks/DoD3q5w5.js.br +0 -0
  409. package/build/client/_app/immutable/chunks/DoD3q5w5.js.gz +0 -0
  410. package/build/client/_app/immutable/chunks/DtXXy94i.js.br +0 -0
  411. package/build/client/_app/immutable/chunks/DtXXy94i.js.gz +0 -0
  412. package/build/client/_app/immutable/chunks/Dy2CFyD6.js +0 -2
  413. package/build/client/_app/immutable/chunks/Dy2CFyD6.js.br +0 -0
  414. package/build/client/_app/immutable/chunks/Dy2CFyD6.js.gz +0 -0
  415. package/build/client/_app/immutable/chunks/DyBwTDJp.js +0 -2
  416. package/build/client/_app/immutable/chunks/DyBwTDJp.js.br +0 -0
  417. package/build/client/_app/immutable/chunks/DyBwTDJp.js.gz +0 -0
  418. package/build/client/_app/immutable/chunks/ILTCveYH.js +0 -1
  419. package/build/client/_app/immutable/chunks/ILTCveYH.js.br +0 -0
  420. package/build/client/_app/immutable/chunks/ILTCveYH.js.gz +0 -0
  421. package/build/client/_app/immutable/chunks/JcG4w2gF.js.br +0 -0
  422. package/build/client/_app/immutable/chunks/JcG4w2gF.js.gz +0 -0
  423. package/build/client/_app/immutable/chunks/UqjCSZmA.js.br +0 -0
  424. package/build/client/_app/immutable/chunks/UqjCSZmA.js.gz +0 -0
  425. package/build/client/_app/immutable/chunks/_YcrHZ6P.js +0 -1
  426. package/build/client/_app/immutable/chunks/_YcrHZ6P.js.br +0 -2
  427. package/build/client/_app/immutable/chunks/_YcrHZ6P.js.gz +0 -0
  428. package/build/client/_app/immutable/chunks/i6ygh6h8.js +0 -1
  429. package/build/client/_app/immutable/chunks/i6ygh6h8.js.br +0 -2
  430. package/build/client/_app/immutable/chunks/i6ygh6h8.js.gz +0 -0
  431. package/build/client/_app/immutable/chunks/oRi68ch3.js +0 -1
  432. package/build/client/_app/immutable/chunks/oRi68ch3.js.br +0 -0
  433. package/build/client/_app/immutable/chunks/oRi68ch3.js.gz +0 -0
  434. package/build/client/_app/immutable/chunks/pPpIn6tB.js.br +0 -0
  435. package/build/client/_app/immutable/chunks/pPpIn6tB.js.gz +0 -0
  436. package/build/client/_app/immutable/chunks/r0sHOWrM.js +0 -1
  437. package/build/client/_app/immutable/chunks/r0sHOWrM.js.br +0 -0
  438. package/build/client/_app/immutable/chunks/r0sHOWrM.js.gz +0 -0
  439. package/build/client/_app/immutable/chunks/wcTQUnZO.js.br +0 -0
  440. package/build/client/_app/immutable/chunks/wcTQUnZO.js.gz +0 -0
  441. package/build/client/_app/immutable/entry/app.DdO0gkPg.js +0 -2
  442. package/build/client/_app/immutable/entry/app.DdO0gkPg.js.br +0 -0
  443. package/build/client/_app/immutable/entry/app.DdO0gkPg.js.gz +0 -0
  444. package/build/client/_app/immutable/entry/start.eAjDq0c9.js +0 -1
  445. package/build/client/_app/immutable/entry/start.eAjDq0c9.js.br +0 -2
  446. package/build/client/_app/immutable/entry/start.eAjDq0c9.js.gz +0 -0
  447. package/build/client/_app/immutable/nodes/0.nG3DdvIX.js +0 -3
  448. package/build/client/_app/immutable/nodes/0.nG3DdvIX.js.br +0 -0
  449. package/build/client/_app/immutable/nodes/0.nG3DdvIX.js.gz +0 -0
  450. package/build/client/_app/immutable/nodes/1.Ceu0XS6v.js +0 -1
  451. package/build/client/_app/immutable/nodes/1.Ceu0XS6v.js.br +0 -0
  452. package/build/client/_app/immutable/nodes/1.Ceu0XS6v.js.gz +0 -0
  453. package/build/client/_app/immutable/nodes/10.dm2dgy31.js +0 -13
  454. package/build/client/_app/immutable/nodes/10.dm2dgy31.js.br +0 -0
  455. package/build/client/_app/immutable/nodes/10.dm2dgy31.js.gz +0 -0
  456. package/build/client/_app/immutable/nodes/15.D2I0y3ys.js.br +0 -0
  457. package/build/client/_app/immutable/nodes/15.D2I0y3ys.js.gz +0 -0
  458. package/build/client/_app/immutable/nodes/17.CKxGp0E7.js +0 -3
  459. package/build/client/_app/immutable/nodes/17.CKxGp0E7.js.br +0 -0
  460. package/build/client/_app/immutable/nodes/17.CKxGp0E7.js.gz +0 -0
  461. package/build/client/_app/immutable/nodes/18.DHJxyQpw.js +0 -11
  462. package/build/client/_app/immutable/nodes/18.DHJxyQpw.js.br +0 -0
  463. package/build/client/_app/immutable/nodes/18.DHJxyQpw.js.gz +0 -0
  464. package/build/client/_app/immutable/nodes/2.DesR2keg.js +0 -35
  465. package/build/client/_app/immutable/nodes/2.DesR2keg.js.br +0 -0
  466. package/build/client/_app/immutable/nodes/2.DesR2keg.js.gz +0 -0
  467. package/build/client/_app/immutable/nodes/3.BUKrXGR_.js +0 -1
  468. package/build/client/_app/immutable/nodes/3.BUKrXGR_.js.br +0 -0
  469. package/build/client/_app/immutable/nodes/3.BUKrXGR_.js.gz +0 -0
  470. package/build/client/_app/immutable/nodes/4.C8VxVbVn.js.br +0 -0
  471. package/build/client/_app/immutable/nodes/4.C8VxVbVn.js.gz +0 -0
  472. package/build/client/_app/immutable/nodes/5.BjrnKYaA.js.br +0 -0
  473. package/build/client/_app/immutable/nodes/5.BjrnKYaA.js.gz +0 -0
  474. package/build/client/_app/immutable/nodes/6.C_hEzPrU.js +0 -1
  475. package/build/client/_app/immutable/nodes/6.C_hEzPrU.js.br +0 -0
  476. package/build/client/_app/immutable/nodes/6.C_hEzPrU.js.gz +0 -0
  477. package/build/client/_app/immutable/nodes/8.BTYaOiDC.js +0 -2
  478. package/build/client/_app/immutable/nodes/8.BTYaOiDC.js.br +0 -0
  479. package/build/client/_app/immutable/nodes/8.BTYaOiDC.js.gz +0 -0
  480. package/build/client/_app/immutable/nodes/9.DVspuDYY.js +0 -2
  481. package/build/client/_app/immutable/nodes/9.DVspuDYY.js.br +0 -0
  482. package/build/client/_app/immutable/nodes/9.DVspuDYY.js.gz +0 -0
  483. package/build/server/chunks/0-D_duQDWy.js +0 -9
  484. package/build/server/chunks/0-D_duQDWy.js.map +0 -1
  485. package/build/server/chunks/1-C0HdTvXW.js +0 -9
  486. package/build/server/chunks/10-DcfhCR4R.js +0 -9
  487. package/build/server/chunks/10-DcfhCR4R.js.map +0 -1
  488. package/build/server/chunks/15-BQcb9C_y.js +0 -9
  489. package/build/server/chunks/17-DuVCTioj.js +0 -9
  490. package/build/server/chunks/17-DuVCTioj.js.map +0 -1
  491. package/build/server/chunks/18-CT0VFW_p.js +0 -9
  492. package/build/server/chunks/18-CT0VFW_p.js.map +0 -1
  493. package/build/server/chunks/2-DgTzKQAP.js +0 -9
  494. package/build/server/chunks/2-DgTzKQAP.js.map +0 -1
  495. package/build/server/chunks/3-eQMSMzXP.js +0 -9
  496. package/build/server/chunks/3-eQMSMzXP.js.map +0 -1
  497. package/build/server/chunks/4-OaAJtDqP.js +0 -9
  498. package/build/server/chunks/4-OaAJtDqP.js.map +0 -1
  499. package/build/server/chunks/5-CBdMutbv.js +0 -9
  500. package/build/server/chunks/5-CBdMutbv.js.map +0 -1
  501. package/build/server/chunks/6-FoEi7ggm.js +0 -9
  502. package/build/server/chunks/6-FoEi7ggm.js.map +0 -1
  503. package/build/server/chunks/8-B44yRkfX.js +0 -9
  504. package/build/server/chunks/8-B44yRkfX.js.map +0 -1
  505. package/build/server/chunks/9-eUjFpHzI.js +0 -9
  506. package/build/server/chunks/9-eUjFpHzI.js.map +0 -1
  507. package/build/server/chunks/ChatStepTrace-BivoNYOY.js.map +0 -1
  508. package/build/server/chunks/_layout.svelte-B-0DHjLB.js +0 -45
  509. package/build/server/chunks/_layout.svelte-B-0DHjLB.js.map +0 -1
  510. package/build/server/chunks/_layout.svelte-B88WMyk0.js.map +0 -1
  511. package/build/server/chunks/_layout.svelte-wi6o5Ecu.js.map +0 -1
  512. package/build/server/chunks/_page.svelte-57pyhszV.js.map +0 -1
  513. package/build/server/chunks/_page.svelte-BSVJ2d2G.js.map +0 -1
  514. package/build/server/chunks/_page.svelte-BoHt2cpr.js +0 -61
  515. package/build/server/chunks/_page.svelte-BoHt2cpr.js.map +0 -1
  516. package/build/server/chunks/_page.svelte-CeS_21Ho.js.map +0 -1
  517. package/build/server/chunks/_page.svelte-DHSYVLoj.js.map +0 -1
  518. package/build/server/chunks/_page.svelte-DhFNFMnl.js.map +0 -1
  519. package/build/server/chunks/_server.ts-D_eo_OAK.js +0 -139
  520. package/build/server/chunks/_server.ts-D_eo_OAK.js.map +0 -1
  521. package/build/server/chunks/error.svelte-DmKKN1RU.js +0 -15
  522. package/build/server/chunks/source-selection-CcN1cgXc.js.map +0 -1
  523. package/build/server/chunks/trpc-client-D8L6vWf4.js +0 -14
  524. package/build/server/chunks/trpc-client-D8L6vWf4.js.map +0 -1
@@ -0,0 +1,82 @@
1
+ export const gitModePhases = [
2
+ 'idle',
3
+ 'preparing',
4
+ 'flushing',
5
+ 'refreshing',
6
+ 'awaiting-changes',
7
+ 'processing',
8
+ 'restarting',
9
+ 'fatal'
10
+ ] as const
11
+
12
+ export type GitModePhase = (typeof gitModePhases)[number]
13
+ export type GitModePreparationStage = 'preflight' | 'browser-writes'
14
+ export type ActivationReason = 'page-open' | 'focus'
15
+ export type ChangeAction = 'save' | 'discard'
16
+
17
+ export type GitModeFatalKind = 'branch-mismatch' | 'merge-conflict' | 'general'
18
+
19
+ export interface GitModeFatal {
20
+ kind: GitModeFatalKind
21
+ title: string
22
+ message: string
23
+ prUrl: string | null
24
+ }
25
+
26
+ export interface GitModeStatus {
27
+ enabled: boolean
28
+ phase: GitModePhase
29
+ operationId: string | null
30
+ hasChanges: boolean
31
+ canPrepareRelease: boolean
32
+ fatal: GitModeFatal | null
33
+ prUrl: string | null
34
+ reloadToken: string | null
35
+ deferredReason: string | null
36
+ tabNeedsFlush: boolean
37
+ preparationStage: GitModePreparationStage | null
38
+ }
39
+
40
+ export interface ChangeChoice {
41
+ action: ChangeAction
42
+ description?: string
43
+ }
44
+
45
+ export interface GitModeConfig {
46
+ enabled: boolean
47
+ projectDir: string
48
+ currentBranch: string
49
+ personalBranch: string
50
+ idleMs: number
51
+ currentUpstream: string
52
+ currentUpstreamRemote: string
53
+ currentUpstreamBranch: string
54
+ personalUpstream: string
55
+ personalUpstreamRemote: string
56
+ personalUpstreamBranch: string
57
+ launchId: string
58
+ runtimeStatePath: string
59
+ restartExitCode: number
60
+ }
61
+
62
+ export interface GitModeService {
63
+ isUsageBlocked(): boolean
64
+ status(input: { tabId: string }): Promise<GitModeStatus>
65
+ unregister(input: { tabId: string }): Promise<GitModeStatus>
66
+ activate(input: { tabId: string; reason: ActivationReason }): Promise<GitModeStatus>
67
+ flushAck(input: {
68
+ tabId: string
69
+ operationId: string
70
+ stage: GitModePreparationStage
71
+ blockedReason?: string
72
+ }): Promise<GitModeStatus>
73
+ startManual(input: { tabId: string } & ChangeChoice): Promise<GitModeStatus>
74
+ prepareRelease(input: { tabId: string }): Promise<GitModeStatus>
75
+ resolveChanges(
76
+ input: {
77
+ tabId: string
78
+ operationId: string
79
+ } & ChangeChoice
80
+ ): Promise<GitModeStatus>
81
+ dispose(): Promise<void>
82
+ }
@@ -0,0 +1,46 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+
3
+ import { RepositoryWriteTracker } from './write-tracker'
4
+
5
+ describe('RepositoryWriteTracker', () => {
6
+ it('drains all operations admitted before the repository lock', async () => {
7
+ const tracker = new RepositoryWriteTracker()
8
+ let releaseFirst!: () => void
9
+ let releaseSecond!: () => void
10
+ const first = tracker.track(() => new Promise<void>((resolve) => (releaseFirst = resolve)))
11
+ const second = tracker.track(() => new Promise<void>((resolve) => (releaseSecond = resolve)))
12
+ const drained = vi.fn()
13
+ const draining = tracker.drain().then(drained)
14
+ await Promise.resolve()
15
+
16
+ expect(tracker.activeCount).toBe(2)
17
+ releaseFirst()
18
+ await first
19
+ await Promise.resolve()
20
+ expect(drained).not.toHaveBeenCalled()
21
+
22
+ releaseSecond()
23
+ await Promise.all([second, draining])
24
+ expect(drained).toHaveBeenCalledOnce()
25
+ expect(tracker.activeCount).toBe(0)
26
+ })
27
+
28
+ it('resolves immediately when no writes are active', async () => {
29
+ const tracker = new RepositoryWriteTracker()
30
+ await expect(tracker.drain()).resolves.toBeUndefined()
31
+ })
32
+
33
+ it('atomically closes admission while allowing previously admitted writes to drain', async () => {
34
+ const tracker = new RepositoryWriteTracker()
35
+ let release!: () => void
36
+ const admitted = tracker.track(() => new Promise<void>((resolve) => (release = resolve)))
37
+
38
+ tracker.close()
39
+ await expect(tracker.track(async () => {})).rejects.toThrow(/shutting down/)
40
+
41
+ const draining = tracker.drain()
42
+ release()
43
+ await Promise.all([admitted, draining])
44
+ expect(tracker.activeCount).toBe(0)
45
+ })
46
+ })
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Counts repository-facing backend work that was admitted before Git mode closed its write gate.
3
+ * JavaScript runs the admission check and `track` call synchronously, so a Git lock transition
4
+ * either observes an already-counted operation or causes the caller to be rejected.
5
+ */
6
+ export class RepositoryWriteTracker {
7
+ private active = 0
8
+ private accepting = true
9
+ private idleWaiters = new Set<() => void>()
10
+
11
+ track<T>(operation: () => Promise<T>): Promise<T> {
12
+ if (!this.accepting) {
13
+ return Promise.reject(new Error('Bosun is shutting down; repository writes are closed.'))
14
+ }
15
+ this.active += 1
16
+ return Promise.resolve()
17
+ .then(operation)
18
+ .finally(() => {
19
+ this.active -= 1
20
+ if (this.active !== 0) return
21
+ for (const resolve of this.idleWaiters) resolve()
22
+ this.idleWaiters.clear()
23
+ })
24
+ }
25
+
26
+ close(): void {
27
+ this.accepting = false
28
+ }
29
+
30
+ async drain(): Promise<void> {
31
+ while (this.active > 0) {
32
+ await new Promise<void>((resolve) => this.idleWaiters.add(resolve))
33
+ }
34
+ }
35
+
36
+ get activeCount(): number {
37
+ return this.active
38
+ }
39
+ }
@@ -0,0 +1,27 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest'
2
+
3
+ import {
4
+ registerManagedBackendRestartHandler,
5
+ scheduleManagedBackendRestart
6
+ } from './backend-restart'
7
+
8
+ describe('managed backend restart', () => {
9
+ afterEach(() => {
10
+ vi.useRealTimers()
11
+ delete process.env.BOSUN_NPX_RUN
12
+ })
13
+
14
+ it('routes a managed restart through graceful shutdown with the requested exit code', async () => {
15
+ vi.useFakeTimers()
16
+ process.env.BOSUN_NPX_RUN = 'true'
17
+ const handler = vi.fn()
18
+ const unregister = registerManagedBackendRestartHandler(handler)
19
+
20
+ expect(scheduleManagedBackendRestart(76)).toBe(true)
21
+ await vi.advanceTimersByTimeAsync(500)
22
+
23
+ expect(handler).toHaveBeenCalledOnce()
24
+ expect(handler).toHaveBeenCalledWith(76)
25
+ unregister()
26
+ })
27
+ })
@@ -2,13 +2,27 @@ const MANAGED_BACKEND_RESTART_EXIT_CODE = 75
2
2
  const MANAGED_BACKEND_RESTART_DELAY_MS = 500
3
3
 
4
4
  let restartTimer: ReturnType<typeof setTimeout> | null = null
5
+ let restartHandler: ((exitCode: number) => void | Promise<void>) | null = null
5
6
 
6
- export function scheduleManagedBackendRestart(): boolean {
7
+ export function registerManagedBackendRestartHandler(
8
+ handler: (exitCode: number) => void | Promise<void>
9
+ ): () => void {
10
+ restartHandler = handler
11
+ return () => {
12
+ if (restartHandler === handler) restartHandler = null
13
+ }
14
+ }
15
+
16
+ export function scheduleManagedBackendRestart(
17
+ exitCode = MANAGED_BACKEND_RESTART_EXIT_CODE
18
+ ): boolean {
7
19
  if (process.env.BOSUN_NPX_RUN !== 'true') return false
8
20
  if (restartTimer) return true
21
+ if (!Number.isInteger(exitCode) || exitCode < 1 || exitCode > 255) return false
9
22
 
10
23
  restartTimer = setTimeout(() => {
11
- process.exit(MANAGED_BACKEND_RESTART_EXIT_CODE)
24
+ if (restartHandler) void restartHandler(exitCode)
25
+ else process.exit(exitCode)
12
26
  }, MANAGED_BACKEND_RESTART_DELAY_MS)
13
27
  restartTimer.unref()
14
28
  return true
@@ -0,0 +1,67 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http'
2
+ import { describe, expect, it, vi } from 'vitest'
3
+
4
+ import { createCors, isAllowedBrowserOrigin } from './cors'
5
+
6
+ const ALLOWED = 'http://localhost:5177'
7
+
8
+ describe('createCors', () => {
9
+ it('allows the exact configured origin and never emits a wildcard', () => {
10
+ const { req, res, next, headers } = harness('POST', ALLOWED)
11
+ createCors(ALLOWED)(req, res, next)
12
+
13
+ expect(next).toHaveBeenCalledOnce()
14
+ expect(headers.get('Access-Control-Allow-Origin')).toBe(ALLOWED)
15
+ expect([...headers.values()]).not.toContain('*')
16
+ })
17
+
18
+ it.each([undefined, 'null', 'https://example.com', 'http://localhost:5178'])(
19
+ 'rejects a state-changing request from %s',
20
+ (origin) => {
21
+ const { req, res, next, writeHead } = harness('POST', origin)
22
+ createCors(ALLOWED)(req, res, next)
23
+
24
+ expect(next).not.toHaveBeenCalled()
25
+ expect(writeHead).toHaveBeenCalledWith(403, expect.any(Object))
26
+ }
27
+ )
28
+
29
+ it('rejects a preflight from another origin', () => {
30
+ const { req, res, next, writeHead } = harness('OPTIONS', 'https://example.com')
31
+ createCors(ALLOWED)(req, res, next)
32
+
33
+ expect(next).not.toHaveBeenCalled()
34
+ expect(writeHead).toHaveBeenCalledWith(403)
35
+ })
36
+
37
+ it('allows an originless GET without granting browser read access', () => {
38
+ const { req, res, next, headers } = harness('GET', undefined)
39
+ createCors(ALLOWED)(req, res, next)
40
+
41
+ expect(next).toHaveBeenCalledOnce()
42
+ expect(headers.has('Access-Control-Allow-Origin')).toBe(false)
43
+ })
44
+ })
45
+
46
+ describe('isAllowedBrowserOrigin', () => {
47
+ it('requires an exact match', () => {
48
+ expect(isAllowedBrowserOrigin(ALLOWED, ALLOWED)).toBe(true)
49
+ expect(isAllowedBrowserOrigin(undefined, ALLOWED)).toBe(false)
50
+ expect(isAllowedBrowserOrigin('null', ALLOWED)).toBe(false)
51
+ })
52
+ })
53
+
54
+ function harness(method: string, origin: string | undefined) {
55
+ const headers = new Map<string, string | number | readonly string[]>()
56
+ const writeHead = vi.fn()
57
+ const end = vi.fn()
58
+ const next = vi.fn()
59
+ const req = { method, headers: { origin } } as unknown as IncomingMessage
60
+ const res = {
61
+ setHeader: (name: string, value: string | number | readonly string[]) =>
62
+ headers.set(name, value),
63
+ writeHead,
64
+ end
65
+ } as unknown as ServerResponse
66
+ return { req, res, next, headers, writeHead, end }
67
+ }
@@ -1,14 +1,42 @@
1
- import type { IncomingMessage, ServerResponse } from 'http'
2
-
3
- export function cors(req: IncomingMessage, res: ServerResponse, next: () => void) {
4
- res.setHeader('Access-Control-Allow-Origin', '*')
5
- res.setHeader('Access-Control-Request-Method', '*')
6
- res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT')
7
- res.setHeader('Access-Control-Allow-Headers', '*')
8
- if (req.method === 'OPTIONS') {
9
- res.writeHead(200)
10
- res.end()
11
- return
1
+ import type { IncomingMessage, ServerResponse } from 'node:http'
2
+
3
+ const STATE_CHANGING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE'])
4
+
5
+ export function isAllowedBrowserOrigin(origin: string | undefined, allowedOrigin: string): boolean {
6
+ return origin === allowedOrigin
7
+ }
8
+
9
+ export function createCors(allowedOrigin: string) {
10
+ if (!allowedOrigin) throw new Error('Bosun browser origin is not configured.')
11
+
12
+ return function cors(req: IncomingMessage, res: ServerResponse, next: () => void) {
13
+ const origin = normalizeHeader(req.headers.origin)
14
+ const allowed = isAllowedBrowserOrigin(origin, allowedOrigin)
15
+
16
+ res.setHeader('Vary', 'Origin')
17
+ if (allowed) {
18
+ res.setHeader('Access-Control-Allow-Origin', allowedOrigin)
19
+ res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, PATCH, DELETE')
20
+ res.setHeader('Access-Control-Allow-Headers', 'content-type, x-trpc-source')
21
+ }
22
+
23
+ if (req.method === 'OPTIONS') {
24
+ res.writeHead(allowed ? 204 : 403)
25
+ res.end()
26
+ return
27
+ }
28
+
29
+ if (STATE_CHANGING_METHODS.has(req.method ?? '') && !allowed) {
30
+ res.writeHead(403, { 'Content-Type': 'text/plain; charset=utf-8' })
31
+ res.end('Bosun rejected a state-changing request from an untrusted browser origin.')
32
+ return
33
+ }
34
+
35
+ next()
12
36
  }
13
- next()
37
+ }
38
+
39
+ function normalizeHeader(value: string | string[] | undefined): string | undefined {
40
+ if (Array.isArray(value)) return value.length === 1 ? value[0] : undefined
41
+ return value
14
42
  }
@@ -0,0 +1,49 @@
1
+ import { createContext } from '@recombine-ai/engine'
2
+
3
+ import { getAgentFactories } from '../lib/get-agent-factories'
4
+ import { getRootPath } from '../lib/get-root-path'
5
+
6
+ export const noop = () => void 0
7
+ export const noopAsync = () => Promise.resolve()
8
+
9
+ export async function loadAgentSteps(agentId: string) {
10
+ const { factory, basePath } = await getAgentFactory(agentId)
11
+ const ctx = createContext({})
12
+ const steps: any[] = []
13
+ const stepRegistry = {
14
+ addStep: (step: any) => {
15
+ steps.push(step)
16
+ },
17
+ getSteps: () => steps
18
+ }
19
+
20
+ await factory({
21
+ ctx,
22
+ getMessages: () => [],
23
+ logger: console,
24
+ scheduler: {
25
+ clearAllPendingActions: noopAsync,
26
+ registerAction: () => noopAsync
27
+ },
28
+ sendMessage: noopAsync,
29
+ stepRegistry,
30
+ stepTracer: {
31
+ addStepTrace: noop,
32
+ flush: noopAsync
33
+ },
34
+ config: {
35
+ enableTimers: false,
36
+ isTest: false
37
+ }
38
+ })
39
+
40
+ return { basePath, steps }
41
+ }
42
+
43
+ export async function getAgentFactory(agentId: string) {
44
+ const rootPath = await getRootPath()
45
+ const agentFactories = await getAgentFactories(rootPath)
46
+ const factory = agentFactories.factories[agentId]
47
+ if (!factory) throw new Error(`Cannot find agent ${agentId}`)
48
+ return { factory, basePath: agentFactories.basePath }
49
+ }
@@ -4,12 +4,37 @@ import { createAgents } from './agents'
4
4
  import { fsContextPersistence, fsStatePersistence } from './fs-persistence'
5
5
  import { MessageDispatcher } from './message-dispatcher'
6
6
 
7
- export async function oldServer(ws: WebSocket) {
7
+ export interface OldServerOptions {
8
+ isUsageBlocked?: () => boolean
9
+ trackRepositoryOperation?: <T>(operation: () => Promise<T>) => Promise<T>
10
+ }
11
+
12
+ export async function oldServer(ws: WebSocket, options: OldServerOptions = {}) {
8
13
  console.log('== Client connected ==')
14
+ const isUsageBlocked = options.isUsageBlocked ?? (() => false)
15
+ const trackRepositoryOperation =
16
+ options.trackRepositoryOperation ?? (<T>(operation: () => Promise<T>) => operation())
17
+ const rejectBlockedConnection = () => {
18
+ ws.send(
19
+ JSON.stringify({ channel: 'error', message: 'Bosun is refreshing the project. Please wait.' })
20
+ )
21
+ ws.close(1013, 'Bosun is refreshing the project')
22
+ }
23
+ if (isUsageBlocked()) {
24
+ rejectBlockedConnection()
25
+ return
26
+ }
9
27
 
10
28
  const agents = createAgents(new MessageDispatcher(ws), fsStatePersistence, fsContextPersistence)
11
-
12
- await agents.load()
29
+ const loaded = await trackRepositoryOperation(async () => {
30
+ if (isUsageBlocked()) {
31
+ rejectBlockedConnection()
32
+ return false
33
+ }
34
+ await agents.load()
35
+ return true
36
+ })
37
+ if (!loaded) return
13
38
 
14
39
  // Queue websocket message handling so client-side multi-send sequences (e.g. select state -> send chat)
15
40
  // are applied deterministically and don't race when handlers `await`.
@@ -23,62 +48,87 @@ export async function oldServer(ws: WebSocket) {
23
48
  : event.toString()
24
49
 
25
50
  messageQueue = messageQueue
26
- .then(async () => {
27
- let msg: WsMessage
28
- try {
29
- msg = JSON.parse(raw) as WsMessage
30
- } catch (error) {
31
- console.error('Error parsing websocket message', error)
32
- return
33
- }
51
+ .then(() =>
52
+ trackRepositoryOperation(async () => {
53
+ if (isUsageBlocked()) {
54
+ ws.send(
55
+ JSON.stringify({
56
+ channel: 'error',
57
+ message: 'Bosun is refreshing the project. Please wait.'
58
+ })
59
+ )
60
+ return
61
+ }
34
62
 
35
- // @ts-ignore
36
- console.log('--> ', msg.channel, msg.event?.type || '')
63
+ let msg: WsMessage
64
+ try {
65
+ msg = JSON.parse(raw) as WsMessage
66
+ } catch (error) {
67
+ console.error('Error parsing websocket message', error)
68
+ return
69
+ }
37
70
 
38
- switch (msg.channel) {
39
- case 'app-events':
40
- switch (msg.event.type) {
41
- case 'select-agent':
42
- await agents.select(
43
- msg.event.agent,
44
- msg.event.state,
45
- msg.event.region,
46
- msg.event.promptOverrides
47
- )
48
- break
49
- case 'prompt-overrides-updated':
50
- await agents.updatePromptOverrides(msg.event.prompts)
51
- break
52
- case 'reload-project':
53
- await agents.reload()
54
- break
55
- case 'context-updated':
56
- await agents.updateContext(msg.event.context)
57
- break
58
- case 'prompt-updated':
59
- await agents.updatePrompt(msg.event.prompt)
60
- break
61
- case 'trigger-action':
62
- await agents.triggerAction(msg.event.action)
63
- break
64
- case 'step-selected':
65
- await agents.selectStep(msg.event.step)
66
- break
67
- case 'hangup':
68
- await agents.hangup(msg.event.agentId, msg.event.region)
69
- break
71
+ // @ts-ignore
72
+ console.log('--> ', msg.channel, msg.event?.type || '')
70
73
 
71
- default:
72
- console.error(`Unknown event type: ${msg.event.type}`)
73
- }
74
- break
75
- case 'chat':
76
- await agents.handleMessage(msg.message)
77
- break
78
- default:
79
- console.error(`Unknown channel: ${msg.channel}`)
80
- }
81
- })
74
+ switch (msg.channel) {
75
+ case 'app-events':
76
+ switch (msg.event.type) {
77
+ case 'git-sync-request':
78
+ ws.send(
79
+ JSON.stringify({
80
+ channel: 'app-events',
81
+ event: {
82
+ type: 'git-sync-complete',
83
+ requestId: msg.event.requestId
84
+ }
85
+ })
86
+ )
87
+ break
88
+ case 'git-sync-complete':
89
+ break
90
+ case 'select-agent':
91
+ await agents.select(
92
+ msg.event.agent,
93
+ msg.event.state,
94
+ msg.event.region,
95
+ msg.event.promptOverrides
96
+ )
97
+ break
98
+ case 'prompt-overrides-updated':
99
+ await agents.updatePromptOverrides(msg.event.prompts)
100
+ break
101
+ case 'reload-project':
102
+ await agents.reload()
103
+ break
104
+ case 'context-updated':
105
+ await agents.updateContext(msg.event.context)
106
+ break
107
+ case 'prompt-updated':
108
+ await agents.updatePrompt(msg.event.prompt)
109
+ break
110
+ case 'trigger-action':
111
+ await agents.triggerAction(msg.event.action)
112
+ break
113
+ case 'step-selected':
114
+ await agents.selectStep(msg.event.step)
115
+ break
116
+ case 'hangup':
117
+ await agents.hangup(msg.event.agentId, msg.event.region)
118
+ break
119
+
120
+ default:
121
+ console.error(`Unknown event type: ${msg.event.type}`)
122
+ }
123
+ break
124
+ case 'chat':
125
+ await agents.handleMessage(msg.message)
126
+ break
127
+ default:
128
+ console.error(`Unknown channel: ${msg.channel}`)
129
+ }
130
+ })
131
+ )
82
132
  .catch((error) => {
83
133
  console.error('Error handling message', error)
84
134
  try {
@@ -9,22 +9,51 @@ export type PromptEditProposal = {
9
9
  createdAt: number
10
10
  }
11
11
 
12
- const proposals = new Map<string, PromptEditProposal>()
12
+ export interface PromptEditTestSourceGuard {
13
+ suiteKey: string
14
+ testId: string
15
+ allowedFingerprints: string[]
16
+ }
17
+
18
+ type StoredPromptEditProposal = PromptEditProposal & {
19
+ testSourceGuard?: PromptEditTestSourceGuard
20
+ }
21
+
22
+ const proposals = new Map<string, StoredPromptEditProposal>()
13
23
  const PROPOSAL_TTL_MS = 12 * 60 * 60 * 1000
14
24
 
15
25
  export function createPromptEditProposal(
16
- proposal: Omit<PromptEditProposal, 'id' | 'createdAt'>
26
+ proposal: Omit<PromptEditProposal, 'id' | 'createdAt'> & {
27
+ testSourceGuard?: PromptEditTestSourceGuard
28
+ }
17
29
  ): PromptEditProposal {
18
30
  removeExpiredPromptEditProposals()
19
31
  const stored = { ...proposal, id: randomUUID(), createdAt: Date.now() }
20
32
  proposals.set(stored.id, stored)
21
- return { ...stored }
33
+ return publicProposal(stored)
22
34
  }
23
35
 
24
36
  export function getPromptEditProposal(id: string): PromptEditProposal | null {
25
37
  removeExpiredPromptEditProposals()
26
38
  const proposal = proposals.get(id)
27
- return proposal ? { ...proposal } : null
39
+ return proposal ? publicProposal(proposal) : null
40
+ }
41
+
42
+ export function getPromptEditProposalForAcceptance(id: string): StoredPromptEditProposal | null {
43
+ removeExpiredPromptEditProposals()
44
+ const proposal = proposals.get(id)
45
+ return proposal
46
+ ? {
47
+ ...proposal,
48
+ testSourceGuard: proposal.testSourceGuard
49
+ ? {
50
+ suiteKey: proposal.testSourceGuard.suiteKey,
51
+ testId: proposal.testSourceGuard.testId,
52
+ allowedFingerprints: [...proposal.testSourceGuard.allowedFingerprints]
53
+ }
54
+ : undefined
55
+ }
56
+ : null
28
57
  }
29
58
 
30
59
  export function deletePromptEditProposal(id: string): boolean {
@@ -36,3 +65,8 @@ function removeExpiredPromptEditProposals(now = Date.now()) {
36
65
  if (proposal.createdAt + PROPOSAL_TTL_MS <= now) proposals.delete(id)
37
66
  }
38
67
  }
68
+
69
+ function publicProposal(proposal: StoredPromptEditProposal): PromptEditProposal {
70
+ const { testSourceGuard: _testSourceGuard, ...result } = proposal
71
+ return { ...result }
72
+ }