@recombine-ai/bosun 0.1.10 → 0.2.0-draft

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 (439) hide show
  1. package/build/academy/academy.ts +584 -0
  2. package/build/academy/csv/index.ts +155 -0
  3. package/build/academy/data.ts +299 -0
  4. package/build/academy/emulate-agents.ts +129 -0
  5. package/build/academy/google-sheets/index.ts +187 -0
  6. package/build/academy/runPromptTests.cli.ts +99 -0
  7. package/build/academy/suite.ts +99 -0
  8. package/build/client/_app/immutable/assets/0.3Ve1RxLg.css +1 -0
  9. package/build/client/_app/immutable/assets/0.3Ve1RxLg.css.br +0 -0
  10. package/build/client/_app/immutable/assets/0.3Ve1RxLg.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/3.C7pCuiHL.css +1 -0
  12. package/build/client/_app/immutable/assets/3.C7pCuiHL.css.br +0 -0
  13. package/build/client/_app/immutable/assets/3.C7pCuiHL.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/4.Baezuvdj.css +1 -0
  15. package/build/client/_app/immutable/assets/4.Baezuvdj.css.br +0 -0
  16. package/build/client/_app/immutable/assets/4.Baezuvdj.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/6.CebW_jOJ.css +1 -0
  18. package/build/client/_app/immutable/assets/6.CebW_jOJ.css.br +0 -0
  19. package/build/client/_app/immutable/assets/6.CebW_jOJ.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/8.f3T7i0UW.css +1 -0
  21. package/build/client/_app/immutable/assets/8.f3T7i0UW.css.br +0 -0
  22. package/build/client/_app/immutable/assets/8.f3T7i0UW.css.gz +0 -0
  23. package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css +1 -0
  24. package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css.br +0 -0
  25. package/build/client/_app/immutable/assets/AgentSidebar.BEG0l2mN.css.gz +0 -0
  26. package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css +1 -0
  27. package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css.br +1 -0
  28. package/build/client/_app/immutable/assets/Link.D7uHGZ0C.css.gz +0 -0
  29. package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css +1 -0
  30. package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css.br +0 -0
  31. package/build/client/_app/immutable/assets/Tab.DrtF13Tg.css.gz +0 -0
  32. package/build/client/_app/immutable/chunks/B6Eu_a6G.js +8 -0
  33. package/build/client/_app/immutable/chunks/B6Eu_a6G.js.br +0 -0
  34. package/build/client/_app/immutable/chunks/B6Eu_a6G.js.gz +0 -0
  35. package/build/client/_app/immutable/chunks/B946i1vX.js +1 -0
  36. package/build/client/_app/immutable/chunks/B946i1vX.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/B946i1vX.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/BDr6IUDE.js +1 -0
  39. package/build/client/_app/immutable/chunks/BDr6IUDE.js.br +0 -0
  40. package/build/client/_app/immutable/chunks/BDr6IUDE.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/BJ0PAzRz.js +1 -0
  42. package/build/client/_app/immutable/chunks/BJ0PAzRz.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/BJ0PAzRz.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/BQsXEsya.js +2 -0
  45. package/build/client/_app/immutable/chunks/BQsXEsya.js.br +0 -0
  46. package/build/client/_app/immutable/chunks/BQsXEsya.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/BVH8cl8Q.js +1 -0
  48. package/build/client/_app/immutable/chunks/BVH8cl8Q.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/BVH8cl8Q.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/Bckf35or.js +1 -0
  51. package/build/client/_app/immutable/chunks/Bckf35or.js.br +1 -0
  52. package/build/client/_app/immutable/chunks/Bckf35or.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/BcyK4bvI.js +1 -0
  54. package/build/client/_app/immutable/chunks/BcyK4bvI.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/BcyK4bvI.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/BpsvkpCa.js +1 -0
  57. package/build/client/_app/immutable/chunks/BpsvkpCa.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/BpsvkpCa.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/C7b8kjFl.js +33 -0
  60. package/build/client/_app/immutable/chunks/C7b8kjFl.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/C7b8kjFl.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/{D5O98MXA.js → C9ihsQgF.js} +2 -2
  63. package/build/client/_app/immutable/chunks/C9ihsQgF.js.br +6 -0
  64. package/build/client/_app/immutable/chunks/C9ihsQgF.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/CEHtmspK.js +1 -0
  66. package/build/client/_app/immutable/chunks/CEHtmspK.js.br +0 -0
  67. package/build/client/_app/immutable/chunks/CEHtmspK.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/CHop8m-3.js +1 -0
  69. package/build/client/_app/immutable/chunks/CHop8m-3.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/CHop8m-3.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/CUWa2xqt.js +1 -0
  72. package/build/client/_app/immutable/chunks/CUWa2xqt.js.br +0 -0
  73. package/build/client/_app/immutable/chunks/CUWa2xqt.js.gz +0 -0
  74. package/build/client/_app/immutable/chunks/ClfaR3Y2.js +1 -0
  75. package/build/client/_app/immutable/chunks/ClfaR3Y2.js.br +0 -0
  76. package/build/client/_app/immutable/chunks/ClfaR3Y2.js.gz +0 -0
  77. package/build/client/_app/immutable/chunks/DAgYAbDT.js +3 -0
  78. package/build/client/_app/immutable/chunks/DAgYAbDT.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/DAgYAbDT.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/DBCXNg0T.js +1 -0
  81. package/build/client/_app/immutable/chunks/DBCXNg0T.js.br +0 -0
  82. package/build/client/_app/immutable/chunks/DBCXNg0T.js.gz +0 -0
  83. package/build/client/_app/immutable/chunks/DDncCuU5.js +1 -0
  84. package/build/client/_app/immutable/chunks/DDncCuU5.js.br +2 -0
  85. package/build/client/_app/immutable/chunks/DDncCuU5.js.gz +0 -0
  86. package/build/client/_app/immutable/chunks/DHQ8_yIz.js +1 -0
  87. package/build/client/_app/immutable/chunks/DHQ8_yIz.js.br +0 -0
  88. package/build/client/_app/immutable/chunks/DHQ8_yIz.js.gz +0 -0
  89. package/build/client/_app/immutable/chunks/Deb2U3a-.js +1 -0
  90. package/build/client/_app/immutable/chunks/Deb2U3a-.js.br +0 -0
  91. package/build/client/_app/immutable/chunks/Deb2U3a-.js.gz +0 -0
  92. package/build/client/_app/immutable/chunks/{B8bx6-qu.js → DgNsppMf.js} +1 -1
  93. package/build/client/_app/immutable/chunks/DgNsppMf.js.br +0 -0
  94. package/build/client/_app/immutable/chunks/DgNsppMf.js.gz +0 -0
  95. package/build/client/_app/immutable/chunks/DgSSnt2u.js +1 -0
  96. package/build/client/_app/immutable/chunks/DgSSnt2u.js.br +0 -0
  97. package/build/client/_app/immutable/chunks/DgSSnt2u.js.gz +0 -0
  98. package/build/client/_app/immutable/chunks/Dr0H-PA9.js +1 -0
  99. package/build/client/_app/immutable/chunks/Dr0H-PA9.js.br +0 -0
  100. package/build/client/_app/immutable/chunks/Dr0H-PA9.js.gz +0 -0
  101. package/build/client/_app/immutable/chunks/HA3qddzj.js +1 -0
  102. package/build/client/_app/immutable/chunks/HA3qddzj.js.br +0 -0
  103. package/build/client/_app/immutable/chunks/HA3qddzj.js.gz +0 -0
  104. package/build/client/_app/immutable/chunks/LPKWlFs0.js +1 -0
  105. package/build/client/_app/immutable/chunks/LPKWlFs0.js.br +3 -0
  106. package/build/client/_app/immutable/chunks/LPKWlFs0.js.gz +0 -0
  107. package/build/client/_app/immutable/chunks/VpPuF4LW.js +3 -0
  108. package/build/client/_app/immutable/chunks/VpPuF4LW.js.br +0 -0
  109. package/build/client/_app/immutable/chunks/VpPuF4LW.js.gz +0 -0
  110. package/build/client/_app/immutable/chunks/XyRovF4A.js +1 -0
  111. package/build/client/_app/immutable/chunks/XyRovF4A.js.br +0 -0
  112. package/build/client/_app/immutable/chunks/XyRovF4A.js.gz +0 -0
  113. package/build/client/_app/immutable/chunks/mRVZsLQ4.js +1 -0
  114. package/build/client/_app/immutable/chunks/mRVZsLQ4.js.br +2 -0
  115. package/build/client/_app/immutable/chunks/mRVZsLQ4.js.gz +0 -0
  116. package/build/client/_app/immutable/entry/app.CVDHq7dN.js +2 -0
  117. package/build/client/_app/immutable/entry/app.CVDHq7dN.js.br +0 -0
  118. package/build/client/_app/immutable/entry/app.CVDHq7dN.js.gz +0 -0
  119. package/build/client/_app/immutable/entry/start.a4wXr-rh.js +1 -0
  120. package/build/client/_app/immutable/entry/start.a4wXr-rh.js.br +2 -0
  121. package/build/client/_app/immutable/entry/start.a4wXr-rh.js.gz +0 -0
  122. package/build/client/_app/immutable/nodes/0.q5P1PqkU.js +3 -0
  123. package/build/client/_app/immutable/nodes/0.q5P1PqkU.js.br +0 -0
  124. package/build/client/_app/immutable/nodes/0.q5P1PqkU.js.gz +0 -0
  125. package/build/client/_app/immutable/nodes/1.TfmDsqd-.js +1 -0
  126. package/build/client/_app/immutable/nodes/1.TfmDsqd-.js.br +0 -0
  127. package/build/client/_app/immutable/nodes/1.TfmDsqd-.js.gz +0 -0
  128. package/build/client/_app/immutable/nodes/10.BpXsBlTN.js +1 -0
  129. package/build/client/_app/immutable/nodes/10.BpXsBlTN.js.br +0 -0
  130. package/build/client/_app/immutable/nodes/10.BpXsBlTN.js.gz +0 -0
  131. package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js +1 -0
  132. package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js.br +0 -0
  133. package/build/client/_app/immutable/nodes/11.Bs_5a_H1.js.gz +0 -0
  134. package/build/client/_app/immutable/nodes/2.BWtLQzzv.js +3 -0
  135. package/build/client/_app/immutable/nodes/2.BWtLQzzv.js.br +0 -0
  136. package/build/client/_app/immutable/nodes/2.BWtLQzzv.js.gz +0 -0
  137. package/build/client/_app/immutable/nodes/3.BlYIVobe.js +1 -0
  138. package/build/client/_app/immutable/nodes/3.BlYIVobe.js.br +0 -0
  139. package/build/client/_app/immutable/nodes/3.BlYIVobe.js.gz +0 -0
  140. package/build/client/_app/immutable/nodes/4.DMboagHp.js +38 -0
  141. package/build/client/_app/immutable/nodes/4.DMboagHp.js.br +0 -0
  142. package/build/client/_app/immutable/nodes/4.DMboagHp.js.gz +0 -0
  143. package/build/client/_app/immutable/nodes/5.DJDEfbU1.js +1 -0
  144. package/build/client/_app/immutable/nodes/5.DJDEfbU1.js.br +0 -0
  145. package/build/client/_app/immutable/nodes/5.DJDEfbU1.js.gz +0 -0
  146. package/build/client/_app/immutable/nodes/6.Co1n7leD.js +12 -0
  147. package/build/client/_app/immutable/nodes/6.Co1n7leD.js.br +0 -0
  148. package/build/client/_app/immutable/nodes/6.Co1n7leD.js.gz +0 -0
  149. package/build/client/_app/immutable/nodes/7.3clSez0f.js +1 -0
  150. package/build/client/_app/immutable/nodes/7.3clSez0f.js.br +0 -0
  151. package/build/client/_app/immutable/nodes/7.3clSez0f.js.gz +0 -0
  152. package/build/client/_app/immutable/nodes/8.D4xImLsM.js +1 -0
  153. package/build/client/_app/immutable/nodes/8.D4xImLsM.js.br +0 -0
  154. package/build/client/_app/immutable/nodes/8.D4xImLsM.js.gz +0 -0
  155. package/build/client/_app/immutable/nodes/9.C1KWPSTf.js +1 -0
  156. package/build/client/_app/immutable/nodes/9.C1KWPSTf.js.br +0 -0
  157. package/build/client/_app/immutable/nodes/9.C1KWPSTf.js.gz +0 -0
  158. package/build/client/_app/version.json +1 -1
  159. package/build/client/_app/version.json.br +0 -0
  160. package/build/client/_app/version.json.gz +0 -0
  161. package/build/server/chunks/0-CgyQG-Vf.js +9 -0
  162. package/build/server/chunks/0-CgyQG-Vf.js.map +1 -0
  163. package/build/server/chunks/1-DACiLfsu.js +9 -0
  164. package/build/server/chunks/{1-dPD-duO8.js.map → 1-DACiLfsu.js.map} +1 -1
  165. package/build/server/chunks/10-zMqY0bCj.js +9 -0
  166. package/build/server/chunks/10-zMqY0bCj.js.map +1 -0
  167. package/build/server/chunks/11-B7cPB4ip.js +9 -0
  168. package/build/server/chunks/11-B7cPB4ip.js.map +1 -0
  169. package/build/server/chunks/2-uTf78dNT.js +9 -0
  170. package/build/server/chunks/2-uTf78dNT.js.map +1 -0
  171. package/build/server/chunks/3-DOOLRXaZ.js +9 -0
  172. package/build/server/chunks/3-DOOLRXaZ.js.map +1 -0
  173. package/build/server/chunks/4-CLK_BxY0.js +9 -0
  174. package/build/server/chunks/4-CLK_BxY0.js.map +1 -0
  175. package/build/server/chunks/5-DfZ6yJrz.js +9 -0
  176. package/build/server/chunks/5-DfZ6yJrz.js.map +1 -0
  177. package/build/server/chunks/6-B2BoZUr6.js +22 -0
  178. package/build/server/chunks/6-B2BoZUr6.js.map +1 -0
  179. package/build/server/chunks/{5-p3BDfNc2.js → 7-DmgY6drC.js} +6 -6
  180. package/build/server/chunks/7-DmgY6drC.js.map +1 -0
  181. package/build/server/chunks/8-Bku8n4Ko.js +9 -0
  182. package/build/server/chunks/8-Bku8n4Ko.js.map +1 -0
  183. package/build/server/chunks/{7-C_AGqUAU.js → 9-nwlpMH7t.js} +5 -5
  184. package/build/server/chunks/9-nwlpMH7t.js.map +1 -0
  185. package/build/server/chunks/AgentSidebar-CZIBBsSh.js +141 -0
  186. package/build/server/chunks/AgentSidebar-CZIBBsSh.js.map +1 -0
  187. package/build/server/chunks/Button-OUO_MioZ.js +44 -0
  188. package/build/server/chunks/Button-OUO_MioZ.js.map +1 -0
  189. package/build/server/chunks/ContextEditor-stz14-2o.js +48 -0
  190. package/build/server/chunks/ContextEditor-stz14-2o.js.map +1 -0
  191. package/build/server/chunks/{Dropdown-B-UCol1v.js → Dropdown-BTr_XiAm.js} +2 -2
  192. package/build/server/chunks/Dropdown-BTr_XiAm.js.map +1 -0
  193. package/build/server/chunks/{Input-DLAEH36y.js → Input-B_jIG2tD.js} +2 -2
  194. package/build/server/chunks/Input-B_jIG2tD.js.map +1 -0
  195. package/build/server/chunks/{Icon-DDJ9D6Sq.js → Link-DaOJVbdB.js} +25 -42
  196. package/build/server/chunks/Link-DaOJVbdB.js.map +1 -0
  197. package/build/server/chunks/{Panel-KZDoG3_L.js → Panel-CmvYn6IC.js} +2 -2
  198. package/build/server/chunks/Panel-CmvYn6IC.js.map +1 -0
  199. package/build/server/chunks/Tab-n348Mfiq.js +84 -0
  200. package/build/server/chunks/Tab-n348Mfiq.js.map +1 -0
  201. package/build/server/chunks/_layout.svelte-CP6tz6DB.js +62 -0
  202. package/build/server/chunks/_layout.svelte-CP6tz6DB.js.map +1 -0
  203. package/build/server/chunks/{_layout.svelte-BoAJDYC1.js → _layout.svelte-CvGX8M4U.js} +68 -18
  204. package/build/server/chunks/_layout.svelte-CvGX8M4U.js.map +1 -0
  205. package/build/server/chunks/{_page.svelte-CdEfc0bc.js → _page.svelte-AHHrodUG.js} +94 -86
  206. package/build/server/chunks/_page.svelte-AHHrodUG.js.map +1 -0
  207. package/build/server/chunks/_page.svelte-Bm-iBjXM.js +80 -0
  208. package/build/server/chunks/_page.svelte-Bm-iBjXM.js.map +1 -0
  209. package/build/server/chunks/_page.svelte-D5Xqk3cI.js +52 -0
  210. package/build/server/chunks/_page.svelte-D5Xqk3cI.js.map +1 -0
  211. package/build/server/chunks/{_page.svelte-CNhxx79k.js → _page.svelte-DKBFi-JF.js} +202 -240
  212. package/build/server/chunks/_page.svelte-DKBFi-JF.js.map +1 -0
  213. package/build/server/chunks/{_page.svelte-DQUdiD4S.js → _page.svelte-DSefP5E9.js} +6 -5
  214. package/build/server/chunks/_page.svelte-DSefP5E9.js.map +1 -0
  215. package/build/server/chunks/{_page.svelte-kLLxi8vG.js → _page.svelte-Dldwxu4m.js} +28 -6
  216. package/build/server/chunks/_page.svelte-Dldwxu4m.js.map +1 -0
  217. package/build/server/chunks/{_page.svelte-Cc0DAAQW.js → _page.svelte-lU1-SHJj.js} +5 -4
  218. package/build/server/chunks/_page.svelte-lU1-SHJj.js.map +1 -0
  219. package/build/server/chunks/{_page.svelte-nsIWq28L.js → _page.svelte-vGR-ltk7.js} +7 -27
  220. package/build/server/chunks/_page.svelte-vGR-ltk7.js.map +1 -0
  221. package/build/server/chunks/{_server.ts-d0Tii8aZ.js → _server.ts-3D9tpnMZ.js} +3 -2
  222. package/build/server/chunks/_server.ts-3D9tpnMZ.js.map +1 -0
  223. package/build/server/chunks/{_server.ts-BBxm_xV1.js → _server.ts-B56wS_0L.js} +4 -1
  224. package/build/server/chunks/_server.ts-B56wS_0L.js.map +1 -0
  225. package/build/server/chunks/{_server.ts-CLKPeFqF.js → _server.ts-BCBY3OIY.js} +3 -2
  226. package/build/server/chunks/_server.ts-BCBY3OIY.js.map +1 -0
  227. package/build/server/chunks/{_server.ts-BmZBSYvJ.js → _server.ts-BCfiuZgS.js} +19 -8
  228. package/build/server/chunks/_server.ts-BCfiuZgS.js.map +1 -0
  229. package/build/server/chunks/_server.ts-BkL-sSQA.js.map +1 -1
  230. package/build/server/chunks/{_server.ts-DEHw6op6.js → _server.ts-D0C3cRDU.js} +3 -2
  231. package/build/server/chunks/_server.ts-D0C3cRDU.js.map +1 -0
  232. package/build/server/chunks/{_server.ts-BYDdbqNr.js → _server.ts-Dc989xbA.js} +3 -2
  233. package/build/server/chunks/_server.ts-Dc989xbA.js.map +1 -0
  234. package/build/server/chunks/_server.ts-Ddto8x_p.js.map +1 -1
  235. package/build/server/chunks/{_server.ts-BIcKE9RQ.js → _server.ts-I-18L-Sg.js} +3 -2
  236. package/build/server/chunks/_server.ts-I-18L-Sg.js.map +1 -0
  237. package/build/server/chunks/_server.ts-iuWHhHZx.js +629 -0
  238. package/build/server/chunks/_server.ts-iuWHhHZx.js.map +1 -0
  239. package/build/server/chunks/agents-context-C4MM7lSl.js +6 -0
  240. package/build/server/chunks/agents-context-C4MM7lSl.js.map +1 -0
  241. package/build/server/chunks/{client2-tp0-IQU0.js → client-BhnXtftB.js} +6 -29
  242. package/build/server/chunks/client-BhnXtftB.js.map +1 -0
  243. package/build/server/chunks/{index2-CVBATI2G.js → context-Dy9MY1Z0.js} +253 -965
  244. package/build/server/chunks/context-Dy9MY1Z0.js.map +1 -0
  245. package/build/server/chunks/{data-CbXDDeDB.js → data-BltJc-uF.js} +29 -89
  246. package/build/server/chunks/data-BltJc-uF.js.map +1 -0
  247. package/build/server/chunks/error.svelte-Cn6umEWY.js +14 -0
  248. package/build/server/chunks/error.svelte-Cn6umEWY.js.map +1 -0
  249. package/build/server/chunks/errors-B8liwVcD.js +17 -0
  250. package/build/server/chunks/errors-B8liwVcD.js.map +1 -0
  251. package/build/server/chunks/{events-A18hGvKp.js → events-BFcZEt66.js} +3 -9
  252. package/build/server/chunks/events-BFcZEt66.js.map +1 -0
  253. package/build/server/chunks/{index-BoStl4QO.js → index-C0ds_eUO.js} +8 -3
  254. package/build/server/chunks/index-C0ds_eUO.js.map +1 -0
  255. package/build/server/chunks/index-server-CMCI3p2Y.js +18 -0
  256. package/build/server/chunks/index-server-CMCI3p2Y.js.map +1 -0
  257. package/build/server/chunks/index2-B1rkViAM.js +860 -0
  258. package/build/server/chunks/index2-B1rkViAM.js.map +1 -0
  259. package/build/server/chunks/index3-CVYj52gl.js.map +1 -1
  260. package/build/server/chunks/index4-DSZuWW-A.js +47 -0
  261. package/build/server/chunks/index4-DSZuWW-A.js.map +1 -0
  262. package/build/server/chunks/main-DL75vM4l.js +2250 -0
  263. package/build/server/chunks/main-DL75vM4l.js.map +1 -0
  264. package/build/server/chunks/{state.svelte-Dze7OxC_.js → state.svelte-CBgyohE1.js} +2 -2
  265. package/build/server/chunks/state.svelte-CBgyohE1.js.map +1 -0
  266. package/build/server/chunks/suite-4--Gr0jF.js +60 -0
  267. package/build/server/chunks/suite-4--Gr0jF.js.map +1 -0
  268. package/build/server/chunks/ws-client-CyJORDFw.js +98 -0
  269. package/build/server/chunks/ws-client-CyJORDFw.js.map +1 -0
  270. package/build/server/index.js +167 -90
  271. package/build/server/index.js.map +1 -1
  272. package/build/server/manifest.js +83 -75
  273. package/build/server/manifest.js.map +1 -1
  274. package/package.json +3 -1
  275. package/src/ws-server/projects.ts +82 -9
  276. package/build/client/_app/immutable/assets/0.7xdY7TSX.css +0 -1
  277. package/build/client/_app/immutable/assets/0.7xdY7TSX.css.br +0 -0
  278. package/build/client/_app/immutable/assets/0.7xdY7TSX.css.gz +0 -0
  279. package/build/client/_app/immutable/assets/10.C1o6a69m.css +0 -1
  280. package/build/client/_app/immutable/assets/10.C1o6a69m.css.br +0 -1
  281. package/build/client/_app/immutable/assets/10.C1o6a69m.css.gz +0 -0
  282. package/build/client/_app/immutable/assets/4.858mUNwe.css +0 -1
  283. package/build/client/_app/immutable/assets/4.858mUNwe.css.br +0 -0
  284. package/build/client/_app/immutable/assets/4.858mUNwe.css.gz +0 -0
  285. package/build/client/_app/immutable/assets/6.CD1QZ0pt.css +0 -1
  286. package/build/client/_app/immutable/assets/6.CD1QZ0pt.css.br +0 -0
  287. package/build/client/_app/immutable/assets/6.CD1QZ0pt.css.gz +0 -0
  288. package/build/client/_app/immutable/chunks/2PVbuV1X.js +0 -1
  289. package/build/client/_app/immutable/chunks/2PVbuV1X.js.br +0 -1
  290. package/build/client/_app/immutable/chunks/2PVbuV1X.js.gz +0 -0
  291. package/build/client/_app/immutable/chunks/9OGf6H2n.js +0 -1
  292. package/build/client/_app/immutable/chunks/9OGf6H2n.js.br +0 -2
  293. package/build/client/_app/immutable/chunks/9OGf6H2n.js.gz +0 -0
  294. package/build/client/_app/immutable/chunks/B8bx6-qu.js.br +0 -1
  295. package/build/client/_app/immutable/chunks/B8bx6-qu.js.gz +0 -0
  296. package/build/client/_app/immutable/chunks/BDTuVTVZ.js +0 -1
  297. package/build/client/_app/immutable/chunks/BDTuVTVZ.js.br +0 -0
  298. package/build/client/_app/immutable/chunks/BDTuVTVZ.js.gz +0 -0
  299. package/build/client/_app/immutable/chunks/BTGV3Gq0.js +0 -8
  300. package/build/client/_app/immutable/chunks/BTGV3Gq0.js.br +0 -0
  301. package/build/client/_app/immutable/chunks/BTGV3Gq0.js.gz +0 -0
  302. package/build/client/_app/immutable/chunks/BUJtMu79.js +0 -3
  303. package/build/client/_app/immutable/chunks/BUJtMu79.js.br +0 -0
  304. package/build/client/_app/immutable/chunks/BUJtMu79.js.gz +0 -0
  305. package/build/client/_app/immutable/chunks/BUoURvZ_.js +0 -1
  306. package/build/client/_app/immutable/chunks/BUoURvZ_.js.br +0 -0
  307. package/build/client/_app/immutable/chunks/BUoURvZ_.js.gz +0 -0
  308. package/build/client/_app/immutable/chunks/BdOqksoz.js +0 -1
  309. package/build/client/_app/immutable/chunks/BdOqksoz.js.br +0 -0
  310. package/build/client/_app/immutable/chunks/BdOqksoz.js.gz +0 -0
  311. package/build/client/_app/immutable/chunks/Be371ezp.js +0 -2
  312. package/build/client/_app/immutable/chunks/Be371ezp.js.br +0 -0
  313. package/build/client/_app/immutable/chunks/Be371ezp.js.gz +0 -0
  314. package/build/client/_app/immutable/chunks/Bmx4ManB.js +0 -1
  315. package/build/client/_app/immutable/chunks/Bmx4ManB.js.br +0 -0
  316. package/build/client/_app/immutable/chunks/Bmx4ManB.js.gz +0 -0
  317. package/build/client/_app/immutable/chunks/C2Y9UxTx.js +0 -1
  318. package/build/client/_app/immutable/chunks/C2Y9UxTx.js.br +0 -0
  319. package/build/client/_app/immutable/chunks/C2Y9UxTx.js.gz +0 -0
  320. package/build/client/_app/immutable/chunks/CYuXdPQc.js +0 -1
  321. package/build/client/_app/immutable/chunks/CYuXdPQc.js.br +0 -0
  322. package/build/client/_app/immutable/chunks/CYuXdPQc.js.gz +0 -0
  323. package/build/client/_app/immutable/chunks/CpZGG0E7.js +0 -1
  324. package/build/client/_app/immutable/chunks/CpZGG0E7.js.br +0 -0
  325. package/build/client/_app/immutable/chunks/CpZGG0E7.js.gz +0 -0
  326. package/build/client/_app/immutable/chunks/CpdYAO0i.js +0 -1
  327. package/build/client/_app/immutable/chunks/CpdYAO0i.js.br +0 -0
  328. package/build/client/_app/immutable/chunks/CpdYAO0i.js.gz +0 -0
  329. package/build/client/_app/immutable/chunks/CtpS-ZbM.js +0 -1
  330. package/build/client/_app/immutable/chunks/CtpS-ZbM.js.br +0 -0
  331. package/build/client/_app/immutable/chunks/CtpS-ZbM.js.gz +0 -0
  332. package/build/client/_app/immutable/chunks/D5O98MXA.js.br +0 -0
  333. package/build/client/_app/immutable/chunks/D5O98MXA.js.gz +0 -0
  334. package/build/client/_app/immutable/chunks/DIiF2tGe.js +0 -1
  335. package/build/client/_app/immutable/chunks/DIiF2tGe.js.br +0 -0
  336. package/build/client/_app/immutable/chunks/DIiF2tGe.js.gz +0 -0
  337. package/build/client/_app/immutable/chunks/D_4dC3JZ.js +0 -1
  338. package/build/client/_app/immutable/chunks/D_4dC3JZ.js.br +0 -0
  339. package/build/client/_app/immutable/chunks/D_4dC3JZ.js.gz +0 -0
  340. package/build/client/_app/immutable/chunks/DveC87gn.js +0 -33
  341. package/build/client/_app/immutable/chunks/DveC87gn.js.br +0 -0
  342. package/build/client/_app/immutable/chunks/DveC87gn.js.gz +0 -0
  343. package/build/client/_app/immutable/chunks/ISgeSat5.js +0 -1
  344. package/build/client/_app/immutable/chunks/ISgeSat5.js.br +0 -0
  345. package/build/client/_app/immutable/chunks/ISgeSat5.js.gz +0 -0
  346. package/build/client/_app/immutable/chunks/f4SQk-uT.js +0 -3
  347. package/build/client/_app/immutable/chunks/f4SQk-uT.js.br +0 -0
  348. package/build/client/_app/immutable/chunks/f4SQk-uT.js.gz +0 -0
  349. package/build/client/_app/immutable/entry/app.BCqdi-0A.js +0 -2
  350. package/build/client/_app/immutable/entry/app.BCqdi-0A.js.br +0 -0
  351. package/build/client/_app/immutable/entry/app.BCqdi-0A.js.gz +0 -0
  352. package/build/client/_app/immutable/entry/start.FFZ3vuST.js +0 -1
  353. package/build/client/_app/immutable/entry/start.FFZ3vuST.js.br +0 -2
  354. package/build/client/_app/immutable/entry/start.FFZ3vuST.js.gz +0 -0
  355. package/build/client/_app/immutable/nodes/0.BFGm6g4L.js +0 -1
  356. package/build/client/_app/immutable/nodes/0.BFGm6g4L.js.br +0 -0
  357. package/build/client/_app/immutable/nodes/0.BFGm6g4L.js.gz +0 -0
  358. package/build/client/_app/immutable/nodes/1.BldvfsiS.js +0 -1
  359. package/build/client/_app/immutable/nodes/1.BldvfsiS.js.br +0 -0
  360. package/build/client/_app/immutable/nodes/1.BldvfsiS.js.gz +0 -0
  361. package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js +0 -1
  362. package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js.br +0 -0
  363. package/build/client/_app/immutable/nodes/10.Bdd6Le3Q.js.gz +0 -0
  364. package/build/client/_app/immutable/nodes/2.c7KihIjN.js +0 -3
  365. package/build/client/_app/immutable/nodes/2.c7KihIjN.js.br +0 -0
  366. package/build/client/_app/immutable/nodes/2.c7KihIjN.js.gz +0 -0
  367. package/build/client/_app/immutable/nodes/4.BokOq116.js +0 -12
  368. package/build/client/_app/immutable/nodes/4.BokOq116.js.br +0 -0
  369. package/build/client/_app/immutable/nodes/4.BokOq116.js.gz +0 -0
  370. package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js +0 -1
  371. package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js.br +0 -0
  372. package/build/client/_app/immutable/nodes/5.BqyMuHwQ.js.gz +0 -0
  373. package/build/client/_app/immutable/nodes/6.CMaZNrkR.js +0 -38
  374. package/build/client/_app/immutable/nodes/6.CMaZNrkR.js.br +0 -0
  375. package/build/client/_app/immutable/nodes/6.CMaZNrkR.js.gz +0 -0
  376. package/build/client/_app/immutable/nodes/7.CvDadi99.js +0 -1
  377. package/build/client/_app/immutable/nodes/7.CvDadi99.js.br +0 -0
  378. package/build/client/_app/immutable/nodes/7.CvDadi99.js.gz +0 -0
  379. package/build/client/_app/immutable/nodes/8.CLZUC68b.js +0 -1
  380. package/build/client/_app/immutable/nodes/8.CLZUC68b.js.br +0 -0
  381. package/build/client/_app/immutable/nodes/8.CLZUC68b.js.gz +0 -0
  382. package/build/client/_app/immutable/nodes/9.BY1rgYUV.js +0 -1
  383. package/build/client/_app/immutable/nodes/9.BY1rgYUV.js.br +0 -0
  384. package/build/client/_app/immutable/nodes/9.BY1rgYUV.js.gz +0 -0
  385. package/build/server/chunks/0-DMd6Dk79.js +0 -9
  386. package/build/server/chunks/0-DMd6Dk79.js.map +0 -1
  387. package/build/server/chunks/1-dPD-duO8.js +0 -9
  388. package/build/server/chunks/10-Ci_AhluU.js +0 -9
  389. package/build/server/chunks/10-Ci_AhluU.js.map +0 -1
  390. package/build/server/chunks/2-C0B7VzbP.js +0 -9
  391. package/build/server/chunks/2-C0B7VzbP.js.map +0 -1
  392. package/build/server/chunks/3-DGFu_uy6.js +0 -19
  393. package/build/server/chunks/3-DGFu_uy6.js.map +0 -1
  394. package/build/server/chunks/4-MwbWFUCO.js +0 -22
  395. package/build/server/chunks/4-MwbWFUCO.js.map +0 -1
  396. package/build/server/chunks/5-p3BDfNc2.js.map +0 -1
  397. package/build/server/chunks/6-B6EVTx8w.js +0 -9
  398. package/build/server/chunks/6-B6EVTx8w.js.map +0 -1
  399. package/build/server/chunks/7-C_AGqUAU.js.map +0 -1
  400. package/build/server/chunks/8-Dr1vf8BH.js +0 -9
  401. package/build/server/chunks/8-Dr1vf8BH.js.map +0 -1
  402. package/build/server/chunks/9-BA8KMX2q.js +0 -9
  403. package/build/server/chunks/9-BA8KMX2q.js.map +0 -1
  404. package/build/server/chunks/AgentDropdown-C3XtwkaV.js +0 -162
  405. package/build/server/chunks/AgentDropdown-C3XtwkaV.js.map +0 -1
  406. package/build/server/chunks/Dropdown-B-UCol1v.js.map +0 -1
  407. package/build/server/chunks/Icon-DDJ9D6Sq.js.map +0 -1
  408. package/build/server/chunks/Input-DLAEH36y.js.map +0 -1
  409. package/build/server/chunks/Panel-KZDoG3_L.js.map +0 -1
  410. package/build/server/chunks/_layout.svelte-22nlfSFq.js +0 -9
  411. package/build/server/chunks/_layout.svelte-22nlfSFq.js.map +0 -1
  412. package/build/server/chunks/_layout.svelte-BoAJDYC1.js.map +0 -1
  413. package/build/server/chunks/_page.svelte-CNhxx79k.js.map +0 -1
  414. package/build/server/chunks/_page.svelte-Cc0DAAQW.js.map +0 -1
  415. package/build/server/chunks/_page.svelte-CdEfc0bc.js.map +0 -1
  416. package/build/server/chunks/_page.svelte-DQUdiD4S.js.map +0 -1
  417. package/build/server/chunks/_page.svelte-kLLxi8vG.js.map +0 -1
  418. package/build/server/chunks/_page.svelte-nsIWq28L.js.map +0 -1
  419. package/build/server/chunks/_server.ts-BBxm_xV1.js.map +0 -1
  420. package/build/server/chunks/_server.ts-BIcKE9RQ.js.map +0 -1
  421. package/build/server/chunks/_server.ts-BYDdbqNr.js.map +0 -1
  422. package/build/server/chunks/_server.ts-BmZBSYvJ.js.map +0 -1
  423. package/build/server/chunks/_server.ts-CLKPeFqF.js.map +0 -1
  424. package/build/server/chunks/_server.ts-DEHw6op6.js.map +0 -1
  425. package/build/server/chunks/_server.ts-DTyPQO2I.js +0 -93
  426. package/build/server/chunks/_server.ts-DTyPQO2I.js.map +0 -1
  427. package/build/server/chunks/_server.ts-d0Tii8aZ.js.map +0 -1
  428. package/build/server/chunks/client-DpkplAAP.js +0 -25
  429. package/build/server/chunks/client-DpkplAAP.js.map +0 -1
  430. package/build/server/chunks/client2-tp0-IQU0.js.map +0 -1
  431. package/build/server/chunks/context-DVQH5kJk.js +0 -113
  432. package/build/server/chunks/context-DVQH5kJk.js.map +0 -1
  433. package/build/server/chunks/data-CbXDDeDB.js.map +0 -1
  434. package/build/server/chunks/error.svelte-DNcHZkvg.js +0 -29
  435. package/build/server/chunks/error.svelte-DNcHZkvg.js.map +0 -1
  436. package/build/server/chunks/events-A18hGvKp.js.map +0 -1
  437. package/build/server/chunks/index-BoStl4QO.js.map +0 -1
  438. package/build/server/chunks/index2-CVBATI2G.js.map +0 -1
  439. package/build/server/chunks/state.svelte-Dze7OxC_.js.map +0 -1
