niceeval 0.5.4 → 0.6.1

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 (337) hide show
  1. package/INDEX.md +55 -0
  2. package/dist/agents/types.d.ts +321 -0
  3. package/dist/context/types.d.ts +335 -0
  4. package/dist/i18n/core.d.ts +11 -0
  5. package/dist/i18n/en.d.ts +181 -0
  6. package/dist/i18n/index.d.ts +5 -0
  7. package/dist/i18n/zh-CN.d.ts +183 -0
  8. package/dist/o11y/otlp/parse.d.ts +3 -0
  9. package/dist/o11y/otlp/receiver.d.ts +21 -0
  10. package/dist/o11y/otlp/turn-otel.d.ts +43 -0
  11. package/dist/o11y/types.d.ts +190 -0
  12. package/dist/report/aggregate.d.ts +57 -0
  13. package/dist/report/aggregate.js +212 -0
  14. package/dist/report/built-ins/experiment-comparison.d.ts +1 -0
  15. package/dist/report/built-ins/experiment-comparison.js +13 -0
  16. package/dist/report/built-ins/index.d.ts +1 -0
  17. package/dist/report/built-ins/index.js +2 -0
  18. package/dist/report/components.d.ts +180 -0
  19. package/dist/report/components.js +132 -0
  20. package/dist/report/compute.d.ts +106 -0
  21. package/dist/report/compute.js +600 -0
  22. package/dist/report/flag.d.ts +6 -0
  23. package/dist/report/flag.js +8 -0
  24. package/dist/report/format.d.ts +26 -0
  25. package/dist/report/format.js +109 -0
  26. package/dist/report/index.d.ts +19 -0
  27. package/dist/report/index.js +30 -0
  28. package/dist/report/load.d.ts +12 -0
  29. package/dist/report/load.js +56 -0
  30. package/dist/report/locale.d.ts +94 -0
  31. package/dist/report/locale.js +183 -0
  32. package/dist/report/metrics.d.ts +21 -0
  33. package/dist/report/metrics.js +115 -0
  34. package/dist/report/primitives.d.ts +64 -0
  35. package/dist/report/primitives.js +113 -0
  36. package/dist/report/react/AttemptList.d.ts +23 -0
  37. package/dist/report/react/AttemptList.js +19 -0
  38. package/dist/report/react/DeltaTable.d.ts +8 -0
  39. package/dist/report/react/DeltaTable.js +24 -0
  40. package/dist/report/react/EvalList.d.ts +10 -0
  41. package/dist/report/react/EvalList.js +0 -0
  42. package/dist/report/react/ExperimentList.d.ts +11 -0
  43. package/dist/report/react/ExperimentList.js +67 -0
  44. package/dist/report/react/GroupSummary.d.ts +8 -0
  45. package/dist/report/react/GroupSummary.js +8 -0
  46. package/dist/report/react/MetricBars.d.ts +10 -0
  47. package/dist/report/react/MetricBars.js +48 -0
  48. package/dist/report/react/MetricLine.d.ts +9 -0
  49. package/dist/report/react/MetricLine.js +68 -0
  50. package/dist/report/react/MetricMatrix.d.ts +10 -0
  51. package/dist/report/react/MetricMatrix.js +23 -0
  52. package/dist/report/react/MetricScatter.d.ts +9 -0
  53. package/dist/report/react/MetricScatter.js +96 -0
  54. package/dist/report/react/MetricTable.d.ts +11 -0
  55. package/dist/report/react/MetricTable.js +26 -0
  56. package/dist/report/react/RunOverview.d.ts +8 -0
  57. package/dist/report/react/RunOverview.js +12 -0
  58. package/dist/report/react/Scoreboard.d.ts +8 -0
  59. package/dist/report/react/Scoreboard.js +26 -0
  60. package/dist/report/react/cell.d.ts +9 -0
  61. package/dist/report/react/cell.js +9 -0
  62. package/dist/report/react/chart-math.d.ts +14 -0
  63. package/dist/report/react/chart-math.js +68 -0
  64. package/dist/report/react/colors.d.ts +14 -0
  65. package/dist/report/react/colors.js +45 -0
  66. package/dist/report/react/fixtures.d.ts +19 -0
  67. package/dist/report/react/fixtures.js +398 -0
  68. package/dist/report/react/format.d.ts +3 -0
  69. package/dist/report/react/format.js +7 -0
  70. package/dist/report/react/index.d.ts +6 -0
  71. package/dist/report/react/index.js +14 -0
  72. package/dist/report/report.d.ts +24 -0
  73. package/dist/report/report.js +49 -0
  74. package/dist/report/text/faces.d.ts +29 -0
  75. package/dist/report/text/faces.js +541 -0
  76. package/dist/report/text/layout.d.ts +75 -0
  77. package/dist/report/text/layout.js +173 -0
  78. package/dist/report/text/plot.d.ts +37 -0
  79. package/dist/report/text/plot.js +81 -0
  80. package/dist/report/text/table.d.ts +8 -0
  81. package/dist/report/text/table.js +86 -0
  82. package/dist/report/tree.d.ts +99 -0
  83. package/dist/report/tree.js +228 -0
  84. package/dist/report/types.d.ts +408 -0
  85. package/dist/report/types.js +4 -0
  86. package/dist/report/web.d.ts +15 -0
  87. package/dist/report/web.js +37 -0
  88. package/dist/results/locator.d.ts +75 -0
  89. package/dist/results/locator.js +0 -0
  90. package/dist/results/select.d.ts +45 -0
  91. package/dist/results/select.js +230 -0
  92. package/dist/results/source-hash.d.ts +9 -0
  93. package/dist/results/types.d.ts +204 -0
  94. package/dist/runner/eval-source.d.ts +22 -0
  95. package/dist/runner/fingerprint.d.ts +23 -0
  96. package/dist/runner/types.d.ts +332 -0
  97. package/dist/sandbox/docker-stream.d.ts +24 -0
  98. package/dist/sandbox/docker.d.ts +84 -0
  99. package/dist/sandbox/e2b.d.ts +31 -0
  100. package/dist/sandbox/errors.d.ts +4 -0
  101. package/dist/sandbox/local-files.d.ts +6 -0
  102. package/dist/sandbox/paths.d.ts +4 -0
  103. package/dist/sandbox/registry.d.ts +13 -0
  104. package/dist/sandbox/resolve.d.ts +40 -0
  105. package/dist/sandbox/retry.d.ts +10 -0
  106. package/dist/sandbox/shell.d.ts +11 -0
  107. package/dist/sandbox/source-files.d.ts +13 -0
  108. package/dist/sandbox/types.d.ts +203 -0
  109. package/dist/sandbox/vercel.d.ts +37 -0
  110. package/dist/scoring/types.d.ts +70 -0
  111. package/dist/shared/aggregate.d.ts +29 -0
  112. package/dist/shared/aggregate.js +55 -0
  113. package/dist/shared/types.d.ts +27 -0
  114. package/dist/shared/verdict.d.ts +27 -0
  115. package/dist/shared/verdict.js +34 -0
  116. package/dist/tty-line.d.ts +6 -0
  117. package/dist/types.d.ts +7 -0
  118. package/dist/util.d.ts +22 -0
  119. package/docs-site/zh/concepts/adapter.mdx +7 -7
  120. package/docs-site/zh/concepts/assert.mdx +19 -18
  121. package/docs-site/zh/concepts/evals.mdx +12 -11
  122. package/docs-site/zh/concepts/experiment.mdx +2 -2
  123. package/docs-site/zh/concepts/judge.mdx +9 -9
  124. package/docs-site/zh/concepts/overview.mdx +3 -3
  125. package/docs-site/zh/concepts/tier.mdx +6 -6
  126. package/docs-site/zh/example/claude-code-codex-plugin.mdx +9 -5
  127. package/docs-site/zh/example/claude-code-codex-skill.mdx +12 -7
  128. package/docs-site/zh/guides/agent-feedback-loop.mdx +237 -78
  129. package/docs-site/zh/guides/connect-otel.mdx +3 -3
  130. package/docs-site/zh/guides/connect-your-agent.mdx +2 -2
  131. package/docs-site/zh/guides/custom-reports.mdx +196 -36
  132. package/docs-site/zh/guides/experiments.mdx +7 -1
  133. package/docs-site/zh/guides/fixtures.mdx +4 -2
  134. package/docs-site/zh/guides/official-adapters.mdx +31 -9
  135. package/docs-site/zh/guides/publish-report.mdx +4 -4
  136. package/docs-site/zh/guides/report-components.mdx +194 -55
  137. package/docs-site/zh/guides/reporters.mdx +2 -2
  138. package/docs-site/zh/guides/results-data.mdx +61 -34
  139. package/docs-site/zh/guides/runner.mdx +2 -2
  140. package/docs-site/zh/guides/sandbox-agent.mdx +3 -2
  141. package/docs-site/zh/guides/{sandbox-backends.mdx → sandbox-providers.mdx} +12 -12
  142. package/docs-site/zh/guides/viewing-results.mdx +200 -79
  143. package/docs-site/zh/guides/write-experiment.mdx +9 -1
  144. package/docs-site/zh/guides/write-send.mdx +4 -3
  145. package/docs-site/zh/index.mdx +4 -3
  146. package/docs-site/zh/introduction.mdx +2 -1
  147. package/docs-site/zh/quickstart.mdx +5 -3
  148. package/docs-site/zh/reference/builtin-agents.mdx +38 -13
  149. package/docs-site/zh/reference/capabilities.mdx +1 -1
  150. package/docs-site/zh/reference/cli.mdx +36 -13
  151. package/docs-site/zh/reference/define-agent.mdx +15 -13
  152. package/docs-site/zh/reference/define-config.mdx +1 -1
  153. package/docs-site/zh/reference/define-eval.mdx +3 -3
  154. package/docs-site/zh/reference/events.mdx +9 -3
  155. package/docs-site/zh/reference/expect.mdx +13 -8
  156. package/package.json +10 -6
  157. package/src/agents/bub.ts +129 -42
  158. package/src/agents/claude-code.test.ts +152 -0
  159. package/src/agents/claude-code.ts +127 -13
  160. package/src/agents/codex.test.ts +192 -0
  161. package/src/agents/codex.ts +151 -12
  162. package/src/agents/index.ts +9 -3
  163. package/src/agents/manifest.ts +41 -0
  164. package/src/agents/plugin-config.test.ts +94 -0
  165. package/src/agents/shared.ts +33 -2
  166. package/src/agents/skills.test.ts +214 -0
  167. package/src/agents/skills.ts +304 -0
  168. package/src/agents/streaming.ts +5 -5
  169. package/src/agents/types.ts +59 -3
  170. package/src/cli.ts +74 -47
  171. package/src/context/context.test.ts +20 -2
  172. package/src/context/control-flow.ts +1 -1
  173. package/src/context/session.test.ts +92 -1
  174. package/src/context/session.ts +23 -1
  175. package/src/context/types.ts +4 -4
  176. package/src/define.test.ts +8 -8
  177. package/src/define.ts +11 -11
  178. package/src/expect/index.ts +5 -5
  179. package/src/i18n/en.ts +33 -15
  180. package/src/i18n/zh-CN.ts +37 -21
  181. package/src/index.ts +1 -1
  182. package/src/o11y/execution-tree.test.ts +452 -0
  183. package/src/o11y/execution-tree.ts +367 -0
  184. package/src/o11y/otlp/receiver.ts +1 -1
  185. package/src/o11y/otlp/select.ts +7 -3
  186. package/src/o11y/parsers/claude-code.test.ts +175 -0
  187. package/src/o11y/parsers/claude-code.ts +32 -0
  188. package/src/o11y/types.ts +6 -1
  189. package/src/report/aggregate.ts +26 -20
  190. package/src/report/built-in-user-parity.test.tsx +640 -0
  191. package/src/report/built-ins/experiment-comparison.tsx +19 -0
  192. package/src/report/built-ins/index.ts +2 -0
  193. package/src/report/components.tsx +225 -50
  194. package/src/report/compute.ts +335 -54
  195. package/src/report/dual-render.test.tsx +1129 -0
  196. package/src/report/flag.ts +1 -1
  197. package/src/report/format.ts +35 -2
  198. package/src/report/index.ts +47 -14
  199. package/src/report/load.ts +1 -1
  200. package/src/report/locale.ts +229 -0
  201. package/src/report/metrics.ts +39 -15
  202. package/src/report/primitives.tsx +100 -2
  203. package/src/report/react/AttemptList.tsx +113 -0
  204. package/src/report/react/DeltaTable.tsx +9 -6
  205. package/src/report/react/EvalList.tsx +0 -0
  206. package/src/report/react/ExperimentList.tsx +220 -0
  207. package/src/report/react/GroupSummary.tsx +66 -0
  208. package/src/report/react/MetricBars.tsx +24 -13
  209. package/src/report/react/MetricLine.tsx +21 -21
  210. package/src/report/react/MetricMatrix.tsx +8 -4
  211. package/src/report/react/MetricScatter.tsx +126 -96
  212. package/src/report/react/MetricTable.tsx +115 -15
  213. package/src/report/react/RunOverview.tsx +48 -26
  214. package/src/report/react/Scoreboard.tsx +15 -7
  215. package/src/report/react/cell.tsx +18 -9
  216. package/src/{view/app/lib/chart.ts → report/react/chart-math.ts} +2 -6
  217. package/src/report/react/colors.ts +24 -15
  218. package/src/report/react/enhance.js +168 -0
  219. package/src/report/react/fixtures.ts +169 -34
  220. package/src/report/react/format.ts +1 -1
  221. package/src/report/react/index.tsx +21 -6
  222. package/src/report/react/render.test.tsx +180 -31
  223. package/src/report/react/styles.css +432 -213
  224. package/src/report/report.test.ts +398 -94
  225. package/src/report/report.ts +29 -11
  226. package/src/report/text/faces.ts +344 -96
  227. package/src/report/text/layout.ts +76 -11
  228. package/src/report/text/table.ts +98 -0
  229. package/src/report/tree.ts +103 -20
  230. package/src/report/types.ts +184 -25
  231. package/src/report/web.ts +46 -19
  232. package/src/results/annotated-source.test.ts +146 -0
  233. package/src/results/annotated-source.ts +128 -0
  234. package/src/results/attempt-evidence.test.ts +158 -0
  235. package/src/results/attempt-evidence.ts +158 -0
  236. package/src/results/attempt-source.ts +48 -0
  237. package/src/results/copy.ts +154 -139
  238. package/src/results/format.ts +54 -47
  239. package/src/results/host-equivalence.test.ts +527 -0
  240. package/src/results/index.ts +56 -14
  241. package/src/results/locator.test.ts +198 -0
  242. package/src/results/locator.ts +0 -0
  243. package/src/results/open.ts +392 -175
  244. package/src/results/results.test.ts +943 -494
  245. package/src/results/select.ts +129 -23
  246. package/src/results/skipped-notice.ts +0 -0
  247. package/src/results/source-hash.ts +28 -0
  248. package/src/results/types.ts +98 -62
  249. package/src/results/writer.ts +304 -176
  250. package/src/runner/attempt.test.ts +170 -0
  251. package/src/runner/attempt.ts +48 -13
  252. package/src/runner/discover.test.ts +65 -0
  253. package/src/runner/discover.ts +6 -2
  254. package/src/runner/eval-source.test.ts +121 -0
  255. package/src/runner/eval-source.ts +45 -0
  256. package/src/runner/fingerprint.ts +54 -1
  257. package/src/runner/remote-sandbox.ts +1 -1
  258. package/src/runner/report.test.ts +6 -8
  259. package/src/runner/report.ts +5 -4
  260. package/src/runner/reporters/artifacts.ts +27 -41
  261. package/src/runner/reporters/braintrust.test.ts +3 -3
  262. package/src/runner/reporters/braintrust.ts +1 -1
  263. package/src/runner/reporters/console.ts +6 -6
  264. package/src/runner/reporters/json.ts +4 -4
  265. package/src/runner/reporters/live.test.ts +56 -0
  266. package/src/runner/reporters/live.ts +36 -10
  267. package/src/runner/reporters/quiet.test.ts +66 -0
  268. package/src/runner/reporters/quiet.ts +49 -0
  269. package/src/runner/reporters/shared.ts +5 -5
  270. package/src/runner/reporters/table.ts +17 -17
  271. package/src/runner/run.ts +61 -102
  272. package/src/runner/types.ts +43 -32
  273. package/src/sandbox/checkpoint.ts +1 -1
  274. package/src/sandbox/docker.ts +15 -2
  275. package/src/sandbox/e2b.ts +11 -5
  276. package/src/sandbox/errors.ts +13 -0
  277. package/src/sandbox/index.ts +3 -3
  278. package/src/sandbox/local-files.ts +1 -1
  279. package/src/sandbox/registry.ts +6 -5
  280. package/src/sandbox/resolve.ts +38 -23
  281. package/src/sandbox/retry.test.ts +68 -0
  282. package/src/sandbox/retry.ts +44 -0
  283. package/src/sandbox/types.ts +24 -24
  284. package/src/sandbox/vercel.ts +17 -3
  285. package/src/scoring/collector.ts +3 -3
  286. package/src/scoring/judge.ts +2 -2
  287. package/src/scoring/scoped.ts +13 -1
  288. package/src/scoring/types.ts +7 -7
  289. package/src/scoring/verdict.ts +4 -4
  290. package/src/shared/aggregate.ts +23 -3
  291. package/src/shared/types.ts +2 -2
  292. package/src/shared/{outcome.ts → verdict.ts} +15 -15
  293. package/src/show/compose.ts +12 -132
  294. package/src/show/index.ts +119 -95
  295. package/src/show/render.ts +462 -159
  296. package/src/show/show.test.ts +471 -253
  297. package/src/source-loc.ts +1 -1
  298. package/src/tty-line.ts +32 -0
  299. package/src/types.ts +2 -2
  300. package/src/util.test.ts +21 -1
  301. package/src/util.ts +5 -1
  302. package/src/view/app/App.tsx +33 -198
  303. package/src/view/app/components/AttemptModal.tsx +6 -6
  304. package/src/view/app/components/CodeView.tsx +2 -2
  305. package/src/view/app/components/CopyControls.tsx +32 -36
  306. package/src/view/app/components/SkippedRunsBanner.tsx +140 -0
  307. package/src/view/app/components/ui/badge.tsx +1 -1
  308. package/src/view/app/components/ui/dialog.tsx +2 -2
  309. package/src/view/app/i18n.ts +40 -31
  310. package/src/view/app/lib/artifact-url.ts +1 -1
  311. package/src/view/app/lib/attempt-route.test.ts +37 -47
  312. package/src/view/app/lib/attempt-route.ts +26 -26
  313. package/src/view/app/lib/rows.ts +9 -112
  314. package/src/view/app/lib/verdict.ts +25 -0
  315. package/src/view/app/main.tsx +9 -12
  316. package/src/view/app/pages/RunsPage.tsx +4 -4
  317. package/src/view/app/pages/TracesPage.tsx +3 -3
  318. package/src/view/app/shared.ts +0 -1
  319. package/src/view/app/types.ts +6 -51
  320. package/src/view/artifact-serving.test.ts +136 -0
  321. package/src/view/client-dist/app.css +1 -1
  322. package/src/view/client-dist/app.js +21 -21
  323. package/src/view/data.test.ts +214 -143
  324. package/src/view/data.ts +166 -120
  325. package/src/view/index.ts +23 -11
  326. package/src/view/server.ts +52 -17
  327. package/src/view/shared/types.ts +22 -31
  328. package/src/view/styles.css +117 -327
  329. package/src/view/view-report.test.ts +146 -98
  330. package/src/report/default-report.tsx +0 -222
  331. package/src/report/dual-face.test.tsx +0 -527
  332. package/src/report/react/CaseList.tsx +0 -70
  333. package/src/view/app/components/CostScoreChart.tsx +0 -147
  334. package/src/view/app/components/ExperimentTable.tsx +0 -284
  335. package/src/view/app/components/GroupSelector.tsx +0 -61
  336. package/src/view/app/components/primitives.tsx +0 -43
  337. package/src/view/app/lib/outcome.ts +0 -82
