niceeval 0.13.2 → 0.13.3

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 (494) hide show
  1. package/dist/agents/bub.cjs +4 -4
  2. package/dist/agents/bub.cjs.map +1 -1
  3. package/dist/agents/bub.d.cts +2 -2
  4. package/dist/agents/bub.d.mts +2 -2
  5. package/dist/agents/bub.d.ts +2 -2
  6. package/dist/agents/claude-code-native.cjs +213 -0
  7. package/dist/agents/claude-code-native.cjs.map +1 -0
  8. package/dist/agents/claude-code-native.d.cts +5 -0
  9. package/dist/agents/claude-code-native.d.mts +5 -0
  10. package/dist/agents/claude-code-native.d.ts +5 -0
  11. package/dist/agents/claude-code-native.js +6 -0
  12. package/dist/agents/claude-code-native.js.map +1 -0
  13. package/dist/agents/claude-code.cjs +26 -80
  14. package/dist/agents/claude-code.cjs.map +1 -1
  15. package/dist/agents/codex-app-server.cjs +314 -0
  16. package/dist/agents/codex-app-server.cjs.map +1 -0
  17. package/dist/agents/codex-app-server.d.cts +9 -0
  18. package/dist/agents/codex-app-server.d.mts +9 -0
  19. package/dist/agents/codex-app-server.d.ts +9 -0
  20. package/dist/agents/codex-app-server.js +6 -0
  21. package/dist/agents/codex-app-server.js.map +1 -0
  22. package/dist/agents/codex.cjs +19 -68
  23. package/dist/agents/codex.cjs.map +1 -1
  24. package/dist/agents/codex.d.cts +3 -3
  25. package/dist/agents/codex.d.mts +3 -3
  26. package/dist/agents/codex.d.ts +3 -3
  27. package/dist/agents/index.cjs +3 -1
  28. package/dist/agents/index.cjs.map +1 -1
  29. package/dist/agents/index.d.cts +1 -0
  30. package/dist/agents/index.d.mts +1 -0
  31. package/dist/agents/index.d.ts +1 -0
  32. package/dist/agents/index.js +84 -82
  33. package/dist/agents/index.mjs +84 -82
  34. package/dist/agents/managed-jsonl.cjs +207 -0
  35. package/dist/agents/managed-jsonl.cjs.map +1 -0
  36. package/dist/agents/managed-jsonl.d.cts +39 -0
  37. package/dist/agents/managed-jsonl.d.mts +39 -0
  38. package/dist/agents/managed-jsonl.d.ts +39 -0
  39. package/dist/agents/managed-jsonl.js +6 -0
  40. package/dist/agents/managed-jsonl.js.map +1 -0
  41. package/dist/agents/managed-process.cjs +31 -0
  42. package/dist/agents/managed-process.cjs.map +1 -0
  43. package/dist/agents/managed-process.d.cts +3 -0
  44. package/dist/agents/managed-process.d.mts +3 -0
  45. package/dist/agents/managed-process.d.ts +3 -0
  46. package/dist/agents/managed-process.js +6 -0
  47. package/dist/agents/managed-process.js.map +1 -0
  48. package/dist/agents/omp.cjs +18 -1
  49. package/dist/agents/omp.cjs.map +1 -1
  50. package/dist/agents/sdk-streams.cjs +11 -4
  51. package/dist/agents/sdk-streams.cjs.map +1 -1
  52. package/dist/agents/types.cjs.map +1 -1
  53. package/dist/agents/types.d.cts +8 -0
  54. package/dist/agents/types.d.mts +8 -0
  55. package/dist/agents/types.d.ts +8 -0
  56. package/dist/analysis/bindings.cjs +74 -19
  57. package/dist/analysis/bindings.cjs.map +1 -1
  58. package/dist/analysis/bindings.d.cts +534 -156
  59. package/dist/analysis/bindings.d.mts +534 -156
  60. package/dist/analysis/bindings.d.ts +534 -156
  61. package/dist/analysis/domain-view.cjs.map +1 -1
  62. package/dist/analysis/domain-view.d.cts +137 -8
  63. package/dist/analysis/domain-view.d.mts +137 -8
  64. package/dist/analysis/domain-view.d.ts +137 -8
  65. package/dist/analysis/index.cjs.map +1 -1
  66. package/dist/analysis/index.d.cts +1 -1
  67. package/dist/analysis/index.d.mts +1 -1
  68. package/dist/analysis/index.d.ts +1 -1
  69. package/dist/assertions/api.cjs.map +1 -1
  70. package/dist/assertions/api.d.cts +62 -0
  71. package/dist/assertions/api.d.mts +62 -0
  72. package/dist/assertions/api.d.ts +62 -0
  73. package/dist/assertions/judge.cjs +56 -5
  74. package/dist/assertions/judge.cjs.map +1 -1
  75. package/dist/assertions/match.cjs +66 -42
  76. package/dist/assertions/match.cjs.map +1 -1
  77. package/dist/assertions/match.d.cts +13 -0
  78. package/dist/assertions/match.d.mts +13 -0
  79. package/dist/assertions/match.d.ts +13 -0
  80. package/dist/assertions/record/attachment.cjs +104 -33
  81. package/dist/assertions/record/attachment.cjs.map +1 -1
  82. package/dist/assertions/record/attachment.d.cts +294 -57
  83. package/dist/assertions/record/attachment.d.mts +294 -57
  84. package/dist/assertions/record/attachment.d.ts +294 -57
  85. package/dist/assertions/record/codec.cjs +91 -17
  86. package/dist/assertions/record/codec.cjs.map +1 -1
  87. package/dist/assertions/record/codec.d.cts +280 -52
  88. package/dist/assertions/record/codec.d.mts +280 -52
  89. package/dist/assertions/record/codec.d.ts +280 -52
  90. package/dist/assertions/record/index.js +2 -0
  91. package/dist/assertions/record/model.cjs +16 -0
  92. package/dist/assertions/record/model.cjs.map +1 -1
  93. package/dist/assertions/record/model.d.cts +120 -13
  94. package/dist/assertions/record/model.d.mts +120 -13
  95. package/dist/assertions/record/model.d.ts +120 -13
  96. package/dist/assertions/record/model.js +2 -0
  97. package/dist/assertions/record/producer.cjs +70 -50
  98. package/dist/assertions/record/producer.cjs.map +1 -1
  99. package/dist/assertions/record/producer.d.cts +8 -7
  100. package/dist/assertions/record/producer.d.mts +8 -7
  101. package/dist/assertions/record/producer.d.ts +8 -7
  102. package/dist/assertions/runtime.cjs +49 -7
  103. package/dist/assertions/runtime.cjs.map +1 -1
  104. package/dist/cli/application.cjs +40 -0
  105. package/dist/cli/application.cjs.map +1 -0
  106. package/dist/cli/application.d.cts +129 -0
  107. package/dist/cli/application.d.mts +129 -0
  108. package/dist/cli/application.d.ts +129 -0
  109. package/dist/cli/application.js +24 -0
  110. package/dist/cli/application.js.map +1 -0
  111. package/dist/cli/bootstrap.cjs +10 -4
  112. package/dist/cli/bootstrap.cjs.map +1 -1
  113. package/dist/cli/node-application.cjs +123 -0
  114. package/dist/cli/node-application.cjs.map +1 -0
  115. package/dist/cli/node-application.d.cts +14 -0
  116. package/dist/cli/node-application.d.mts +14 -0
  117. package/dist/cli/node-application.d.ts +14 -0
  118. package/dist/cli/node-application.js +26 -0
  119. package/dist/cli/node-application.js.map +1 -0
  120. package/dist/cli/program.cjs +2807 -0
  121. package/dist/cli/program.cjs.map +1 -0
  122. package/dist/cli/program.d.cts +352 -0
  123. package/dist/cli/program.d.mts +352 -0
  124. package/dist/cli/program.d.ts +352 -0
  125. package/dist/cli/program.js +36 -0
  126. package/dist/cli/program.js.map +1 -0
  127. package/dist/cli/project-configuration.cjs +134 -0
  128. package/dist/cli/project-configuration.cjs.map +1 -0
  129. package/dist/cli/project-configuration.d.cts +64 -0
  130. package/dist/cli/project-configuration.d.mts +64 -0
  131. package/dist/cli/project-configuration.d.ts +64 -0
  132. package/dist/cli/project-configuration.js +22 -0
  133. package/dist/cli/project-configuration.js.map +1 -0
  134. package/dist/cli/record.cjs +20 -4
  135. package/dist/cli/record.cjs.map +1 -1
  136. package/dist/cli/record.d.cts +3 -3
  137. package/dist/cli/record.d.mts +3 -3
  138. package/dist/cli/record.d.ts +3 -3
  139. package/dist/cli.cjs +19 -3130
  140. package/dist/cli.cjs.map +1 -1
  141. package/dist/cli.d.cts +2 -148
  142. package/dist/cli.d.mts +2 -148
  143. package/dist/cli.d.ts +2 -148
  144. package/dist/cli.js +22 -30
  145. package/dist/context/assert-first.cjs +21 -15
  146. package/dist/context/assert-first.cjs.map +1 -1
  147. package/dist/context/assert-first.d.cts +1 -0
  148. package/dist/context/assert-first.d.mts +1 -0
  149. package/dist/context/assert-first.d.ts +1 -0
  150. package/dist/context/attempt-resources.cjs +13 -0
  151. package/dist/context/attempt-resources.cjs.map +1 -0
  152. package/dist/context/attempt-resources.d.cts +3 -0
  153. package/dist/context/attempt-resources.d.mts +3 -0
  154. package/dist/context/attempt-resources.d.ts +3 -0
  155. package/dist/context/attempt-resources.js +8 -0
  156. package/dist/context/attempt-resources.js.map +1 -0
  157. package/dist/context/session.cjs +4 -3
  158. package/dist/context/session.cjs.map +1 -1
  159. package/dist/context/session.d.cts +1 -0
  160. package/dist/context/session.d.mts +1 -0
  161. package/dist/context/session.d.ts +1 -0
  162. package/dist/eval/record/verdict.cjs +3 -2
  163. package/dist/eval/record/verdict.cjs.map +1 -1
  164. package/dist/experiment/host/index.cjs +1 -6
  165. package/dist/experiment/host/index.cjs.map +1 -1
  166. package/dist/experiment/host/index.d.cts +1 -0
  167. package/dist/experiment/host/index.d.mts +1 -0
  168. package/dist/experiment/host/index.d.ts +1 -0
  169. package/dist/load-config.cjs +13 -4
  170. package/dist/load-config.cjs.map +1 -1
  171. package/dist/load-config.d.cts +4 -3
  172. package/dist/load-config.d.mts +4 -3
  173. package/dist/load-config.d.ts +4 -3
  174. package/dist/load-config.js +4 -2
  175. package/dist/o11y/parsers/codex.cjs +29 -7
  176. package/dist/o11y/parsers/codex.cjs.map +1 -1
  177. package/dist/record/codec/core.d.cts +0 -2
  178. package/dist/record/codec/core.d.mts +0 -2
  179. package/dist/record/codec/core.d.ts +0 -2
  180. package/dist/record/codec/identifiers.cjs +2 -3
  181. package/dist/record/codec/identifiers.cjs.map +1 -1
  182. package/dist/record/codec/identifiers.d.cts +1 -2
  183. package/dist/record/codec/identifiers.d.mts +1 -2
  184. package/dist/record/codec/identifiers.d.ts +1 -2
  185. package/dist/record/codec/identifiers.js +10 -12
  186. package/dist/record/codec/index.js +42 -44
  187. package/dist/record/definition/attachment.cjs +1 -0
  188. package/dist/record/definition/attachment.cjs.map +1 -1
  189. package/dist/record/definition/attachment.d.cts +14 -0
  190. package/dist/record/definition/attachment.d.mts +14 -0
  191. package/dist/record/definition/attachment.d.ts +14 -0
  192. package/dist/record/family/assertions-v1.cjs +104 -0
  193. package/dist/record/family/assertions-v1.cjs.map +1 -0
  194. package/dist/record/family/assertions-v1.d.cts +2 -0
  195. package/dist/record/family/assertions-v1.d.mts +2 -0
  196. package/dist/record/family/assertions-v1.d.ts +2 -0
  197. package/dist/record/family/assertions-v1.js +6 -0
  198. package/dist/record/family/assertions-v1.js.map +1 -0
  199. package/dist/record/family/assertions.cjs +16 -5
  200. package/dist/record/family/assertions.cjs.map +1 -1
  201. package/dist/record/family/assertions.d.cts +510 -56
  202. package/dist/record/family/assertions.d.mts +510 -56
  203. package/dist/record/family/assertions.d.ts +510 -56
  204. package/dist/record/family/assertions.js +14 -10
  205. package/dist/record/family/catalog.cjs +17 -1
  206. package/dist/record/family/catalog.cjs.map +1 -1
  207. package/dist/record/family/catalog.d.cts +1292 -104
  208. package/dist/record/family/catalog.d.mts +1292 -104
  209. package/dist/record/family/catalog.d.ts +1292 -104
  210. package/dist/record/family/catalog.js +22 -20
  211. package/dist/record/family/index.js +144 -138
  212. package/dist/record/family/observability-v1.cjs +5 -0
  213. package/dist/record/family/observability-v1.cjs.map +1 -1
  214. package/dist/record/family/observability.cjs +1 -1
  215. package/dist/record/family/observability.cjs.map +1 -1
  216. package/dist/record/host/runtime.cjs +323 -173
  217. package/dist/record/host/runtime.cjs.map +1 -1
  218. package/dist/record/host/types.cjs.map +1 -1
  219. package/dist/record/host/types.d.cts +9 -7
  220. package/dist/record/host/types.d.mts +9 -7
  221. package/dist/record/host/types.d.ts +9 -7
  222. package/dist/record/model/core.cjs.map +1 -1
  223. package/dist/record/model/core.d.cts +1 -2
  224. package/dist/record/model/core.d.mts +1 -2
  225. package/dist/record/model/core.d.ts +1 -2
  226. package/dist/record/model/definition.cjs +1 -2
  227. package/dist/record/model/definition.cjs.map +1 -1
  228. package/dist/record/model/definition.d.cts +1 -7
  229. package/dist/record/model/definition.d.mts +1 -7
  230. package/dist/record/model/definition.d.ts +1 -7
  231. package/dist/record/model/identifiers.cjs +2 -3
  232. package/dist/record/model/identifiers.cjs.map +1 -1
  233. package/dist/record/model/identifiers.d.cts +1 -3
  234. package/dist/record/model/identifiers.d.mts +1 -3
  235. package/dist/record/model/identifiers.d.ts +1 -3
  236. package/dist/record/model/identifiers.js +36 -38
  237. package/dist/record/model/index.js +60 -62
  238. package/dist/record/platform/node.cjs +17 -7
  239. package/dist/record/platform/node.cjs.map +1 -1
  240. package/dist/record/platform/services.cjs.map +1 -1
  241. package/dist/record/platform/services.d.cts +8 -3
  242. package/dist/record/platform/services.d.mts +8 -3
  243. package/dist/record/platform/services.d.ts +8 -3
  244. package/dist/record/reader/format.cjs +16 -65
  245. package/dist/record/reader/format.cjs.map +1 -1
  246. package/dist/record/reader/format.d.cts +5 -9
  247. package/dist/record/reader/format.d.mts +5 -9
  248. package/dist/record/reader/format.d.ts +5 -9
  249. package/dist/record/reader/index.js +10 -8
  250. package/dist/record/reader/runtime.cjs +63 -32
  251. package/dist/record/reader/runtime.cjs.map +1 -1
  252. package/dist/record/reader/runtime.d.cts +40 -4
  253. package/dist/record/reader/runtime.d.mts +40 -4
  254. package/dist/record/reader/runtime.d.ts +40 -4
  255. package/dist/record/reader/runtime.js +6 -4
  256. package/dist/report/assets/enhance.js +5 -5
  257. package/dist/report/assets/styles.css +190 -24
  258. package/dist/report/built-in/result-components.cjs +8 -5
  259. package/dist/report/built-in/result-components.cjs.map +1 -1
  260. package/dist/report/built-in/standard.cjs +3 -0
  261. package/dist/report/built-in/standard.cjs.map +1 -1
  262. package/dist/report/built-in/standard.d.cts +2 -0
  263. package/dist/report/built-in/standard.d.mts +2 -0
  264. package/dist/report/built-in/standard.d.ts +2 -0
  265. package/dist/report/client-dist/app.js +53 -0
  266. package/dist/report/components/attempt-detail/compute.cjs +108 -231
  267. package/dist/report/components/attempt-detail/compute.cjs.map +1 -1
  268. package/dist/report/components/attempt-detail/compute.d.cts +11 -45
  269. package/dist/report/components/attempt-detail/compute.d.mts +11 -45
  270. package/dist/report/components/attempt-detail/compute.d.ts +11 -45
  271. package/dist/report/components/attempt-detail/compute.js +2 -4
  272. package/dist/report/components/attempt-detail/content.cjs +4 -4
  273. package/dist/report/components/attempt-detail/content.cjs.map +1 -1
  274. package/dist/report/components/attempt-detail/validate.cjs +47 -4
  275. package/dist/report/components/attempt-detail/validate.cjs.map +1 -1
  276. package/dist/report/components/entity-lists/compute.cjs +9 -15
  277. package/dist/report/components/entity-lists/compute.cjs.map +1 -1
  278. package/dist/report/components/entity-lists/content.cjs +53 -40
  279. package/dist/report/components/entity-lists/content.cjs.map +1 -1
  280. package/dist/report/components/entity-lists/index.cjs +1 -3
  281. package/dist/report/components/entity-lists/index.cjs.map +1 -1
  282. package/dist/report/components/experiment-detail/compute.cjs +4 -6
  283. package/dist/report/components/experiment-detail/compute.cjs.map +1 -1
  284. package/dist/report/components/summaries/index.cjs +5 -1
  285. package/dist/report/components/summaries/index.cjs.map +1 -1
  286. package/dist/report/definition/cell.cjs +14 -7
  287. package/dist/report/definition/cell.cjs.map +1 -1
  288. package/dist/report/definition/cell.d.cts +4 -0
  289. package/dist/report/definition/cell.d.mts +4 -0
  290. package/dist/report/definition/cell.d.ts +4 -0
  291. package/dist/report/definition/primitives/assertion-evidence.cjs +96 -0
  292. package/dist/report/definition/primitives/assertion-evidence.cjs.map +1 -0
  293. package/dist/report/definition/primitives/assertion-evidence.d.cts +11 -0
  294. package/dist/report/definition/primitives/assertion-evidence.d.mts +11 -0
  295. package/dist/report/definition/primitives/assertion-evidence.d.ts +11 -0
  296. package/dist/report/definition/primitives/assertion-evidence.js +6 -0
  297. package/dist/report/definition/primitives/assertion-evidence.js.map +1 -0
  298. package/dist/report/definition/primitives/conversation.cjs +7 -0
  299. package/dist/report/definition/primitives/conversation.cjs.map +1 -1
  300. package/dist/report/definition/primitives/conversation.d.cts +2 -0
  301. package/dist/report/definition/primitives/conversation.d.mts +2 -0
  302. package/dist/report/definition/primitives/conversation.d.ts +2 -0
  303. package/dist/report/definition/primitives/turn-trace.cjs +53 -3
  304. package/dist/report/definition/primitives/turn-trace.cjs.map +1 -1
  305. package/dist/report/definition/primitives.cjs +14 -1
  306. package/dist/report/definition/primitives.cjs.map +1 -1
  307. package/dist/report/definition/report.cjs +16 -8
  308. package/dist/report/definition/report.cjs.map +1 -1
  309. package/dist/report/definition/report.d.cts +6 -0
  310. package/dist/report/definition/report.d.mts +6 -0
  311. package/dist/report/definition/report.d.ts +6 -0
  312. package/dist/report/definition/table-text.cjs +12 -3
  313. package/dist/report/definition/table-text.cjs.map +1 -1
  314. package/dist/report/definition/table-text.d.cts +6 -1
  315. package/dist/report/definition/table-text.d.mts +6 -1
  316. package/dist/report/definition/table-text.d.ts +6 -1
  317. package/dist/report/execution/model.cjs +6 -14
  318. package/dist/report/execution/model.cjs.map +1 -1
  319. package/dist/report/execution/model.d.cts +5 -10
  320. package/dist/report/execution/model.d.mts +5 -10
  321. package/dist/report/execution/model.d.ts +5 -10
  322. package/dist/report/execution/model.js +6 -6
  323. package/dist/report/execution/paths.cjs +0 -11
  324. package/dist/report/execution/paths.cjs.map +1 -1
  325. package/dist/report/execution/paths.d.cts +0 -1
  326. package/dist/report/execution/paths.d.mts +0 -1
  327. package/dist/report/execution/paths.d.ts +0 -1
  328. package/dist/report/execution/paths.js +6 -8
  329. package/dist/report/host/execute.cjs +13 -22
  330. package/dist/report/host/execute.cjs.map +1 -1
  331. package/dist/report/host/execute.d.cts +1 -4
  332. package/dist/report/host/execute.d.mts +1 -4
  333. package/dist/report/host/execute.d.ts +1 -4
  334. package/dist/report/host/from-record.cjs +3 -0
  335. package/dist/report/host/from-record.cjs.map +1 -1
  336. package/dist/report/host/from-record.d.cts +4 -1
  337. package/dist/report/host/from-record.d.mts +4 -1
  338. package/dist/report/host/from-record.d.ts +4 -1
  339. package/dist/report/host/site-assets.cjs +1 -2
  340. package/dist/report/host/site-assets.cjs.map +1 -1
  341. package/dist/report/host/site-assets.d.cts +0 -1
  342. package/dist/report/host/site-assets.d.mts +0 -1
  343. package/dist/report/host/site-assets.d.ts +0 -1
  344. package/dist/report/host/site-assets.js +2 -4
  345. package/dist/report/host/static.cjs +71 -346
  346. package/dist/report/host/static.cjs.map +1 -1
  347. package/dist/report/host/static.d.cts +1 -3
  348. package/dist/report/host/static.d.mts +1 -3
  349. package/dist/report/host/static.d.ts +1 -3
  350. package/dist/report/host/static.js +2 -2
  351. package/dist/report/host/view-session.cjs.map +1 -1
  352. package/dist/report/host/view-session.d.cts +1 -1
  353. package/dist/report/host/view-session.d.mts +1 -1
  354. package/dist/report/host/view-session.d.ts +1 -1
  355. package/dist/report/model/locale.cjs +1 -1
  356. package/dist/report/model/locale.cjs.map +1 -1
  357. package/dist/report/model/locale.d.cts +1 -1
  358. package/dist/report/model/locale.d.mts +1 -1
  359. package/dist/report/model/locale.d.ts +1 -1
  360. package/dist/report/model/pricing.cjs +2 -2
  361. package/dist/report/model/pricing.cjs.map +1 -1
  362. package/dist/report/react/enhance.js +5 -5
  363. package/dist/report/react/styles.css +190 -24
  364. package/dist/runner/adoption.cjs +4 -7
  365. package/dist/runner/adoption.cjs.map +1 -1
  366. package/dist/runner/attempt-resources.cjs +60 -0
  367. package/dist/runner/attempt-resources.cjs.map +1 -0
  368. package/dist/runner/attempt-resources.d.cts +13 -0
  369. package/dist/runner/attempt-resources.d.mts +13 -0
  370. package/dist/runner/attempt-resources.d.ts +13 -0
  371. package/dist/runner/attempt-resources.js +6 -0
  372. package/dist/runner/attempt-resources.js.map +1 -0
  373. package/dist/runner/attempt.cjs +37 -3
  374. package/dist/runner/attempt.cjs.map +1 -1
  375. package/dist/runner/feedback/failure.cjs +77 -2
  376. package/dist/runner/feedback/failure.cjs.map +1 -1
  377. package/dist/runner/feedback/failure.d.cts +2 -1
  378. package/dist/runner/feedback/failure.d.mts +2 -1
  379. package/dist/runner/feedback/failure.d.ts +2 -1
  380. package/dist/runner/project-current.cjs +2 -13
  381. package/dist/runner/project-current.cjs.map +1 -1
  382. package/dist/runner/project-current.d.cts +4 -2
  383. package/dist/runner/project-current.d.mts +4 -2
  384. package/dist/runner/project-current.d.ts +4 -2
  385. package/dist/runner/reporters/braintrust.cjs +7 -7
  386. package/dist/runner/reporters/braintrust.cjs.map +1 -1
  387. package/dist/runner/reuse-readback.cjs +3 -4
  388. package/dist/runner/reuse-readback.cjs.map +1 -1
  389. package/dist/runner/run.cjs +5 -2
  390. package/dist/runner/run.cjs.map +1 -1
  391. package/dist/sandbox/backend.cjs +32 -2
  392. package/dist/sandbox/backend.cjs.map +1 -1
  393. package/dist/sandbox/backend.d.cts +12 -1
  394. package/dist/sandbox/backend.d.mts +12 -1
  395. package/dist/sandbox/backend.d.ts +12 -1
  396. package/dist/sandbox/backend.js +28 -22
  397. package/dist/sandbox/docker.cjs +140 -0
  398. package/dist/sandbox/docker.cjs.map +1 -1
  399. package/dist/sandbox/docker.d.cts +3 -1
  400. package/dist/sandbox/docker.d.mts +3 -1
  401. package/dist/sandbox/docker.d.ts +3 -1
  402. package/dist/sandbox/e2b.cjs +42 -0
  403. package/dist/sandbox/e2b.cjs.map +1 -1
  404. package/dist/sandbox/e2b.d.cts +2 -0
  405. package/dist/sandbox/e2b.d.mts +2 -0
  406. package/dist/sandbox/e2b.d.ts +2 -0
  407. package/dist/sandbox/local.cjs +64 -0
  408. package/dist/sandbox/local.cjs.map +1 -1
  409. package/dist/sandbox/local.d.cts +3 -1
  410. package/dist/sandbox/local.d.mts +3 -1
  411. package/dist/sandbox/local.d.ts +3 -1
  412. package/dist/sandbox/managed-process.cjs +49 -0
  413. package/dist/sandbox/managed-process.cjs.map +1 -0
  414. package/dist/sandbox/managed-process.d.cts +11 -0
  415. package/dist/sandbox/managed-process.d.mts +11 -0
  416. package/dist/sandbox/managed-process.d.ts +11 -0
  417. package/dist/sandbox/managed-process.js +6 -0
  418. package/dist/sandbox/managed-process.js.map +1 -0
  419. package/dist/sandbox/types.cjs.map +1 -1
  420. package/dist/sandbox/types.d.cts +24 -0
  421. package/dist/sandbox/types.d.mts +24 -0
  422. package/dist/sandbox/types.d.ts +24 -0
  423. package/dist/sandbox/vercel.cjs +1 -0
  424. package/dist/sandbox/vercel.cjs.map +1 -1
  425. package/dist/sandbox/vercel.d.cts +1 -0
  426. package/dist/sandbox/vercel.d.mts +1 -0
  427. package/dist/sandbox/vercel.d.ts +1 -0
  428. package/dist/view/server.cjs +2 -37
  429. package/dist/view/server.cjs.map +1 -1
  430. package/dist/view/server.d.cts +0 -3
  431. package/dist/view/server.d.mts +0 -3
  432. package/dist/view/server.d.ts +0 -3
  433. package/docs-site/zh/reference/builtin-agents.mdx +7 -7
  434. package/docs-site/zh/reference/official-adapters.mdx +4 -4
  435. package/docs-site/zh/reference/report-components.mdx +2 -2
  436. package/docs-site/zh/tutorials/configuration.mdx +2 -2
  437. package/docs-site/zh/tutorials/deploy-report-site.mdx +24 -2
  438. package/docs-site/zh/tutorials/publish-report.mdx +4 -4
  439. package/docs-site/zh/tutorials/sandbox-agent.mdx +5 -5
  440. package/docs-site/zh/tutorials/theming.mdx +2 -2
  441. package/package.json +4 -6
  442. package/dist/record/migration/index.cjs +0 -5
  443. package/dist/record/migration/index.cjs.map +0 -1
  444. package/dist/record/migration/index.d.cts +0 -11
  445. package/dist/record/migration/index.d.mts +0 -11
  446. package/dist/record/migration/index.d.ts +0 -11
  447. package/dist/record/migration/index.js +0 -6
  448. package/dist/record/migration/index.js.map +0 -1
  449. package/dist/report/host/site-runtime.cjs +0 -92
  450. package/dist/report/host/site-runtime.cjs.map +0 -1
  451. package/dist/report/host/site-runtime.d.cts +0 -9
  452. package/dist/report/host/site-runtime.d.mts +0 -9
  453. package/dist/report/host/site-runtime.d.ts +0 -9
  454. package/dist/report/host/site-runtime.js +0 -10
  455. package/dist/report/host/site-runtime.js.map +0 -1
  456. package/dist/view/client-dist/app.css +0 -2
  457. package/dist/view/client-dist/app.js +0 -49
  458. package/dist/view/data.cjs +0 -3
  459. package/dist/view/data.cjs.map +0 -1
  460. package/dist/view/data.d.cts +0 -9
  461. package/dist/view/data.d.mts +0 -9
  462. package/dist/view/data.d.ts +0 -9
  463. package/dist/view/data.js +0 -4
  464. package/dist/view/data.js.map +0 -1
  465. package/dist/view/index.cjs +0 -24
  466. package/dist/view/index.cjs.map +0 -1
  467. package/dist/view/index.d.cts +0 -9
  468. package/dist/view/index.d.mts +0 -9
  469. package/dist/view/index.d.ts +0 -9
  470. package/dist/view/index.js +0 -28
  471. package/dist/view/index.js.map +0 -1
  472. package/dist/view/report-view-cache.cjs +0 -200
  473. package/dist/view/report-view-cache.cjs.map +0 -1
  474. package/dist/view/report-view-cache.d.cts +0 -67
  475. package/dist/view/report-view-cache.d.mts +0 -67
  476. package/dist/view/report-view-cache.d.ts +0 -67
  477. package/dist/view/report-view-cache.js +0 -8
  478. package/dist/view/report-view-cache.js.map +0 -1
  479. package/dist/view/shared/types.cjs +0 -3
  480. package/dist/view/shared/types.cjs.map +0 -1
  481. package/dist/view/shared/types.d.cts +0 -51
  482. package/dist/view/shared/types.d.mts +0 -51
  483. package/dist/view/shared/types.d.ts +0 -51
  484. package/dist/view/shared/types.js +0 -4
  485. package/dist/view/shared/types.js.map +0 -1
  486. package/dist/view/site.cjs +0 -32
  487. package/dist/view/site.cjs.map +0 -1
  488. package/dist/view/site.d.cts +0 -24
  489. package/dist/view/site.d.mts +0 -24
  490. package/dist/view/site.d.ts +0 -24
  491. package/dist/view/site.js +0 -8
  492. package/dist/view/site.js.map +0 -1
  493. package/dist/view/styles.css +0 -170
  494. package/dist/view/template.html +0 -17
