@prismatic-io/lux 0.0.2-preview.15 → 0.0.2-preview.16

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 (382) hide show
  1. package/lib/answerers/claude-code/index.d.ts +14 -2
  2. package/lib/answerers/claude-code/index.d.ts.map +1 -1
  3. package/lib/answerers/claude-code/index.js +3 -3
  4. package/lib/answerers/claude-code/index.js.map +1 -1
  5. package/lib/answerers/persona/index.d.ts +28 -2
  6. package/lib/answerers/persona/index.d.ts.map +1 -1
  7. package/lib/answerers/persona/index.js +3 -3
  8. package/lib/answerers/persona/index.js.map +1 -1
  9. package/lib/answerers/terminal/index.d.ts +8 -2
  10. package/lib/answerers/terminal/index.d.ts.map +1 -1
  11. package/lib/answerers/terminal/index.js +3 -2
  12. package/lib/answerers/terminal/index.js.map +1 -1
  13. package/lib/assertions/core/resource-checks.d.ts.map +1 -1
  14. package/lib/assertions/core/resource-checks.js +3 -5
  15. package/lib/assertions/core/resource-checks.js.map +1 -1
  16. package/lib/assertions/rubric/index.d.ts.map +1 -1
  17. package/lib/assertions/rubric/index.js +7 -1
  18. package/lib/assertions/rubric/index.js.map +1 -1
  19. package/lib/assertions/rubric/internal.d.ts +16 -5
  20. package/lib/assertions/rubric/internal.d.ts.map +1 -1
  21. package/lib/assertions/rubric/internal.js +10 -6
  22. package/lib/assertions/rubric/internal.js.map +1 -1
  23. package/lib/authoring.d.ts +32 -2
  24. package/lib/authoring.d.ts.map +1 -1
  25. package/lib/authoring.js +33 -1
  26. package/lib/authoring.js.map +1 -1
  27. package/lib/cli/bin.js +2 -13
  28. package/lib/cli/bin.js.map +1 -1
  29. package/lib/cli/command-runtime.d.ts +3 -3
  30. package/lib/cli/command-runtime.d.ts.map +1 -1
  31. package/lib/cli/command-runtime.js +17 -6
  32. package/lib/cli/command-runtime.js.map +1 -1
  33. package/lib/cli/init-templates.d.ts +11 -0
  34. package/lib/cli/init-templates.d.ts.map +1 -0
  35. package/lib/cli/init-templates.js +207 -0
  36. package/lib/cli/init-templates.js.map +1 -0
  37. package/lib/cli/init.d.ts +7 -0
  38. package/lib/cli/init.d.ts.map +1 -1
  39. package/lib/cli/init.js +23 -173
  40. package/lib/cli/init.js.map +1 -1
  41. package/lib/cli/output-schemas.d.ts +1399 -0
  42. package/lib/cli/output-schemas.d.ts.map +1 -0
  43. package/lib/cli/output-schemas.js +91 -0
  44. package/lib/cli/output-schemas.js.map +1 -0
  45. package/lib/cli/program.d.ts +135 -4
  46. package/lib/cli/program.d.ts.map +1 -1
  47. package/lib/cli/program.js +725 -520
  48. package/lib/cli/program.js.map +1 -1
  49. package/lib/cli/render/reporter.d.ts.map +1 -1
  50. package/lib/cli/render/reporter.js +24 -4
  51. package/lib/cli/render/reporter.js.map +1 -1
  52. package/lib/cli/run-options.d.ts +0 -4
  53. package/lib/cli/run-options.d.ts.map +1 -1
  54. package/lib/cli/run-options.js +8 -19
  55. package/lib/cli/run-options.js.map +1 -1
  56. package/lib/cli/view.d.ts +5 -3
  57. package/lib/cli/view.d.ts.map +1 -1
  58. package/lib/cli/view.js +120 -78
  59. package/lib/cli/view.js.map +1 -1
  60. package/lib/core/annotation.d.ts +6 -2
  61. package/lib/core/annotation.d.ts.map +1 -1
  62. package/lib/core/annotation.js +2 -1
  63. package/lib/core/annotation.js.map +1 -1
  64. package/lib/core/answerer.d.ts +12 -0
  65. package/lib/core/answerer.d.ts.map +1 -1
  66. package/lib/core/answerer.js +2 -0
  67. package/lib/core/answerer.js.map +1 -1
  68. package/lib/core/assertion.d.ts +3 -0
  69. package/lib/core/assertion.d.ts.map +1 -1
  70. package/lib/core/assertion.js +3 -0
  71. package/lib/core/assertion.js.map +1 -1
  72. package/lib/core/case.d.ts +24 -2
  73. package/lib/core/case.d.ts.map +1 -1
  74. package/lib/core/case.js +5 -1
  75. package/lib/core/case.js.map +1 -1
  76. package/lib/core/driver.d.ts +40 -0
  77. package/lib/core/driver.d.ts.map +1 -1
  78. package/lib/core/driver.js +12 -0
  79. package/lib/core/driver.js.map +1 -1
  80. package/lib/core/environment.d.ts +18 -0
  81. package/lib/core/environment.d.ts.map +1 -0
  82. package/lib/core/environment.js +21 -0
  83. package/lib/core/environment.js.map +1 -0
  84. package/lib/core/evaluation-clusters.d.ts +17 -0
  85. package/lib/core/evaluation-clusters.d.ts.map +1 -0
  86. package/lib/core/evaluation-clusters.js +23 -0
  87. package/lib/core/evaluation-clusters.js.map +1 -0
  88. package/lib/core/experiment.d.ts +11 -0
  89. package/lib/core/experiment.d.ts.map +1 -1
  90. package/lib/core/experiment.js +31 -17
  91. package/lib/core/experiment.js.map +1 -1
  92. package/lib/core/file-tree.d.ts +7 -0
  93. package/lib/core/file-tree.d.ts.map +1 -0
  94. package/lib/core/file-tree.js +35 -0
  95. package/lib/core/file-tree.js.map +1 -0
  96. package/lib/core/index.d.ts +1 -0
  97. package/lib/core/index.d.ts.map +1 -1
  98. package/lib/core/index.js +1 -0
  99. package/lib/core/index.js.map +1 -1
  100. package/lib/core/lifecycle-fixtures.d.ts.map +1 -1
  101. package/lib/core/lifecycle-fixtures.js +4 -2
  102. package/lib/core/lifecycle-fixtures.js.map +1 -1
  103. package/lib/core/platform-process.d.ts +5 -1
  104. package/lib/core/platform-process.d.ts.map +1 -1
  105. package/lib/core/platform-process.js +48 -10
  106. package/lib/core/platform-process.js.map +1 -1
  107. package/lib/core/run.d.ts +93 -1
  108. package/lib/core/run.d.ts.map +1 -1
  109. package/lib/core/run.js +16 -0
  110. package/lib/core/run.js.map +1 -1
  111. package/lib/core/usage.d.ts +5 -0
  112. package/lib/core/usage.d.ts.map +1 -1
  113. package/lib/core/usage.js +3 -0
  114. package/lib/core/usage.js.map +1 -1
  115. package/lib/drivers/claude-code/index.d.ts +65 -2
  116. package/lib/drivers/claude-code/index.d.ts.map +1 -1
  117. package/lib/drivers/claude-code/index.js +30 -3
  118. package/lib/drivers/claude-code/index.js.map +1 -1
  119. package/lib/drivers/codex/app-events.d.ts.map +1 -1
  120. package/lib/drivers/codex/app-events.js +41 -30
  121. package/lib/drivers/codex/app-events.js.map +1 -1
  122. package/lib/drivers/codex/exec-events.d.ts +4 -0
  123. package/lib/drivers/codex/exec-events.d.ts.map +1 -0
  124. package/lib/drivers/codex/exec-events.js +230 -0
  125. package/lib/drivers/codex/exec-events.js.map +1 -0
  126. package/lib/drivers/codex/index.d.ts +76 -4
  127. package/lib/drivers/codex/index.d.ts.map +1 -1
  128. package/lib/drivers/codex/index.js +35 -232
  129. package/lib/drivers/codex/index.js.map +1 -1
  130. package/lib/drivers/cursor/acp-transport.d.ts +38 -0
  131. package/lib/drivers/cursor/acp-transport.d.ts.map +1 -0
  132. package/lib/drivers/cursor/acp-transport.js +152 -0
  133. package/lib/drivers/cursor/acp-transport.js.map +1 -0
  134. package/lib/drivers/cursor/config.d.ts +22 -0
  135. package/lib/drivers/cursor/config.d.ts.map +1 -0
  136. package/lib/drivers/cursor/config.js +26 -0
  137. package/lib/drivers/cursor/config.js.map +1 -0
  138. package/lib/drivers/cursor/events.d.ts +13 -0
  139. package/lib/drivers/cursor/events.d.ts.map +1 -0
  140. package/lib/drivers/cursor/events.js +73 -0
  141. package/lib/drivers/cursor/events.js.map +1 -0
  142. package/lib/drivers/cursor/index.d.ts +37 -0
  143. package/lib/drivers/cursor/index.d.ts.map +1 -0
  144. package/lib/drivers/cursor/index.js +276 -0
  145. package/lib/drivers/cursor/index.js.map +1 -0
  146. package/lib/drivers/cursor/interaction.d.ts +7 -0
  147. package/lib/drivers/cursor/interaction.d.ts.map +1 -0
  148. package/lib/drivers/cursor/interaction.js +66 -0
  149. package/lib/drivers/cursor/interaction.js.map +1 -0
  150. package/lib/drivers/mcp/index.d.ts +35 -2
  151. package/lib/drivers/mcp/index.d.ts.map +1 -1
  152. package/lib/drivers/mcp/index.js +16 -3
  153. package/lib/drivers/mcp/index.js.map +1 -1
  154. package/lib/drivers/shared/experiment-behavior.d.ts +13 -0
  155. package/lib/drivers/shared/experiment-behavior.d.ts.map +1 -0
  156. package/lib/drivers/shared/experiment-behavior.js +197 -0
  157. package/lib/drivers/shared/experiment-behavior.js.map +1 -0
  158. package/lib/drivers/shared/experiment-policy.d.ts +4 -0
  159. package/lib/drivers/shared/experiment-policy.d.ts.map +1 -0
  160. package/lib/drivers/shared/experiment-policy.js +143 -0
  161. package/lib/drivers/shared/experiment-policy.js.map +1 -0
  162. package/lib/drivers/subprocess/index.d.ts +37 -2
  163. package/lib/drivers/subprocess/index.d.ts.map +1 -1
  164. package/lib/drivers/subprocess/index.js +46 -6
  165. package/lib/drivers/subprocess/index.js.map +1 -1
  166. package/lib/index.d.ts +6 -4
  167. package/lib/index.d.ts.map +1 -1
  168. package/lib/index.js +4 -2
  169. package/lib/index.js.map +1 -1
  170. package/lib/orchestrator/annotation-loader.d.ts +6 -2
  171. package/lib/orchestrator/annotation-loader.d.ts.map +1 -1
  172. package/lib/orchestrator/annotation-loader.js +8 -0
  173. package/lib/orchestrator/annotation-loader.js.map +1 -1
  174. package/lib/orchestrator/annotation-store.d.ts.map +1 -1
  175. package/lib/orchestrator/annotation-store.js +16 -2
  176. package/lib/orchestrator/annotation-store.js.map +1 -1
  177. package/lib/orchestrator/campaign-lifecycle.d.ts +1 -0
  178. package/lib/orchestrator/campaign-lifecycle.d.ts.map +1 -1
  179. package/lib/orchestrator/campaign-lifecycle.js +4 -1
  180. package/lib/orchestrator/campaign-lifecycle.js.map +1 -1
  181. package/lib/orchestrator/compare.d.ts +4 -0
  182. package/lib/orchestrator/compare.d.ts.map +1 -1
  183. package/lib/orchestrator/compare.js +13 -1
  184. package/lib/orchestrator/compare.js.map +1 -1
  185. package/lib/orchestrator/comparison-identity.d.ts.map +1 -1
  186. package/lib/orchestrator/comparison-identity.js +1 -0
  187. package/lib/orchestrator/comparison-identity.js.map +1 -1
  188. package/lib/orchestrator/config.d.ts +42 -0
  189. package/lib/orchestrator/config.d.ts.map +1 -1
  190. package/lib/orchestrator/config.js +6 -0
  191. package/lib/orchestrator/config.js.map +1 -1
  192. package/lib/orchestrator/discover.d.ts +1 -0
  193. package/lib/orchestrator/discover.d.ts.map +1 -1
  194. package/lib/orchestrator/discover.js +7 -1
  195. package/lib/orchestrator/discover.js.map +1 -1
  196. package/lib/orchestrator/doctor.d.ts.map +1 -1
  197. package/lib/orchestrator/doctor.js +34 -26
  198. package/lib/orchestrator/doctor.js.map +1 -1
  199. package/lib/orchestrator/driver-capabilities.d.ts +3 -0
  200. package/lib/orchestrator/driver-capabilities.d.ts.map +1 -0
  201. package/lib/orchestrator/driver-capabilities.js +10 -0
  202. package/lib/orchestrator/driver-capabilities.js.map +1 -0
  203. package/lib/orchestrator/driver-identity.d.ts +5 -0
  204. package/lib/orchestrator/driver-identity.d.ts.map +1 -0
  205. package/lib/orchestrator/driver-identity.js +41 -0
  206. package/lib/orchestrator/driver-identity.js.map +1 -0
  207. package/lib/orchestrator/experiment-context.d.ts +10 -0
  208. package/lib/orchestrator/experiment-context.d.ts.map +1 -1
  209. package/lib/orchestrator/experiment-contracts.d.ts +10 -0
  210. package/lib/orchestrator/experiment-contracts.d.ts.map +1 -1
  211. package/lib/orchestrator/experiment-corpus.d.ts.map +1 -1
  212. package/lib/orchestrator/experiment-corpus.js +17 -19
  213. package/lib/orchestrator/experiment-corpus.js.map +1 -1
  214. package/lib/orchestrator/experiment-effects.d.ts +33 -0
  215. package/lib/orchestrator/experiment-effects.d.ts.map +1 -0
  216. package/lib/orchestrator/experiment-effects.js +44 -0
  217. package/lib/orchestrator/experiment-effects.js.map +1 -0
  218. package/lib/orchestrator/experiment-evaluation.d.ts.map +1 -1
  219. package/lib/orchestrator/experiment-evaluation.js +36 -3
  220. package/lib/orchestrator/experiment-evaluation.js.map +1 -1
  221. package/lib/orchestrator/experiment-identity.d.ts.map +1 -1
  222. package/lib/orchestrator/experiment-identity.js +18 -29
  223. package/lib/orchestrator/experiment-identity.js.map +1 -1
  224. package/lib/orchestrator/experiment-loader.d.ts +7 -2
  225. package/lib/orchestrator/experiment-loader.d.ts.map +1 -1
  226. package/lib/orchestrator/experiment-report.d.ts +70 -0
  227. package/lib/orchestrator/experiment-report.d.ts.map +1 -1
  228. package/lib/orchestrator/experiment-report.js +9 -1
  229. package/lib/orchestrator/experiment-report.js.map +1 -1
  230. package/lib/orchestrator/experiment-runs.d.ts +22 -1
  231. package/lib/orchestrator/experiment-runs.d.ts.map +1 -1
  232. package/lib/orchestrator/experiment-runs.js +13 -5
  233. package/lib/orchestrator/experiment-runs.js.map +1 -1
  234. package/lib/orchestrator/experiment-runtime-identity.d.ts +0 -16
  235. package/lib/orchestrator/experiment-runtime-identity.d.ts.map +1 -1
  236. package/lib/orchestrator/experiment-runtime-identity.js +5 -220
  237. package/lib/orchestrator/experiment-runtime-identity.js.map +1 -1
  238. package/lib/orchestrator/experiment-selection.d.ts.map +1 -1
  239. package/lib/orchestrator/experiment-selection.js +52 -0
  240. package/lib/orchestrator/experiment-selection.js.map +1 -1
  241. package/lib/orchestrator/experiment.d.ts +0 -2
  242. package/lib/orchestrator/experiment.d.ts.map +1 -1
  243. package/lib/orchestrator/experiment.js +23 -15
  244. package/lib/orchestrator/experiment.js.map +1 -1
  245. package/lib/orchestrator/fs-read.d.ts +1 -6
  246. package/lib/orchestrator/fs-read.d.ts.map +1 -1
  247. package/lib/orchestrator/fs-read.js +2 -32
  248. package/lib/orchestrator/fs-read.js.map +1 -1
  249. package/lib/orchestrator/grader-experiment.d.ts +17 -1
  250. package/lib/orchestrator/grader-experiment.d.ts.map +1 -1
  251. package/lib/orchestrator/grader-experiment.js +52 -7
  252. package/lib/orchestrator/grader-experiment.js.map +1 -1
  253. package/lib/orchestrator/grading.d.ts.map +1 -1
  254. package/lib/orchestrator/grading.js +13 -6
  255. package/lib/orchestrator/grading.js.map +1 -1
  256. package/lib/orchestrator/list-runs.d.ts +1 -0
  257. package/lib/orchestrator/list-runs.d.ts.map +1 -1
  258. package/lib/orchestrator/list-runs.js +27 -6
  259. package/lib/orchestrator/list-runs.js.map +1 -1
  260. package/lib/orchestrator/optimization-lifecycle.d.ts.map +1 -1
  261. package/lib/orchestrator/optimization-lifecycle.js +3 -1
  262. package/lib/orchestrator/optimization-lifecycle.js.map +1 -1
  263. package/lib/orchestrator/orchestrator.d.ts +6 -1
  264. package/lib/orchestrator/orchestrator.d.ts.map +1 -1
  265. package/lib/orchestrator/orchestrator.js +17 -143
  266. package/lib/orchestrator/orchestrator.js.map +1 -1
  267. package/lib/orchestrator/paired-effects.d.ts +34 -0
  268. package/lib/orchestrator/paired-effects.d.ts.map +1 -0
  269. package/lib/orchestrator/paired-effects.js +158 -0
  270. package/lib/orchestrator/paired-effects.js.map +1 -0
  271. package/lib/orchestrator/provenance.d.ts +5 -1
  272. package/lib/orchestrator/provenance.d.ts.map +1 -1
  273. package/lib/orchestrator/provenance.js +16 -3
  274. package/lib/orchestrator/provenance.js.map +1 -1
  275. package/lib/orchestrator/regrade.d.ts +1 -0
  276. package/lib/orchestrator/regrade.d.ts.map +1 -1
  277. package/lib/orchestrator/run-execution.d.ts +2 -0
  278. package/lib/orchestrator/run-execution.d.ts.map +1 -1
  279. package/lib/orchestrator/run-execution.js +18 -3
  280. package/lib/orchestrator/run-execution.js.map +1 -1
  281. package/lib/orchestrator/run-lifecycle.d.ts +1 -0
  282. package/lib/orchestrator/run-lifecycle.d.ts.map +1 -1
  283. package/lib/orchestrator/run-lifecycle.js +3 -2
  284. package/lib/orchestrator/run-lifecycle.js.map +1 -1
  285. package/lib/orchestrator/suite-runs.d.ts +3 -1
  286. package/lib/orchestrator/suite-runs.d.ts.map +1 -1
  287. package/lib/orchestrator/suite-runs.js +12 -2
  288. package/lib/orchestrator/suite-runs.js.map +1 -1
  289. package/lib/orchestrator/suite-summary.d.ts.map +1 -1
  290. package/lib/orchestrator/suite-summary.js +2 -1
  291. package/lib/orchestrator/suite-summary.js.map +1 -1
  292. package/lib/previewer/server.d.ts +6 -0
  293. package/lib/previewer/server.d.ts.map +1 -1
  294. package/lib/previewer/server.js +21 -5
  295. package/lib/previewer/server.js.map +1 -1
  296. package/package.json +2 -2
  297. package/skills/lux/references/cli.md +5 -2
  298. package/skills/lux-answerer/SKILL.md +1 -1
  299. package/src/answerers/claude-code/index.ts +3 -3
  300. package/src/answerers/persona/index.ts +3 -3
  301. package/src/answerers/terminal/index.ts +4 -9
  302. package/src/assertions/core/resource-checks.ts +3 -5
  303. package/src/assertions/rubric/index.ts +7 -1
  304. package/src/assertions/rubric/internal.ts +13 -8
  305. package/src/authoring.ts +331 -2
  306. package/src/cli/bin.ts +2 -12
  307. package/src/cli/command-runtime.ts +20 -9
  308. package/src/cli/init-templates.ts +223 -0
  309. package/src/cli/init.ts +38 -184
  310. package/src/cli/output-schemas.ts +106 -0
  311. package/src/cli/program.ts +621 -548
  312. package/src/cli/render/reporter.ts +25 -4
  313. package/src/cli/run-options.ts +8 -25
  314. package/src/cli/view.ts +45 -84
  315. package/src/core/annotation.ts +2 -1
  316. package/src/core/answerer.ts +9 -0
  317. package/src/core/assertion.ts +3 -0
  318. package/src/core/case.ts +5 -1
  319. package/src/core/driver.ts +38 -0
  320. package/src/core/environment.ts +22 -0
  321. package/src/core/evaluation-clusters.ts +35 -0
  322. package/src/core/experiment.ts +60 -23
  323. package/src/core/file-tree.ts +35 -0
  324. package/src/core/index.ts +1 -0
  325. package/src/core/lifecycle-fixtures.ts +4 -2
  326. package/src/core/platform-process.ts +54 -6
  327. package/src/core/run.ts +20 -0
  328. package/src/core/usage.ts +8 -0
  329. package/src/drivers/claude-code/index.ts +34 -3
  330. package/src/drivers/codex/app-events.ts +43 -33
  331. package/src/drivers/codex/exec-events.ts +258 -0
  332. package/src/drivers/codex/index.ts +37 -262
  333. package/src/drivers/cursor/README.md +57 -0
  334. package/src/drivers/cursor/acp-transport.ts +182 -0
  335. package/src/drivers/cursor/config.ts +29 -0
  336. package/src/drivers/cursor/events.ts +83 -0
  337. package/src/drivers/cursor/index.ts +316 -0
  338. package/src/drivers/cursor/interaction.ts +90 -0
  339. package/src/drivers/mcp/index.ts +16 -3
  340. package/src/drivers/shared/experiment-behavior.ts +214 -0
  341. package/src/drivers/shared/experiment-policy.ts +195 -0
  342. package/src/drivers/subprocess/index.ts +45 -6
  343. package/src/index.ts +16 -0
  344. package/src/orchestrator/annotation-loader.ts +10 -0
  345. package/src/orchestrator/annotation-store.ts +24 -3
  346. package/src/orchestrator/campaign-lifecycle.ts +5 -1
  347. package/src/orchestrator/compare.ts +16 -1
  348. package/src/orchestrator/comparison-identity.ts +1 -0
  349. package/src/orchestrator/config.ts +6 -0
  350. package/src/orchestrator/discover.ts +8 -1
  351. package/src/orchestrator/doctor.ts +40 -22
  352. package/src/orchestrator/driver-capabilities.ts +16 -0
  353. package/src/orchestrator/driver-identity.ts +59 -0
  354. package/src/orchestrator/experiment-corpus.ts +23 -28
  355. package/src/orchestrator/experiment-effects.ts +61 -0
  356. package/src/orchestrator/experiment-evaluation.ts +45 -5
  357. package/src/orchestrator/experiment-identity.ts +27 -36
  358. package/src/orchestrator/experiment-report.ts +21 -1
  359. package/src/orchestrator/experiment-runs.ts +11 -4
  360. package/src/orchestrator/experiment-runtime-identity.ts +5 -243
  361. package/src/orchestrator/experiment-selection.ts +77 -0
  362. package/src/orchestrator/experiment.ts +26 -24
  363. package/src/orchestrator/fs-read.ts +2 -32
  364. package/src/orchestrator/grader-experiment.ts +72 -8
  365. package/src/orchestrator/grading.ts +15 -6
  366. package/src/orchestrator/list-runs.ts +29 -6
  367. package/src/orchestrator/optimization-lifecycle.ts +4 -1
  368. package/src/orchestrator/orchestrator.ts +26 -183
  369. package/src/orchestrator/paired-effects.ts +209 -0
  370. package/src/orchestrator/provenance.ts +23 -3
  371. package/src/orchestrator/run-execution.ts +18 -3
  372. package/src/orchestrator/run-lifecycle.ts +4 -2
  373. package/src/orchestrator/suite-runs.ts +10 -1
  374. package/src/orchestrator/suite-summary.ts +2 -1
  375. package/src/previewer/server.ts +27 -5
  376. package/viewer/app.js +27 -6
  377. package/viewer/detail.js +22 -5
  378. package/lib/cli/skills.d.ts +0 -38
  379. package/lib/cli/skills.d.ts.map +0 -1
  380. package/lib/cli/skills.js +0 -84
  381. package/lib/cli/skills.js.map +0 -1
  382. package/src/cli/skills.ts +0 -129