@@ -0,0 +1,155 @@
1
+ import { readFile, writeFile, access } from 'node:fs/promises'
2
+ import path from 'node:path'
3
+ import { readdir } from 'node:fs/promises'
4
+
5
+ // CSV functionality removed; this module only handles project paths and config JSON.
6
+
7
+ // Resolve the base path for a given project (folder containing workflows.ts)
8
+ export async function getProjectBasePath(project: string): Promise<string> {
9
+ const projectsDir = 'projects'
10
+ console.log('[academy] getProjectBasePath', { project, cwd: process.cwd(), projectsDir })
11
+
12
+ // Fast path: direct read (works with symlinks)
13
+ const directDir = path.join(projectsDir, project)
14
+ const directPkg = path.join(directDir, 'package.json')
15
+ try {
16
+ const raw = await readFile(directPkg, 'utf8')
17
+ const pkg = JSON.parse(raw)
18
+ const agentsRoot = pkg?.bosun?.root ?? 'src/bosun/workflows.ts'
19
+ const agentsRootPath = path.resolve(directDir, agentsRoot)
20
+ const basePath = path.dirname(agentsRootPath)
21
+ console.log('[academy] basePath (direct)', { directPkg, agentsRoot, basePath })
22
+ return basePath
23
+ } catch (e: any) {
24
+ console.warn('[academy] direct package.json read failed', { directPkg, error: e?.message })
25
+ }
26
+
27
+ // Fallback: scan projects directory (include symlinks)
28
+ let entries: any[] = []
29
+ try {
30
+ entries = await readdir(projectsDir, { withFileTypes: true } as any)
31
+ console.log(
32
+ '[academy] projects entries',
33
+ entries.map((ent: any) => ({
34
+ name: ent.name,
35
+ isDir: ent.isDirectory?.(),
36
+ isLink: ent.isSymbolicLink?.()
37
+ }))
38
+ )
39
+ } catch (err: any) {
40
+ console.warn('[academy] projects folder not found; using CWD as fallback', {
41
+ projectsDir,
42
+ error: err?.message
43
+ })
44
+ // Attempt to derive base path from cwd package.json (if present)
45
+ const cwd = process.cwd()
46
+ const cwdPkg = path.join(cwd, 'package.json')
47
+ try {
48
+ const raw = await readFile(cwdPkg, 'utf8')
49
+ const pkg = JSON.parse(raw)
50
+ const agentsRoot = pkg?.bosun?.root ?? 'src/bosun/workflows.ts'
51
+ const agentsRootPath = path.resolve(cwd, agentsRoot)
52
+ const basePath = path.dirname(agentsRootPath)
53
+ console.log('[academy] basePath (cwd fallback with pkg)', { cwdPkg, agentsRoot, basePath })
54
+ return basePath
55
+ } catch {
56
+ console.log('[academy] returning CWD as basePath (no pkg fallback)')
57
+ return cwd
58
+ }
59
+ }
60
+
61
+ for (const ent of entries) {
62
+ const name = ent.name
63
+ if (name !== project) continue
64
+ const dir = path.join(projectsDir, name)
65
+ const pkgPath = path.join(dir, 'package.json')
66
+ try {
67
+ const raw = await readFile(pkgPath, 'utf8')
68
+ const pkg = JSON.parse(raw)
69
+ const agentsRoot = pkg?.bosun?.root ?? 'src/bosun/workflows.ts'
70
+ const agentsRootPath = path.resolve(dir, agentsRoot)
71
+ const basePath = path.dirname(agentsRootPath)
72
+ console.log('[academy] basePath (scanned)', { pkgPath, agentsRoot, basePath })
73
+ return basePath
74
+ } catch (e: any) {
75
+ console.warn('[academy] failed reading candidate package.json', {
76
+ pkgPath,
77
+ error: e?.message
78
+ })
79
+ }
80
+ }
81
+
82
+ console.error('[academy] project not found (after scan)', { project, projectsDir })
83
+ throw new Error(`Project not found: ${project}`)
84
+ }
85
+
86
+ // Resolve the project root directory. Supports two modes:
87
+ // - Bosun dev (projects/<project>)
88
+ // - CLI from inside a project repo (cwd)
89
+ export async function getProjectRootPath(project: string): Promise<string> {
90
+ const projectsDir = 'projects'
91
+ // 1) Direct projects/<project>
92
+ const directDir = path.join(projectsDir, project)
93
+ const directPkg = path.join(directDir, 'package.json')
94
+ try {
95
+ await access(directPkg)
96
+ return directDir
97
+ } catch {}
98
+
99
+ // 2) If projects folder missing or inaccessible, fallback to CWD if it looks like a project
100
+ try {
101
+ const cwd = process.cwd()
102
+ const cwdPkg = path.join(cwd, 'package.json')
103
+ await access(cwdPkg)
104
+ return cwd
105
+ } catch {}
106
+
107
+ // 3) Scan projects folder for named entry
108
+ try {
109
+ const entries = (await readdir(projectsDir, { withFileTypes: true } as any)) as any[]
110
+ for (const ent of entries as any[]) {
111
+ const entryName = (ent as any).name ?? String(ent)
112
+ if (entryName !== project) continue
113
+ const dir = path.join(projectsDir, entryName)
114
+ const pkgPath = path.join(dir, 'package.json')
115
+ try {
116
+ await access(pkgPath)
117
+ return dir
118
+ } catch {}
119
+ }
120
+ } catch {}
121
+
122
+ throw new Error(`Project not found: ${project}`)
123
+ }
124
+
125
+ // Removed: all CSV helpers (read/write)
126
+
127
+ export async function tryReadConfig(
128
+ project: string,
129
+ agent: string
130
+ ): Promise<{
131
+ repeats?: number
132
+ concurrency?: number
133
+ } | null> {
134
+ const base = await getProjectBasePath(project)
135
+ const jsonPath = path.join(base, `${agent}.config.json`)
136
+ try {
137
+ await access(jsonPath)
138
+ const raw = await readFile(jsonPath, 'utf8')
139
+ const obj = JSON.parse(raw)
140
+ return obj
141
+ } catch {
142
+ return null
143
+ }
144
+ }
145
+
146
+ export async function writeConfig(
147
+ project: string,
148
+ agent: string,
149
+ config: { repeats?: number; concurrency?: number }
150
+ ): Promise<void> {
151
+ const base = await getProjectBasePath(project)
152
+ const jsonPath = path.join(base, `${agent}.config.json`)
153
+ const body = JSON.stringify(config ?? {}, null, 2)
154
+ await writeFile(jsonPath, body, 'utf8')
155
+ }
@@ -0,0 +1,299 @@
1
+ import { tryReadConfig, writeConfig, getProjectRootPath } from './csv'
2
+ import { readdir, readFile } from 'node:fs/promises'
3
+ import path from 'node:path'
4
+ import {
5
+ readSuite,
6
+ writeSuite,
7
+ getSuiteFilePath,
8
+ upsertSuiteMeta,
9
+ type TestRow as SuiteRow
10
+ } from './suite'
11
+
12
+ export type CsvRow = Record<string, string>
13
+
14
+ export type TestRow = SuiteRow
15
+
16
+ export type RunConfig = {
17
+ repeats?: number
18
+ concurrency?: number
19
+ defaultContext?: Record<string, unknown>
20
+ }
21
+
22
+ export type RunResult = {
23
+ success: boolean
24
+ result: string
25
+ evaluation: string
26
+ rendered_prompt: string
27
+ received_prompt: string
28
+ stringified_conversation: string
29
+ received_context: string
30
+ traces: any[]
31
+ errors: string
32
+ logs: string[]
33
+ }
34
+
35
+ export type TestResult = {
36
+ test_id: string
37
+ success_rate_percent?: number
38
+ success_rate?: string
39
+ results: RunResult[]
40
+ report_timestamp: string // ISO
41
+ is_old: boolean
42
+ }
43
+
44
+ // Utility: ensure each row has an id; persist if any are missing.
45
+ export async function loadTests(
46
+ project: string,
47
+ agent: string
48
+ ): Promise<{ rows: TestRow[]; headers: string[] }> {
49
+ const suite = await readSuite(project, agent)
50
+ // Ensure ids exist; write back if any are missing
51
+ let changed = false
52
+ const rows: TestRow[] = suite.tests.map((r) => {
53
+ const id = (r.id || '').trim()
54
+ if (!id) changed = true
55
+ return { ...r, id: id || globalThis.crypto?.randomUUID?.() || randomUUID() }
56
+ })
57
+ if (changed) {
58
+ await writeSuite(project, agent, { ...suite, tests: rows })
59
+ }
60
+ const headers = [
61
+ 'id',
62
+ 'pinned',
63
+ 'scenario',
64
+ 'author',
65
+ 'category',
66
+ 'assertion_type',
67
+ 'assertion_value',
68
+ 'conversation',
69
+ 'expected_output',
70
+ 'timeout',
71
+ 'similarity_threshold',
72
+ 'context'
73
+ ]
74
+ return { rows, headers }
75
+ }
76
+
77
+ // Utility: update a single row by id and write the CSV
78
+ export async function patchTest(
79
+ project: string,
80
+ agent: string,
81
+ id: string,
82
+ patch: Partial<TestRow>
83
+ ): Promise<TestRow | null> {
84
+ const suite = await readSuite(project, agent)
85
+ const idx = suite.tests.findIndex((r) => r.id === id)
86
+ if (idx < 0) return null
87
+ const current = suite.tests[idx]
88
+ const updated: TestRow = {
89
+ id: id,
90
+ pinned:
91
+ String(patch.pinned ?? current.pinned ?? 'TRUE').toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE',
92
+ scenario: String(patch.scenario ?? current.scenario ?? ''),
93
+ author: String(patch.author ?? (current as any).author ?? ''),
94
+ category: String(patch.category ?? (current as any).category ?? ''),
95
+ assertion_type: String(patch.assertion_type ?? current.assertion_type ?? 'llm-rubric'),
96
+ assertion_value: String(patch.assertion_value ?? current.assertion_value ?? ''),
97
+ conversation: String(patch.conversation ?? current.conversation ?? ''),
98
+ expected_output: String(patch.expected_output ?? current.expected_output ?? ''),
99
+ timeout: String(patch.timeout ?? current.timeout ?? '0'),
100
+ similarity_threshold: String(
101
+ patch.similarity_threshold ?? current.similarity_threshold ?? '60'
102
+ ),
103
+ context: typeof patch.context === 'string' ? patch.context : (current.context ?? '')
104
+ }
105
+ const nextRows = suite.tests.map((r, i) => (i === idx ? updated : r))
106
+ await writeSuite(project, agent, { ...suite, tests: nextRows })
107
+ return updated
108
+ }
109
+
110
+ // Batch update multiple rows in a single read/write to avoid race conditions
111
+ export async function patchTestsBatch(
112
+ project: string,
113
+ agent: string,
114
+ updates: Array<{ id: string; patch: Partial<TestRow> }>
115
+ ): Promise<TestRow[]> {
116
+ if (!Array.isArray(updates) || updates.length === 0) return []
117
+ const suite = await readSuite(project, agent)
118
+ const byId = new Map(suite.tests.map((r) => [r.id, r]))
119
+ const updatedRows: TestRow[] = []
120
+ for (const { id, patch } of updates) {
121
+ const current = byId.get(id)
122
+ if (!current) continue
123
+ const updated: TestRow = {
124
+ id: id,
125
+ pinned:
126
+ String(patch.pinned ?? current.pinned ?? 'TRUE').toUpperCase() === 'TRUE'
127
+ ? 'TRUE'
128
+ : 'FALSE',
129
+ scenario: String(patch.scenario ?? current.scenario ?? ''),
130
+ author: String(patch.author ?? (current as any).author ?? ''),
131
+ category: String(patch.category ?? (current as any).category ?? ''),
132
+ assertion_type: String(patch.assertion_type ?? current.assertion_type ?? 'llm-rubric'),
133
+ assertion_value: String(patch.assertion_value ?? current.assertion_value ?? ''),
134
+ conversation: String(patch.conversation ?? current.conversation ?? ''),
135
+ expected_output: String(patch.expected_output ?? current.expected_output ?? ''),
136
+ timeout: String(patch.timeout ?? current.timeout ?? '0'),
137
+ similarity_threshold: String(
138
+ patch.similarity_threshold ?? current.similarity_threshold ?? '60'
139
+ ),
140
+ context: typeof patch.context === 'string' ? patch.context : (current.context ?? '')
141
+ }
142
+ byId.set(id, updated)
143
+ updatedRows.push(updated)
144
+ }
145
+ const nextRows: TestRow[] = suite.tests.map((r) => byId.get(r.id) ?? r)
146
+ await writeSuite(project, agent, { ...suite, tests: nextRows })
147
+ return updatedRows
148
+ }
149
+
150
+ // Add a new row at the top
151
+ export async function addTest(
152
+ project: string,
153
+ agent: string,
154
+ seed?: Partial<TestRow>
155
+ ): Promise<TestRow> {
156
+ const suite = await readSuite(project, agent).catch(() => ({ version: 1, tests: [] }))
157
+ const id = globalThis.crypto?.randomUUID?.() || randomUUID()
158
+ const row: TestRow = {
159
+ id,
160
+ pinned:
161
+ ((seed?.pinned || 'TRUE') as any).toString().toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE',
162
+ scenario: seed?.scenario ?? 'New scenario',
163
+ author: seed?.author ?? '',
164
+ category: seed?.category ?? '',
165
+ assertion_type: seed?.assertion_type ?? 'llm-rubric',
166
+ assertion_value: seed?.assertion_value ?? '',
167
+ conversation: seed?.conversation ?? 'user: ...',
168
+ expected_output: seed?.expected_output ?? '',
169
+ timeout: String((seed as any)?.timeout ?? '0'),
170
+ similarity_threshold: String((seed as any)?.similarity_threshold ?? '60'),
171
+ context: typeof seed?.context === 'string' ? (seed?.context as string) : '{}'
172
+ }
173
+ const nextRows = [row, ...suite.tests]
174
+ await writeSuite(project, agent, { ...(suite as any), tests: nextRows })
175
+ return row
176
+ }
177
+
178
+ export async function deleteTest(project: string, agent: string, id: string): Promise<boolean> {
179
+ const suite = await readSuite(project, agent)
180
+ const filtered = suite.tests.filter((r) => r.id !== id)
181
+ if (filtered.length === suite.tests.length) return false
182
+ await writeSuite(project, agent, { ...suite, tests: filtered })
183
+ return true
184
+ }
185
+
186
+ export async function reorderTests(project: string, agent: string, order: string[]): Promise<void> {
187
+ const suite = await readSuite(project, agent)
188
+ const map = new Map(suite.tests.map((r) => [r.id, r]))
189
+ const next: TestRow[] = []
190
+ for (const id of order) {
191
+ const r = map.get(id)
192
+ if (r) {
193
+ next.push(r)
194
+ map.delete(id)
195
+ }
196
+ }
197
+ // Append any rows that were not included in order (safety)
198
+ for (const r of map.values()) next.push(r)
199
+ await writeSuite(project, agent, { ...suite, tests: next })
200
+ }
201
+
202
+ export async function loadConfig(project: string, agent: string): Promise<RunConfig> {
203
+ const cfg = (await tryReadConfig(project, agent)) || {}
204
+ // Always source defaultContext from the suite meta, not config
205
+ let defaultContext: Record<string, unknown> = {}
206
+ try {
207
+ const suite = await (await import('./suite')).readSuite(project, agent)
208
+ defaultContext = (suite.meta?.defaultContext as any) || {}
209
+ } catch {
210
+ // ignore
211
+ }
212
+ return {
213
+ repeats: typeof (cfg as any).repeats === 'number' ? (cfg as any).repeats : 1,
214
+ concurrency: typeof (cfg as any).concurrency === 'number' ? (cfg as any).concurrency : 1,
215
+ defaultContext
216
+ }
217
+ }
218
+
219
+ export async function saveConfig(project: string, agent: string, cfg: RunConfig): Promise<void> {
220
+ // Merge patch into existing config, persisting only repeats/concurrency
221
+ const current = (await tryReadConfig(project, agent)) || {}
222
+ const next = {
223
+ repeats: typeof cfg.repeats === 'number' ? cfg.repeats : (current as any).repeats,
224
+ concurrency:
225
+ typeof cfg.concurrency === 'number' ? cfg.concurrency : (current as any).concurrency
226
+ }
227
+ await writeConfig(project, agent, next)
228
+ // Persist defaultContext exclusively in the suite meta (do not write to config)
229
+ if (cfg && typeof cfg.defaultContext !== 'undefined') {
230
+ await upsertSuiteMeta(project, agent, { defaultContext: cfg.defaultContext })
231
+ }
232
+ }
233
+
234
+ // We no longer migrate legacy reports automatically. Please update old reports manually.
235
+
236
+ export async function loadLatestResultsByTest(
237
+ project: string,
238
+ agent: string
239
+ ): Promise<Record<string, TestResult>> {
240
+ const projectRoot = await getProjectRootPath(project)
241
+ const outDir = path.join(projectRoot, 'data', 'test_runs')
242
+ let entries: string[] = []
243
+ try {
244
+ entries = await readdir(outDir)
245
+ } catch {
246
+ return {}
247
+ }
248
+ const prefix = `${agent}.`
249
+ const suffix = `.report.json`
250
+ const files = entries.filter((n) => n.startsWith(prefix) && n.endsWith(suffix)).sort()
251
+ if (!files.length) return {}
252
+
253
+ const latestFile = files[files.length - 1]
254
+ const latestTs = latestFile
255
+ .slice(prefix.length, latestFile.length - suffix.length)
256
+ .replace(/-/g, ':')
257
+
258
+ const results: Record<string, TestResult> = {}
259
+ for (const name of files) {
260
+ const full = path.join(outDir, name)
261
+ const raw = await readFile(full, 'utf8')
262
+ const parsed = JSON.parse(raw) as any
263
+ const rows = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.rows) ? parsed.rows : []
264
+ const ts = name.slice(prefix.length, name.length - suffix.length).replace(/-/g, ':')
265
+ for (const r of rows) {
266
+ const test_id = (r as any).test_id
267
+ if (!test_id) {
268
+ throw new Error(
269
+ `Missing test_id in report ${name}. Please add 'test_id' and provenance columns manually.`
270
+ )
271
+ }
272
+ const par = String((r as any).pinned_at_run ?? 'TRUE').toUpperCase()
273
+ if (par === 'FALSE') continue
274
+ // Always prefer newer timestamp
275
+ const prev = results[test_id]
276
+ const rec: TestResult = {
277
+ test_id,
278
+ success_rate_percent: (r as any).success_rate_percent,
279
+ success_rate: (r as any).success_rate,
280
+ results: Array.isArray((r as any).results) ? ((r as any).results as RunResult[]) : [],
281
+ report_timestamp: ts,
282
+ is_old: ts < latestTs
283
+ }
284
+ if (!prev || prev.report_timestamp < ts) {
285
+ results[test_id] = rec
286
+ }
287
+ }
288
+ }
289
+ return results
290
+ }
291
+
292
+ // Fallback UUID for Node environments without global crypto
293
+ function randomUUID() {
294
+ const rnd = () =>
295
+ Math.floor(Math.random() * 0xffffffff)
296
+ .toString(16)
297
+ .padStart(8, '0')
298
+ return `${rnd()}-${rnd().slice(0, 4)}-${rnd().slice(0, 4)}-${rnd().slice(0, 4)}-${rnd()}${rnd()}`
299
+ }
@@ -0,0 +1,129 @@
1
+ import {
2
+ createContext,
3
+ type Message,
4
+ type TestAgent,
5
+ type TestTextAgent,
6
+ type TestVoiceAgent,
7
+ type StepTracer
8
+ } from '@recombine-ai/engine'
9
+ import { loadProjects } from '../../ws-server/projects'
10
+
11
+ export async function loadAgents(props: {
12
+ agentId: string
13
+ getMessages: () => Message[]
14
+ sendMessage: (message: Message | string) => Promise<void>
15
+ stepTracer: StepTracer
16
+ logger?: {
17
+ log: (...args: any[]) => void
18
+ debug: (...args: any[]) => void
19
+ warn: (...args: any[]) => void
20
+ error: (...args: any[]) => void
21
+ }
22
+ context?: Record<string, any>
23
+ timeoutSeconds: number
24
+ }): Promise<void> {
25
+ const {
26
+ agentId,
27
+ getMessages,
28
+ sendMessage,
29
+ stepTracer: stepTracer,
30
+ logger: providedLogger,
31
+ context,
32
+ timeoutSeconds
33
+ } = props
34
+ const projects = await loadProjects()
35
+ if (!projects.length) throw new Error('No projects found')
36
+
37
+ // Pick target agent
38
+ let proj = projects[0]
39
+ let name = Object.keys(proj.factories)[0]
40
+ if (agentId) {
41
+ if (agentId.includes('/')) {
42
+ const [p, n] = agentId.split('/')
43
+ const found = projects.find((x) => x.project === p)
44
+ if (!found) throw new Error(`Project not found: ${p}`)
45
+ if (!found.factories[n]) throw new Error(`Agent not found: ${agentId}`)
46
+ proj = found
47
+ name = n
48
+ } else {
49
+ if (!proj.factories[agentId])
50
+ throw new Error(`Agent not found in default project: ${agentId}`)
51
+ name = agentId
52
+ }
53
+ }
54
+
55
+ const factory = proj.factories[name]
56
+ if (!factory) throw new Error('Factory not found')
57
+
58
+ // Minimal stubs
59
+ const logger = providedLogger || {
60
+ log: () => {},
61
+ debug: () => {},
62
+ error: () => {},
63
+ warn: () => {}
64
+ }
65
+ const scheduler = {
66
+ clearAllPendingActions: async () => {},
67
+ registerAction: () => async () => {},
68
+ triggerAction: async () => {},
69
+ serialize: () => ({}) as any,
70
+ setState: (_: any) => {}
71
+ }
72
+ const ctx = createContext({})
73
+ if (context && typeof context === 'object') {
74
+ // Apply provided context before agent lifecycle
75
+ ctx.swap(context)
76
+ }
77
+
78
+ // Maintain in-run history so sendMessage appends to it, mirroring ws-server behavior
79
+ const history = getMessages()
80
+ const getMessagesWithHistory = () => history
81
+ const sendMessageWithHistory = async (message: Message | string) => {
82
+ const m =
83
+ typeof message === 'string' ? ({ sender: 'agent', text: message } as Message) : message
84
+ try {
85
+ history.push(m)
86
+ } catch {
87
+ // Best-effort: if history is immutable, ignore push errors
88
+ logger.log('Failed to push message to history:', m)
89
+ }
90
+ await sendMessage(m)
91
+ }
92
+
93
+ const agent = (await factory({
94
+ stepTracer: stepTracer,
95
+ tracer: {
96
+ addStep: (step) => {}
97
+ },
98
+ logger: logger,
99
+ scheduler: scheduler as any,
100
+ getMessages: getMessagesWithHistory,
101
+ sendMessage: sendMessageWithHistory,
102
+ sendAction: async () => {},
103
+ ctx
104
+ })) as TestTextAgent
105
+
106
+ process.on('unhandledRejection', (r) => {
107
+ console.error('UNHANDLED', r)
108
+ })
109
+
110
+ try {
111
+ await agent.respondToMessage()
112
+ await new Promise((resolve) => setTimeout(resolve, timeoutSeconds * 1000))
113
+ } catch (err) {
114
+ const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
115
+ const stack = err instanceof Error ? err.stack : undefined
116
+ try {
117
+ logger.error('Error in agent.respondToMessage():', msg)
118
+ } catch {
119
+ /* noop */
120
+ }
121
+ if (stack) {
122
+ try {
123
+ logger.error(stack)
124
+ } catch {
125
+ /* noop */
126
+ }
127
+ }
128
+ }
129
+ }