@@ -44,13 +44,13 @@ description: "NiceEval 内置的 claude-code、codex、bub 适配器分别做到
44
44
  ### codex
45
45
 
46
46
  - 连接方式:Sandbox 里跑 `codex exec --json`(续接时是 `codex exec resume <id> --json`),stdout JSONL 当 transcript。命令带 `--dangerously-bypass-approvals-and-sandbox` 与 `--dangerously-bypass-hook-trust`:Sandbox 里没人能回答 codex 的交互确认,插件或 `postSetup` 装好的 hook 因此不需要交互授信就能生效。
47
- - 鉴权:`OPENAI_API_KEY`,可选 `OPENAI_BASE_URL` 接 OpenAI 兼容代理。配置项见下方 `CodexConfig`。
47
+ - 鉴权:`CODEX_API_KEY`,可选 `CODEX_BASE_URL` 接 OpenAI 兼容代理。配置项见下方 `CodexConfig`。
48
48
  - `tracing` 通过 `~/.codex/config.toml` 的 `[otel.trace_exporter.otlp-http]` 段配置,协议 `http/json`。
49
49
 
50
50
  ### bub
51
51
 
52
52
  - 连接方式:Sandbox 里跑 `bub run` + `--session-id`,从 `~/.bub/tapes/<hash>.jsonl` 读 tape 当 transcript。
