@prismatic-io/lux 0.0.2-preview.14 → 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 (388) 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 -5
  167. package/lib/index.d.ts.map +1 -1
  168. package/lib/index.js +4 -3
  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 -2
  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/references/eval-authoring.md +0 -7
  299. package/skills/lux-answerer/SKILL.md +1 -1
  300. package/src/answerers/claude-code/index.ts +3 -3
  301. package/src/answerers/persona/index.ts +3 -3
  302. package/src/answerers/terminal/index.ts +4 -9
  303. package/src/assertions/core/resource-checks.ts +3 -5
  304. package/src/assertions/rubric/index.ts +7 -1
  305. package/src/assertions/rubric/internal.ts +13 -8
  306. package/src/authoring.ts +331 -2
  307. package/src/cli/bin.ts +2 -12
  308. package/src/cli/command-runtime.ts +20 -9
  309. package/src/cli/init-templates.ts +223 -0
  310. package/src/cli/init.ts +38 -184
  311. package/src/cli/output-schemas.ts +106 -0
  312. package/src/cli/program.ts +621 -548
  313. package/src/cli/render/reporter.ts +25 -4
  314. package/src/cli/run-options.ts +8 -25
  315. package/src/cli/view.ts +45 -84
  316. package/src/core/annotation.ts +2 -1
  317. package/src/core/answerer.ts +9 -0
  318. package/src/core/assertion.ts +3 -0
  319. package/src/core/case.ts +5 -1
  320. package/src/core/driver.ts +38 -0
  321. package/src/core/environment.ts +22 -0
  322. package/src/core/evaluation-clusters.ts +35 -0
  323. package/src/core/experiment.ts +60 -23
  324. package/src/core/file-tree.ts +35 -0
  325. package/src/core/index.ts +1 -0
  326. package/src/core/lifecycle-fixtures.ts +4 -2
  327. package/src/core/platform-process.ts +54 -6
  328. package/src/core/run.ts +20 -0
  329. package/src/core/usage.ts +8 -0
  330. package/src/drivers/claude-code/index.ts +34 -3
  331. package/src/drivers/codex/app-events.ts +43 -33
  332. package/src/drivers/codex/exec-events.ts +258 -0
  333. package/src/drivers/codex/index.ts +37 -262
  334. package/src/drivers/cursor/README.md +57 -0
  335. package/src/drivers/cursor/acp-transport.ts +182 -0
  336. package/src/drivers/cursor/config.ts +29 -0
  337. package/src/drivers/cursor/events.ts +83 -0
  338. package/src/drivers/cursor/index.ts +316 -0
  339. package/src/drivers/cursor/interaction.ts +90 -0
  340. package/src/drivers/mcp/index.ts +16 -3
  341. package/src/drivers/shared/experiment-behavior.ts +214 -0
  342. package/src/drivers/shared/experiment-policy.ts +195 -0
  343. package/src/drivers/subprocess/index.ts +45 -6
  344. package/src/index.ts +16 -5
  345. package/src/orchestrator/annotation-loader.ts +10 -0
  346. package/src/orchestrator/annotation-store.ts +24 -3
  347. package/src/orchestrator/campaign-lifecycle.ts +5 -1
  348. package/src/orchestrator/compare.ts +16 -1
  349. package/src/orchestrator/comparison-identity.ts +1 -0
  350. package/src/orchestrator/config.ts +6 -2
  351. package/src/orchestrator/discover.ts +8 -1
  352. package/src/orchestrator/doctor.ts +40 -22
  353. package/src/orchestrator/driver-capabilities.ts +16 -0
  354. package/src/orchestrator/driver-identity.ts +59 -0
  355. package/src/orchestrator/experiment-corpus.ts +23 -28
  356. package/src/orchestrator/experiment-effects.ts +61 -0
  357. package/src/orchestrator/experiment-evaluation.ts +45 -5
  358. package/src/orchestrator/experiment-identity.ts +27 -36
  359. package/src/orchestrator/experiment-report.ts +21 -1
  360. package/src/orchestrator/experiment-runs.ts +11 -4
  361. package/src/orchestrator/experiment-runtime-identity.ts +5 -243
  362. package/src/orchestrator/experiment-selection.ts +77 -0
  363. package/src/orchestrator/experiment.ts +26 -24
  364. package/src/orchestrator/fs-read.ts +2 -32
  365. package/src/orchestrator/grader-experiment.ts +72 -8
  366. package/src/orchestrator/grading.ts +15 -6
  367. package/src/orchestrator/list-runs.ts +29 -6
  368. package/src/orchestrator/optimization-lifecycle.ts +4 -1
  369. package/src/orchestrator/orchestrator.ts +26 -183
  370. package/src/orchestrator/paired-effects.ts +209 -0
  371. package/src/orchestrator/provenance.ts +23 -3
  372. package/src/orchestrator/run-execution.ts +18 -3
  373. package/src/orchestrator/run-lifecycle.ts +4 -2
  374. package/src/orchestrator/suite-runs.ts +10 -1
  375. package/src/orchestrator/suite-summary.ts +2 -1
  376. package/src/previewer/server.ts +27 -5
  377. package/viewer/app.js +27 -6
  378. package/viewer/detail.js +22 -5
  379. package/lib/answerers/scripted/index.d.ts +0 -18
  380. package/lib/answerers/scripted/index.d.ts.map +0 -1
  381. package/lib/answerers/scripted/index.js +0 -63
  382. package/lib/answerers/scripted/index.js.map +0 -1
  383. package/lib/cli/skills.d.ts +0 -38
  384. package/lib/cli/skills.d.ts.map +0 -1
  385. package/lib/cli/skills.js +0 -84
  386. package/lib/cli/skills.js.map +0 -1
  387. package/src/answerers/scripted/index.ts +0 -78
  388. package/src/cli/skills.ts +0 -129
