reeval 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +12 -12
  2. package/dist/{agent-Dhd5FJCZ.js → agent-6FefIhX7.js} +6 -6
  3. package/dist/{agent-Dhd5FJCZ.js.map → agent-6FefIhX7.js.map} +1 -1
  4. package/dist/{agent-gjBiZis8.js → agent-WSmTaesf.js} +52 -17
  5. package/dist/agent-WSmTaesf.js.map +1 -0
  6. package/dist/{analysis-BV3TCznv.js → analysis-DlGBDjTj.js} +4 -4
  7. package/dist/{analysis-BV3TCznv.js.map → analysis-DlGBDjTj.js.map} +1 -1
  8. package/dist/{assemble-Dd_mZYnu.js → assemble-BCZzTyR7.js} +259 -18
  9. package/dist/assemble-BCZzTyR7.js.map +1 -0
  10. package/dist/assemble-C5qq5yT2.js +2 -0
  11. package/dist/capture-Bp74Z6Fr.js +1257 -0
  12. package/dist/capture-Bp74Z6Fr.js.map +1 -0
  13. package/dist/capture-DS-cPyuE.js +2 -0
  14. package/dist/{cli-r9CDqoFL.js → cli-CVrMh_qz.js} +210 -112
  15. package/dist/cli-CVrMh_qz.js.map +1 -0
  16. package/dist/{cli-spec-DOyxAMc2.js → cli-spec-CKEYa8V2.js} +6 -5
  17. package/dist/cli-spec-CKEYa8V2.js.map +1 -0
  18. package/dist/cli.js +2 -2
  19. package/dist/{client-LsfDiD-X.js → client-Bbo9SPlK.js} +31 -201
  20. package/dist/client-Bbo9SPlK.js.map +1 -0
  21. package/dist/{command-l4ZFCeMh.js → command-BFP0hKEb.js} +7 -7
  22. package/dist/{command-l4ZFCeMh.js.map → command-BFP0hKEb.js.map} +1 -1
  23. package/dist/command-BrmXUC-W.js +2 -0
  24. package/dist/{command-DMR69l5G.js → command-C5xFPKHM.js} +21 -20
  25. package/dist/command-C5xFPKHM.js.map +1 -0
  26. package/dist/{command-Cej2t3y-.js → command-CzIFp1JQ.js} +10 -10
  27. package/dist/{command-Cej2t3y-.js.map → command-CzIFp1JQ.js.map} +1 -1
  28. package/dist/{command-D6r2pwO5.js → command-DUT5l13I.js} +221 -54
  29. package/dist/command-DUT5l13I.js.map +1 -0
  30. package/dist/{commands-BA_NCh2h.js → commands-CLmPBrTS.js} +6 -6
  31. package/dist/{commands-BA_NCh2h.js.map → commands-CLmPBrTS.js.map} +1 -1
  32. package/dist/{commands-DgOUkcSO.js → commands-fI3G2Wnh.js} +1 -1
  33. package/dist/{config-DuQDCx0B.js → config-CGvBeewH.js} +18 -8
  34. package/dist/config-CGvBeewH.js.map +1 -0
  35. package/dist/{context-CvUv7DUb.js → context-DbSMEVKs.js} +1 -5
  36. package/dist/{context-CvUv7DUb.js.map → context-DbSMEVKs.js.map} +1 -1
  37. package/dist/{db-o_osRkqr.js → db-CSSFtGcN.js} +1 -1
  38. package/dist/{db-CjX7JF4o.js → db-CfQFwJtq.js} +209 -40
  39. package/dist/db-CfQFwJtq.js.map +1 -0
  40. package/dist/{docker-DaUaG4XZ.js → docker-CRQGQbIt.js} +17 -5
  41. package/dist/docker-CRQGQbIt.js.map +1 -0
  42. package/dist/{docker-ZaYeKE2w.js → docker-DV2GNgle.js} +2 -2
  43. package/dist/{docker-ZaYeKE2w.js.map → docker-DV2GNgle.js.map} +1 -1
  44. package/dist/{docker-Dnya8eo9.js → docker-Df_YOxxB.js} +1 -1
  45. package/dist/{doctor-Bk6aJeec.js → doctor-DlKycx5H.js} +13 -13
  46. package/dist/{doctor-Bk6aJeec.js.map → doctor-DlKycx5H.js.map} +1 -1
  47. package/dist/{egress-BKbyriEa.js → egress-BhzNh7Yi.js} +18 -10
  48. package/dist/egress-BhzNh7Yi.js.map +1 -0
  49. package/dist/{environment-DiCljXMD.js → environment-1jE-HhO-.js} +2 -2
  50. package/dist/{environment-DiCljXMD.js.map → environment-1jE-HhO-.js.map} +1 -1
  51. package/dist/fake-instructions-CUI33I_F.js +32 -0
  52. package/dist/fake-instructions-CUI33I_F.js.map +1 -0
  53. package/dist/family-D2b7WD10.js +67 -0
  54. package/dist/family-D2b7WD10.js.map +1 -0
  55. package/dist/files-AiEKuEZe.js +2 -0
  56. package/dist/files-BMCvfB4X.js +2 -0
  57. package/dist/{files-TNrZJQ3Y.js → files-CSzVADHn.js} +5 -5
  58. package/dist/{files-TNrZJQ3Y.js.map → files-CSzVADHn.js.map} +1 -1
  59. package/dist/{files-BSMSnQMa.js → files-DJUFg-4e.js} +3 -3
  60. package/dist/{files-BSMSnQMa.js.map → files-DJUFg-4e.js.map} +1 -1
  61. package/dist/{git-DNGtrOg9.js → git-DfG-YJ1u.js} +2 -2
  62. package/dist/{git-DNGtrOg9.js.map → git-DfG-YJ1u.js.map} +1 -1
  63. package/dist/{harness-CDRaaGvR.js → harness-CeCp2GSW.js} +52 -12
  64. package/dist/harness-CeCp2GSW.js.map +1 -0
  65. package/dist/harness.d.ts +26 -13
  66. package/dist/harness.js +1 -1
  67. package/dist/{header-BZF8Xss1.js → header-CALhmafp.js} +10 -3
  68. package/dist/{header-BZF8Xss1.js.map → header-CALhmafp.js.map} +1 -1
  69. package/dist/{images-BpwFDT1E.js → images-BMgdpMAX.js} +6 -6
  70. package/dist/{images-BpwFDT1E.js.map → images-BMgdpMAX.js.map} +1 -1
  71. package/dist/index.d.ts +17 -5
  72. package/dist/index.js +165 -67
  73. package/dist/index.js.map +1 -1
  74. package/dist/init-B6vegaP_.js +2 -0
  75. package/dist/{init-CBWt1rZT.js → init-BIdLF0F9.js} +4 -4
  76. package/dist/{init-CBWt1rZT.js.map → init-BIdLF0F9.js.map} +1 -1
  77. package/dist/{invocations-DArYWyXN.js → invocations-CLaL8AuW.js} +3 -3
  78. package/dist/{invocations-DArYWyXN.js.map → invocations-CLaL8AuW.js.map} +1 -1
  79. package/dist/{judge-7WjNdU9z.js → judge-CeYPN8P_.js} +2 -2
  80. package/dist/{judge-7WjNdU9z.js.map → judge-CeYPN8P_.js.map} +1 -1
  81. package/dist/judge.d.ts +5 -4
  82. package/dist/judge.js +4 -3
  83. package/dist/judge.js.map +1 -1
  84. package/dist/{live-DZkCtmNP.js → live-S0qODb6o.js} +2 -2
  85. package/dist/{live-DZkCtmNP.js.map → live-S0qODb6o.js.map} +1 -1
  86. package/dist/{model-Cp6NoAT3.js → model-B1BZoZ9b.js} +9 -8
  87. package/dist/model-B1BZoZ9b.js.map +1 -0
  88. package/dist/{model-DyQbu7KF.js → model-BOnlAPzs.js} +288 -38
  89. package/dist/model-BOnlAPzs.js.map +1 -0
  90. package/dist/{model-Bv8uUZ07.js → model-DEQo3FkZ.js} +6 -6
  91. package/dist/model-DEQo3FkZ.js.map +1 -0
  92. package/dist/model-DWeg5J7z.js +2 -0
  93. package/dist/{model-BeoRxCcJ.js → model-FXko2kl7.js} +1 -1
  94. package/dist/{options-Ge_x32XE.js → options-CKqyPGxX.js} +161 -34
  95. package/dist/options-CKqyPGxX.js.map +1 -0
  96. package/dist/pairs-DDsjgm5F.js +149 -0
  97. package/dist/pairs-DDsjgm5F.js.map +1 -0
  98. package/dist/{patch-CGCVipPu.js → patch-bDV8YFW0.js} +2 -2
  99. package/dist/{patch-CGCVipPu.js.map → patch-bDV8YFW0.js.map} +1 -1
  100. package/dist/{plan-BqBadHYj.js → plan-DUydFc_1.js} +69 -31
  101. package/dist/plan-DUydFc_1.js.map +1 -0
  102. package/dist/{preflight-CyaAZE9r.js → preflight-BkoSxf4C.js} +3 -3
  103. package/dist/{preflight-CyaAZE9r.js.map → preflight-BkoSxf4C.js.map} +1 -1
  104. package/dist/{preflight-CFtZNTLt.js → preflight-D5LW7Oqi.js} +1 -1
  105. package/dist/{prepare-Zr1xOMUX.js → prepare-CUAWHebF.js} +5 -5
  106. package/dist/{prepare-Zr1xOMUX.js.map → prepare-CUAWHebF.js.map} +1 -1
  107. package/dist/{prepare-Dl7-t3fO.js → prepare-oji2oO8W.js} +2 -2
  108. package/dist/process-CSVO_jsc.js +119 -0
  109. package/dist/process-CSVO_jsc.js.map +1 -0
  110. package/dist/{provenance-Byl2T6LJ.js → provenance-D7HK3vzt.js} +2 -2
  111. package/dist/{provenance-Byl2T6LJ.js.map → provenance-D7HK3vzt.js.map} +1 -1
  112. package/dist/{providers-Cflw7Ks-.js → providers-B1DzMvmH.js} +3 -3
  113. package/dist/{providers-Cflw7Ks-.js.map → providers-B1DzMvmH.js.map} +1 -1
  114. package/dist/{providers-SBMExI53.js → providers-CpEfNU1F.js} +1 -1
  115. package/dist/{query-DUSLlic0.js → query-BjBMLa-C.js} +2 -2
  116. package/dist/{query-DUSLlic0.js.map → query-BjBMLa-C.js.map} +1 -1
  117. package/dist/query-oPO_XrTy.js +2 -0
  118. package/dist/{questions-ZdT3JDyQ.js → questions-B8by4Bbt.js} +28 -119
  119. package/dist/questions-B8by4Bbt.js.map +1 -0
  120. package/dist/{record-CbuQH4l1.js → record-BRP9vZrj.js} +21 -1
  121. package/dist/record-BRP9vZrj.js.map +1 -0
  122. package/dist/{results-owJR-NFm.js → results-Di7m8dQ3.js} +4 -4
  123. package/dist/{results-owJR-NFm.js.map → results-Di7m8dQ3.js.map} +1 -1
  124. package/dist/{resume-BL4Yw7Ld.js → resume-SUz1GskV.js} +4 -4
  125. package/dist/{resume-BL4Yw7Ld.js.map → resume-SUz1GskV.js.map} +1 -1
  126. package/dist/runtime-DdsfnRz_.js +344 -0
  127. package/dist/runtime-DdsfnRz_.js.map +1 -0
  128. package/dist/{sandbox--ZXuscAZ.js → sandbox-D5v-of6d.js} +10 -5
  129. package/dist/sandbox-D5v-of6d.js.map +1 -0
  130. package/dist/sandbox.d.ts +4 -3
  131. package/dist/sandbox.js +1 -1
  132. package/dist/{server-yFVUxAm0.js → server-BNnXtmS8.js} +9 -9
  133. package/dist/{server-yFVUxAm0.js.map → server-BNnXtmS8.js.map} +1 -1
  134. package/dist/server-BNwoKzlm.js +2 -0
  135. package/dist/source-Bk_0ZaEY.js +2 -0
  136. package/dist/{source-M3gS517R.js → source-Dof0NQBm.js} +2 -2
  137. package/dist/{source-M3gS517R.js.map → source-Dof0NQBm.js.map} +1 -1
  138. package/dist/{src-79JhW-zG.js → src-8rRXy4u9.js} +71 -124
  139. package/dist/src-8rRXy4u9.js.map +1 -0
  140. package/dist/src-BGWuWp6I.js +3 -0
  141. package/dist/src-BRt0O02i.js +3 -0
  142. package/dist/src-Bx2x1ekD.js +3 -0
  143. package/dist/{src-s-VffoYK.js → src-C1E9HDWO.js} +5 -3
  144. package/dist/{src-s-VffoYK.js.map → src-C1E9HDWO.js.map} +1 -1
  145. package/dist/{src-IOr1rhEg.js → src-COgE7991.js} +10 -8
  146. package/dist/{src-IOr1rhEg.js.map → src-COgE7991.js.map} +1 -1
  147. package/dist/{src-CokPbYCb.js → src-C_4Umgh2.js} +23 -14
  148. package/dist/{src-CokPbYCb.js.map → src-C_4Umgh2.js.map} +1 -1
  149. package/dist/{src-DxFJrMUA.js → src-D95O-Smv.js} +12 -7
  150. package/dist/{src-DxFJrMUA.js.map → src-D95O-Smv.js.map} +1 -1
  151. package/dist/{src-DTcalvuF.js → src-DDNXsD9H.js} +28 -4
  152. package/dist/{src-DTcalvuF.js.map → src-DDNXsD9H.js.map} +1 -1
  153. package/dist/src-DLa-ESW0.js +4 -0
  154. package/dist/{src-DSE0FWaU.js → src-DVy58-zZ.js} +2 -2
  155. package/dist/{src-DSE0FWaU.js.map → src-DVy58-zZ.js.map} +1 -1
  156. package/dist/src-cN0aB-WR.js +3 -0
  157. package/dist/{src-DH0jhpoi.js → src-cdIVjC5b.js} +1 -1
  158. package/dist/src-sIsDHWYq.js +3 -0
  159. package/dist/state-Bo5zg4da.js +2 -0
  160. package/dist/{state-DEj_utaE.js → state-CiXyLqg0.js} +10 -10
  161. package/dist/{state-DEj_utaE.js.map → state-CiXyLqg0.js.map} +1 -1
  162. package/dist/studio-app/assets/index-B9MCTfuu.css +2 -0
  163. package/dist/studio-app/assets/{index-Bbl0oTxu.js → index-CROH2NB3.js} +12 -12
  164. package/dist/studio-app/index.html +2 -2
  165. package/dist/{summary-D012KlUM.js → summary-2OAWF2N7.js} +7 -7
  166. package/dist/{summary-D012KlUM.js.map → summary-2OAWF2N7.js.map} +1 -1
  167. package/dist/{summary--FBuB_sr.js → summary-BTksrIxn.js} +63 -5
  168. package/dist/summary-BTksrIxn.js.map +1 -0
  169. package/dist/testing.d.ts +14 -0
  170. package/dist/testing.js +2 -0
  171. package/dist/{tools-CJHw-zCo.js → tools-B10Uj7OI.js} +4 -4
  172. package/dist/tools-B10Uj7OI.js.map +1 -0
  173. package/dist/types-C5vI3g1C.js.map +1 -1
  174. package/dist/{types-BsRSknLe.d.ts → types-D8RLfkFP.d.ts} +453 -42
  175. package/dist/{usage-DsYUqIUM.js → usage-DDF_6tkV.js} +4 -2
  176. package/dist/{usage-DsYUqIUM.js.map → usage-DDF_6tkV.js.map} +1 -1
  177. package/dist/view/index.d.ts +60 -15
  178. package/dist/view/index.js +7 -6
  179. package/dist/views-Cs2Oqayd.js +3 -0
  180. package/dist/{views-jhL9Jb8A.js → views-Dqa5ojfZ.js} +4 -4
  181. package/dist/{views-jhL9Jb8A.js.map → views-Dqa5ojfZ.js.map} +1 -1
  182. package/dist/{worker-entry-OwnsrUdr.js → worker-entry-BAikHl9F.js} +9 -4
  183. package/dist/worker-entry-BAikHl9F.js.map +1 -0
  184. package/dist/{workspace-C4_J0pqb.js → workspace-C-TrNIUc.js} +4 -4
  185. package/dist/{workspace-C4_J0pqb.js.map → workspace-C-TrNIUc.js.map} +1 -1
  186. package/dist/{workspace-wudSz_W-.js → workspace-Do_SiWBs.js} +1 -1
  187. package/docker/Dockerfile +7 -5
  188. package/package.json +9 -4
  189. package/dist/agent-gjBiZis8.js.map +0 -1
  190. package/dist/assemble-D8sZ4Jiv.js +0 -2
  191. package/dist/assemble-Dd_mZYnu.js.map +0 -1
  192. package/dist/capture-CisAmy-G.js +0 -587
  193. package/dist/capture-CisAmy-G.js.map +0 -1
  194. package/dist/capture-DquyqAHC.js +0 -2
  195. package/dist/cli-r9CDqoFL.js.map +0 -1
  196. package/dist/cli-spec-DOyxAMc2.js.map +0 -1
  197. package/dist/client-LsfDiD-X.js.map +0 -1
  198. package/dist/command-Cxfgghqo.js +0 -2
  199. package/dist/command-D6r2pwO5.js.map +0 -1
  200. package/dist/command-DMR69l5G.js.map +0 -1
  201. package/dist/config-DuQDCx0B.js.map +0 -1
  202. package/dist/db-CjX7JF4o.js.map +0 -1
  203. package/dist/docker-DaUaG4XZ.js.map +0 -1
  204. package/dist/egress-BKbyriEa.js.map +0 -1
  205. package/dist/files-DmZGPsWK.js +0 -2
  206. package/dist/files-Tb8wY0Ze.js +0 -2
  207. package/dist/harness-CDRaaGvR.js.map +0 -1
  208. package/dist/init-1THeGfut.js +0 -2
  209. package/dist/model-Bv8uUZ07.js.map +0 -1
  210. package/dist/model-Cp6NoAT3.js.map +0 -1
  211. package/dist/model-D_pF3Vcl.js +0 -2
  212. package/dist/model-DyQbu7KF.js.map +0 -1
  213. package/dist/options-Ge_x32XE.js.map +0 -1
  214. package/dist/plan-BqBadHYj.js.map +0 -1
  215. package/dist/query-CvutWHaL.js +0 -2
  216. package/dist/questions-ZdT3JDyQ.js.map +0 -1
  217. package/dist/record-CbuQH4l1.js.map +0 -1
  218. package/dist/sandbox--ZXuscAZ.js.map +0 -1
  219. package/dist/server-CNPsB0cT.js +0 -2
  220. package/dist/source-Cmc5SKFn.js +0 -2
  221. package/dist/src--L8B4WGa.js +0 -3
  222. package/dist/src-79JhW-zG.js.map +0 -1
  223. package/dist/src-BLN459er.js +0 -3
  224. package/dist/src-Bz66jDtE.js +0 -3
  225. package/dist/src-CfUwg9UY.js +0 -3
  226. package/dist/src-DV_3QDHA.js +0 -4
  227. package/dist/src-Ljh2vKXm.js +0 -3
  228. package/dist/state-DkqbCVVp.js +0 -2
  229. package/dist/studio-app/assets/index-CUx6GoL5.css +0 -2
  230. package/dist/summary--FBuB_sr.js.map +0 -1
  231. package/dist/tools-CJHw-zCo.js.map +0 -1
  232. package/dist/views-yPmmoo8f.js +0 -3
  233. package/dist/worker-entry-OwnsrUdr.js.map +0 -1