53
- - 鉴权:`OPENAI_API_KEY` + `OPENAI_BASE_URL`(OpenAI 兼容代理)。配置项见下方 `BubConfig`。
53
+ - 鉴权:`BUB_API_KEY` + `BUB_API_BASE`(OpenAI 兼容代理)。配置项见下方 `BubConfig`。
54
54
  - `tracing` 通过环境变量注入(`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` 等),协议 `http/protobuf`。
55
55
  - 安装走 `uv tool install`(非 npm 包),首次安装带 checkpoint 缓存以加速后续 Sandbox。
56
56
 
@@ -168,7 +168,7 @@ preTeardown?: readonly SandboxCommand[];
168
168
  apiKey?: string;
169
169
  ```
170
170
 
171
- 代理 / OpenAI API key。省略时读 OPENAI_API_KEY env。
171
+ 代理 / OpenAI API key。省略时读 CODEX_API_KEY env。
172
172
 
173
173
  #### `baseUrl`
174
174
 
@@ -176,7 +176,7 @@ apiKey?: string;
176
176
  baseUrl?: string;
177
177
  ```
178
178
 
179
- OpenAI 兼容代理 base URL(如 `https://s2a.example.com/v1`)。省略时读 OPENAI_BASE_URL env。
179
+ OpenAI 兼容代理 base URL(如 `https://s2a.example.com/v1`)。省略时读 CODEX_BASE_URL env。
180
180
 