@@ -3,13 +3,22 @@
3
3
  // MetricBars.data 就是 MetricMatrix.data(同一份矩阵数据的另一种摆法),别名显式化。
4
4
  //
5
5
  // 官方组件在宿主里自动接上证据室:web 面的 attemptHref 缺省取 ctx.attemptHref
6
- // (宿主注入的证据室深链);显式传 prop 可覆盖(嵌进自己应用时自定去处)
6
+ // (宿主注入的证据室深链);显式传 prop 可覆盖(嵌进自己应用时自定去处)。三个实体列表
7
+ // (ExperimentList / EvalList / AttemptList)没有这个覆盖口子——它们的 locator 徽标恒经
8
+ // ctx.attemptHref / ctx.attemptCommand,不接受 attemptHref/attemptCommand prop(docs/feature/reports/library.md
9
+ // 「嵌入自己的 React 页面」的函数签名没有这个参数),证据室深链在这三个组件上不是可选行为。
7
10
 
8
11
  import { defineComponent, isHostWebContextActive } from "./tree.ts";
9
- import type { AttemptRef } from "../results/index.ts";
12
+ import type { ReportComponent } from "./tree.ts";
13
+ import type { ReportLocale } from "./locale.ts";
14
+ import type { AttemptLocator } from "../results/locator.ts";
15
+ import type { Selection } from "../results/types.ts";
10
16
  import type {
11
- CaseListData,
17
+ AttemptListItem,
12
18
  DeltaData,
19
+ EvalListItem,
20
+ ExperimentListItem,
21
+ GroupSummaryData,
13
22
  LineData,
14
23
  MatrixData,
15
24
  OverviewData,
@@ -18,8 +27,11 @@ import type {
18
27
  TableData,
19
28
  } from "./types.ts";
20
29
  import {
21
- caseListData,
30
+ attemptListData,
22
31
  deltaData,
32
+ evalListData,
33
+ experimentListData,
34
+ groupSummaryData,
23
35
  lineData,
24
36
  matrixData,
25
37
  overviewData,
@@ -27,10 +39,14 @@ import {
27
39
  scoreboardData,
28
40
  tableData,
29
41
  } from "./compute.ts";
42
+ import type { ScatterDataOptions } from "./compute.ts";
30
43
  import {
44
+ attemptListText,
31
45
  barsText,
32
- caseListText,
33
46
  deltaText,
47
+ evalListText,
48
+ experimentListText,
49
+ groupSummaryText,
34
50
  lineText,
35
51
  matrixText,
36
52
  overviewText,
@@ -39,6 +55,10 @@ import {
39
55
  tableText,
40
56
  } from "./text/faces.ts";
41
57
  import { RunOverview as RunOverviewWeb } from "./react/RunOverview.tsx";
58
+ import { GroupSummary as GroupSummaryWeb } from "./react/GroupSummary.tsx";
59
+ import { ExperimentList as ExperimentListWeb } from "./react/ExperimentList.tsx";
60
+ import { EvalList as EvalListWeb } from "./react/EvalList.tsx";
61
+ import { AttemptList as AttemptListWeb } from "./react/AttemptList.tsx";
42
62
  import { MetricTable as MetricTableWeb } from "./react/MetricTable.tsx";
43
63
  import { MetricMatrix as MetricMatrixWeb } from "./react/MetricMatrix.tsx";
44
64
  import { MetricBars as MetricBarsWeb } from "./react/MetricBars.tsx";
@@ -46,93 +66,250 @@ import { Scoreboard as ScoreboardWeb } from "./react/Scoreboard.tsx";
46
66
  import { MetricScatter as MetricScatterWeb } from "./react/MetricScatter.tsx";
47
67
  import { MetricLine as MetricLineWeb } from "./react/MetricLine.tsx";
48
68
  import { DeltaTable as DeltaTableWeb } from "./react/DeltaTable.tsx";
49
- import { CaseList as CaseListWeb } from "./react/CaseList.tsx";
50
69
 
51
70
  // ───────────────────────── props ─────────────────────────
52
71
 
53
72
  export interface RunOverviewProps {
54
73
  data: OverviewData;
74
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
75
+ locale?: ReportLocale;
76
+ className?: string;
77
+ }
78
+
79
+ export interface GroupSummaryProps {
80
+ data: GroupSummaryData;
81
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
82
+ locale?: ReportLocale;
83
+ className?: string;
84
+ }
85
+
86
+ /**
87
+ * 三个实体列表都只收算好的 `items`(`.data(selection)` 的产物,报告作者先 `.filter()`/
88
+ * `.slice()` 再传入)——没有 selection-form,组件不提供另一套过滤 DSL
89
+ * (docs/feature/reports/library.md「实体列表」)。
90
+ */
91
+ export interface ExperimentListProps {
92
+ items: ExperimentListItem[];
93
+ /** web 面在比较表前显示实验过滤框;text 面忽略。 */
94
+ filter?: boolean;
95
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
96
+ locale?: ReportLocale;
97
+ className?: string;
98
+ }
99
+
100
+ export interface EvalListProps {
101
+ items: EvalListItem[];
102
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
103
+ locale?: ReportLocale;
104
+ className?: string;
105
+ }
106
+
107
+ export interface AttemptListProps {
108
+ items: AttemptListItem[];
109
+ /** items 被 slice 时如实显示剩余数量;省略即 items.length(未截断)。 */
110
+ total?: number;
111
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
112
+ locale?: ReportLocale;
55
113
  className?: string;
56
114
  }
57
115
 
58
116
  export interface MetricTableProps {
59
117
  data: TableData;
60
118
  /** 传了,格子可点、下钻去处你定;不传,宿主里走证据室深链,宿主外纯展示。 */
61
- attemptHref?: (ref: AttemptRef) => string;
119
+ attemptHref?: (locator: AttemptLocator) => string;
120
+ /**
121
+ * web 面在表格前渲染一个过滤输入框(`<input class="nre-filter" data-nre-filter>`),
122
+ * 由渐进增强 runtime(enhance.js)接管:输入过滤行 textContent。无 JS 时输入框
123
+ * 静默无功能,表格内容依旧完整可读。默认 false;text 面不受影响。
124
+ */
125
+ filter?: boolean;
126
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
127
+ locale?: ReportLocale;
62
128
  className?: string;
63
129
  }
64
130
 
65
131
  export interface MetricMatrixProps {
66
132
  data: MatrixData;
67
- attemptHref?: (ref: AttemptRef) => string;
133
+ attemptHref?: (locator: AttemptLocator) => string;
134
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
135
+ locale?: ReportLocale;
68
136
  className?: string;
69
137
  }
70
138
 
71
139
  export interface ScoreboardProps {
72
140
  data: ScoreboardData;
141
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
142
+ locale?: ReportLocale;
73
143
  className?: string;
74
144
  }
75
145
 
76
- export interface MetricScatterProps {
77
- data: ScatterData;
146
+ /** MetricScatter 两臂共享的纯渲染选项(不含数据来源)。 */
147
+ interface MetricScatterRenderProps {
78
148
  /** 点一个点 → 该配置的下钻页。 */
79
149
  pointHref?: (row: ScatterData["rows"][number]) => string;
150
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
151
+ locale?: ReportLocale;
80
152
  className?: string;
81
153
  }
82
154
 
155
+ /** resolve 之后 web / text 面看到的形态:数据已备好,零 IO。 */
156
+ export interface MetricScatterResolvedProps extends MetricScatterRenderProps {
157
+ data: ScatterData;
158
+ }
159
+
160
+ /**
161
+ * 互斥两臂:要么直接给算好的 `data`(用于用户自己的 React 页面 / 预计算 / 跨边界序列化),
162
+ * 要么给 `selection` + 计算选项让宿主在渲染前解析(见 tree.ts 的 resolveReportTree)。
163
+ * 同时传 `data` 与 `selection`、或两者都不传,都在 typecheck 阶段失败。计算选项复用
164
+ * `ScatterDataOptions`,不手写会漂移的副本。
165
+ */
166
+ export type MetricScatterProps =
167
+ | (MetricScatterResolvedProps & {
168
+ selection?: never;
169
+ points?: never;
170
+ series?: never;
171
+ x?: never;
172
+ y?: never;
173
+ })
174
+ | ({ data?: never } & ScatterDataOptions & MetricScatterRenderProps & { selection: Selection });
175
+
83
176
  export interface MetricLineProps {
84
177
  data: LineData;
85
178
  pointHref?: (row: LineData["rows"][number]) => string;
179
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
180
+ locale?: ReportLocale;
86
181
  className?: string;
87
182
  }
88
183
 
89
184
  export interface DeltaTableProps {
90
185
  data: DeltaData;
91
- className?: string;
92
- }
93
-
94
- export interface CaseListProps {
95
- data: CaseListData;
96
- attemptHref?: (ref: AttemptRef) => string;
186
+ /** chrome 文案 locale;省略时随宿主上下文(宿主外默认 "en")。 */
187
+ locale?: ReportLocale;
97
188
  className?: string;
98
189
  }
99
190
 
100
191
  // ───────────────────────── 装配 ─────────────────────────
101
192
 
102
- /** 页头 KPI 条:何时跑的、几个配置、几道题、通过率、总成本;选集的警告随行显示在条内。 */
103
- export const RunOverview = Object.assign(
193
+ const SCATTER_UNRESOLVED_MESSAGE =
194
+ "MetricScatter received unresolved (selection-form) props outside the report host pipeline. " +
195
+ "Render through defineReport + niceeval show/view (or renderReportToText/renderReportToStaticHtml), " +
196
+ "or precompute with `await MetricScatter.data(selection, options)` and pass the result as `data`.";
197
+
198
+ /** 渲染面(web / text)只吃已解析的数据形态;selection 形态漏解析时直说,而不是画一张空组件。 */
199
+ function requireScatterData(props: { data?: ScatterData }): ScatterData {
200
+ if (props.data === undefined) throw new Error(SCATTER_UNRESOLVED_MESSAGE);
201
+ return props.data;
202
+ }
203
+
204
+ /** 页头 KPI 条:何时跑的、几个配置、几道题、通过率、总成本;Selection 的警告随行显示在条内。 */
205
+ export const RunOverview: ReportComponent<RunOverviewProps> & { data: typeof overviewData } = Object.assign(
104
206
  defineComponent<RunOverviewProps>({
105
- web: (props) => <RunOverviewWeb {...props} />,
106
- text: ({ data }) => overviewText(data),
207
+ web: (props, ctx) => <RunOverviewWeb {...props} locale={props.locale ?? ctx.locale} />,
208
+ text: ({ data }, ctx) => overviewText(data, ctx),
107
209
  }),
108
210
  { data: overviewData },
109
211
  );
110
212
  RunOverview.displayName = "RunOverview";
111
213
 
214
+ /**
215
+ * 组摘要:一组 experiment(典型用法是同一 `<Section>` 内的全部 experiment)的紧凑统计——
216
+ * 通过率(旧 GroupSelector 卡片口径)、experiment/eval/attempt 数、eval 级折叠计票、
217
+ * 总成本、最后运行时间。
218
+ */
219
+ export const GroupSummary: ReportComponent<GroupSummaryProps> & { data: typeof groupSummaryData } = Object.assign(
220
+ defineComponent<GroupSummaryProps>({
221
+ web: (props, ctx) => <GroupSummaryWeb {...props} locale={props.locale ?? ctx.locale} />,
222
+ text: ({ data }, ctx) => groupSummaryText(data, ctx),
223
+ }),
224
+ { data: groupSummaryData },
225
+ );
226
+ GroupSummary.displayName = "GroupSummary";
227
+
228
+ /**
229
+ * 实验列表:每项一个 experiment,固定展示身份、配置(flags)、Eval 判定构成和官方两级聚合
230
+ * 汇总指标;展开到这个 experiment 的 Eval,每道题内联该题全部 Attempt 的 locator 徽标。
231
+ * 没有 selection-form:`ExperimentList.data(selection)` 产出普通数组,过滤由报告作者对
232
+ * 数组调用 `.filter()`。
233
+ */
234
+ export const ExperimentList: ReportComponent<ExperimentListProps> & { data: typeof experimentListData } =
235
+ Object.assign(
236
+ defineComponent<ExperimentListProps>({
237
+ web: (props, ctx) => <ExperimentListWeb {...props} locale={props.locale ?? ctx.locale} attemptHref={ctx.attemptHref} />,
238
+ text: ({ items }, ctx) => experimentListText(items, ctx),
239
+ }),
240
+ { data: experimentListData },
241
+ );
242
+ ExperimentList.displayName = "ExperimentList";
243
+
244
+ /**
245
+ * Eval 列表:每项一个 `experimentId + evalId`,固定展示判定、Attempt 数、分数、成本、耗时
246
+ * 与失败原因;展开到这道题的 Attempt(与 AttemptList 同一份 AttemptListItem)。
247
+ */
248
+ export const EvalList: ReportComponent<EvalListProps> & { data: typeof evalListData } = Object.assign(
249
+ defineComponent<EvalListProps>({
250
+ web: (props, ctx) => <EvalListWeb {...props} locale={props.locale ?? ctx.locale} attemptHref={ctx.attemptHref} />,
251
+ text: ({ items }, ctx) => evalListText(items, ctx),
252
+ }),
253
+ { data: evalListData },
254
+ );
255
+ EvalList.displayName = "EvalList";
256
+
257
+ /**
258
+ * Attempt 列表:实体列表的叶子层,每项一个 Attempt,固定展示判定、断言、error、Judge 评语
259
+ * (assertions 的 detail/evidence)与证据引用(locator)。它不预设只看失败;
260
+ * 报告作者过滤 `AttemptListItem[]`、用 `.slice()` 限量,`total` 让渲染面如实报告剩余数量。
261
+ */
262
+ export const AttemptList: ReportComponent<AttemptListProps> & { data: typeof attemptListData } = Object.assign(
263
+ defineComponent<AttemptListProps>({
264
+ web: (props, ctx) => <AttemptListWeb {...props} locale={props.locale ?? ctx.locale} attemptHref={ctx.attemptHref} />,
265
+ text: ({ items, total }, ctx) => attemptListText(items, total, ctx),
266
+ }),
267
+ { data: attemptListData },
268
+ );
269
+ AttemptList.displayName = "AttemptList";
270
+
112
271
  /** 榜单:一行一个维度值、一列一个指标,回答「谁整体更好」。 */
113
- export const MetricTable = Object.assign(
272
+ export const MetricTable: ReportComponent<MetricTableProps> & { data: typeof tableData } = Object.assign(
114
273
  defineComponent<MetricTableProps>({
115
- web: (props, ctx) => <MetricTableWeb {...props} attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)} />,
116
- text: ({ data }) => tableText(data),
274
+ web: (props, ctx) => (
275
+ <MetricTableWeb
276
+ {...props}
277
+ locale={props.locale ?? ctx.locale}
278
+ attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)}
279
+ />
280
+ ),
281
+ text: ({ data }, ctx) => tableText(data, ctx),
117
282
  }),
118
283
  { data: tableData },
119
284
  );
120
285
  MetricTable.displayName = "MetricTable";
121
286
 
122
287
  /** 逐题格子:行 × 列两个维度、格子里一个指标,回答「哪道题谁挂了」。 */
123
- export const MetricMatrix = Object.assign(
288
+ export const MetricMatrix: ReportComponent<MetricMatrixProps> & { data: typeof matrixData } = Object.assign(
124
289
  defineComponent<MetricMatrixProps>({
125
- web: (props, ctx) => <MetricMatrixWeb {...props} attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)} />,
126
- text: ({ data }) => matrixText(data),
290
+ web: (props, ctx) => (
291
+ <MetricMatrixWeb
292
+ {...props}
293
+ locale={props.locale ?? ctx.locale}
294
+ attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)}
295
+ />
296
+ ),
297
+ text: ({ data }, ctx) => matrixText(data, ctx),
127
298
  }),