@@ -1,10 +1,14 @@
1
1
  //#region src/view/effort.d.ts
2
2
  /** Below this two-sided p, an effort difference is an effect. */
3
3
  declare const EFFORT_ALPHA = 0.05;
4
+ /** Some counted attempts reported no usage. Not a verdict; never printed as one. */
5
+ declare const TOKENS_UNREPORTED = "some cells did not report usage";
4
6
  type EffortSample = {
5
7
  tools: number;
6
8
  agentMs: number;
7
9
  fileEdits: number;
10
+ /** Total tokens when this attempt reported usage; omitted when the harness dropped it. */
11
+ tokens?: number;
8
12
  };
9
13
  type Spread = {
10
14
  median: number;
@@ -17,10 +21,13 @@ type CellEffort = {
17
21
  tools: Spread;
18
22
  agentMs: Spread;
19
23
  fileEdits: number;
24
+ /** Over the counted attempts that reported usage; omitted when none did. */
25
+ tokens?: Spread;
20
26
  };
21
27
  /**
22
28
  * `fewer` / `more`: the exact rank test's p is below `EFFORT_ALPHA`. `noise`: it isn't.
23
- * `insufficient`: too few attempts for the test to ever reach it (2 against 2 can't).
29
+ * `insufficient`: too few attempts for the test to ever reach it (2 against 2 can't). Never
30
+ * means a harness dropped usage.
24
31
  */
25
32
  type EffortVerdict = 'fewer' | 'more' | 'noise' | 'insufficient';
26
33
  type EffortContrast = {
@@ -37,8 +44,23 @@ type EffortContrast = {
37
44
  /** On tool calls, the steadier measure; `timeVerdict` on agent time. */
38
45
  verdict: EffortVerdict;
39
46
  timeVerdict: EffortVerdict;
47
+ /**
48
+ * Token medians' ratio when both sides have at least one usage sample; null when the
49
+ * control's is 0 or the token test was omitted.
50
+ */
51
+ tokensRatio: number | null;
52
+ tokensP: number | null;
53
+ /**
54
+ * Rank-test verdict on the attempts that reported usage. Null when either side has no
55
+ * token sample — omitted, not `insufficient`.
56
+ */
57
+ tokensVerdict: EffortVerdict | null;
58
+ /** Set when some counted attempts on either side reported no usage. Not a verdict. */
59
+ tokensNote?: typeof TOKENS_UNREPORTED;
40
60
  };
41
- declare const effortSample: (a: Pick<AttemptRecord, 'activity' | 'timings'>) => EffortSample;
61
+ declare const effortSample: (a: Pick<AttemptRecord, 'activity' | 'timings' | 'usage'>) => EffortSample;
62
+ /** Token totals from the attempts that reported usage; empty when none did. */
63
+ declare const tokenValues: (samples: EffortSample[]) => number[];
42
64
  declare function effortOf(samples: EffortSample[]): CellEffort | null;
43
65
  /** The verdict of an exact rank test of `xs` (variant) against `ys` (control). */
44
66
  declare function effortVerdict(xs: number[], ys: number[]): {
@@ -59,13 +81,14 @@ declare function formatSeconds(ms: number): string;
59
81
  declare const VERDICT_TEXT: Record<EffortVerdict, (what: string) => string>;
60
82
  /**
61
83
  * `tools 5 vs 43 (×0.11), agent 21s vs 46s (×0.47): too few attempts to test` for a variant
62
- * against its control; with enough attempts, `fewer tool calls (p = 0.029)`.
84
+ * against its control; with enough attempts, `fewer tool calls (p = 0.029)`. Tokens fold in
85
+ * when both sides have usage samples; they are omitted (not `insufficient`) when either does not.
63
86
  */
64
87
  declare function effortLabel(c: EffortContrast): string;
65
- /** One cell's effort on its own: `tools 43 · agent 46s`. */
66
- declare const effortSummary: (e: Pick<CellEffort, 'tools' | 'agentMs'>) => string;
88
+ /** One cell's effort on its own: `tools 43 · agent 46s`, plus tokens when any attempt reported them. */
89
+ declare const effortSummary: (e: Pick<CellEffort, 'tools' | 'agentMs' | 'tokens'>) => string;
67
90
  /** The same cell between two runs: `tools 44 → 10 (×0.23) · agent 45s → 21s (×0.47)`. */
68
- declare function effortChangeLabel(base: Pick<CellEffort, 'tools' | 'agentMs'>, head: Pick<CellEffort, 'tools' | 'agentMs'>): string;
91
+ declare function effortChangeLabel(base: Pick<CellEffort, 'tools' | 'agentMs' | 'tokens'>, head: Pick<CellEffort, 'tools' | 'agentMs' | 'tokens'>): string;
69
92
  //#endregion
70
93
  //#region src/history/types.d.ts
71
94
  /** Stays 1 while reeval is pre-release: the record changes in place. */
@@ -86,10 +109,19 @@ type ArtifactRef = FileRef & {
86
109
  capture?: {
87
110
  port: number;
88
111
  path: string;
112
+ /** The live window, never the string `'full-page'`. */
89
113
  viewport?: {
90
114
  width: number;
91
115
  height: number;
92
116
  };
117
+ /** Saved PNG used `captureBeyondViewport`. */
118
+ fullPage?: boolean;
119
+ /** Goal strings only; wait beats omitted. */
120
+ instructions?: string[];
121
+ use?: {
122
+ model: string;
123
+ moves: number;
124
+ };
93
125
  };
94
126
  };
95
127
  type GitInfo = {
@@ -149,6 +181,8 @@ type JudgementRecord = {
149
181
  key: string;
150
182
  /** Transient provider errors retried before this verdict, with the backoff before each retry. */
151
183
  retries?: JudgeRetry[];
184
+ /** Captures this call sent the judge as file parts, when any. */
185
+ artifacts?: JudgeArtifactRef[];
152
186
  };
153
187
  type AttemptFiles = {
154
188
  /** Each environment setup step's command, exit code, duration and output. */
@@ -197,6 +231,17 @@ type AttemptRecord = {
197
231
  * recorded them.
198
232
  */
199
233
  servedModels: string[] | null;
234
+ /**
235
+ * The reasoning effort the harness factory asked for (`claudeCode({ effort: 'high' })`);
236
+ * null when the factory left it unset. Fast is not this.
237
+ */
238
+ effort: string | null;
239
+ /**
240
+ * The reasoning effort the harness's API said it ran at, from `servedModels` /
241
+ * each turn's `model` (`medium` from `gpt-5.6-luna[effort=medium]`); null when those
242
+ * labels name none. Fast (`[fast=true]`) is not this.
243
+ */
244
+ servedEffort: string | null;
200
245
  outcome: Outcome;
201
246
  error: AttemptError | null;
202
247
  durationMs: number;
@@ -218,12 +263,21 @@ type AttemptRecord = {
218
263
  }>;
219
264
  /** Tokens across the attempt's turns; null when the harness reported none. */
220
265
  usage: TokenUsage | null;
266
+ /**
267
+ * Tokens the capture vision loop used. Infrastructure only: never folded
268
+ * into `usage`, effort, compare or lift.
269
+ */
270
+ captureUse?: {
271
+ model: string;
272
+ moves: number;
273
+ usage: TokenUsage | null;
274
+ };
221
275
  timings: PhaseTimings;
222
- /** Counts from the transcript, so a run's shape is visible without reading it. */
276
+ /** Counts from the transcript, so a run's shape is visible without reading it. `webSearches` includes refused searches. */
223
277
  activity: {
224
278
  tools: number;
225
279
  fileEdits: number;
226
- /** Null when a turn with none couldn't report them (`unreported`), not a count of 0 that isn't one. */
280
+ /** Every `web-search` event, including refused ones. Null when a turn with none couldn't report them (`unreported`). */
227
281
  webSearches: number | null;
228
282
  webFetches: number | null;
229
283
  reasoningMs: number;
@@ -237,6 +291,8 @@ type AttemptRecord = {
237
291
  durationMs: number;
238
292
  log?: FileRef;
239
293
  }>;
294
+ /** Every `expect` and `expect.soft` matcher call that settled, in call order; unset with none. */
295
+ assertions?: AssertionRecord[];
240
296
  /** Files under a dependency directory (node_modules/, .venv/, …) collapse to one entry with `count`. */
241
297
  changedFiles: Array<FileChange & {
242
298
  count?: number;
@@ -271,17 +327,123 @@ type EvalEntry = {
271
327
  outcome: Outcome;
272
328
  /** A placeholder, `evaluate.todo` or `group.todo`: it never runs, and its outcome is `skipped`. */
273
329
  todo: boolean;
274
- /** pass / (pass + fail) over the gated cells' attempts; infra errors and skips excluded. */
330
+ /** pass@1, pass / (pass + fail), over the gated cells' attempts; infra errors and skips excluded. */
275
331
  passRate: number | null;
276
332
  cells: CellRecord[];
277
333
  attempts: AttemptRecord[];
278
334
  /**
279
335
  * The compare's questions, answered after its attempts by pairwise votes, one per question;
280
- * unset without any. They annotate: `outcome` and `passRate` never depend on them.
336
+ * unset without any. They annotate: `outcome` and `passRate` never depend on them. Each vote
337
+ * may include a short `reason` (capped). `reeval analyze` includes each answer in the digest
338
+ * (rates by cut, votes, ties, a failed call, a sample of reasons).
281
339
  */
282
340
  answers?: CompareAnswer[];
341
+ /** Set on each case of a pooled `evaluate.each`; `RunRecord.families` has the suite. */
342
+ family?: {
343
+ id: string;
344
+ name: string;
345
+ case: number;
346
+ cases: number;
347
+ };
348
+ };
349
+ /** A 95% interval on a pooled rate or difference. */
350
+ type FamilyInterval = {
351
+ lo: number;
352
+ hi: number;
353
+ level: 0.95;
354
+ /**
355
+ * `wilson` / `newcombe-paired`: one counted attempt a case and side, so each case is one
356
+ * Bernoulli trial (or pair). `t-cases`: several, so a t interval over the cases' pass@1, with
357
+ * attempts within a case never counted as independent.
358
+ */
359
+ method: 'wilson' | 'newcombe-paired' | 't-cases';
283
360
  };
284
- /** A variant cell's pass rate against the control's, on the same harness and sandbox. */
361
+ /** One cell's pass rate over a family's cases. */
362
+ type FamilyRate = {
363
+ /** The cell's key, the same in every case. */
364
+ cell: string;
365
+ /** Cases with at least one counted attempt in this cell. */
366
+ cases: number;
367
+ /** Passes and counted attempts over those cases. */
368
+ pass: number;
369
+ counted: number;
370
+ /** The mean of the cases' pass@1; at one attempt a case, `pass / counted`. */
371
+ rate: number;
372
+ interval: FamilyInterval;
373
+ };
374
+ /**
375
+ * `lift` / `drop`: the interval excludes 0. `noise`: it doesn't. `insufficient`: fewer than 6
376
+ * discordant pairs (one attempt a case) or 6 paired cases (several), where no test can decide.
377
+ */
378
+ type FamilyVerdict = 'lift' | 'drop' | 'noise' | 'insufficient';
379
+ /** One effort metric over a family's paired cases. */
380
+ type FamilyEffortMetric = {
381
+ /** Cases with a value on both sides. */
382
+ pairs: number;
383
+ /** The median over cases of the variant's per-case median, over the control's; null at 0. */
384
+ ratio: number | null;
385
+ /** Wilcoxon signed-rank over the per-case differences; null when every difference is 0. */
386
+ p: number | null;
387
+ /** `insufficient` below 6 non-zero differences, where the exact test can't reach 0.05. */
388
+ verdict: 'fewer' | 'more' | 'noise' | 'insufficient';
389
+ };
390
+ /** The variant's effort against the control's, paired by case. */
391
+ type FamilyEffort = {
392
+ tools: FamilyEffortMetric;
393
+ agentMs: FamilyEffortMetric;
394
+ /** Over the cases where every counted attempt reported usage; omitted when none did. */
395
+ tokens?: FamilyEffortMetric;
396
+ };
397
+ /** A variant cell against its control over a family's cases, paired by case. */
398
+ type FamilyLift = {
399
+ /** The variant cell's key. */
400
+ variant: string;
401
+ /** The control cell's key. */
402
+ vs: string;
403
+ /** Cases with counted attempts on both sides. */
404
+ pairs: number;
405
+ /** Mean pass@1 over the paired cases on each side. */
406
+ variantRate: number;
407
+ controlRate: number;
408
+ /** Set at one attempt a case and side: pairs where only one side passed. */
409
+ discordant?: {
410
+ variantOnly: number;
411
+ controlOnly: number;
412
+ };
413
+ /** Variant minus control, from -1 to 1. */
414
+ points: number;
415
+ interval: FamilyInterval;
416
+ /** McNemar's exact p (one attempt a case), else Wilcoxon signed-rank over the cases. */
417
+ p: number | null;
418
+ /** The interval spans 0. */
419
+ withinNoise: boolean;
420
+ verdict: FamilyVerdict;
421
+ /** The compare's `minLift`: on a family it gates this lower bound, not each case's. */
422
+ minLift?: number;
423
+ /** `fail` when `interval.lo` is below `minLift`. */
424
+ outcome: 'pass' | 'fail';
425
+ effort?: FamilyEffort;
426
+ };
427
+ /** A pooled `evaluate.each`: its cases as samples of one suite. Each case is also an eval. */
428
+ type FamilyRecord = {
429
+ /** `file › group › … › template`. */
430
+ id: string;
431
+ file: string;
432
+ group: string[];
433
+ /** The name template, e.g. `fixes $id`. */
434
+ name: string;
435
+ /** Cases in the list. */
436
+ cases: number;
437
+ /** Cases with an eval in this run; fewer when a filter or tag left some out. */
438
+ ran: number;
439
+ /** One per cell. */
440
+ rates: FamilyRate[];
441
+ /** One per variant cell, with `compare`. */
442
+ lifts: FamilyLift[];
443
+ /** `fail` when a lift is below its `minLift`. The cases still pass or fail on their own. */
444
+ outcome: 'pass' | 'fail';
445
+ };
446
+ /** A variant cell's pass@1 against the control's, on the same harness and sandbox. */
285
447
  type Lift = {
286
448
  /** The control cell's key. */
287
449
  vs: string;
@@ -294,7 +456,7 @@ type Lift = {
294
456
  pass: number;
295
457
  counted: number;
296
458
  };
297
- /** Variant pass rate minus control pass rate, from -1 to 1. */
459
+ /** Variant pass@1 minus control pass@1, from -1 to 1. */
298
460
  points: number;
299
461
  /** 95% interval on the difference, by Newcombe's hybrid score method from two Wilson intervals. */
300
462
  interval: {
@@ -332,6 +494,11 @@ type CellRecord = Cell & {
332
494
  harnessKind: string;
333
495
  /** The configured harness model, when it has one. */
334
496
  model: string | null;
497
+ /**
498
+ * The reasoning effort the harness factory asked for; null when it left it unset.
499
+ * Fast is not this.
500
+ */
501
+ effort: string | null;
335
502
  /** How the attempts decide the cell's outcome; `'none'` when it doesn't fail the eval. */
336
503
  gate: CellGate;
337
504
  /** Environment keys the variant replaced on the control's (or a child on its parent's). */
@@ -341,14 +508,39 @@ type CellRecord = Cell & {
341
508
  fail: number;
342
509
  infraError: number;
343
510
  skipped: number;
511
+ /** pass@1: pass / (pass + fail); infra errors and skips excluded. */
344
512
  passRate: number | null;
345
513
  /**
346
- * By `gate`. `'all'` matches `{ passRate: 1 }` (infra only when nothing counted); `'none'`
514
+ * By `gate`. `'all'` (pass^k: every counted attempt passes) matches `{ passRate: 1 }`;
515
+ * `{ passRate }` is a pass@1 threshold. Infra only when nothing counted; `'none'`
347
516
  * reports the worst outcome. A variant below its `minLift` fails too.
348
517
  */
349
518
  outcome: Outcome;
350
519
  lift?: Lift;
520
+ /**
521
+ * Each check (assertion label) seen in any attempt of the eval, over this cell's counted
522
+ * attempts; on a variant cell, the control's beside it. Unset when no attempt recorded any.
523
+ */
524
+ checks?: CellCheck[];
351
525
  };
526
+ /** How often one check passed: a counted attempt that never reached it counts it `notRun`. */
527
+ type CheckTally = {
528
+ pass: number;
529
+ fail: number;
530
+ error: number;
531
+ notRun: number;
532
+ };
533
+ /**
534
+ * One check over a cell's counted attempts. `verdict` (variant cells): `discriminates` when it
535
+ * passes on every counted attempt of one side and none of the other; `both-pass` or `both-fail`
536
+ * when it does the same on both sides, so it can't tell them apart; `mixed` otherwise.
537
+ */
538
+ type CellCheck = CheckTally & {
539
+ label: string;
540
+ control?: CheckTally;
541
+ verdict?: CheckVerdict;
542
+ };
543
+ type CheckVerdict = 'discriminates' | 'both-pass' | 'both-fail' | 'mixed';
352
544
  /** Counts attempts, except `evals`. */
353
545
  type RunSummary = {
354
546
  evals: number;
@@ -447,6 +639,8 @@ type RunRecord = {
447
639
  };
448
640
  summary: RunSummary;
449
641
  evals: EvalEntry[];
642
+ /** Each pooled `evaluate.each` that ran; unset when none did. */
643
+ families?: FamilyRecord[];
450
644
  };
451
645
  /** What ran and graded the agents: the machine, images, harnesses and judge. */
452
646
  type Stack = {
@@ -478,21 +672,31 @@ type Stack = {
478
672
  /** Exact versions of the packages that run and grade the agent. */
479
673
  packages: Record<string, string>;
480
674
  /**
481
- * Each harness: its configured `model`, and `resolvedModels`, what it reported serving across
482
- * the run's turns with the variant it resolved (`composer-2.5[fast=true]` for `composer-2.5`
483
- * without `params`); empty when it reports none.
675
+ * Each harness: its configured `model` and requested `effort`, `resolvedModels` (what it
676
+ * reported serving, with the variant it resolved), and `resolvedEffort` (reasoning-effort
677
+ * suffixes those labels named). Fast (`[fast=true]`) is not `resolvedEffort`.
484
678
  */
485
679
  harnesses: Array<{
486
680
  id: string;
487
681
  kind: string;
488
682
  /** The configured model, when the harness has one. */
489
683
  model: string | null;
684
+ /**
685
+ * The reasoning effort the harness factory asked for; null when it left it unset.
686
+ * Fast is not this.
687
+ */
688
+ effort: string | null;
490
689
  /**
491
690
  * The models the harness reported serving, across every turn in the run, with the variant it
492
691
  * resolved (`composer-2.5[fast=true]` for `composer-2.5` with no `params`); empty when it
493
692
  * reports none.
494
693
  */
495
694
  resolvedModels: string[];
695
+ /**
696
+ * Reasoning-effort suffixes those served models named (`medium` from
697
+ * `gpt-5.6-luna[effort=medium]`); empty when they name none. Fast is not this.
698
+ */
699
+ resolvedEffort: string[];
496
700
  }>;
497
701
  /**
498
702
  * The run's judge: the config's, with what the profile's `judge` and `defaults.judge` set over it.
@@ -535,7 +739,7 @@ type HistoryCell = Pick<CellRecord, 'key' | 'role' | 'variant' | 'harness' | 'mo
535
739
  hi: number;
536
740
  withinNoise: boolean;
537
741
  };
538
- /** Median tool calls and agent time over the counted attempts; null when none counted. */
742
+ /** Median tool calls, agent time and tokens over the counted attempts; null when none counted. */
539
743
  effort: CellEffort | null;
540
744
  };
541
745
  /**
@@ -575,6 +779,8 @@ type HistoryEntry = {
575
779
  passRate: number | null;
576
780
  cells: HistoryCell[];
577
781
  }>;
782
+ /** The run's pooled families; unset when none ran. */
783
+ families?: Array<Pick<FamilyRecord, 'id' | 'name' | 'cases' | 'ran' | 'outcome'>>;
578
784
  };
579
785
  //#endregion
580
786
  //#region src/types.d.ts
@@ -609,6 +815,8 @@ type TranscriptEvent = EventTime & ({
609
815
  query: string;
610
816
  /** How many sources the harness says it used; Cursor sends no URLs or titles. */
611
817
  references: number | null;
818
+ /** Whether the search succeeded. Absent means it did. */
819
+ ok?: boolean;
612
820
  durationMs: number | null;
613
821
  } | {
614
822
  type: 'web-fetch';
@@ -640,14 +848,67 @@ type ExecResult = {
640
848
  stdout: string;
641
849
  stderr: string;
642
850
  };
643
- /** CSS pixels for `c.capture()`. Default 1280×720 when the call and cascade omit it. */
644
- type Viewport = {
851
+ /** Live tab size for `c.capture()`. Default 1280×720 when the call and cascade omit `viewport`. */
852
+ type CaptureWindow = {
645
853
  width: number;
646
854
  height: number;
647
855
  };
856
+ /**
857
+ * Author camera. `{ width, height }` is the live window and the saved PNG.
858
+ * `'full-page'` keeps the default window and saves with `captureBeyondViewport`.
859
+ */
860
+ type Viewport = CaptureWindow | 'full-page';
861
+ /**
862
+ * Chromium look-ready events. `'load'` is `window` load (`Page.loadEventFired`).
863
+ * `'idle'` is `Page.lifecycleEvent` `networkAlmostIdle`.
864
+ */
865
+ type CaptureWait = 'load' | 'idle';
866
+ /** Same shape at top-level `wait` and `{ wait }` between instructions. */
867
+ type Wait = CaptureWait | {
868
+ ms: number;
869
+ };
870
+ type CaptureInstruction = string | {
871
+ wait: Wait;
872
+ };
873
+ type CaptureUseAction = {
874
+ type: 'click';
875
+ x: number;
876
+ y: number;
877
+ } | {
878
+ type: 'type';
879
+ text: string;
880
+ } | {
881
+ type: 'key';
882
+ key: 'Tab' | 'Enter';
883
+ } | {
884
+ type: 'scroll';
885
+ x: number;
886
+ y: number;
887
+ dy: number;
888
+ } | {
889
+ type: 'drag';
890
+ x: number;
891
+ y: number;
892
+ toX: number;
893
+ toY: number;
894
+ } | {
895
+ type: 'hover';
896
+ x: number;
897
+ y: number;
898
+ } | {
899
+ type: 'done';
900
+ };
901
+ /** One list per instruction string. Tests; never downloads a model. */
902
+ type CaptureUseScript = CaptureUseAction[][];
903
+ /** Resolved vision driver after cascade, call override and analysis fallback. */
904
+ type CaptureUse = {
905
+ model: string;
906
+ } | {
907
+ fake: CaptureUseScript;
908
+ };
648
909
  /**
649
910
  * Camera defaults for `c.capture()`. Cascades config → profile defaults → group → eval,
650
- * shallow-merged. `viewport` on a level replaces the whole object. `port` is not an option:
911
+ * shallow-merged. `viewport` on a level replaces the whole value. `port` is not an option:
651
912
  * pass it as the first argument to `c.capture`.
652
913
  */
653
914
  type CaptureOptions = {
@@ -656,6 +917,11 @@ type CaptureOptions = {
656
917
  timeout?: Duration;
657
918
  /** `false` refuses the host `chrome-headless-shell` binary. `c.capture()` then throws. */
658
919
  browser?: boolean;
920
+ /**
921
+ * Vision model for `instructions`. Cascades like `question`. Default is the analysis
922
+ * model when that model accepts images; never Jev.
923
+ */
924
+ model?: string;
659
925
  };
660
926
  /** A background process started by `c.exec(..., { background: true })` or `c.serve`. */
661
927
  type BackgroundHandle = {
@@ -672,6 +938,7 @@ type Capture = {
672
938
  port: number;
673
939
  /** Path on the app, as passed in. */
674
940
  path: string;
941
+ /** What the author asked, including `'full-page'`. */
675
942
  viewport: Viewport;
676
943
  /** `artifacts/<name>.png` under the attempt directory. */
677
944
  file: {
@@ -683,13 +950,19 @@ type Capture = {
683
950
  /**
684
951
  * Optional camera and path for `c.capture(port | ServeHandle, options?)`.
685
952
  * `port` is the first argument, not a field here. Default `path` is `/`;
686
- * default `name` is derived from the path.
953
+ * default `name` is derived from the path. `wait` and `instructions` are call-only.
687
954
  */
688
955
  type CaptureCall = {
689
956
  name?: string;
690
957
  path?: string;
691
958
  viewport?: Viewport;
692
959
  timeout?: Duration;
960
+ /** Look-ready once, before the first model shot or the saved PNG. Default `'load'`. */
961
+ wait?: Wait;
962
+ /** Journey: goal strings and `{ wait }` beats. Tests may pass `fakeInstructions(...)`. */
963
+ instructions?: CaptureInstruction[];
964
+ /** Overrides cascaded `capture.model` for this call. */
965
+ model?: string;
693
966
  };
694
967
  type FileChange = {
695
968
  path: string;
@@ -747,19 +1020,44 @@ type Turn = TurnData & {
747
1020
  type JSONValue = null | boolean | number | string | JSONValue[] | {
748
1021
  [key: string]: JSONValue;
749
1022
  };
1023
+ /** JSON fields the judge sees for the turn: task, output, files, diff, optional contents. */
1024
+ type JudgeJsonState = {
1025
+ [key: string]: JSONValue;
1026
+ };
1027
+ /** A capture sent to `experimental_decide` as a file part. */
1028
+ type JudgeFilePart = {
1029
+ type: 'file';
1030
+ mediaType: string;
1031
+ data: Uint8Array;
1032
+ };
1033
+ /**
1034
+ * What `experimental_decide` (and a fake judge) receive: a JSON object when the call has no
1035
+ * captures, or an ordered list of one JSON part plus each capture's file part.
1036
+ */
1037
+ type JudgeState = JudgeJsonState | Array<{
1038
+ type: 'json';
1039
+ value: JudgeJsonState;
1040
+ } | JudgeFilePart>;
1041
+ /** A capture this judge call sent as a file part. Bytes live in `artifacts/<name>.png`. */
1042
+ type JudgeArtifactRef = {
1043
+ name: string;
1044
+ /** `artifacts/<name>.png` under the attempt directory. */
1045
+ path: string;
1046
+ sha256: string;
1047
+ bytes: number;
1048
+ mediaType: 'image/png';
1049
+ };
750
1050
  /**
751
1051
  * A canned judge for tests and dry runs; see `fakeJudge()` in `reeval/judge`. `score` as a
752
1052
  * function of the state the judge would see works per group, eval or call, not in the config.
753
1053
  */
754
1054
  type FakeJudgeModel = {
755
1055
  kind: 'fake-judge';
756
- score: number | ((state: {
757
- [key: string]: JSONValue;
758
- }) => number);
1056
+ score: number | ((state: JudgeState) => number);
759
1057
  };
760
1058
  /**
761
1059
  * `'provider/model'` (e.g. `'typesafe-ai/jev-1.13.0'`, `'google/gemini-3.8-flash'`), an AI SDK
762
- * evaluation model object (per group, eval or call only), or a fake judge.
1060
+ * decision model object (per group, eval or call only), or a fake judge.
763
1061
  */
764
1062
  type JudgeModel = string | FakeJudgeModel | {
765
1063
  readonly specificationVersion: string;
@@ -783,6 +1081,11 @@ type JudgeOptions = {
783
1081
  type JudgeCallOptions = JudgeOptions & {
784
1082
  /** What to grade instead of the latest turn: another turn, or a value used as the output. */
785
1083
  on?: Turn | JSONValue;
1084
+ /**
1085
+ * Captures this call sends the judge as file parts. A `c.capture()` handle or its name.
1086
+ * Call-only: the bytes are on this attempt. The provider that cannot take files fails the call.
1087
+ */
1088
+ artifacts?: Array<Capture | string>;
786
1089
  };
787
1090
  type Verdict = {
788
1091
  verdict: 'pass' | 'fail';
@@ -793,6 +1096,8 @@ type Verdict = {
793
1096
  model: string;
794
1097
  /** The model id the provider says served the call, when it reports one. */
795
1098
  resolvedModel?: string;
1099
+ /** Captures this call sent the judge as file parts, when any. */
1100
+ artifacts?: JudgeArtifactRef[];
796
1101
  };
797
1102
  /**
798
1103
  * What `c.judge()` returns when the call failed (the provider's error, after any retries): the attempt fails as a judge error once the eval's body has finished,
@@ -806,7 +1111,10 @@ type JudgeFailure = Omit<Verdict, 'verdict' | 'score' | 'resolvedModel'> & {
806
1111
  type AttemptContext = {
807
1112
  /** Sends the next turn of this eval's agent session, starting the sandbox on first use. */
808
1113
  send(prompt: string): Promise<Turn>;
809
- /** Asks the judge a yes/no question about the latest turn (or `options.on`). */
1114
+ /**
1115
+ * Asks the judge a yes/no question about the latest turn (or `options.on`).
1116
+ * `options.artifacts` is a list of `c.capture()` handles or names.
1117
+ */
810
1118
  judge(question: string, options?: JudgeCallOptions): Promise<Verdict | JudgeFailure>;
811
1119
  exec(command: string): Promise<ExecResult>;
812
1120
  exec(command: string, options: {
@@ -823,11 +1131,18 @@ type AttemptContext = {
823
1131
  /**
824
1132
  * Screenshots a path on a tunneled sandbox port and writes `artifacts/<name>.png`.
825
1133
  * First argument is the container port or a `ServeHandle` from `c.serve`.
1134
+ * `instructions` runs a vision journey on that same tab first.
826
1135
  * Needs a sandbox, same as `c.exec`.
827
1136
  */
828
1137
  capture(target: number | ServeHandle, options?: CaptureCall): Promise<Capture>;
829
1138
  /** Workspace-relative, or `~/` for the home directory; `null` when there's no such file. */
830
1139
  readFile(path: string): Promise<string | null>;
1140
+ /**
1141
+ * Writes a file into the sandbox (workspace-relative, or `~/`), creating its directories.
1142
+ * Later turns' `diff` leaves it out, as it does the environment's files, but shows any change
1143
+ * made to it afterwards. Needs a sandbox, same as `c.exec`.
1144
+ */
1145
+ writeFile(path: string, contents: string | Uint8Array): Promise<void>;
831
1146
  /**
832
1147
  * Starts the sandbox and the agent session without a turn, for checks on what the environment
833
1148
  * set up. `c.send()` starts them too; calling both starts them once.
@@ -867,6 +1182,11 @@ type FakeHarnessDescriptor = {
867
1182
  * and variant (`composer-2.5[fast=true]`); unset, it reports none.
868
1183
  */
869
1184
  servedModel?: string;
1185
+ /**
1186
+ * Requested reasoning effort, recorded as `effort` on the cell. Use `servedModel` for what the
1187
+ * turn reports (`fake-1[effort=medium]`). Fast is not this.
1188
+ */
1189
+ effort?: string;
870
1190
  /** Tool calls the fake agent reports on every turn, before writing files. */
871
1191
  tools?: Array<{
872
1192
  tool: string;
@@ -933,7 +1253,12 @@ type CursorHarnessDescriptor = {
933
1253
  * model catalog (`fast=true` for `composer-2.5`), sent explicitly; pass the ones that change cost.
934
1254
  */
935
1255
  params?: Record<string, string>;
936
- /** Cell id; defaults to `cursor:<model>`. */
1256
+ /**
1257
+ * Reasoning effort, mapped onto the catalog param `Cursor.models.list()` names for this model
1258
+ * (`reasoning_effort`, `effort`, …). Not Fast: that stays `params.fast`.
1259
+ */
1260
+ effort?: string;
1261
+ /** Cell id; defaults to `cursor:<model>`, or `cursor:<model>[effort=<value>]` when `effort` is set. */
937
1262
  id?: string;
938
1263
  /** The most Cursor attempts at once, across the run, e.g. for the account's rate limits. */
939
1264
  maxConcurrent?: number;
@@ -943,12 +1268,19 @@ type CursorHarnessDescriptor = {
943
1268
  */
944
1269
  startTimeout?: Duration;
945
1270
  };
1271
+ /** Reasoning effort the Claude Code Agent SDK `/effort` control takes. */
1272
+ type ClaudeCodeEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
946
1273
  /** Claude Code through `@ai-sdk/harness-claude-code`, made by `claudeCode()`. */
947
1274
  type ClaudeCodeHarnessDescriptor = {
948
1275
  kind: 'claude-code';
949
1276
  /** A model id or alias the `claude` CLI accepts, e.g. `claude-sonnet-5` or `sonnet`. */
950
1277
  model: string;
951
- /** Cell id; defaults to `claude-code:<model>`. */
1278
+ /**
1279
+ * Reasoning effort the Agent SDK `/effort` control takes: `low`, `medium`, `high`,
1280
+ * `xhigh` (Extra in the UI) or `max`.
1281
+ */
1282
+ effort?: ClaudeCodeEffort;
1283
+ /** Cell id; defaults to `claude-code:<model>`, or `claude-code:<model>[effort=<value>]` when `effort` is set. */
952
1284
  id?: string;
953
1285
  /** The most Claude Code attempts at once, across the run, e.g. for the account's rate limits. */
954
1286
  maxConcurrent?: number;
@@ -963,7 +1295,12 @@ type AntigravityHarnessDescriptor = {
963
1295
  kind: 'antigravity';
964
1296
  /** A model slug `agy models` lists for a Gemini API key, e.g. `gemini-3.8-flash-medium`. */
965
1297
  model: string;
966
- /** Cell id; defaults to `antigravity:<model>`. */
1298
+ /**
1299
+ * Reasoning effort passed as `agy --effort`, e.g. `low`, `medium`, `high` or `max`. The
1300
+ * slug's `-low`/`-medium`/`-high` suffix is the same knob baked into `model`.
1301
+ */
1302
+ effort?: string;
1303
+ /** Cell id; defaults to `antigravity:<model>`, or `antigravity:<model>[effort=<value>]` when `effort` is set. */
967
1304
  id?: string;
968
1305
  /** The most Antigravity attempts at once, across the run, e.g. for the key's rate limits. */
969
1306
  maxConcurrent?: number;
@@ -985,7 +1322,12 @@ type OpenCodeHarnessDescriptor = {
985
1322
  * `anthropic/claude-haiku-4-5`; the provider picks the key.
986
1323
  */
987
1324
  model: string;
988
- /** Cell id; defaults to `opencode:<model>`. */
1325
+ /**
1326
+ * Reasoning effort for that provider: `options.reasoningEffort` (OpenAI) or `options.thinking`
1327
+ * (Anthropic). Values are whatever that provider takes.
1328
+ */
1329
+ effort?: string;
1330
+ /** Cell id; defaults to `opencode:<model>`, or `opencode:<model>[effort=<value>]` when `effort` is set. */
989
1331
  id?: string;
990
1332
  /** The most OpenCode attempts at once, across the run, e.g. for the key's rate limits. */
991
1333
  maxConcurrent?: number;
@@ -1003,7 +1345,11 @@ type GooseHarnessDescriptor = {
1003
1345
  kind: 'goose';
1004
1346
  /** A Gemini model id, run on Goose's `google` provider, e.g. `gemini-3.8-flash`. */
1005
1347
  model: string;
1006
- /** Cell id; defaults to `goose:<model>`. */
1348
+ /**
1349
+ * Reasoning effort as `GOOSE_THINKING_EFFORT`, e.g. `off`, `low`, `medium`, `high` or `max`.
1350
+ */
1351
+ effort?: string;
1352
+ /** Cell id; defaults to `goose:<model>`, or `goose:<model>[effort=<value>]` when `effort` is set. */
1007
1353
  id?: string;
1008
1354
  /** The most Goose attempts at once, across the run, e.g. for the key's rate limits. */
1009
1355
  maxConcurrent?: number;
@@ -1022,7 +1368,12 @@ type PiHarnessDescriptor = {
1022
1368
  kind: 'pi';
1023
1369
  /** A Gemini model id, run on pi's `google` provider, e.g. `gemini-3.8-flash`. */
1024
1370
  model: string;
1025
- /** Cell id; defaults to `pi:<model>`. */
1371
+ /**
1372
+ * Reasoning effort, passed as pi's `--thinking` (the CLI's name). Values are whatever that
1373
+ * flag takes, e.g. `off`, `minimal`, `low`, `medium`, `high`, `xhigh` or `max`.
1374
+ */
1375
+ effort?: string;
1376
+ /** Cell id; defaults to `pi:<model>`, or `pi:<model>[effort=<value>]` when `effort` is set. */
1026
1377
  id?: string;
1027
1378
  /** The most pi attempts at once, across the run, e.g. for the key's rate limits. */
1028
1379
  maxConcurrent?: number;
@@ -1040,7 +1391,12 @@ type CodexHarnessDescriptor = {
1040
1391
  kind: 'codex';
1041
1392
  /** An OpenAI model id Codex runs on the Responses API, e.g. `gpt-5.6-luna`. */
1042
1393
  model: string;
1043
- /** Cell id; defaults to `codex:<model>`. */
1394
+ /**
1395
+ * Reasoning effort as Codex's `model_reasoning_effort`, e.g. `low`, `medium`, `high`,
1396
+ * `xhigh`, `max` or `ultra`.
1397
+ */
1398
+ effort?: string;
1399
+ /** Cell id; defaults to `codex:<model>`, or `codex:<model>[effort=<value>]` when `effort` is set. */
1044
1400
  id?: string;
1045
1401
  /** The most Codex attempts at once, across the run, e.g. for the key's rate limits. */
1046
1402
  maxConcurrent?: number;
@@ -1085,8 +1441,13 @@ type DockerSandboxDescriptor = {
1085
1441
  root?: boolean;
1086
1442
  /** Linux capabilities to add back, e.g. `['NET_RAW']`; every other one is dropped. */
1087
1443
  capabilities?: string[];
1088
- /** The container's memory, with no swap on top: `'4g'` (default), `'512m'`, or bytes. */
1444
+ /** The container's memory: `'4g'` (default), `'512m'`, or bytes. */
1089
1445
  memory?: string | number;
1446
+ /**
1447
+ * Swap on top of `memory`, in the same units. Default: as much as `memory`; `0` makes `memory`
1448
+ * the hard ceiling. A host without swap has none to give.
1449
+ */
1450
+ swap?: string | number;
1090
1451
  /** CPUs the container may use, fractions allowed. Default 2, capped at the Docker host's. */
1091
1452
  cpus?: number;
1092
1453
  /** Processes and threads at once. Default 1024. */
@@ -1397,16 +1758,27 @@ type CompareOptions<E = Environment> = {
1397
1758
  * win rates and never change pass, fail or the exit code.
1398
1759
  */
1399
1760
  questions?: CompareQuestion[];
1761
+ /**
1762
+ * The factor every question varies when pairing, when a question does not name its own
1763
+ * `across`. `'environment'` holds the harness; `'harness'` holds the environment. A list of
1764
+ * both, or omitted, asks both pair kinds.
1765
+ */
1766
+ across?: PairFactor | PairFactor[];
1400
1767
  };
1401
1768
  /**
1402
1769
  * A question for pairwise judgement: its text, or the text and the `'provider/model'` that
1403
1770
  * answers it. Without a model, `analysis.model` answers, else the judge's when it's a language model.
1771
+ * `across` is the factor it varies when pairing; without it (and without a one-factor
1772
+ * `compare.across`) both pair kinds run.
1404
1773
  */
1405
1774
  type CompareQuestion = string | {
1406
1775
  question: string;
1407
1776
  model?: string;
1777
+ across?: PairFactor;
1408
1778
  };
1409
- /** Which pairs a vote is over: two arms on one harness, or two harnesses on one arm. */
1779
+ /** A matrix factor a compare question varies when pairing; the others are held. */
1780
+ type PairFactor = 'environment' | 'harness';
1781
+ /** Which pairs a vote is over: two environments on one harness, or two harnesses on one environment. */
1410
1782
  type CompareCut = 'within' | 'across';
1411
1783
  /** One judgement of one pair of attempts, in one order. */
1412
1784
  type PairVote = {
@@ -1425,6 +1797,8 @@ type PairVote = {
1425
1797
  winner: string | 'tie';
1426
1798
  /** True for the repeat that showed `b` first. */
1427
1799
  swapped: boolean;
1800
+ /** The model's short reason for this pick; omitted when it gave none. Capped. */
1801
+ reason?: string;
1428
1802
  };
1429
1803
  /** A compare question's answer: every vote, and each side's wins over decided votes per cut. */
1430
1804
  type CompareAnswer = {
@@ -1447,7 +1821,8 @@ type CompareAnswer = {
1447
1821
  type PinnableKey = 'harness' | 'runs' | 'compare';
1448
1822
  /**
1449
1823
  * How a cell's attempts decide its outcome: `'all'` (the default) passes only when every attempt
1450
- * passes; `{ passRate }` passes when at least that share of its passes and fails are passes.
1824
+ * passes (pass^k); `{ passRate }` passes when its pass@1 (passes over passes and fails) is at
1825
+ * least that share.
1451
1826
  */
1452
1827
  type GatePolicy = 'all' | {
1453
1828
  passRate: number;
@@ -1477,7 +1852,7 @@ type EvalOptionFields = {
1477
1852
  */
1478
1853
  egress?: EgressPolicy;
1479
1854
  judge?: JudgeOptions;
1480
- /** Screenshot defaults for `c.capture()`. Shallow-merged; `viewport` replaces the whole object. */
1855
+ /** Screenshot defaults for `c.capture()`. Shallow-merged; `viewport` and `model` replace the value. */
1481
1856
  capture?: CaptureOptions;
1482
1857
  /** Per attempt. */
1483
1858
  timeout?: Duration;
@@ -1586,14 +1961,19 @@ type FakeAnalysisModel = {
1586
1961
  };
1587
1962
  /**
1588
1963
  * How it answers compare questions: a fixed pick, a function of the blinded pair, or
1589
- * `{ error }` to fail every call. Default `'tie'`.
1964
+ * `{ error }` to fail every call. A pick may be `{ winner, reason? }`. Default `'tie'`.
1590
1965
  */
1591
- vote?: FakeVote | ((pair: BlindPair) => FakeVote) | {
1966
+ vote?: FakePick | ((pair: BlindPair) => FakePick) | {
1592
1967
  error: string;
1593
1968
  };
1594
1969
  };
1595
1970
  /** A blinded label's pick: the attempt shown first (`A`), second (`B`), or neither. */
1596
1971
  type FakeVote = 'A' | 'B' | 'tie';
1972
+ /** A fake compare-question pick, optionally with a reason. */
1973
+ type FakePick = FakeVote | {
1974
+ winner: FakeVote;
1975
+ reason?: string;
1976
+ };
1597
1977
  /** What a compare question's model is shown: the prompt, and the two diffs in slot order. */
1598
1978
  type BlindPair = {
1599
1979
  question: string;
@@ -1692,11 +2072,23 @@ type PrepareFailureRecord = {
1692
2072
  log: string | null;
1693
2073
  setBy: string[];
1694
2074
  };
1695
- /** Why an attempt failed; `prepare` when its sandbox couldn't be prepared. */
2075
+ /**
2076
+ * The sandbox ran out of a resource during the attempt: `oom` is the kernel killing `kills`
2077
+ * processes at its memory limit. The attempt is then an infra error, whatever its checks said.
2078
+ */
2079
+ type ResourceFailureRecord = {
2080
+ cause: 'oom';
2081
+ kills: number;
2082
+ };
2083
+ /**
2084
+ * Why an attempt failed; `prepare` when its sandbox couldn't be prepared, `resource` when it ran
2085
+ * out of one.
2086
+ */
1696
2087
  type AttemptError = {
1697
2088
  kind: ErrorKind;
1698
2089
  message: string;
1699
2090
  prepare?: PrepareFailureRecord;
2091
+ resource?: ResourceFailureRecord;
1700
2092
  };
1701
2093
  /** Where an eval's time went, in ms. `agentMs` is the harness turns; `diffMs` reading changes. */
1702
2094
  type PhaseTimings = {
@@ -1831,6 +2223,25 @@ type StartRetry = {
1831
2223
  /** How long it waited before giving up on that start. */
1832
2224
  waitedMs: number;
1833
2225
  };
2226
+ /** One `expect` or `expect.soft` matcher call an attempt made. */
2227
+ type AssertionRecord = {
2228
+ /**
2229
+ * `expect`'s second argument, or `<matcher> <first argument>` (or the command `c.exec` ran, or
2230
+ * the judge's question), cut at 60 characters; ` #2`, ` #3` on repeats within the attempt.
2231
+ */
2232
+ label: string;
2233
+ /** The eval gave the label. */
2234
+ labelled: boolean;
2235
+ /** `toHaveFile`, `not.toBe`, `resolves.toBe`, `poll.toBe`. */
2236
+ matcher: string;
2237
+ /** `error`: the matcher couldn't answer (a subject it can't read, an event the harness doesn't report). */
2238
+ status: 'pass' | 'fail' | 'error';
2239
+ soft: boolean;
2240
+ /** Why it failed or couldn't answer, cut at 1 KB. */
2241
+ message?: string;
2242
+ /** Async matchers only (`toHaveFile`, `toSucceed`, `.resolves`, `expect.poll`). */
2243
+ durationMs?: number;
2244
+ };
1834
2245
  /** Which environment ran as the control, so the studio can show it. */
1835
2246
  type EvalCompareMeta = {
1836
2247
  baseline: string;
@@ -1858,5 +2269,5 @@ type SandboxWarning = {
1858
2269
  message: string;
1859
2270
  };
1860
2271
  //#endregion
1861
- export { JudgeFailure as $, effortVerdict as $t, EnvironmentHelpers as A, FileRef as At, FakeNoteInput as B, EffortSample as Bt, DirectoryOptions as C, Verdict as Ct, EgressRecord as D, AttemptRecord as Dt, EgressPolicy as E, ArtifactRef as Et, EvalOptions as F, RunRecord as Ft, GroupOptions as G, cellEffort as Gt, FakeScriptStep as H, Spread as Ht, ExecResult as I, StackSummary as It, HarnessEdit as J, effortChangeLabel as Jt, HarnessData as K, cellSamples as Kt, FakeAnalysisModel as L, CellEffort as Lt, EnvironmentSpec as M, HistoryEntry as Mt, EsConfig as N, JudgementRecord as Nt, EnvVars as O, CellRecord as Ot, EvalFn as P, Lift as Pt, JudgeCallOptions as Q, effortSummary as Qt, FakeHarnessDescriptor as R, EFFORT_ALPHA as Rt, Diff as S, TurnStatus as St, Duration as T, WebEventType as Tt, FakeVote as U, VERDICT_TEXT as Ut, FakeSandboxDescriptor as V, EffortVerdict as Vt, GooseHarnessDescriptor as W, cellContrast as Wt, HistoryConfig as X, effortOf as Xt, HarnessOption as Y, effortLabel as Yt, HostFile as Z, effortSample as Zt, CompareOptions as _, SkillSource as _t, BackgroundHandle as a, PairVote as at, ConfigJudgeOptions as b, Turn as bt, Capture as c, Profile as ct, Cell as d, SandboxDescriptor as dt, formatCount as en, JudgeModel as et, CellRole as f, SandboxWarning as ft, CompareCut as g, SetupStep as gt, CompareAnswer as h, ServeHandle as ht, AttemptContext as i, Outcome as it, EnvironmentInput as j, HistoryCell as jt, Environment as k, EvalEntry as kt, CaptureCall as l, ProfileDefaults as lt, CodexHarnessDescriptor as m, SecretTemplate as mt, AnalysisConfig as n, formatSeconds as nn, McpServer as nt, BlindPair as o, PiHarnessDescriptor as ot, ClaudeCodeHarnessDescriptor as p, Secret as pt, HarnessDescriptor as q, contrastEffort as qt, AntigravityHarnessDescriptor as r, OpenCodeHarnessDescriptor as rt, Budget as s, PinnableKey as st, AgentHarnessDescriptor as t, formatRatio as tn, JudgeOptions as tt, CaptureOptions as u, ProfileLimit as ut, CompareQuestion as v, TokenUsage as vt, DockerSandboxDescriptor as w, Viewport as wt, CursorHarnessDescriptor as x, TurnData as xt, ConfigHelpers as y, TranscriptEvent as yt, FakeJudgeModel as z, EffortContrast as zt };
1862
- //# sourceMappingURL=types-BsRSknLe.d.ts.map
2272
+ export { HarnessData as $, EffortContrast as $t, DirectoryOptions as A, Turn as At, EsConfig as B, EvalEntry as Bt, CompareCut as C, Secret as Ct, ConfigJudgeOptions as D, SkillSource as Dt, ConfigHelpers as E, SetupStep as Et, EnvVars as F, Wait as Ft, FakeHarnessDescriptor as G, HistoryCell as Gt, EvalOptions as H, FamilyRate as Ht, Environment as I, WebEventType as It, FakeSandboxDescriptor as J, Lift as Jt, FakeJudgeModel as K, HistoryEntry as Kt, EnvironmentHelpers as L, ArtifactRef as Lt, Duration as M, TurnStatus as Mt, EgressPolicy as N, Verdict as Nt, CursorHarnessDescriptor as O, TokenUsage as Ot, EgressRecord as P, Viewport as Pt, GroupOptions as Q, EFFORT_ALPHA as Qt, EnvironmentInput as R, AttemptRecord as Rt, CompareAnswer as S, SandboxWarning as St, CompareQuestion as T, ServeHandle as Tt, ExecResult as U, FamilyRecord as Ut, EvalFn as V, FamilyLift as Vt, FakeAnalysisModel as W, FileRef as Wt, FakeVote as X, StackSummary as Xt, FakeScriptStep as Y, RunRecord as Yt, GooseHarnessDescriptor as Z, CellEffort as Zt, Cell as _, formatSeconds as _n, PinnableKey as _t, BackgroundHandle as a, cellContrast as an, JudgeArtifactRef as at, ClaudeCodeHarnessDescriptor as b, ProfileLimit as bt, Capture as c, contrastEffort as cn, JudgeModel as ct, CaptureOptions as d, effortOf as dn, McpServer as dt, EffortSample as en, HarnessDescriptor as et, CaptureUse as f, effortSample as fn, OpenCodeHarnessDescriptor as ft, CaptureWindow as g, formatRatio as gn, PiHarnessDescriptor as gt, CaptureWait as h, formatCount as hn, PairVote as ht, AttemptContext as i, VERDICT_TEXT as in, HostFile as it, DockerSandboxDescriptor as j, TurnData as jt, Diff as k, TranscriptEvent as kt, CaptureCall as l, effortChangeLabel as ln, JudgeOptions as lt, CaptureUseScript as m, effortVerdict as mn, PairFactor as mt, AnalysisConfig as n, Spread as nn, HarnessOption as nt, BlindPair as o, cellEffort as on, JudgeCallOptions as ot, CaptureUseAction as p, effortSummary as pn, Outcome as pt, FakeNoteInput as q, JudgementRecord as qt, AntigravityHarnessDescriptor as r, TOKENS_UNREPORTED as rn, HistoryConfig as rt, Budget as s, cellSamples as sn, JudgeFailure as st, AgentHarnessDescriptor as t, EffortVerdict as tn, HarnessEdit as tt, CaptureInstruction as u, effortLabel as un, JudgeState as ut, CellRole as v, tokenValues as vn, Profile as vt, CompareOptions as w, SecretTemplate as wt, CodexHarnessDescriptor as x, SandboxDescriptor as xt, ClaudeCodeEffort as y, ProfileDefaults as yt, EnvironmentSpec as z, CellRecord as zt };
2273
+ //# sourceMappingURL=types-D8RLfkFP.d.ts.map