181
181
  #### `env`
182
182
 
@@ -187,7 +187,7 @@ env?: Readonly<globalThis.Record<string, string>>;
187
187
  注入每次 Codex CLI 进程的额外环境变量。首轮 `codex exec` 与续轮 `codex exec resume`
188
188
  使用同一份声明;Codex 启动的 lifecycle Hook、MCP 动态 header 与命令子进程都会继承。
189
189
  值只经 Sandbox command options 传入,不拼进 shell 文本或写入 setup manifest,并全部按
190
- 潜在敏感值从 timing / execution / error 证据中脱敏。`OPENAI_API_KEY` 仍由 `apiKey` 或
190
+ 潜在敏感值从 timing / execution / error 证据中脱敏。`CODEX_API_KEY` 仍由 `apiKey` 或
191
191
  宿主同名环境变量提供,Adapter 的鉴权值会覆盖这里的同名键。
192
192
  env value 不进入 carry 身份。会改变被测行为的非敏感值必须同时声明在 Experiment flags
193
193
  或所属 Plugin identity;只轮换凭据不会让旧结果失效。
@@ -267,7 +267,7 @@ preTeardown?: readonly SandboxCommand[];
267
267
  apiKey?: string;
268
268
  ```
269
269
 
270
- OpenAI 兼容代理的 API key。省略时读 OPENAI_API_KEY env。
270
+ OpenAI 兼容代理的 API key。省略时读 BUB_API_KEY env。
271
271
 
272
272
  #### `apiBase`
273
273
 
@@ -275,7 +275,7 @@ OpenAI 兼容代理的 API key。省略时读 OPENAI_API_KEY env。
275
275
  apiBase?: string;
276
276
  ```
277
277
 
278
- OpenAI 兼容代理的 base URL。省略时读 OPENAI_BASE_URL env。
278
+ OpenAI 兼容代理的 base URL。省略时读 BUB_API_BASE env。
279
279
 
280
280
  #### `skills`
281
281
 