@@ -0,0 +1,223 @@
1
+ type StarterDriver = "subprocess" | "claude-code" | "codex" | "cursor";
2
+
3
+ export const luxConfigBody = (
4
+ withExperiment: boolean,
5
+ driver?: StarterDriver,
6
+ model?: string,
7
+ ): string => {
8
+ const subjectRoot = withExperiment ? ' subjectRoot: ".",\n' : "";
9
+ const profiles = withExperiment ? " profiles: { starter: {} },\n" : "";
10
+ const selectedDriver = driver ?? (withExperiment ? undefined : "subprocess");
11
+ const modelField = model ? `model: ${JSON.stringify(model)}, ` : "";
12
+ let defaultDriver: string;
13
+ if (selectedDriver === "subprocess") {
14
+ defaultDriver = ` defaultDriver: { name: "subprocess", config: {
15
+ command: process.execPath,
16
+ args: [fileURLToPath(new URL("./agent/demo.mjs", import.meta.url))],
17
+ inheritEnv: false,
18
+ } },
19
+ `;
20
+ } else if (selectedDriver) {
21
+ const efforts = { "claude-code": 'effort: "low"', codex: 'reasoningEffort: "low"', cursor: "" };
22
+ defaultDriver = ` defaultDriver: { name: ${JSON.stringify(selectedDriver)}, config: { ${modelField}${efforts[selectedDriver]} } },
23
+ `;
24
+ } else {
25
+ defaultDriver = ` // Select a driver with lux init --experiment --driver codex --force.
26
+ // defaultDriver: { name: "codex", config: { reasoningEffort: "low" } },
27
+ `;
28
+ }
29
+ return `${selectedDriver === "subprocess" ? 'import { fileURLToPath } from "node:url";\n' : ""}import type { LuxConfig } from "@prismatic-io/lux";
30
+
31
+ /**
32
+ * Lux project configuration. Drivers, answerers, and assertions
33
+ * register here; \`lux run\` discovers cases under \`casesRoot\`.
34
+ */
35
+ const config: LuxConfig = {
36
+ casesRoot: "./cases",
37
+ fixturesRoot: "./fixtures",
38
+ runsRoot: "./.lux-runs",
39
+ ${subjectRoot} // Runners default to cheap models and low effort instead of inheriting CLI defaults.
40
+ ${defaultDriver} // Persona answerers and rubric judges default to cheap models and low effort.
41
+ // Override both explicitly when a stronger harness is worth the added cost:
42
+ // harness: { provider: "codex", model: "YOUR_HARNESS_MODEL" },
43
+ defaultAnswerer: "persona",
44
+ ${profiles} // drivers: [/* register drivers here */],
45
+ // answerers: [/* register answerers here */],
46
+ // assertions: [/* register custom assertions here */],
47
+ };
48
+
49
+ export default config;
50
+ `;
51
+ };
52
+
53
+ export const DEMO_AGENT_BODY = `import { writeFile } from "node:fs/promises";
54
+ import { join } from "node:path";
55
+
56
+ const send = (event) => process.stdout.write(JSON.stringify(event) + "\\n");
57
+ send({ type: "ready", agentId: "addition-demo" });
58
+ await writeFile(join(process.env.LUX_ARTIFACTS_DIR, "add.mjs"), "export const add = (a, b) => a + b;\\n");
59
+ send({ type: "done", summary: "Wrote add.mjs" });
60
+ `;
61
+
62
+ const ADDITION_COMMAND = `node --input-type=module -e "import assert from 'node:assert/strict'; import { add } from './add.mjs'; assert.equal(add(2, 3), 5); assert.equal(add(-2, 2), 0); assert.equal(add(0, 0), 0);"`;
63
+
64
+ export const SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
65
+
66
+ export default defineEvalCase({
67
+ id: "addition",
68
+ prompt: "Write add.mjs exporting add(a, b). It must add two numbers, including negative numbers and zero.",
69
+ assertions: [
70
+ { id: "completed", type: "run-succeeded" },
71
+ { id: "module-written", type: "file-exists", path: "add.mjs" },
72
+ {
73
+ id: "adds-correctly",
74
+ type: "command-exits-zero",
75
+ command: ${JSON.stringify(ADDITION_COMMAND)},
76
+ },
77
+ ],
78
+ });
79
+ `;
80
+
81
+ export const EXPERIMENT_SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
82
+
83
+ /**
84
+ * A starter smoke case. It inherits the default driver from lux.config.ts.
85
+ */
86
+ export default defineEvalCase({
87
+ id: "hello-world",
88
+ prompt: "Say hello to the world.",
89
+ assertions: [{ id: "completed", type: "run-succeeded" }],
90
+ });
91
+ `;
92
+
93
+ export const README_BODY = `# Lux evals
94
+
95
+ This directory holds your evaluation cases.
96
+
97
+ ## Layout
98
+
99
+ - \`lux.config.ts\` — project configuration: default driver/answerer and registered plugins.
100
+ - \`cases/\` — one TypeScript file per eval case. Default-export a \`defineEvalCase({...})\`.
101
+ - \`fixtures/\` — starting state for cases that need pre-staged input.
102
+ - \`.lux-runs/\` — run output, gitignored.
103
+
104
+ ## Setup
105
+
106
+ Install Lux in the project so authored TypeScript cases can resolve its API:
107
+
108
+ \`\`\`bash
109
+ npm install --save-dev @prismatic-io/lux
110
+ \`\`\`
111
+
112
+ ## First result
113
+
114
+ The default starter uses a local deterministic agent and makes no model calls.
115
+ Run \`npm exec -- lux run\`, then \`npm exec -- lux view\` to inspect its
116
+ artifact and behavioral assertions. In \`agent/demo.mjs\`, replace \`a + b\`
117
+ with \`a - b\` and run again: the agent completes, but the behavioral assertion
118
+ fails. Restore addition and rerun to see it pass.
119
+
120
+ For a real coding agent, scaffold with \`lux init --driver claude-code\` or
121
+ \`lux init --driver codex\`. Cursor requires an explicit model:
122
+ \`lux init --driver cursor --model <model-id>\`. These modes make model calls
123
+ when you run cases and require the corresponding authenticated CLI.
124
+
125
+ ## Run cases
126
+
127
+ \`lux run\` discovers every case under \`casesRoot\` and runs it. Filter by
128
+ name/path substring, by \`--tag\`, or repeat each matched eval with \`--loop\`:
129
+
130
+ \`\`\`bash
131
+ npm exec -- lux run # every discovered case
132
+ npm exec -- lux run addition # cases whose id/path contains "hello-world"
133
+ npm exec -- lux run cases/addition.ts # one file directly
134
+ npm exec -- lux run --tag smoke # cases tagged "smoke" (meta.tags)
135
+ npm exec -- lux run --loop 5 # run each matched eval 5 times
136
+ \`\`\`
137
+
138
+ See the [Lux docs](https://github.com/prismatic-io/lux) for the full design.
139
+ `;
140
+
141
+ export const STARTER_PROMPT_BODY = `# Starter agent instructions
142
+
143
+ Complete the requested task and verify the result. Ask for clarification when
144
+ missing information changes the correct outcome.
145
+ `;
146
+
147
+ export const experimentCaseBody = (
148
+ id: string,
149
+ split: "train" | "validation" | "test",
150
+ task: string,
151
+ ): string => {
152
+ const checks = {
153
+ train: "assert.equal(result(2, 3), 5); assert.equal(result(-2, 2), 0)",
154
+ validation:
155
+ "assert.equal(result(12, 0, 10), 10); assert.equal(result(-1, 0, 10), 0); assert.equal(result(5, 0, 10), 5)",
156
+ test: "assert.equal(result(' Lux REVIEW '), 'lux review'); assert.equal(result(''), '')",
157
+ };
158
+ const command = `node --input-type=module -e "import assert from 'node:assert/strict'; import { result } from './result.mjs'; ${checks[split]};"`;
159
+ return `import { defineEvalCase, subjectPath } from "@prismatic-io/lux";
160
+
161
+ export default defineEvalCase({
162
+ id: ${JSON.stringify(id)},
163
+ prompt: [
164
+ \`Read \${subjectPath("prompts/agent.md")} and use it as task guidance.\`,
165
+ ${JSON.stringify(task)},
166
+ ].join("\\n\\n"),
167
+ assertions: [
168
+ { id: "completed", type: "run-succeeded" },
169
+ { id: "behavior", type: "command-exits-zero", command: ${JSON.stringify(command)} },
170
+ ],
171
+ meta: { tags: [${JSON.stringify(split)}] },
172
+ });
173
+ `;
174
+ };
175
+
176
+ export const STARTER_EXPERIMENT_BODY = `import { defineExperiment } from "@prismatic-io/lux";
177
+
178
+ export default defineExperiment({
179
+ id: "starter-agent-improvement",
180
+ subject: {
181
+ root: "..",
182
+ mutable: ["prompts/agent.md"],
183
+ },
184
+ profiles: ["starter"],
185
+ splits: {
186
+ train: { tags: ["train"] },
187
+ validation: { tags: ["validation"] },
188
+ test: { tags: ["test"] },
189
+ },
190
+ repetitions: { search: 1, promotion: 2 },
191
+ objectives: {
192
+ constraints: [
193
+ { metric: "quality.passRate", min: 1 },
194
+ { metric: "quality.passRate", min: 1, split: "test" },
195
+ { metric: "quality.caseRegressions", max: 0 },
196
+ { metric: "quality.caseRegressions", max: 0, split: "test" },
197
+ ],
198
+ minimize: [
199
+ { metric: "agent.total" },
200
+ { metric: "subject.bytes" },
201
+ ],
202
+ },
203
+ optimizer: {
204
+ algorithm: "reflective",
205
+ config: {
206
+ provider: "claude-code",
207
+ model: "YOUR_OPTIMIZER_MODEL",
208
+ reasoningEffort: "low",
209
+ },
210
+ },
211
+ budget: {
212
+ maxCandidates: 4,
213
+ patience: 1,
214
+ maxMetricCalls: 40,
215
+ maxJudgeCalls: 40,
216
+ maxProposalCalls: 3,
217
+ maxTokens: 1_000_000,
218
+ maxCostUsd: 25,
219
+ maxUnpricedModelCalls: 25,
220
+ maxWallTimeMs: 1_800_000,
221
+ },
222
+ });
223
+ `;
package/src/cli/init.ts CHANGED
@@ -2,14 +2,34 @@ import { randomUUID } from "node:crypto";
2
2
  import { constants, lstat, mkdir, open, realpath, rename, rm, writeFile } from "node:fs/promises";