128
299
  { data: matrixData },
129
300
  );
130
301
  MetricMatrix.displayName = "MetricMatrix";
131
302
 
132
303
  /** 分组条形:同一份矩阵数据的另一种摆法;MetricBars.data 就是 MetricMatrix.data 的别名。 */
133
- export const MetricBars = Object.assign(
304
+ export const MetricBars: ReportComponent<MetricMatrixProps> & { data: typeof matrixData } = Object.assign(
134
305
  defineComponent<MetricMatrixProps>({
135
- web: (props, ctx) => <MetricBarsWeb {...props} attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)} />,
306
+ web: (props, ctx) => (
307
+ <MetricBarsWeb
308
+ {...props}
309
+ locale={props.locale ?? ctx.locale}
310
+ attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)}
311
+ />
312
+ ),
136
313
  text: ({ data }) => barsText(data),
137
314
  }),
138
315
  { data: matrixData },
@@ -140,29 +317,37 @@ export const MetricBars = Object.assign(
140
317
  MetricBars.displayName = "MetricBars";
141
318
 
142
319
  /** 考试成绩单:总分 + 分科小计,固定分母、missing 如实报。 */
143
- export const Scoreboard = Object.assign(
320
+ export const Scoreboard: ReportComponent<ScoreboardProps> & { data: typeof scoreboardData } = Object.assign(
144
321
  defineComponent<ScoreboardProps>({
145
- web: (props) => <ScoreboardWeb {...props} />,
146
- text: ({ data }) => scoreboardText(data),
322
+ web: (props, ctx) => <ScoreboardWeb {...props} locale={props.locale ?? ctx.locale} />,
323
+ text: ({ data }, ctx) => scoreboardText(data, ctx),
147
324
  }),
148
325
  { data: scoreboardData },
149
326
  );
150
327
  Scoreboard.displayName = "Scoreboard";
151
328
 
152
329
  /** 质量 × 成本 frontier:每个点一个配置、两个指标各占一轴,「好」的角落恒在右上。 */
153
- export const MetricScatter = Object.assign(
154
- defineComponent<MetricScatterProps>({
155
- web: (props) => <MetricScatterWeb {...props} />,
156
- text: ({ data }, ctx) => scatterText(data, ctx),
330
+ export const MetricScatter: ReportComponent<MetricScatterProps> & { data: typeof scatterData } = Object.assign(
331
+ defineComponent<MetricScatterProps, MetricScatterResolvedProps>({
332
+ resolve: async (props) => {
333
+ if ("data" in props && props.data !== undefined) return props;
334
+ const { selection, points, series, x, y, ...rest } = props;
335
+ return { ...rest, data: await scatterData(selection, { points, series, x, y }) };
336
+ },
337
+ web: (props, ctx) => {
338
+ requireScatterData(props);
339
+ return <MetricScatterWeb {...props} locale={props.locale ?? ctx.locale} />;
340
+ },
341
+ text: (props, ctx) => scatterText(requireScatterData(props), ctx),
157
342
  }),
158
343
  { data: scatterData },
159
344
  );
160
345
  MetricScatter.displayName = "MetricScatter";
161
346
 
162
347
  /** 趋势线:x 是 experiment 声明的 flag(flag()),同系列按 x 排序连线。 */
163
- export const MetricLine = Object.assign(
348
+ export const MetricLine: ReportComponent<MetricLineProps> & { data: typeof lineData } = Object.assign(
164
349
  defineComponent<MetricLineProps>({
165
- web: (props) => <MetricLineWeb {...props} />,
350
+ web: (props, ctx) => <MetricLineWeb {...props} locale={props.locale ?? ctx.locale} />,
166
351
  text: ({ data }, ctx) => lineText(data, ctx),
167
352
  }),
168
353
  { data: lineData },
@@ -170,21 +355,11 @@ export const MetricLine = Object.assign(
170
355
  MetricLine.displayName = "MetricLine";
171
356
 
172
357
  /** 成对对比:每行一对配置、格子里 A、B、Δ 三个值,涨跌好坏由 better 判定。 */
173
- export const DeltaTable = Object.assign(
358
+ export const DeltaTable: ReportComponent<DeltaTableProps> & { data: typeof deltaData } = Object.assign(
174
359
  defineComponent<DeltaTableProps>({
175
- web: (props) => <DeltaTableWeb {...props} />,
176
- text: ({ data }) => deltaText(data),
360
+ web: (props, ctx) => <DeltaTableWeb {...props} locale={props.locale ?? ctx.locale} />,
361
+ text: ({ data }, ctx) => deltaText(data, ctx),
177
362
  }),
178
363
  { data: deltaData },
179
364
  );
180
365
  DeltaTable.displayName = "DeltaTable";
181
-
182
- /** 失败案例清单:榜单回答「多少」,它回答「为什么」;truncated 如实报剩余。 */
183
- export const CaseList = Object.assign(
184
- defineComponent<CaseListProps>({
185
- web: (props, ctx) => <CaseListWeb {...props} attemptHref={props.attemptHref ?? (isHostWebContextActive() ? ctx.attemptHref : undefined)} />,
186
- text: (props, ctx) => caseListText(props.data, ctx),
187
- }),
188
- { data: caseListData },
189
- );
190
- CaseList.displayName = "CaseList";