@@ -51,6 +51,7 @@ const activateFixture = async <Context extends SuiteLifecycleHookContext>(
51
51
  let useObservations = 0;
52
52
  let settled = false;
53
53
  let completionError: unknown;
54
+ let failed = false;
54
55
  const completion = (async () => {
55
56
  try {
56
57
  await fixture(context, () => {
@@ -80,6 +81,7 @@ const activateFixture = async <Context extends SuiteLifecycleHookContext>(
80
81
  }
81
82
  } catch (error) {
82
83
  completionError = error;
84
+ failed = true;
83
85
  if (useObservations === 0) rejectSetup?.(error);
84
86
  } finally {
85
87
  settled = true;
@@ -90,7 +92,7 @@ const activateFixture = async <Context extends SuiteLifecycleHookContext>(
90
92
  await Promise.resolve();
91
93
  if (settled) {
92
94
  throw new TypeError(
93
- completionError
95
+ failed
94
96
  ? `${label} failed before its lifetime began: ${errorMessage(completionError)}`
95
97
  : `${label} must await use()`,
96
98
  { cause: completionError },
@@ -103,7 +105,7 @@ const activateFixture = async <Context extends SuiteLifecycleHookContext>(
103
105
  cleaned = true;
104
106
  releaseUse?.();
105
107
  await completion;
106
- if (completionError) throw completionError;
108
+ if (failed) throw completionError;
107
109
  };
108
110
  };
109
111
 
@@ -175,10 +175,29 @@ const signalPosixGroup = (child: ChildProcess, signal: NodeJS.Signals): void =>
175
175
  }
176
176
  };
177
177
 
178
+ const windowsAncestorPids = (
179
+ processes: readonly IProcessInfo[],
180
+ owner: { pid: number; ppid: number },
181
+ ): Set<number> => {
182
+ // Windows retains historical parent PIDs; reuse can make unrelated live
183
+ // processes appear beneath a new child. Never reap the caller's own ancestry.
184
+ const protectedPids = new Set([owner.pid]);
185
+ const byPid = new Map(processes.map((entry) => [entry.pid, entry]));
186
+ let ancestorPid = owner.ppid;
187
+ while (ancestorPid > 0 && !protectedPids.has(ancestorPid)) {
188
+ protectedPids.add(ancestorPid);
189
+ ancestorPid = byPid.get(ancestorPid)?.ppid ?? 0;
190
+ }
191
+ return protectedPids;
192
+ };
193
+
178
194
  export const windowsDescendants = (
179
195
  rootPid: number,
180
196
  processes: readonly IProcessInfo[],
197
+ owner: { pid: number; ppid: number } = process,
181
198
  ): IProcessInfo[] => {
199
+ const protectedPids = windowsAncestorPids(processes, owner);
200
+ if (!validWindowsPid(rootPid) || protectedPids.has(rootPid)) return [];
182
201
  const descendants: IProcessInfo[] = [];
183
202
  const parentPids = new Set([rootPid]);
184
203
  let found = true;
@@ -186,6 +205,8 @@ export const windowsDescendants = (
186
205
  found = false;
187
206
  for (const candidate of processes) {
188
207
  if (
208
+ validWindowsPid(candidate.pid) &&
209
+ !protectedPids.has(candidate.pid) &&
189
210
  !parentPids.has(candidate.pid) &&
190
211
  parentPids.has(candidate.ppid) &&
191
212
  !descendants.some((descendant) => descendant.pid === candidate.pid)
@@ -200,17 +221,32 @@ export const windowsDescendants = (
200
221
  return root ? [root, ...descendants] : descendants;
201
222
  };
202
223
 
203
- const windowsProcessList = async (pid: number): Promise<IProcessInfo[]> => {
224
+ const windowsProcessList = async (): Promise<IProcessInfo[]> => {
204
225
  const { getAllProcesses } = await import("@vscode/windows-process-tree");
205
226
  return new Promise((resolve) => {
206
- getAllProcesses((processes) => resolve(windowsDescendants(pid, processes)));
227
+ getAllProcesses(resolve);
207
228
  });
208
229
  };
209
230
 
210
- const forceWindowsTree = async (pid: number): Promise<void> => {
231
+ export const forceWindowsTree = async (
232
+ pid: number,
233
+ discover: (pid: number) => Promise<IProcessInfo[]> = windowsProcessList,
234
+ signal: (pid: number) => void = signalWindowsProcess,
235
+ discoveryTimeoutMs = 2_000,
236
+ ): Promise<void> => {
237
+ if (!safeWindowsSignalTarget(pid)) return;
211
238
  let processes: IProcessInfo[] = [];
239
+ let timer: NodeJS.Timeout | undefined;
212
240
  try {
213
- processes = await windowsProcessList(pid);
241
+ processes = await Promise.race([
242
+ Promise.resolve().then(() => discover(pid)),
243
+ new Promise<never>((_, reject) => {
244
+ timer = setTimeout(
245
+ () => reject(new Error(`process discovery timed out after ${discoveryTimeoutMs}ms`)),
246
+ discoveryTimeoutMs,
247
+ );
248
+ }),
249
+ ]);
214
250
  } catch (error) {
215
251
  process.emitWarning(
216
252
  `Windows descendant discovery failed; only the direct child can be terminated: ${
@@ -218,12 +254,24 @@ const forceWindowsTree = async (pid: number): Promise<void> => {
218
254
  }`,
219
255
  { code: "LUX_WINDOWS_PROCESS_DISCOVERY" },
220
256
  );
257
+ } finally {
258
+ if (timer) clearTimeout(timer);
259
+ }
260
+ if (windowsAncestorPids(processes, process).has(pid)) return;
261
+ const descendants = windowsDescendants(pid, processes);
262
+ for (const process of descendants.toReversed()) {
263
+ if (safeWindowsSignalTarget(process.pid)) signal(process.pid);
221
264
  }
222
- for (const process of processes.toReversed()) signalWindowsProcess(process.pid);
223
- if (!processes.some((process) => process.pid === pid)) signalWindowsProcess(pid);
265
+ if (!descendants.some((process) => process.pid === pid)) signal(pid);
224
266
  };
225
267
 
268
+ const validWindowsPid = (pid: number): boolean => Number.isSafeInteger(pid) && pid > 0;
269
+
270
+ const safeWindowsSignalTarget = (pid: number): boolean =>
271
+ validWindowsPid(pid) && pid !== process.pid && pid !== process.ppid;
272
+
226
273
  const signalWindowsProcess = (pid: number): void => {
274
+ if (!safeWindowsSignalTarget(pid)) return;
227
275
  try {
228
276
  process.kill(pid, "SIGKILL");
229
277
  } catch {
package/src/core/run.ts CHANGED
@@ -4,6 +4,7 @@ import { AgentActivitySchema } from "./agent-activity.js";
4
4
  import { EvalCaseSchema } from "./case.js";
5
5
  import { ArtifactSchema } from "./driver.js";
6
6
  import { DriverMetricsSchema } from "./driver-metrics.js";
7
+ import { EnvironmentDeclarationSchema } from "./environment.js";
7
8
  import { ErrorEventReasonSchema, ReadyStateSchema, RunEventSchema } from "./events.js";
8
9
  import { ToolOutcomeSummarySchema } from "./tool-events.js";
9
10
  import { RunUsageSchema } from "./usage.js";
@@ -27,7 +28,24 @@ export const RunProvenanceSchema = z.object({
27
28
  arch: z.string(),
28
29
  node: z.string(),
29
30
  bun: z.exactOptional(z.string()),
31
+ host: z.exactOptional(
32
+ z.object({
33
+ osRelease: z.string(),
34
+ cpuModels: z.array(z.string()),
35
+ logicalCpuCount: z.number().int().nonnegative(),
36
+ availableParallelism: z.number().int().positive(),
37
+ totalMemoryBytes: z.number().int().nonnegative(),
38
+ }),
39
+ ),
30
40
  }),
41
+ environment: z.exactOptional(
42
+ z.object({
43
+ /** Declared by the author, not independently verified or enforced by Lux. */
44
+ declared: z.exactOptional(EnvironmentDeclarationSchema),
45
+ /** Effective Lux worker limit for this run's suite; direct runs use one. */
46
+ concurrency: z.number().int().positive(),
47
+ }),
48
+ ),
31
49
  source: z.exactOptional(
32
50
  z.object({
33
51
  /** Case path relative to its repository root, when one was found. */
@@ -106,6 +124,8 @@ export const RunMetadataSchema = z.object({
106
124
  * eval overhead.
107
125
  */
108
126
  usage: RunUsageSchema,
127
+ /** Absent in older records; zero alone did not establish availability. */
128
+ agentUsageAvailability: z.exactOptional(z.enum(["reported", "unavailable"])),
109
129
  modelAccounting: z.exactOptional(
110
130
  z.object({
111
131
  agentCalls: z.number().int().nonnegative(),
package/src/core/usage.ts CHANGED
@@ -121,3 +121,11 @@ export const parseAgentUsage = (raw: unknown): TokenUsage | null => {
121
121
  if (!AGENT_USAGE_KEYS.some((key) => key in raw)) return null;
122
122
  return AgentUsageSchema.safeParse(raw).data ?? null;
123
123
  };
124
+
125
+ /** Legacy nonzero counts remain usable; legacy zero counts are unknown. */
126
+ export const hasAgentUsage = (metadata: {
127
+ usage: RunUsage;
128
+ agentUsageAvailability?: "reported" | "unavailable";
129
+ }): boolean =>
130
+ metadata.agentUsageAvailability === "reported" ||
131
+ (metadata.agentUsageAvailability === undefined && !isUsageEmpty(metadata.usage.agent));
@@ -9,7 +9,7 @@ import {
9
9
  type Artifact,
10
10
  DEFAULT_CLAUDE_MODEL,
11
11
  type DriverEventMap,
12
- type DriverPlugin,
12
+ defineDriver,
13
13
  discoverCliVersion,
14
14
  exec,
15
15
  type ParsedDriverEvent,
@@ -18,6 +18,12 @@ import {
18
18
  TypedEmitter,
19
19
  } from "../../core/index.js";
20
20
  import { walkArtifacts } from "../shared/artifacts.js";
21
+ import {
22
+ claudeConfigRoot,
23
+ claudeUserBehaviorHash,
24
+ configuredClaudeSourceHashes,
25
+ } from "../shared/experiment-behavior.js";
26
+ import { prepareClaudeExperimentConfig } from "../shared/experiment-policy.js";
21
27
  import { copyRegularFileNoFollow } from "../shared/secure-copy.js";
22
28
  import { subprocessDriver } from "../subprocess/index.js";
23
29
  import { ClaudeCodeLineSchema, makeParseEvent } from "./parse-events.js";
@@ -847,11 +853,36 @@ class ClaudeCodeDriverImpl implements AgentDriver {
847
853
  }
848
854
  }
849
855
 
850
- export const claudeCodeDriver: DriverPlugin<ClaudeCodeDriverConfig> = {
856
+ export const claudeCodeDriver = defineDriver({
851
857
  name: "claude-code",
852
858
  configSchema: ClaudeCodeDriverConfigSchema,
859
+ runtime: (config) => ({
860
+ commands: [config.command],
861
+ capabilities: {
862
+ interactive: true,
863
+ "tool-calls": true,
864
+ "tool-results": true,
865
+ artifacts: true,
866
+ subagents: true,
867
+ usage: true,
868
+ cost: true,
869
+ isolation: Boolean(config.isolation),
870
+ },
871
+ }),
872
+ experiment: {
873
+ version: "1",
874
+ prepare: prepareClaudeExperimentConfig,
875
+ identity: async (config, { rootDir }) => {
876
+ const configRoot = claudeConfigRoot({ config });
877
+ return {
878
+ configRoot,
879
+ userBehaviorHash: await claudeUserBehaviorHash(configRoot),
880
+ sources: await configuredClaudeSourceHashes({ name: "claude-code", config }, rootDir),
881
+ };
882
+ },
883
+ },
853
884
  create: (config) => new ClaudeCodeDriverImpl(config),
854
- };
885
+ });
855
886
 
856
887
  // Internal exports for testing
857
888
  export {
@@ -22,10 +22,11 @@ const resultText = (content: unknown): string => {
22
22
  .join("\n");
23
23
  };
24
24
 
25
- const agentCompletionStatus = (status: unknown): "completed" | "failed" | "cancelled" => {
26
- if (status === "failed") return "failed";
27
- if (status === "cancelled" || status === "interrupted") return "cancelled";
28
- return "completed";
25
+ const agentCompletionStatus = (status: unknown): "completed" | "failed" | "cancelled" | null => {
26
+ if (status === "completed") return "completed";
27
+ if (status === "errored") return "failed";
28
+ if (status === "shutdown" || status === "interrupted") return "cancelled";
29
+ return null;
29
30
  };
30
31
 
31
32
  export const appAgentLifecycleProgress = (
@@ -38,36 +39,40 @@ export const appAgentLifecycleProgress = (
38
39
  const receiverThreadIds = Array.isArray(item.receiverThreadIds)
39
40
  ? item.receiverThreadIds.filter((value): value is string => typeof value === "string")
40
41
  : [];
41
- const completionStatus = agentCompletionStatus(item.status);
42
- return receiverThreadIds.map((receiverThreadId) =>
43
- phase === "started"
44
- ? {
45
- id: `agent-spawn-${item.id}-${receiverThreadId}`,
46
- kind: "agent-spawn",
47
- payload: {
48
- agent: {
49
- id: receiverThreadId,
50
- role: "subagent",
51
- parentId: actor?.id ?? "codex",
52
- spawnToolUseId: item.id as string,
53
- ...(typeof item.model === "string" ? { model: item.model } : {}),
54
- },
55
- ...(typeof item.prompt === "string" ? { prompt: item.prompt } : {}),
56
- },
57
- ...(actor ? { agent: actor } : {}),
58
- ts,
59
- }
60
- : {
61
- id: `agent-completed-${item.id}-${receiverThreadId}`,
62
- kind: "agent-completed",
63
- payload: {
64
- agentId: receiverThreadId,
65
- status: completionStatus,
42
+ if (phase !== "completed") return [];
43
+ const states = asRecord(item.agentsStates);
44
+ return receiverThreadIds.flatMap((receiverThreadId): Progress[] => {
45
+ const events: Progress[] = [];
46
+ if (item.tool === "spawnAgent" && item.status === "completed") {
47
+ events.push({
48
+ id: `agent-spawn-${item.id}-${receiverThreadId}`,
49
+ kind: "agent-spawn",
50
+ payload: {
51
+ agent: {
52
+ id: receiverThreadId,
53
+ role: "subagent",
54
+ parentId: actor?.id ?? "codex",
55
+ spawnToolUseId: item.id as string,
56
+ ...(typeof item.model === "string" ? { model: item.model } : {}),
66
57
  },
67
- ...(actor ? { agent: actor } : {}),
68
- ts,
58
+ ...(typeof item.prompt === "string" ? { prompt: item.prompt } : {}),
69
59
  },
70
- );
60
+ ...(actor ? { agent: actor } : {}),
61
+ ts,
62
+ });
63
+ }
64
+ const status = agentCompletionStatus(asRecord(states?.[receiverThreadId])?.status);
65
+ if (status) {
66
+ events.push({
67
+ id: `agent-completed-${item.id}-${receiverThreadId}`,
68
+ kind: "agent-completed",
69
+ payload: { agentId: receiverThreadId, status },
70
+ ...(actor ? { agent: actor } : {}),
71
+ ts,
72
+ });
73
+ }
74
+ return events;
75
+ });
71
76
  };
72
77
 
73
78
  export type RpcId = string | number;
@@ -82,7 +87,12 @@ export class CodexSubagentTracker {
82
87
  spawningThreadId: string | undefined,
83
88
  mainThreadId: string | null,
84
89
  ): void {
85
- if (item?.type !== "collabAgentToolCall" || typeof item.id !== "string") return;
90
+ if (
91
+ item?.type !== "collabAgentToolCall" ||
92
+ item.tool !== "spawnAgent" ||
93
+ typeof item.id !== "string"
94
+ )
95
+ return;
86
96
  const receiverThreadIds = Array.isArray(item.receiverThreadIds)
87
97
  ? item.receiverThreadIds.filter((value): value is string => typeof value === "string")
88
98
  : [];
@@ -0,0 +1,258 @@
1
+ import { z } from "zod";
2
+ import { type ParsedDriverEvent, type TokenUsage, toolResultProgress } from "../../core/index.js";
3
+ import type { CodexDriverConfig } from "./config.js";
4
+
5
+ const CodexUsageSchema = z.object({
6
+ input_tokens: z.number().nonnegative().catch(0),
7
+ cached_input_tokens: z.number().nonnegative().catch(0),
8
+ output_tokens: z.number().nonnegative().catch(0),
9
+ });
10
+
11
+ const parseUsage = (raw: unknown): TokenUsage | null => {
12
+ const usage = CodexUsageSchema.safeParse(raw).data;
13
+ if (!usage) return null;
14
+ return {
15
+ input: Math.max(0, usage.input_tokens - usage.cached_input_tokens),
16
+ output: usage.output_tokens,
17
+ cacheRead: usage.cached_input_tokens,
18
+ cacheCreation: 0,
19
+ };
20
+ };
21
+
22
+ const resultText = (content: unknown): string => {
23
+ if (typeof content === "string") return content;
24
+ if (!Array.isArray(content)) return "";
25
+ return content
26
+ .filter(
27
+ (block): block is { type: "text"; text: string } =>
28
+ typeof block === "object" &&
29
+ block !== null &&
30
+ (block as { type?: unknown }).type === "text" &&
31
+ typeof (block as { text?: unknown }).text === "string",
32
+ )
33
+ .map((block) => block.text)
34
+ .join("\n");
35
+ };
36
+
37
+ const startedItemProgress = (
38
+ item: Record<string, unknown>,
39
+ id: string,
40
+ ): ParsedDriverEvent | null => {
41
+ if (item.type === "command_execution") {
42
+ return {
43
+ tag: "progress",
44
+ progress: {
45
+ id: `tc-${id}`,
46
+ kind: "tool-call",
47
+ payload: { name: "command_execution", input: { command: item.command }, toolUseId: id },
48
+ ts: Date.now(),
49
+ },
50
+ };
51
+ }
52
+ if (item.type === "mcp_tool_call") {
53
+ const tool = typeof item.tool === "string" ? item.tool : String(item.name ?? "mcp_tool_call");
54
+ const server = typeof item.server === "string" ? item.server : undefined;
55
+ return {
56
+ tag: "progress",
57
+ progress: {
58
+ id: `tc-${id}`,
59
+ kind: "tool-call",
60
+ payload: {
61
+ name: tool,
62
+ input: item.arguments ?? item.input,
63
+ toolUseId: id,
64
+ ...(server ? { server } : {}),
65
+ },
66
+ ts: Date.now(),
67
+ },
68
+ };
69
+ }
70
+ if (item.type === "web_search") {
71
+ return {
72
+ tag: "progress",
73
+ progress: {
74
+ id: `tc-${id}`,
75
+ kind: "tool-call",
76
+ payload: { name: "web_search", input: { query: item.query }, toolUseId: id },
77
+ ts: Date.now(),
78
+ },
79
+ };
80
+ }
81
+ if (item.type === "file_change") {
82
+ return {
83
+ tag: "progress",
84
+ progress: {
85
+ id: `tc-${id}`,
86
+ kind: "tool-call",
87
+ payload: { name: "file_change", input: { changes: item.changes }, toolUseId: id },
88
+ ts: Date.now(),
89
+ },
90
+ };
91
+ }
92
+ return null;
93
+ };
94
+
95
+ const completedItemProgress = (
96
+ item: Record<string, unknown>,
97
+ id: string,
98
+ ): ParsedDriverEvent | null => {
99
+ if (item.type === "agent_message" && typeof item.text === "string") {
100
+ return {
101
+ tag: "progress",
102
+ progress: {
103
+ id: `am-${id}`,
104
+ kind: "agent-message",
105
+ payload: { text: item.text },
106
+ ts: Date.now(),
107
+ },
108
+ };
109
+ }
110
+ if (item.type === "reasoning") {
111
+ const text = typeof item.text === "string" ? item.text : item.summary;
112
+ return {
113
+ tag: "progress",
114
+ progress: { id: `reasoning-${id}`, kind: "reasoning", payload: { text }, ts: Date.now() },
115
+ };
116
+ }
117
+ if (item.type === "mcp_tool_call") {
118
+ const tool = typeof item.tool === "string" ? item.tool : String(item.name ?? "mcp_tool_call");
119
+ const raw =
120
+ item.result && typeof item.result === "object"
121
+ ? (item.result as Record<string, unknown>)
122
+ : item;
123
+ const content = raw.content ?? item.result ?? [];
124
+ const structuredContent = raw.structuredContent ?? raw.structured_content;
125
+ return {
126
+ tag: "progress",
127
+ progress: toolResultProgress(
128
+ 0,
129
+ {
130
+ name: tool,
131
+ toolUseId: id,
132
+ content,
133
+ ...(structuredContent && typeof structuredContent === "object"
134
+ ? { structuredContent: structuredContent as Record<string, unknown> }
135
+ : {}),
136
+ isError:
137
+ raw.isError === true ||
138
+ raw.is_error === true ||
139
+ item.status === "failed" ||
140
+ (item.error !== undefined && item.error !== null),
141
+ text: resultText(content) || (typeof item.error === "string" ? item.error : ""),
142
+ },
143
+ Date.now(),
144
+ ),
145
+ };
146
+ }
147
+ if (item.type === "command_execution") {
148
+ const output = item.aggregated_output ?? item.output ?? "";
149
+ const exitCode = typeof item.exit_code === "number" ? item.exit_code : undefined;
150
+ return {
151
+ tag: "progress",
152
+ progress: toolResultProgress(
153
+ 0,
154
+ {
155
+ name: "command_execution",
156
+ toolUseId: id,
157
+ content: { output, ...(exitCode !== undefined ? { exitCode } : {}) },
158
+ isError: item.status === "failed" || (exitCode !== undefined && exitCode !== 0),
159
+ text: typeof output === "string" ? output : JSON.stringify(output),
160
+ },
161
+ Date.now(),
162
+ ),
163
+ };
164
+ }
165
+ if (item.type === "web_search" || item.type === "file_change") {
166
+ const isWebSearch = item.type === "web_search";
167
+ const content = isWebSearch
168
+ ? { query: item.query }
169
+ : { changes: item.changes, status: item.status };
170
+ let text = JSON.stringify(item.changes ?? []);
171
+ if (isWebSearch) text = typeof item.query === "string" ? item.query : "";
172
+ return {
173
+ tag: "progress",
174
+ progress: toolResultProgress(
175
+ 0,
176
+ {
177
+ name: item.type,
178
+ toolUseId: id,
179
+ content,
180
+ isError: item.status === "failed",
181
+ text,
182
+ },
183
+ Date.now(),
184
+ ),
185
+ };
186
+ }
187
+ return null;
188
+ };
189
+
190
+ const itemProgress = (
191
+ item: Record<string, unknown>,
192
+ phase: "started" | "completed",
193
+ ): ParsedDriverEvent | null => {
194
+ const id = typeof item.id === "string" ? item.id : `${String(item.type)}-${Date.now()}`;
195
+ return phase === "started" ? startedItemProgress(item, id) : completedItemProgress(item, id);
196
+ };
197
+
198
+ export const makeParseEvent = (config: CodexDriverConfig, cliVersion?: string) => {
199
+ let threadId: string | undefined;
200
+ return (line: string): ParsedDriverEvent | ParsedDriverEvent[] | null => {
201
+ let event: Record<string, unknown>;
202
+ try {
203
+ event = JSON.parse(line) as Record<string, unknown>;
204
+ } catch {
205
+ return null;
206
+ }
207
+ if (event.type === "thread.started") {
208
+ threadId = typeof event.thread_id === "string" ? event.thread_id : undefined;
209
+ return {
210
+ tag: "ready",
211
+ ready: {
212
+ agentId: "codex",
213
+ model: config.model,
214
+ detail: { ...(threadId ? { threadId } : {}), ...(cliVersion ? { cliVersion } : {}) },
215
+ },
216
+ };
217
+ }
218
+ if (event.type === "item.started" || event.type === "item.completed") {
219
+ if (!event.item || typeof event.item !== "object") return null;
220
+ return itemProgress(
221
+ event.item as Record<string, unknown>,
222
+ event.type === "item.started" ? "started" : "completed",
223
+ );
224
+ }
225
+ if (event.type === "turn.completed") {
226
+ const usage = parseUsage(event.usage);
227
+ const events: ParsedDriverEvent[] = [];
228
+ if (usage) {
229
+ events.push({
230
+ tag: "progress",
231
+ progress: {
232
+ id: `usage-${threadId ?? Date.now()}`,
233
+ kind: "usage",
234
+ payload: usage,
235
+ ts: Date.now(),
236
+ },
237
+ });
238
+ }
239
+ events.push({
240
+ tag: "done",
241
+ done: { exitReason: "done", summary: { threadId, ...(usage ? { usage } : {}) } },
242
+ });
243
+ return events;
244
+ }
245
+ if (event.type === "turn.failed" || event.type === "error") {
246
+ const nestedMessage =
247
+ event.error && typeof event.error === "object"
248
+ ? (event.error as Record<string, unknown>).message
249
+ : undefined;
250
+ let message = "codex reported an error";
251
+ if (typeof event.message === "string") message = event.message;
252
+ else if (typeof event.error === "string") message = event.error;
253
+ else if (typeof nestedMessage === "string") message = nestedMessage;
254
+ return { tag: "error", error: { exitReason: "error", reason: message } };
255
+ }
256
+ return null;
257
+ };
258
+ };