3
3
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
4
  import { z } from "zod";
5
+ import {
6
+ DEMO_AGENT_BODY,
7
+ EXPERIMENT_SAMPLE_CASE_BODY,
8
+ experimentCaseBody,
9
+ luxConfigBody,
10
+ README_BODY,
11
+ SAMPLE_CASE_BODY,
12
+ STARTER_EXPERIMENT_BODY,
13
+ STARTER_PROMPT_BODY,
14
+ } from "./init-templates.js";
5
15
 
6
16
  const InitOptionsSchema = z
7
17
  .object({
8
18
  cwd: z.string().min(1),
9
19
  force: z.boolean().default(false),
10
20
  experiment: z.boolean().default(false),
21
+ driver: z.enum(["subprocess", "claude-code", "codex", "cursor"]).optional(),
22
+ model: z.string().min(1).optional(),
11
23
  })
12
- .strict();
24
+ .strict()
25
+ .refine((options) => options.driver !== "cursor" || options.model !== undefined, {
26
+ path: ["model"],
27
+ message: "Cursor requires an explicit --model",
28
+ })
29
+ .refine((options) => !(options.experiment && options.driver === "subprocess"), {
30
+ path: ["driver"],
31
+ message: "The deterministic starter is for runs; choose a coding agent for experiments",
32
+ });
13
33
  type InitOptions = z.input<typeof InitOptionsSchema>;