@@ -64,8 +64,8 @@ export default defineExperiment({
64
64
 
65
65
  ### codex
66
66
 
67
- - **鉴权**:`OPENAI_API_KEY`(工厂参数 `apiKey` 可覆盖),可选 `OPENAI_BASE_URL`(工厂参数 `baseUrl`)接 OpenAI 兼容代理。
68
- - **Agent 进程环境**:`env` 会注入每次 `codex exec` 与 `codex exec resume`。Codex 启动的 Session 生命周期 Hook、MCP 动态请求头和命令子进程都会继承。值不会拼进 shell 文本或写入安装清单,并按潜在敏感值从 timing、execution 与错误证据中脱敏。`OPENAI_API_KEY` 仍由 `apiKey` 或宿主环境提供,并覆盖 `env` 里的同名键。`PATH` 是 Sandbox 受管变量,不接受经 `env` 声明——出现即在 `codexAgent()` 调用时报错,改用 Sandbox 的 `pathPrepend`(见 [Sandbox provider](/zh/tutorials/sandbox-providers))。
67
+ - **鉴权**:`CODEX_API_KEY`(工厂参数 `apiKey` 可覆盖),可选 `CODEX_BASE_URL`(工厂参数 `baseUrl`)接 OpenAI 兼容代理。
68
+ - **Agent 进程环境**:`env` 会注入每次 `codex exec` 与 `codex exec resume`。Codex 启动的 Session 生命周期 Hook、MCP 动态请求头和命令子进程都会继承。值不会拼进 shell 文本或写入安装清单,并按潜在敏感值从 timing、execution 与错误证据中脱敏。`CODEX_API_KEY` 仍由 `apiKey` 或宿主环境提供,并覆盖 `env` 里的同名键。`PATH` 是 Sandbox 受管变量,不接受经 `env` 声明——出现即在 `codexAgent()` 调用时报错,改用 Sandbox 的 `pathPrepend`(见 [Sandbox provider](/zh/tutorials/sandbox-providers))。
69
69
  - **装 MCP server**:`mcpServers` 配置项,`setup` 阶段追加进 `~/.codex/config.toml` 的 `[mcp_servers.<name>]` 段。两种形态按字段区分:本地 stdio 进程写 `command`(可带 `args` / `env`)。远程 Streamable HTTP 端点写 `url`(可带 `headers`,写成 `[mcp_servers.<name>.http_headers]` 子表)。`url` 要 Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
70
70
 
71
71
  <Warning>
@@ -120,7 +120,7 @@ export default defineExperiment({
120
120
 
121
121
  ### bub
122
122
 
123
- - **鉴权**:`OPENAI_API_KEY` + `OPENAI_BASE_URL`(OpenAI 兼容代理),工厂参数 `apiKey` / `apiBase` 可覆盖。
123
+ - **鉴权**:`BUB_API_KEY` + `BUB_API_BASE`(OpenAI 兼容代理),工厂参数 `apiKey` / `apiBase` 可覆盖。
124
124
  - **装 Skill**:`skills: SkillSpec[]`,与另外两个 Adapter 同一个类型。装进 `.agents/skills/<name>/`,发现指引写进 AGENTS.md。
125
125
  - **装插件**:`pythonPlugins: PythonPluginSpec[]`(`{ package }`:PyPI 包、版本约束或 git URL),`setup` 阶段进 `uv tool install … --with <package>`。这个类型只属于 bub。package 集合进安装 checkpoint key,插件不同的两个变体不会复用同一份安装缓存。
126
126
  - **预制 Bub**:NiceEval 的 E2B 配方会把 Bub、OTel 插件和 Python 插件集合算成安装指纹。Adapter 只复用指纹完全一致的环境。仅在 PATH 里放一个 `bub` 不足以证明兼容。构建入口见 [Sandbox provider · 从官方基线继续构建以提速](/zh/tutorials/sandbox-providers#从官方基线继续构建以提速)。
@@ -148,7 +148,7 @@ export default defineExperiment({
148
148
 
149
149
  | | claude-code | codex | bub |
150
150
  |---|---|---|---|
151
- | 鉴权环境变量 | `ANTHROPIC_API_KEY` | `OPENAI_API_KEY` + 可选 `OPENAI_BASE_URL` | `OPENAI_API_KEY` + `OPENAI_BASE_URL` |
151
+ | 鉴权环境变量 | `ANTHROPIC_API_KEY` | `CODEX_API_KEY` + 可选 `CODEX_BASE_URL` | `BUB_API_KEY` + `BUB_API_BASE` |
152
152
  | 额外 Agent 进程环境 | ❌ | ✅ `env` | ❌ |
153
153
  | MCP server | ✅ `mcpServers`(stdio + HTTP) | ✅ `mcpServers`(stdio + HTTP) | ❌ |
154
154
  | Skill | ✅ `skills: SkillSpec[]`(原生发现) | ✅ `skills: SkillSpec[]`(+ 发现指引) | ✅ `skills: SkillSpec[]`(+ 发现指引) |
@@ -109,13 +109,13 @@ const MetricCard = defineComponent<
109
109
 
110
110
  `show --json` 固定输出英语 JSON。内建 Report 输出 Host 拥有的具名领域文档;自定义 Report 输出一个 Page 的 route、标题、80-column rendered text、下载摘要和问题表。两种 v1 JSON 都在顶层以相同的 `projections` 对象携带该目标 Page 的闭合成本数据;它们不包含作者树、HTML、全站路由或站点 identity。
111
111
 
112
- view 与静态导出使用同一份完整站点版本。同一路由的 HTTP body 与导出目录页面 body 逐字节相同。两者都携带同一个 reload client;静态目录找不到 view 的端点时,它会安静停用。禁用 JavaScript 或断开网络后,正文、导航、详情、完整度、问题和下载仍可读。
112
+ view 与静态导出使用同一份完整站点版本。同一路由的 HTTP body 与导出目录页面 body 逐字节相同。两者都携带同一个 Host runtime;静态目录找不到 view 的端点时,实时刷新会安静停用。目录不需要网络、源 Record 或 NiceEval 安装,但浏览器必须启用随包交付的 JavaScript。禁用时页面显示可操作的错误,不维护第二套阅读路径。
113
113
 
114
114
  ## 样式和资源边界
115
115
 
116
116
  Report CSS 是唯一的产品样式 owner。它负责 reset、基础排版、theme token 与组件样式。View shell 只负责浏览器语言切换、reload 状态和 Host 提示,不重绘 Report 内容。
117
117
 
118
- Report 可以在 `head` 中声明结构化 `meta`、`link`、`style` 和 `script`,也可以选择 theme。脚本只能做渐进增强,不能成为正文、导航、Evidence 或机器文档的唯一入口。自定义样式不能建立第二份 reset、theme 或 View shell。
118
+ Report 可以在 `head` 中声明结构化 `meta`、`link`、`style` 和 `script`,也可以选择 theme。Host runtime 负责报告阅读与导航;作者脚本可以增强作者内容,但不能替代已闭合的正文、Evidence 或机器文档。自定义样式不能建立第二份 reset、theme 或 View shell。
119
119
 
120
120
  ## 相关页面
121
121
 
@@ -79,8 +79,8 @@ export default defineConfig({
79
79
  | --- | --- | --- |
80
80
  | `ANTHROPIC_API_KEY` | `claudeCodeAgent()` | 工厂参数 `apiKey` 可覆盖 |
81
81
  | `ANTHROPIC_BASE_URL` | `claudeCodeAgent()` | 网关地址,工厂参数 `baseUrl` 可覆盖 |
82
- | `OPENAI_API_KEY` | `codexAgent()`、`bubAgent()` | 工厂参数 `apiKey` 可覆盖 |
83
- | `OPENAI_BASE_URL` | `codexAgent()`、`bubAgent()` | OpenAI 兼容代理地址,工厂参数 `baseUrl` / `apiBase` 可覆盖 |
82
+ | `CODEX_API_KEY` / `CODEX_BASE_URL` | `codexAgent()` | key 必需,代理地址可选;工厂参数 `apiKey` / `baseUrl` 可覆盖 |
83
+ | `BUB_API_KEY` / `BUB_API_BASE` | `bubAgent()` | 两者必需;工厂参数 `apiKey` / `apiBase` 可覆盖 |
84
84
  | `OPENCLAW_API_KEY` / `OPENCLAW_BASE_URL` | `openClawAgent()` | key 省略时回落 `ANTHROPIC_API_KEY` |
85
85
  | `OPENCODE_API_KEY` / `OPENCODE_BASE_URL` | `openCodeAgent()` | key 省略时回落 `ANTHROPIC_API_KEY` |
86
86
  | `HERMES_API_KEY` / `HERMES_API_BASE` | `hermesAgent()` | key 省略时依次回落 `OPENROUTER_API_KEY`、`ANTHROPIC_API_KEY` |
@@ -38,13 +38,35 @@ GitHub Actions 的构建任务示例:
38
38
  path: ./report-site
39
39
  ```
40
40
 
41
+ ## 用 Netlify 预览 PR 报告
42
+
43
+ Netlify 的 Git Integration 会为 Pull Request 创建 Deploy Preview。仓库只负责定义构建与输出目录,不需要另写 GitHub Actions 或保存 Netlify token。
44
+
45
+ ```toml netlify.toml
46
+ [build]
47
+ publish = "report-site"
48
+ ignore = "exit 0"
49
+
50
+ [context.deploy-preview]
51
+ command = "pnpm install --frozen-lockfile && pnpm exec niceeval --version && pnpm exec niceeval view --out report-site"
52
+ ignore = "exit 1"
53
+ ```
54
+
55
+ 这个默认命令使用项目 lockfile、项目默认 Report 和 project-current Sample。仓库若只想预览某组结果,可以显式加 `--experiment <selector>`。不要加 `--report` 来重复配置里的默认 Report,也不要安装 `niceeval@latest`。
56
+
57
+ 在 Netlify 连接 GitHub 仓库后,关闭普通 branch deploy,并保留 Deploy Previews。`ignore` 的退出码 `0` 会跳过 production 与普通 branch build;Deploy Preview 的覆盖值 `1` 让 PR 构建继续。
58
+
59
+ Report 与 `niceeval.config.ts` 是构建期执行的 Node 代码。Deploy Preview 不应获得 Provider、Judge、GitHub 或生产环境 secrets。公开仓库还应把非团队成员的 deploy request 设为必须人工批准,并拒绝 fork 与 Dependabot 的报告预览。这个审批策略属于 Netlify 站点设置,不能交给 PR 可修改的 `netlify.toml`。
60
+
61
+ Deploy Preview URL 可能被转发。不要把含敏感内容的 Record 发布到公开预览;需要限制读者时,在 Netlify 单独配置 Preview 访问保护。PR 关闭也不等于预览已经删除,保留期与删除由站点管理员管理。
62
+
41
63
  ## 发布前检查
42
64
 
43
65
  导出前,NiceEval 已验证 `pages` 中全部显式声明的普通 Page、参数 Page 实例、链接、资源、下载、`_niceeval/data/projections.json` 和预算;Host 不补建详情 route。成功目录包含 HTML、Report CSS、reload client、作者 asset、下载文件与 projections 文件,后者的 bytes 属于 revision identity;静态目录缺少 reload 端点时,client 安静停用。
44
66
 
45
- 在部署前断开网络并禁用 JavaScript,打开首页和至少一个参数详情页。正文、导航、完整度、问题和下载仍应可读。若本机 `view` 使用同一选择和 Report,同一路由的 HTTP body 与目录页面 body 应逐字节一致。
67
+ 在部署前断开网络但保持随包交付的 JavaScript 启用,打开首页和至少一个参数详情页。正文、导航、完整度、问题和下载仍应可读;再单独禁用 JavaScript,确认页面显示明确的启用提示。若本机 `view` 使用同一选择和 Report,同一路由的 HTTP body 与目录页面 body 应逐字节一致。
46
68
 
47
- `--out` 必须指向不存在的目录。更新内容时,选择新的 Sample、导出到新目录,再切换托管平台的发布版本;不要覆盖旧目录。
69
+ `--out` 必须指向不存在的目录。固定 Sample 零选中结果时,命令以 `report-sample-empty` 失败且不创建目录。已选中结果中的 empty MetricValue 仍会正常呈现。更新内容时,选择新的 Sample、导出到新目录,再切换托管平台的发布版本;不要覆盖旧目录。
48
70
 
49
71
  ## 下一步
50
72
 
@@ -26,7 +26,7 @@ pnpm exec niceeval view --run <run-id> \
26
26
 
27
27
  这个站点版本同时是本机 view 与静态导出的来源。同一路由的 HTTP body 和导出目录中的页面 body 逐字节相同。`--out` 不接受 `--page`,因为静态目录始终包含整个站点。
28
28
 
29
- Analysis 的 `partial`、`empty`、`unsupported` 与 `failed` 是可显示的数据状态,会带着 samples、total、issues 和 refs 一起写入页面。Page callback 失败、参数实例不合法、路径冲突、资源冲突或预算超限会阻止导出;它们不会产生一份缺页的目录。
29
+ Analysis 的 `partial`、`empty`、`unsupported` 与 `failed` 是可显示的数据状态,会带着 samples、total、issues 和 refs 一起写入页面。固定 Sample 零选中结果时,导出以 `report-sample-empty` 失败且不创建目录。Page callback 失败、参数实例不合法、路径冲突、资源冲突或预算超限也会阻止导出;它们不会产生一份缺页的目录。
30
30
 
31
31
  ## 导出目录的边界
32
32
 
@@ -37,9 +37,9 @@ Analysis 的 `partial`、`empty`、`unsupported` 与 `failed` 是可显示的数
37
37
  - 已关闭的 Source / Diff asset、下载文件和 `_niceeval/data/projections.json`;
38
38
  - 站点阅读所需的导航、正文、完整度和问题内容。
39
39
 
40
- 目录不需要源 Record、NiceEval 安装或网络。`_niceeval/data/projections.json` 的 bytes 与页面、资源一起进入 revision identity。它携带和 view 相同的 reload client;静态目录不存在 view 端点时,client 安静停用,不显示错误,也不发起新的 Analysis 读取。
40
+ 目录不需要源 Record、NiceEval 安装或网络。`_niceeval/data/projections.json` 的 bytes 与页面、资源一起进入 revision identity。它携带和 view 相同的 Host runtime;静态目录不存在 view 端点时,实时刷新安静停用,不显示错误,也不发起新的 Analysis 读取。
41
41
 
42
- 在断网浏览器中关闭 JavaScript 后打开首页和至少一个参数页。正文、导航、详情、完整度、问题和下载仍应可读。
42
+ 在断网浏览器中保持随包交付的 JavaScript 启用,打开首页和至少一个参数页。正文、导航、详情、完整度、问题和下载仍应可读;再单独禁用 JavaScript,确认页面显示明确的启用提示而不是局部报告内容。
43
43
 
44
44
  ## 目标目录保护
45
45
 
@@ -63,4 +63,4 @@ pnpm exec niceeval view --experiment ci --out ./report-site --no-open
63
63
 
64
64
  - [部署报告站](/zh/tutorials/deploy-report-site):交给静态托管服务。
65
65
  - [查看结果](/zh/tutorials/viewing-results):理解单目标 `show` 与全站 `view` 的边界。
66
- - [报告 API](/zh/reference/report-components):定义参数 Page、资源与无 JavaScript 阅读内容。
66
+ - [报告 API](/zh/reference/report-components):定义参数 Page、资源与闭合报告内容。
@@ -13,10 +13,10 @@ Sandbox agent 会在隔离环境中启动 coding-agent CLI,给它 workspace
13
13
  运行 Anthropic Claude Code CLI,需要 `ANTHROPIC_API_KEY`。
14
14
  </Card>
15
15
  <Card title="codex" icon="terminal">
16
- 运行 OpenAI Codex CLI,需要 `OPENAI_API_KEY`。
16
+ 运行 OpenAI Codex CLI,需要 `CODEX_API_KEY`。
17
17
  </Card>
18
18
  <Card title="bub" icon="robot">
19
- 运行 bub coding agent,需要 `OPENAI_API_KEY` 与 `OPENAI_BASE_URL`。
19
+ 运行 bub coding agent,需要 `BUB_API_KEY` 与 `BUB_API_BASE`。
20
20
  </Card>
21
21
  </CardGroup>
22
22
 
@@ -95,10 +95,10 @@ export default defineExperiment({
95
95
  | Agent | 必需变量 |
96
96
  |---|---|
97
97
  | `claude-code` | `ANTHROPIC_API_KEY` |
98
- | `codex` | `OPENAI_API_KEY` |
99
- | `bub` | `OPENAI_API_KEY`、`OPENAI_BASE_URL` |
98
+ | `codex` | `CODEX_API_KEY` |
99
+ | `bub` | `BUB_API_KEY`、`BUB_API_BASE` |
100
100
 
101
- 省略工厂参数时,NiceEval `bubAgent()` `codexAgent()` 都读取这组 OpenAI-compatible 变量。旧的 `BUB_API_KEY`、`BUB_API_BASE`、`CODEX_API_KEY`、`CODEX_BASE_URL` 不再读取;运行 Experiment 前要完成改名。
101
+ 这些是各 Agent 的官方变量名。CI 可以只保存一组共享凭据,但要在 Experiment 中通过 `apiKey`、`baseUrl` `apiBase` 显式传入,不会改变 Adapter 读取的变量名。
102
102
 
103
103
  ## 工作流程
104
104
 
@@ -50,13 +50,13 @@ export const brandTheme = defineTheme({
50
50
 
51
51
  Report 可以通过结构化 `head` 声明 `meta`、`link`、`style` 和 `script`。内联内容、属性顺序和本地资源进入站点闭包,因此 view 与静态导出使用相同 bytes。
52
52
 
53
- 上例的 `head` 是结构化声明。这类样式只能服务作者自己具名的内容。不要加入全局 reset、替换 theme token、重画内建组件或修改 View shell。script 只能渐进增强;正文、导航、Evidence 和机器 JSON 不能依赖它。
53
+ 上例的 `head` 是结构化声明。这类样式只能服务作者自己具名的内容。不要加入全局 reset、替换 theme token、重画内建组件或修改 View shell。Host runtime 负责报告阅读与导航;作者 script 可以增强作者内容,但不能替代已闭合的正文、Evidence 或机器 JSON
54
54
 
55
55
  ## 不会改变的边界
56
56
 
57
57
  主题不会改变 `MetricValue`、分母、state、Evidence 或终端文字语义。`show` 仍关闭一个目标 Page;`view` 与 `view --out` 仍构建完整站点。相同 revision 的 HTTP 页面、导出页面、CSS 与 reload client bytes 一致。
58
58
 
59
- 静态目录没有 view reload 端点时,reload client 会安静停用。断开网络或禁用 JavaScript 后,页面仍要保留正文、导航、详情、问题和下载。
59
+ 静态目录没有 view reload 端点时,实时刷新会安静停用。断开网络但启用随包交付的 JavaScript 时,页面仍保留正文、导航、详情、问题和下载;禁用 JavaScript 时只显示启用提示。
60
60
 
61
61
  ## 下一步
62
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "niceeval",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "Agent-native eval tool — eval agents, services, functions, and coding-agent fixtures",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -235,6 +235,7 @@
235
235
  "openai": "^6.49.0",
236
236
  "react": "^19.0.0",
237
237
  "react-dom": "^19.0.0",
238
+ "react-router-dom": "^7.18.2",
238
239
  "remark": "^15.0.1",
239
240
  "remark-gfm": "^4.0.1",
240
241
  "remark-parse": "^11.0.0",
@@ -247,12 +248,9 @@
247
248
  "@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
248
249
  "@opentelemetry/sdk-trace-node": "^2.8.0",
249
250
  "@playwright/test": "1.61.1",
250
- "@radix-ui/react-collapsible": "^1.1.14",
251
251
  "@radix-ui/react-dialog": "^1.1.17",
252
- "@radix-ui/react-tabs": "^1.1.15",
253
252
  "@standard-schema/spec": "1.1.0",
254
253
  "@tailwindcss/postcss": "^4.3.3",
255
- "@tailwindcss/vite": "^4.3.1",
256
254
  "@types/dockerode": "^3.3.31",
257
255
  "@types/node": "^24.0.0",
258
256
  "@types/react": "^19.2.17",
@@ -262,7 +260,6 @@
262
260
  "@vercel/sandbox": "^2.2.1",
263
261
  "@vitejs/plugin-react": "^6.0.3",
264
262
  "braintrust": "^3.20.0",
265
- "class-variance-authority": "^0.7.1",
266
263
  "clsx": "^2.1.1",
267
264
  "concurrently": "^10.0.5",
268
265
  "dockerode": "^4.0.2",
@@ -330,10 +327,11 @@
330
327
  "pr:body": "tsx scripts/pr-body.ts",
331
328
  "docs:reference": "tsx scripts/generate-reference.ts",
332
329
  "tiers:sync": "node scripts/sync-tiers.mjs sync",
333
- "view:build": "vite build --config src/view/app/vite.config.ts",
330
+ "view:build": "vite build --config src/report/client/vite.config.ts",
334
331
  "build:report": "pnpm run build:package",
335
332
  "build:package": "pnpm run view:build && node scripts/package-runtime/build.mjs",
336
333
  "build:index": "tsx scripts/generate-reference.ts --bundled-index",
334
+ "dev:link": "node scripts/link-consumer.mjs",
337
335
  "site:dev": "cd site && node scripts/dev.mjs",
338
336
  "site:build": "cd site && next build && cd .. && tsx scripts/submit-indexnow.ts",
339
337
  "docs:dev": "node scripts/docs-dev.mjs",
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.currentRecordAdjacentMigrations = void 0;
4
- exports.currentRecordAdjacentMigrations = Object.freeze([]);
5
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAUa,QAAA,+BAA+B,GAAG,MAAM,CAAC,MAAM,CAAC,EAAwD,CAAC,CAAC","sourcesContent":["/**\n * The initial public Record release has no predecessor to migrate. Keep the\n * package-owned adjacent-step shape here so a later released schema can add a\n * fixed `n -> n + 1` entry without reviving registries or third-party hooks.\n * This module is intentionally outside the ordinary reader import graph.\n */\nexport interface RecordAdjacentMigration {\n readonly fromSchemaVersion: number;\n readonly toSchemaVersion: number;\n}\nexport const currentRecordAdjacentMigrations = Object.freeze([] as const satisfies readonly RecordAdjacentMigration[]);\n"]}
@@ -1,11 +0,0 @@
1
- /**
2
- * The initial public Record release has no predecessor to migrate. Keep the
3
- * package-owned adjacent-step shape here so a later released schema can add a
4
- * fixed `n -> n + 1` entry without reviving registries or third-party hooks.
5
- * This module is intentionally outside the ordinary reader import graph.
6
- */
7
- export interface RecordAdjacentMigration {
8
- readonly fromSchemaVersion: number;
9
- readonly toSchemaVersion: number;
10
- }
11
- export declare const currentRecordAdjacentMigrations: readonly [];
@@ -1,11 +0,0 @@
1
- /**
2
- * The initial public Record release has no predecessor to migrate. Keep the
3
- * package-owned adjacent-step shape here so a later released schema can add a
4
- * fixed `n -> n + 1` entry without reviving registries or third-party hooks.
5
- * This module is intentionally outside the ordinary reader import graph.
6
- */
7
- export interface RecordAdjacentMigration {
8
- readonly fromSchemaVersion: number;
9
- readonly toSchemaVersion: number;
10
- }
11
- export declare const currentRecordAdjacentMigrations: readonly [];
@@ -1,11 +0,0 @@
1
- /**
2
- * The initial public Record release has no predecessor to migrate. Keep the
3
- * package-owned adjacent-step shape here so a later released schema can add a
4
- * fixed `n -> n + 1` entry without reviving registries or third-party hooks.
5
- * This module is intentionally outside the ordinary reader import graph.
6
- */
7
- export interface RecordAdjacentMigration {
8
- readonly fromSchemaVersion: number;
9
- readonly toSchemaVersion: number;
10
- }
11
- export declare const currentRecordAdjacentMigrations: readonly [];
@@ -1,6 +0,0 @@
1
- import { createRequire as __niceevalCreateRequire } from "node:module";
2
- const __niceevalRequire = __niceevalCreateRequire(import.meta.url);
3
- const __niceevalCanonical = __niceevalRequire("./index.cjs");
4
- const __niceevalExport0 = __niceevalCanonical["currentRecordAdjacentMigrations"];
5
- export { __niceevalExport0 as currentRecordAdjacentMigrations };
6
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"names":[],"mappings":""}
@@ -1,92 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REPORT_RELOAD_RUNTIME = exports.REPORT_LOCALE_RUNTIME = void 0;
4
- exports.reportSiteRuntime = reportSiteRuntime;
5
- /**
6
- * Host-owned behavior shared byte-for-byte by live view and static export.
7
- * Missing refresh endpoints and locked-down storage are normal static-site
8
- * conditions, so every boundary fails quietly without altering report data.
9
- */
10
- exports.REPORT_LOCALE_RUNTIME = `(() => {
11
- "use strict";
12
- const locales = ["en", "zh-CN"];
13
- const views = Array.from(document.querySelectorAll("[data-niceeval-locale]"));
14
- const selectors = Array.from(document.querySelectorAll("[data-niceeval-locale-select]"));
15
- if (views.length === 0) return;
16
- const stored = () => {
17
- try {
18
- const value = localStorage.getItem("niceeval:view:locale");
19
- return locales.includes(value) ? value : undefined;
20
- } catch { return undefined; }
21
- };
22
- const preferred = () => {
23
- const values = typeof navigator === "undefined" ? [] : [navigator.language, ...(navigator.languages || [])];
24
- return values.some(value => String(value).toLowerCase().startsWith("zh")) ? "zh-CN" : "en";
25
- };
26
- const select = (locale, persist) => {
27
- if (!locales.includes(locale)) return;
28
- for (const view of views) view.hidden = view.dataset.niceevalLocale !== locale;
29
- for (const selector of selectors) selector.value = locale;
30
- document.documentElement.lang = locale;
31
- const title = document.documentElement.getAttribute("data-niceeval-title-" + locale.toLowerCase());
32
- if (title !== null) document.title = title;
33
- if (!persist) return;
34
- try { localStorage.setItem("niceeval:view:locale", locale); } catch {}
35
- };
36
- for (const selector of selectors) {
37
- selector.addEventListener("change", () => select(selector.value, true));
38
- }
39
- for (const experiment of document.querySelectorAll("[data-niceeval-experiment-select]")) {
40
- experiment.addEventListener("change", () => {
41
- if (experiment.value) location.href = experiment.value;
42
- });
43
- }
44
- select(stored() || preferred(), false);
45
- })();`;
46
- exports.REPORT_RELOAD_RUNTIME = `(() => {
47
- "use strict";
48
- if (location.protocol !== "http:" && location.protocol !== "https:") return;
49
- const source = document.currentScript && document.currentScript.src;
50
- if (!source) return;
51
- const endpoint = new URL("refresh", source).toString();
52
- let observed;
53
- let live;
54
- const probe = async () => {
55
- try {
56
- // The runtime file exists in both view and static output with identical
57
- // bytes. Only the live Host adds its revision header, so a generic
58
- // static server stops here without ever requesting a missing endpoint
59
- // (and therefore without producing a browser 404 console error).
60
- if (live === undefined) {
61
- const runtime = await fetch(source, {
62
- cache: "no-store",
63
- credentials: "same-origin",
64
- });
65
- live = runtime.ok && runtime.headers.has("x-niceeval-report-revision");
66
- }
67
- if (!live) return;
68
- const response = await fetch(endpoint, {
69
- cache: "no-store",
70
- credentials: "same-origin",
71
- headers: { "x-niceeval-refresh-probe": "1" },
72
- });
73
- if (response.status !== 204) return;
74
- const identity = response.headers.get("x-niceeval-report-content-hash");
75
- if (response.headers.get("x-niceeval-view-stale") === "1" ||
76
- (observed !== undefined && identity !== null && identity !== observed)) {
77
- location.reload();
78
- return;
79
- }
80
- if (identity !== null) observed = identity;
81
- setTimeout(probe, 1000);
82
- } catch {
83
- // Static, offline, and stopped view endpoints quietly disable reload.
84
- }
85
- };
86
- setTimeout(probe, 1000);
87
- })();`;
88
- /** Package enhancer first, then shell locale and optional reload behavior. */
89
- function reportSiteRuntime(enhancer) {
90
- return `${enhancer.trimEnd()}\n${exports.REPORT_LOCALE_RUNTIME}\n${exports.REPORT_RELOAD_RUNTIME}\n`;
91
- }
92
- //# sourceMappingURL=site-runtime.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"site-runtime.js","sourceRoot":"","sources":["site-runtime.ts"],"names":[],"mappings":";;;AAoFA,8CAEC;AAtFD;;;;GAIG;AACU,QAAA,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmC/B,CAAC;AACM,QAAA,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAyC/B,CAAC;AACP,8EAA8E;AAC9E,SAAgB,iBAAiB,CAAC,QAAgB;IAC9C,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,6BAAqB,KAAK,6BAAqB,IAAI,CAAC;AACzF,CAAC","sourcesContent":["/**\n * Host-owned behavior shared byte-for-byte by live view and static export.\n * Missing refresh endpoints and locked-down storage are normal static-site\n * conditions, so every boundary fails quietly without altering report data.\n */\nexport const REPORT_LOCALE_RUNTIME = `(() => {\n \"use strict\";\n const locales = [\"en\", \"zh-CN\"];\n const views = Array.from(document.querySelectorAll(\"[data-niceeval-locale]\"));\n const selectors = Array.from(document.querySelectorAll(\"[data-niceeval-locale-select]\"));\n if (views.length === 0) return;\n const stored = () => {\n try {\n const value = localStorage.getItem(\"niceeval:view:locale\");\n return locales.includes(value) ? value : undefined;\n } catch { return undefined; }\n };\n const preferred = () => {\n const values = typeof navigator === \"undefined\" ? [] : [navigator.language, ...(navigator.languages || [])];\n return values.some(value => String(value).toLowerCase().startsWith(\"zh\")) ? \"zh-CN\" : \"en\";\n };\n const select = (locale, persist) => {\n if (!locales.includes(locale)) return;\n for (const view of views) view.hidden = view.dataset.niceevalLocale !== locale;\n for (const selector of selectors) selector.value = locale;\n document.documentElement.lang = locale;\n const title = document.documentElement.getAttribute(\"data-niceeval-title-\" + locale.toLowerCase());\n if (title !== null) document.title = title;\n if (!persist) return;\n try { localStorage.setItem(\"niceeval:view:locale\", locale); } catch {}\n };\n for (const selector of selectors) {\n selector.addEventListener(\"change\", () => select(selector.value, true));\n }\n for (const experiment of document.querySelectorAll(\"[data-niceeval-experiment-select]\")) {\n experiment.addEventListener(\"change\", () => {\n if (experiment.value) location.href = experiment.value;\n });\n }\n select(stored() || preferred(), false);\n})();`;\nexport const REPORT_RELOAD_RUNTIME = `(() => {\n \"use strict\";\n if (location.protocol !== \"http:\" && location.protocol !== \"https:\") return;\n const source = document.currentScript && document.currentScript.src;\n if (!source) return;\n const endpoint = new URL(\"refresh\", source).toString();\n let observed;\n let live;\n const probe = async () => {\n try {\n // The runtime file exists in both view and static output with identical\n // bytes. Only the live Host adds its revision header, so a generic\n // static server stops here without ever requesting a missing endpoint\n // (and therefore without producing a browser 404 console error).\n if (live === undefined) {\n const runtime = await fetch(source, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n });\n live = runtime.ok && runtime.headers.has(\"x-niceeval-report-revision\");\n }\n if (!live) return;\n const response = await fetch(endpoint, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n headers: { \"x-niceeval-refresh-probe\": \"1\" },\n });\n if (response.status !== 204) return;\n const identity = response.headers.get(\"x-niceeval-report-content-hash\");\n if (response.headers.get(\"x-niceeval-view-stale\") === \"1\" ||\n (observed !== undefined && identity !== null && identity !== observed)) {\n location.reload();\n return;\n }\n if (identity !== null) observed = identity;\n setTimeout(probe, 1000);\n } catch {\n // Static, offline, and stopped view endpoints quietly disable reload.\n }\n };\n setTimeout(probe, 1000);\n})();`;\n/** Package enhancer first, then shell locale and optional reload behavior. */\nexport function reportSiteRuntime(enhancer: string): string {\n return `${enhancer.trimEnd()}\\n${REPORT_LOCALE_RUNTIME}\\n${REPORT_RELOAD_RUNTIME}\\n`;\n}\n"]}
@@ -1,9 +0,0 @@
1
- /**
2
- * Host-owned behavior shared byte-for-byte by live view and static export.
3
- * Missing refresh endpoints and locked-down storage are normal static-site
4
- * conditions, so every boundary fails quietly without altering report data.
5
- */
6
- export declare const REPORT_LOCALE_RUNTIME = "(() => {\n \"use strict\";\n const locales = [\"en\", \"zh-CN\"];\n const views = Array.from(document.querySelectorAll(\"[data-niceeval-locale]\"));\n const selectors = Array.from(document.querySelectorAll(\"[data-niceeval-locale-select]\"));\n if (views.length === 0) return;\n const stored = () => {\n try {\n const value = localStorage.getItem(\"niceeval:view:locale\");\n return locales.includes(value) ? value : undefined;\n } catch { return undefined; }\n };\n const preferred = () => {\n const values = typeof navigator === \"undefined\" ? [] : [navigator.language, ...(navigator.languages || [])];\n return values.some(value => String(value).toLowerCase().startsWith(\"zh\")) ? \"zh-CN\" : \"en\";\n };\n const select = (locale, persist) => {\n if (!locales.includes(locale)) return;\n for (const view of views) view.hidden = view.dataset.niceevalLocale !== locale;\n for (const selector of selectors) selector.value = locale;\n document.documentElement.lang = locale;\n const title = document.documentElement.getAttribute(\"data-niceeval-title-\" + locale.toLowerCase());\n if (title !== null) document.title = title;\n if (!persist) return;\n try { localStorage.setItem(\"niceeval:view:locale\", locale); } catch {}\n };\n for (const selector of selectors) {\n selector.addEventListener(\"change\", () => select(selector.value, true));\n }\n for (const experiment of document.querySelectorAll(\"[data-niceeval-experiment-select]\")) {\n experiment.addEventListener(\"change\", () => {\n if (experiment.value) location.href = experiment.value;\n });\n }\n select(stored() || preferred(), false);\n})();";
7
- export declare const REPORT_RELOAD_RUNTIME = "(() => {\n \"use strict\";\n if (location.protocol !== \"http:\" && location.protocol !== \"https:\") return;\n const source = document.currentScript && document.currentScript.src;\n if (!source) return;\n const endpoint = new URL(\"refresh\", source).toString();\n let observed;\n let live;\n const probe = async () => {\n try {\n // The runtime file exists in both view and static output with identical\n // bytes. Only the live Host adds its revision header, so a generic\n // static server stops here without ever requesting a missing endpoint\n // (and therefore without producing a browser 404 console error).\n if (live === undefined) {\n const runtime = await fetch(source, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n });\n live = runtime.ok && runtime.headers.has(\"x-niceeval-report-revision\");\n }\n if (!live) return;\n const response = await fetch(endpoint, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n headers: { \"x-niceeval-refresh-probe\": \"1\" },\n });\n if (response.status !== 204) return;\n const identity = response.headers.get(\"x-niceeval-report-content-hash\");\n if (response.headers.get(\"x-niceeval-view-stale\") === \"1\" ||\n (observed !== undefined && identity !== null && identity !== observed)) {\n location.reload();\n return;\n }\n if (identity !== null) observed = identity;\n setTimeout(probe, 1000);\n } catch {\n // Static, offline, and stopped view endpoints quietly disable reload.\n }\n };\n setTimeout(probe, 1000);\n})();";
8
- /** Package enhancer first, then shell locale and optional reload behavior. */
9
- export declare function reportSiteRuntime(enhancer: string): string;
@@ -1,9 +0,0 @@
1
- /**
2
- * Host-owned behavior shared byte-for-byte by live view and static export.
3
- * Missing refresh endpoints and locked-down storage are normal static-site
4
- * conditions, so every boundary fails quietly without altering report data.
5
- */
6
- export declare const REPORT_LOCALE_RUNTIME = "(() => {\n \"use strict\";\n const locales = [\"en\", \"zh-CN\"];\n const views = Array.from(document.querySelectorAll(\"[data-niceeval-locale]\"));\n const selectors = Array.from(document.querySelectorAll(\"[data-niceeval-locale-select]\"));\n if (views.length === 0) return;\n const stored = () => {\n try {\n const value = localStorage.getItem(\"niceeval:view:locale\");\n return locales.includes(value) ? value : undefined;\n } catch { return undefined; }\n };\n const preferred = () => {\n const values = typeof navigator === \"undefined\" ? [] : [navigator.language, ...(navigator.languages || [])];\n return values.some(value => String(value).toLowerCase().startsWith(\"zh\")) ? \"zh-CN\" : \"en\";\n };\n const select = (locale, persist) => {\n if (!locales.includes(locale)) return;\n for (const view of views) view.hidden = view.dataset.niceevalLocale !== locale;\n for (const selector of selectors) selector.value = locale;\n document.documentElement.lang = locale;\n const title = document.documentElement.getAttribute(\"data-niceeval-title-\" + locale.toLowerCase());\n if (title !== null) document.title = title;\n if (!persist) return;\n try { localStorage.setItem(\"niceeval:view:locale\", locale); } catch {}\n };\n for (const selector of selectors) {\n selector.addEventListener(\"change\", () => select(selector.value, true));\n }\n for (const experiment of document.querySelectorAll(\"[data-niceeval-experiment-select]\")) {\n experiment.addEventListener(\"change\", () => {\n if (experiment.value) location.href = experiment.value;\n });\n }\n select(stored() || preferred(), false);\n})();";
7
- export declare const REPORT_RELOAD_RUNTIME = "(() => {\n \"use strict\";\n if (location.protocol !== \"http:\" && location.protocol !== \"https:\") return;\n const source = document.currentScript && document.currentScript.src;\n if (!source) return;\n const endpoint = new URL(\"refresh\", source).toString();\n let observed;\n let live;\n const probe = async () => {\n try {\n // The runtime file exists in both view and static output with identical\n // bytes. Only the live Host adds its revision header, so a generic\n // static server stops here without ever requesting a missing endpoint\n // (and therefore without producing a browser 404 console error).\n if (live === undefined) {\n const runtime = await fetch(source, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n });\n live = runtime.ok && runtime.headers.has(\"x-niceeval-report-revision\");\n }\n if (!live) return;\n const response = await fetch(endpoint, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n headers: { \"x-niceeval-refresh-probe\": \"1\" },\n });\n if (response.status !== 204) return;\n const identity = response.headers.get(\"x-niceeval-report-content-hash\");\n if (response.headers.get(\"x-niceeval-view-stale\") === \"1\" ||\n (observed !== undefined && identity !== null && identity !== observed)) {\n location.reload();\n return;\n }\n if (identity !== null) observed = identity;\n setTimeout(probe, 1000);\n } catch {\n // Static, offline, and stopped view endpoints quietly disable reload.\n }\n };\n setTimeout(probe, 1000);\n})();";
8
- /** Package enhancer first, then shell locale and optional reload behavior. */
9
- export declare function reportSiteRuntime(enhancer: string): string;
@@ -1,9 +0,0 @@
1
- /**
2
- * Host-owned behavior shared byte-for-byte by live view and static export.
3
- * Missing refresh endpoints and locked-down storage are normal static-site
4
- * conditions, so every boundary fails quietly without altering report data.
5
- */
6
- export declare const REPORT_LOCALE_RUNTIME = "(() => {\n \"use strict\";\n const locales = [\"en\", \"zh-CN\"];\n const views = Array.from(document.querySelectorAll(\"[data-niceeval-locale]\"));\n const selectors = Array.from(document.querySelectorAll(\"[data-niceeval-locale-select]\"));\n if (views.length === 0) return;\n const stored = () => {\n try {\n const value = localStorage.getItem(\"niceeval:view:locale\");\n return locales.includes(value) ? value : undefined;\n } catch { return undefined; }\n };\n const preferred = () => {\n const values = typeof navigator === \"undefined\" ? [] : [navigator.language, ...(navigator.languages || [])];\n return values.some(value => String(value).toLowerCase().startsWith(\"zh\")) ? \"zh-CN\" : \"en\";\n };\n const select = (locale, persist) => {\n if (!locales.includes(locale)) return;\n for (const view of views) view.hidden = view.dataset.niceevalLocale !== locale;\n for (const selector of selectors) selector.value = locale;\n document.documentElement.lang = locale;\n const title = document.documentElement.getAttribute(\"data-niceeval-title-\" + locale.toLowerCase());\n if (title !== null) document.title = title;\n if (!persist) return;\n try { localStorage.setItem(\"niceeval:view:locale\", locale); } catch {}\n };\n for (const selector of selectors) {\n selector.addEventListener(\"change\", () => select(selector.value, true));\n }\n for (const experiment of document.querySelectorAll(\"[data-niceeval-experiment-select]\")) {\n experiment.addEventListener(\"change\", () => {\n if (experiment.value) location.href = experiment.value;\n });\n }\n select(stored() || preferred(), false);\n})();";
7
- export declare const REPORT_RELOAD_RUNTIME = "(() => {\n \"use strict\";\n if (location.protocol !== \"http:\" && location.protocol !== \"https:\") return;\n const source = document.currentScript && document.currentScript.src;\n if (!source) return;\n const endpoint = new URL(\"refresh\", source).toString();\n let observed;\n let live;\n const probe = async () => {\n try {\n // The runtime file exists in both view and static output with identical\n // bytes. Only the live Host adds its revision header, so a generic\n // static server stops here without ever requesting a missing endpoint\n // (and therefore without producing a browser 404 console error).\n if (live === undefined) {\n const runtime = await fetch(source, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n });\n live = runtime.ok && runtime.headers.has(\"x-niceeval-report-revision\");\n }\n if (!live) return;\n const response = await fetch(endpoint, {\n cache: \"no-store\",\n credentials: \"same-origin\",\n headers: { \"x-niceeval-refresh-probe\": \"1\" },\n });\n if (response.status !== 204) return;\n const identity = response.headers.get(\"x-niceeval-report-content-hash\");\n if (response.headers.get(\"x-niceeval-view-stale\") === \"1\" ||\n (observed !== undefined && identity !== null && identity !== observed)) {\n location.reload();\n return;\n }\n if (identity !== null) observed = identity;\n setTimeout(probe, 1000);\n } catch {\n // Static, offline, and stopped view endpoints quietly disable reload.\n }\n };\n setTimeout(probe, 1000);\n})();";
8
- /** Package enhancer first, then shell locale and optional reload behavior. */
9
- export declare function reportSiteRuntime(enhancer: string): string;
@@ -1,10 +0,0 @@
1
- import { createRequire as __niceevalCreateRequire } from "node:module";
2
- const __niceevalRequire = __niceevalCreateRequire(import.meta.url);
3
- const __niceevalCanonical = __niceevalRequire("./site-runtime.cjs");
4
- const __niceevalExport0 = __niceevalCanonical["REPORT_LOCALE_RUNTIME"];
5
- export { __niceevalExport0 as REPORT_LOCALE_RUNTIME };
6
- const __niceevalExport1 = __niceevalCanonical["REPORT_RELOAD_RUNTIME"];
7
- export { __niceevalExport1 as REPORT_RELOAD_RUNTIME };
8
- const __niceevalExport2 = __niceevalCanonical["reportSiteRuntime"];
9
- export { __niceevalExport2 as reportSiteRuntime };
10
- //# sourceMappingURL=site-runtime.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"site-runtime.js","sources":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- /*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-font-weight:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-panel:var(--panel);--color-panel-2:var(--panel-2);--color-line:var(--line);--color-line-strong:var(--line-strong);--color-text:var(--text);--color-muted:var(--muted)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.inset-0{inset:0}.top-1\/2{top:50%}.left-1\/2{left:50%}.z-\[200\]{z-index:200}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-7{height:calc(var(--spacing) * 7)}.max-h-\[min\(86vh\,820px\)\]{max-height:min(86vh,820px)}.w-7{width:calc(var(--spacing) * 7)}.w-\[min\(1120px\,calc\(100vw-48px\)\)\]{width:min(1120px,100vw - 48px)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.place-items-center{place-items:center}.items-center{align-items:center}.justify-end{justify-content:flex-end}.gap-\[22px\]{gap:22px}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-\(--radius\){border-radius:var(--radius)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-none{--tw-border-style:none;border-style:none}.border-line{border-color:var(--color-line)}.border-line-strong{border-color:var(--color-line-strong)}.border-transparent{border-color:#0000}.bg-black\/90{background-color:#000000e6}@supports (color:color-mix(in lab, red, red)){.bg-black\/90{background-color:color-mix(in oklab, var(--color-black) 90%, transparent)}}.bg-panel{background-color:var(--color-panel)}.bg-transparent{background-color:#0000}.p-0{padding:0}.px-7{padding-inline:calc(var(--spacing) * 7)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-7{padding-bottom:calc(var(--spacing) * 7)}.font-\[inherit\]{font-family:inherit}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-muted{color:var(--color-muted)}.shadow-\[0_20px_60px_rgba\(0\,0\,0\,0\.45\)\]{--tw-shadow:0 20px 60px var(--tw-shadow-color,#00000073);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:border-line:hover{border-color:var(--color-line)}.hover\:bg-panel-2:hover{background-color:var(--color-panel-2)}.hover\:text-text:hover{color:var(--color-text)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.data-\[state\=active\]\:font-\[560\][data-state=active]{--tw-font-weight:560;font-weight:560}.data-\[state\=active\]\:text-text[data-state=active]{color:var(--color-text)}@media not all and (width>=760px){.max-\[760px\]\:hidden{display:none}}}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--bg:var(--niceeval-color-page,#050505);--panel:var(--niceeval-color-surface,#0b0b0b);--panel-2:var(--niceeval-color-surface-subtle,#111);--line:var(--niceeval-color-border,#262626);--line-strong:var(--niceeval-color-border-strong,#343434);--text:var(--niceeval-color-text,#ededed);--muted:var(--niceeval-color-text-secondary,#a1a1aa);--soft:var(--niceeval-color-text-tertiary,#74747b);--good:var(--niceeval-color-positive,#3ddc97);--bad:var(--niceeval-color-negative,#ff6b6b);--warn:var(--niceeval-color-warning,#e8b84a);--blue:var(--niceeval-color-accent,#cbd6dc);--focus:var(--niceeval-color-focus,#cbd6dc);--radius:var(--niceeval-radius,0);font-family:var(--niceeval-font-sans,ui-sans-serif, system-ui, -apple-system, "Segoe UI", "Helvetica Neue", "PingFang SC", sans-serif)}*{box-sizing:border-box}html{scrollbar-gutter:stable;overflow-y:scroll}body{background:var(--bg);color:var(--text);letter-spacing:0;margin:0}a{color:inherit}.topbar{border-bottom:1px solid var(--line);background:var(--bg);z-index:10;justify-content:space-between;align-items:center;gap:28px;height:64px;padding:0 clamp(20px,5vw,80px);display:flex;position:sticky;top:0}.brand{flex:none;align-items:baseline;gap:12px;font-size:20px;font-weight:690;text-decoration:none;display:flex}.mark{border:1.25px solid var(--text);width:18px;height:18px;display:inline-block;transform:rotate(45deg)}.lang-switch{border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);flex:none;align-items:center;display:inline-flex;overflow:hidden}.lang-switch button{border:0;border-right:1px solid var(--line);min-width:44px;height:30px;color:var(--muted);font:inherit;cursor:pointer;background:0 0;font-size:12px;line-height:1}.lang-switch button:last-child{border-right:0}.lang-switch button:hover{color:var(--text)}.lang-switch button.is-active{background:var(--panel-2);color:var(--text);font-weight:620}main{width:min(1120px,100vw - 40px);margin:0 auto;padding:clamp(52px,7vw,82px) 0 72px}.report-slot{margin:0 auto 36px}@media (width<=760px){.topbar{padding:0 20px}.lang-switch button{min-width:40px}main{width:min(100vw - 28px,1120px);padding-top:42px}}.shell-links{align-items:center;gap:8px;margin-left:auto;display:flex}.shell-links a{color:var(--soft);align-items:center;gap:6px;padding:6px 4px;font-size:13px;text-decoration:none;display:inline-flex}.shell-links a:hover{color:var(--text)}.shell-link-icon{align-items:center;display:inline-flex}.shell-link-icon svg{fill:currentColor;width:14px;height:14px;display:block}.site-footer{color:var(--soft);flex-wrap:wrap;justify-content:center;align-items:baseline;gap:12px;padding:24px 24px 32px;font-size:12px;display:flex}.niceeval-page-error pre{white-space:pre-wrap}.view-rebuild-error{z-index:9999;border:1px solid var(--fail,#a33a30);background:var(--bg,#fff);max-width:50vw;color:var(--fail,#a33a30);white-space:pre-wrap;margin:0;padding:10px;position:fixed;bottom:12px;right:12px}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-font-weight{syntax:"*";inherits:false}