14
34
 
15
35
  const InitResultSchema = z
@@ -133,181 +153,6 @@ const appendGitignoreEntry = async (
133
153
  else result.updated.push(path);
134
154
  };
135
155
 
136
- const luxConfigBody = (withExperiment: boolean): string => {
137
- const subjectRoot = withExperiment ? ' subjectRoot: ".",\n' : "";
138
- const profiles = withExperiment ? " profiles: { starter: {} },\n" : "";
139
- const defaultDriver = withExperiment
140
- ? ` // Choose one driver before running the scaffold.
141
- // defaultDriver: { name: "codex", config: { model: "YOUR_CODEX_MODEL", reasoningEffort: "high" } },
142
- // defaultDriver: { name: "claude-code", config: { model: "YOUR_CLAUDE_MODEL", effort: "high" } },
143
- `
144
- : ` // The subprocess command must implement Lux's lux-jsonl protocol.
145
- // Replace this entire object when using the built-in Codex or Claude Code driver.
146
- defaultDriver: { name: "subprocess", config: { command: "your-agent-cli" } },
147
- `;
148
- return `import type { LuxConfig } from "@prismatic-io/lux";
149
-
150
- /**
151
- * Lux project configuration. Drivers, answerers, and assertions
152
- * register here; \`lux run\` discovers cases under \`casesRoot\`.
153
- */
154
- const config: LuxConfig = {
155
- casesRoot: "./cases",
156
- fixturesRoot: "./fixtures",
157
- runsRoot: "./.lux-runs",
158
- ${subjectRoot} // Runners default to cheap models and low effort instead of inheriting CLI defaults.
159
- ${defaultDriver} // Persona answerers and rubric judges default to cheap models and low effort.
160
- // Override both explicitly when a stronger harness is worth the added cost:
161
- // harness: { provider: "codex", model: "YOUR_HARNESS_MODEL" },
162
- defaultAnswerer: "persona",
163
- ${profiles} // drivers: [/* register drivers here */],
164
- // answerers: [/* register answerers here */],
165
- // assertions: [/* register custom assertions here */],
166
- };
167
-
168
- export default config;
169
- `;
170
- };
171
-
172
- const SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
173
-
174
- /**
175
- * A starter case. It inherits defaultDriver from lux.config.ts.
176
- * Replace the prompt and persona to match the behavior you need.
177
- */
178
- export default defineEvalCase({
179
- id: "hello-world",
180
- prompt: "Say hello to the world.",
181
- persona: "You are a friendly developer. Keep answers short.",
182
- assertions: [
183
- { id: "completed", type: "run-succeeded" },
184
- // { type: "contains", text: "hello" },
185
- // { type: "command-exits-zero", command: "echo done" },
186
- ],
187
- });
188
- `;
189
-
190
- const EXPERIMENT_SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
191
-
192
- /**
193
- * A starter smoke case. It inherits the default driver from lux.config.ts.
194
- */
195
- export default defineEvalCase({
196
- id: "hello-world",
197
- prompt: "Say hello to the world.",
198
- assertions: [{ id: "completed", type: "run-succeeded" }],
199
- });
200
- `;
201
-
202
- const README_BODY = `# Lux evals
203
-
204
- This directory holds your evaluation cases.
205
-
206
- ## Layout
207
-
208
- - \`lux.config.ts\` — project configuration: default driver/answerer and registered plugins.
209
- - \`cases/\` — one TypeScript file per eval case. Default-export a \`defineEvalCase({...})\`.
210
- - \`fixtures/\` — starting state for cases that need pre-staged input.
211
- - \`.lux-runs/\` — run output, gitignored.
212
-
213
- ## Setup
214
-
215
- Install Lux in the project so authored TypeScript cases can resolve its API:
216
-
217
- \`\`\`bash
218
- npm install --save-dev @prismatic-io/lux
219
- \`\`\`
220
-
221
- ## Run cases
222
-
223
- \`lux run\` discovers every case under \`casesRoot\` and runs it. Filter by
224
- name/path substring, by \`--tag\`, or repeat each matched eval with \`--loop\`:
225
-
226
- \`\`\`bash
227
- npm exec -- lux run # every discovered case
228
- npm exec -- lux run hello-world # cases whose id/path contains "hello-world"
229
- npm exec -- lux run cases/hello-world.ts # one file directly
230
- npm exec -- lux run --tag smoke # cases tagged "smoke" (meta.tags)
231
- npm exec -- lux run --loop 5 # run each matched eval 5 times
232
- \`\`\`
233
-
234
- See the [Lux docs](https://github.com/prismatic-io/lux) for the full design.
235
- `;
236
-
237
- const STARTER_PROMPT_BODY = `# Starter agent instructions
238
-
239
- Complete the requested task directly. Prefer deterministic work, use the fewest
240
- tools needed, and ask a question only when proceeding would be unsafe.
241
- `;
242
-
243
- const experimentCaseBody = (
244
- id: string,
245
- split: "train" | "validation" | "test",
246
- task: string,
247
- ): string => `import { defineEvalCase, subjectPath } from "@prismatic-io/lux";
248
-
249
- export default defineEvalCase({
250
- id: ${JSON.stringify(id)},
251
- prompt: [
252
- \`Read \${subjectPath("prompts/agent.md")} and follow it as the system instructions.\`,
253
- ${JSON.stringify(task)},
254
- ].join("\\n\\n"),
255
- assertions: [{ id: "completed", type: "run-succeeded" }],
256
- meta: { tags: [${JSON.stringify(split)}] },
257
- });
258
- `;
259
-
260
- const STARTER_EXPERIMENT_BODY = `import { defineExperiment } from "@prismatic-io/lux";
261
-
262
- export default defineExperiment({
263
- id: "starter-agent-improvement",
264
- subject: {
265
- root: "..",
266
- mutable: ["prompts/agent.md"],
267
- },
268
- profiles: ["starter"],
269
- splits: {
270
- train: { tags: ["train"] },
271
- validation: { tags: ["validation"] },
272
- test: { tags: ["test"] },
273
- },
274
- repetitions: { search: 1, promotion: 2 },
275
- objectives: {
276
- constraints: [
277
- { metric: "quality.passRate", min: 1 },
278
- { metric: "quality.passRate", min: 1, split: "test" },
279
- { metric: "quality.caseRegressions", max: 0 },
280
- { metric: "quality.caseRegressions", max: 0, split: "test" },
281
- ],
282
- minimize: [
283
- { metric: "agent.total" },
284
- { metric: "interrupts.ask" },
285
- { metric: "toolCalls" },
286
- { metric: "subject.bytes" },
287
- ],
288
- },
289
- optimizer: {
290
- algorithm: "reflective",
291
- config: {
292
- provider: "claude-code",
293
- model: "YOUR_OPTIMIZER_MODEL",
294
- reasoningEffort: "low",
295
- },
296
- },
297
- budget: {
298
- maxCandidates: 4,
299
- patience: 1,
300
- maxMetricCalls: 40,
301
- maxJudgeCalls: 40,
302
- maxProposalCalls: 3,
303
- maxTokens: 1_000_000,
304
- maxCostUsd: 25,
305
- maxUnpricedModelCalls: 25,
306
- maxWallTimeMs: 1_800_000,
307
- },
308
- });
309
- `;
310
-
311
156
  export const initProject = async (options: InitOptions): Promise<InitResult> => {
312
157
  const parsedOptions = InitOptionsSchema.parse(options);
313
158
  const experiment = parsedOptions.experiment;
@@ -317,14 +162,23 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
317
162
  await mkdir(parsedOptions.cwd, { recursive: true });
318
163
  const root = await realpath(parsedOptions.cwd);
319
164
 
320
- await writeIfMissing(root, join(root, "lux.config.ts"), luxConfigBody(experiment), result, force);
321
165
  await writeIfMissing(
322
166
  root,
323
- join(root, "cases", "hello-world.ts"),
167
+ join(root, "lux.config.ts"),
168
+ luxConfigBody(experiment, parsedOptions.driver, parsedOptions.model),
169
+ result,
170
+ force,
171
+ );
172
+ await writeIfMissing(
173
+ root,
174
+ join(root, "cases", experiment ? "hello-world.ts" : "addition.ts"),
324
175
  experiment ? EXPERIMENT_SAMPLE_CASE_BODY : SAMPLE_CASE_BODY,
325
176
  result,
326
177
  force,
327
178
  );
179
+ if (!experiment && (!parsedOptions.driver || parsedOptions.driver === "subprocess")) {
180
+ await writeIfMissing(root, join(root, "agent", "demo.mjs"), DEMO_AGENT_BODY, result, force);
181
+ }
328
182
  await writeIfMissing(root, join(root, "fixtures", ".gitkeep"), "", result, force);
329
183
  // README is the user's to evolve once it exists; `--force` refreshes only
330
184
  // the lux-owned scaffold files, never a hand-edited README.
@@ -344,7 +198,7 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
344
198
  experimentCaseBody(
345
199
  "starter/train",
346
200
  "train",
347
- "Complete the representative training task and summarize the result.",
201
+ "Write result.mjs exporting result(a, b), which adds two numbers including negative numbers.",
348
202
  ),
349
203
  result,
350
204
  force,
@@ -355,7 +209,7 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
355
209
  experimentCaseBody(
356
210
  "starter/validation",
357
211
  "validation",
358
- "Complete an independently designed validation task and summarize the result.",
212
+ "Write result.mjs exporting result(value, min, max), which clamps a number to the inclusive bounds.",
359
213
  ),
360
214
  result,
361
215
  force,
@@ -366,7 +220,7 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
366
220
  experimentCaseBody(
367
221
  "starter/test",
368
222
  "test",
369
- "Complete the final held-out task and summarize the result.",
223
+ "Write result.mjs exporting result(text), which trims surrounding whitespace and lowercases the text.",
370
224
  ),
371
225
  result,
372
226
  force,
@@ -397,14 +251,14 @@ export const formatInitReport = (result: InitResult, cwd: string): string => {
397
251
  lines.push("");
398
252
  lines.push("Next steps:");
399
253
  lines.push(" 1. Install @prismatic-io/lux in this project if it is not already present.");
400
- lines.push(" 2. Edit lux.config.ts to choose a driver.");
254
+ lines.push(" 2. Review lux.config.ts and the selected driver.");
401
255
  if (result.experiment) {
402
256
  lines.push(" 3. Replace the starter prompt and split cases with representative evidence.");
403
257
  lines.push(" 4. lux doctor");
404
258
  lines.push(" 5. lux optimize experiments/starter.optimize.ts --plan");
405
259
  } else {
406
- lines.push(" 3. Edit cases/hello-world.ts with a real prompt.");
407
- lines.push(" 4. lux run");
260
+ lines.push(" 3. lux run");
261
+ lines.push(" 4. lux view");
408
262
  }
409
263
  return lines.join("\n");
410
264
  };
@@ -0,0 +1,106 @@
1
+ import { z } from "incur";
2
+ import {
3
+ ActionTimingSchema,
4
+ AgentActivitySchema,
5
+ DriverMetricsSchema,
6
+ GradingReportSchema,
7
+ PersistedCaseSchema,
8
+ RunEventSchema,
9
+ RunMetadataSchema,
10
+ RunUsageSchema,
11
+ } from "../core/index.js";
12
+ import {
13
+ ExperimentRunSchema,
14
+ SuiteComparisonSchema,
15
+ SuiteRunSchema,
16
+ } from "../orchestrator/index.js";
17
+
18
+ const nullableNumber = z.number().nullable();
19
+ const listedRun = z.object({
20
+ caseSlug: z.string(),
21
+ driverName: z.string(),
22
+ ts: z.string(),
23
+ runDir: z.string(),
24
+ exitReason: RunMetadataSchema.shape.exitReason.nullable(),
25
+ driverAgentId: z.string().nullable(),
26
+ startedAt: z.string().nullable(),
27
+ endedAt: z.string().nullable(),
28
+ durationMs: nullableNumber,
29
+ timeToFirstActionMs: nullableNumber,
30
+ timeToFirstMutationMs: nullableNumber,
31
+ timeToFirstDurableMutationMs: nullableNumber,
32
+ driverMetrics: DriverMetricsSchema,
33
+ subagentCount: z.number(),
34
+ casePassed: z.boolean().nullable(),
35
+ caseScore: nullableNumber,
36
+ assertionPassed: z.number(),
37
+ assertionTotal: z.number(),
38
+ readErrors: z.array(z.string()).optional(),
39
+ });
40
+ const suite = SuiteRunSchema.extend({ suiteDir: z.string() });
41
+ const experiment = ExperimentRunSchema.extend({ experimentDir: z.string() });
42
+ const listing = z.object({
43
+ runsRoot: z.string(),
44
+ readErrors: z.array(z.object({ path: z.string(), message: z.string() })).optional(),
45
+ });
46
+ export const ViewOutputSchema = z.union([
47
+ z.object({
48
+ runDir: z.string(),
49
+ case: PersistedCaseSchema.nullable(),
50
+ metadata: RunMetadataSchema.nullable(),
51
+ grading: GradingReportSchema.nullable(),
52
+ events: z.array(RunEventSchema),
53
+ artifacts: z.array(z.string()),
54
+ }),
55
+ suite,
56
+ experiment,
57
+ listing.extend({ runs: z.array(listedRun), suites: z.array(suite).optional() }),
58
+ listing.extend({ suites: z.array(suite) }),
59
+ listing.extend({ experiments: z.array(experiment) }),
60
+ z.object({ url: z.string(), runsRoot: z.string() }),
61
+ ]);
62
+ const interrupts = z.object({ ask: z.number(), approve: z.number(), custom: z.number() });
63
+ const verdict = z.object({ passed: z.boolean(), score: z.number() }).nullable();
64
+ const runComparison = z.object({
65
+ pathA: z.string(),
66
+ pathB: z.string(),
67
+ caseMismatch: z.array(z.object({ field: z.string(), a: z.unknown(), b: z.unknown() })),
68
+ runDelta: z
69
+ .object({
70
+ exitReason: z.object({ a: z.string(), b: z.string() }),
71
+ durationMsA: nullableNumber,
72
+ durationMsB: nullableNumber,
73
+ actionTiming: z.object({ a: ActionTimingSchema, b: ActionTimingSchema }),
74
+ driverMetrics: z.object({ a: DriverMetricsSchema, b: DriverMetricsSchema }),
75
+ agentActivity: z.object({ a: z.array(AgentActivitySchema), b: z.array(AgentActivitySchema) }),
76
+ interruptCounts: z.object({ a: interrupts, b: interrupts }),
77
+ usage: z.object({ a: RunUsageSchema, b: RunUsageSchema }),
78
+ agentUsageAvailable: z.object({ a: z.boolean(), b: z.boolean() }).optional(),
79
+ })
80
+ .nullable(),
81
+ grading: z.object({
82
+ casePassedA: z.boolean().nullable(),
83
+ casePassedB: z.boolean().nullable(),
84
+ caseScoreA: nullableNumber,
85
+ caseScoreB: nullableNumber,
86
+ deltas: z.array(
87
+ z.object({
88
+ id: z.string(),
89
+ type: z.string(),
90
+ name: z.string(),
91
+ before: verdict,
92
+ after: verdict,
93
+ status: z.enum(["added", "removed", "improved", "regressed", "unchanged"]),
94
+ }),
95
+ ),
96
+ improvements: z.number(),
97
+ regressions: z.number(),
98
+ }),
99
+ artifactsDelta: z.object({
100
+ added: z.array(z.string()),
101
+ removed: z.array(z.string()),
102
+ changed: z.array(z.string()),
103
+ unchanged: z.array(z.string()),
104
+ }),
105
+ });
106
+ export const CompareOutputSchema = z.union([SuiteComparisonSchema, runComparison]);