niceeval 0.8.1 → 0.9.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.
- package/INDEX.md +77 -45
- package/dist/agents/types.d.ts +28 -6
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/zh-CN.d.ts +3 -1
- package/dist/report/built-in/index.d.ts +3 -2
- package/dist/report/built-in/index.js +7 -8
- package/dist/report/built-in/standard.d.ts +1 -0
- package/dist/report/built-in/standard.js +30 -0
- package/dist/report/components.d.ts +69 -2
- package/dist/report/components.js +152 -3
- package/dist/report/compute.d.ts +28 -1
- package/dist/report/compute.js +123 -0
- package/dist/report/index.d.ts +4 -4
- package/dist/report/index.js +3 -2
- package/dist/report/locale.d.ts +39 -1
- package/dist/report/locale.js +69 -0
- package/dist/report/react/AttemptList.d.ts +3 -1
- package/dist/report/react/AttemptList.js +3 -3
- package/dist/report/react/CopyFixPrompt.d.ts +12 -0
- package/dist/report/react/CopyFixPrompt.js +12 -0
- package/dist/report/react/HeroCard.d.ts +13 -0
- package/dist/report/react/HeroCard.js +35 -0
- package/dist/report/react/PoweredBy.d.ts +5 -0
- package/dist/report/react/PoweredBy.js +7 -0
- package/dist/report/react/ScopeWarnings.d.ts +12 -0
- package/dist/report/react/ScopeWarnings.js +18 -0
- package/dist/report/react/TraceWaterfall.d.ts +14 -0
- package/dist/report/react/TraceWaterfall.js +22 -0
- package/dist/report/react/index.d.ts +6 -1
- package/dist/report/react/index.js +6 -0
- package/dist/report/report.d.ts +22 -6
- package/dist/report/report.js +68 -55
- package/dist/report/scope-warnings.d.ts +28 -0
- package/dist/report/scope-warnings.js +101 -0
- package/dist/report/text/faces.d.ts +19 -1
- package/dist/report/text/faces.js +61 -0
- package/dist/report/tree.d.ts +1 -1
- package/dist/report/tree.js +7 -2
- package/dist/report/types.d.ts +45 -0
- package/dist/report/web.d.ts +5 -4
- package/dist/report/web.js +7 -22
- package/dist/results/select.d.ts +17 -4
- package/dist/results/select.js +76 -11
- package/dist/results/types.d.ts +26 -0
- package/dist/runner/fingerprint.d.ts +3 -3
- package/dist/runner/sandbox-selection.d.ts +12 -0
- package/dist/runner/types.d.ts +18 -6
- package/dist/sandbox/types.d.ts +12 -0
- package/dist/shared/aggregate.d.ts +1 -1
- package/dist/shared/aggregate.js +1 -1
- package/docs-site/zh/explanation/evals.mdx +2 -1
- package/docs-site/zh/explanation/experiment.mdx +2 -0
- package/docs-site/zh/how-to/custom-reports.mdx +23 -7
- package/docs-site/zh/how-to/experiments.mdx +2 -2
- package/docs-site/zh/how-to/publish-report.mdx +11 -4
- package/docs-site/zh/how-to/viewing-results.mdx +17 -8
- package/docs-site/zh/how-to/write-experiment.mdx +40 -1
- package/docs-site/zh/reference/builtin-agents.mdx +40 -3
- package/docs-site/zh/reference/cli.mdx +3 -3
- package/docs-site/zh/reference/define-eval.mdx +8 -0
- package/docs-site/zh/reference/official-adapters.mdx +10 -5
- package/docs-site/zh/troubleshooting/debugging.mdx +3 -3
- package/package.json +2 -1
- package/src/agents/bub.ts +13 -1
- package/src/agents/claude-code.test.ts +43 -1
- package/src/agents/claude-code.ts +32 -14
- package/src/agents/codex.test.ts +168 -1
- package/src/agents/codex.ts +51 -15
- package/src/agents/mcp.ts +31 -0
- package/src/agents/post-setup.ts +33 -0
- package/src/agents/types.ts +28 -7
- package/src/cli.ts +15 -14
- package/src/define.ts +3 -0
- package/src/i18n/en.ts +8 -5
- package/src/i18n/zh-CN.ts +8 -4
- package/src/index.ts +1 -0
- package/src/report/built-in/index.tsx +8 -7
- package/src/report/built-in/standard.tsx +59 -0
- package/src/report/components.tsx +218 -2
- package/src/report/compute.ts +138 -1
- package/src/report/dual-render.test.tsx +141 -14
- package/src/report/index.ts +20 -0
- package/src/report/locale.ts +83 -1
- package/src/report/react/AttemptList.tsx +13 -1
- package/src/report/react/CopyFixPrompt.tsx +37 -0
- package/src/report/react/HeroCard.tsx +59 -0
- package/src/report/react/PoweredBy.tsx +20 -0
- package/src/report/react/ScopeWarnings.tsx +74 -0
- package/src/report/react/TraceWaterfall.tsx +78 -0
- package/src/report/react/enhance.js +14 -0
- package/src/report/react/index.tsx +11 -0
- package/src/report/react/styles.css +193 -7
- package/src/report/report.ts +99 -64
- package/src/report/scope-warnings.ts +155 -0
- package/src/report/site-components.test.tsx +526 -0
- package/src/report/text/faces.ts +66 -0
- package/src/report/tree.ts +10 -3
- package/src/report/types.ts +51 -0
- package/src/report/web.ts +7 -40
- package/src/results/host-equivalence.test.ts +6 -2
- package/src/results/open.ts +5 -4
- package/src/results/results.test.ts +78 -1
- package/src/results/select.ts +80 -12
- package/src/results/types.ts +27 -0
- package/src/runner/attempt.ts +10 -9
- package/src/runner/discover.test.ts +9 -1
- package/src/runner/discover.ts +3 -3
- package/src/runner/fingerprint.ts +9 -4
- package/src/runner/ledger.test.ts +30 -1
- package/src/runner/ledger.ts +26 -4
- package/src/runner/run.ts +5 -1
- package/src/runner/sandbox-selection.test.ts +131 -0
- package/src/runner/sandbox-selection.ts +110 -0
- package/src/runner/types.ts +19 -2
- package/src/sandbox/types.ts +6 -0
- package/src/shared/aggregate.ts +1 -1
- package/src/show/index.ts +19 -12
- package/src/show/render.ts +12 -12
- package/src/show/report-host.test.ts +34 -17
- package/src/show/report-host.ts +6 -5
- package/src/show/show.test.ts +141 -4
- package/src/view/app/App.test.tsx +79 -17
- package/src/view/app/App.tsx +25 -74
- package/src/view/app/components/CopyControls.tsx +4 -42
- package/src/view/app/i18n.ts +5 -227
- package/src/view/app/lib/rows.ts +3 -21
- package/src/view/app/shared.ts +1 -3
- package/src/view/app/types.ts +2 -2
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +20 -20
- package/src/view/data.ts +21 -10
- package/src/view/index.ts +2 -12
- package/src/view/server.ts +4 -4
- package/src/view/shared/types.ts +11 -6
- package/src/view/styles.css +9 -252
- package/src/view/view-report.test.ts +99 -33
- package/src/view/app/components/LazyArtifact.tsx +0 -51
- package/src/view/app/components/SkippedRunsBanner.tsx +0 -140
- package/src/view/app/pages/AttemptsPage.tsx +0 -80
- package/src/view/app/pages/TracesPage.tsx +0 -35
package/src/view/data.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type HostReportAsset,
|
|
21
21
|
} from "../show/report-host.ts";
|
|
22
22
|
import { selectCurrentResults, filterExperiments } from "../results/select.ts";
|
|
23
|
+
import { evalPrefixPredicate } from "../shared/aggregate.ts";
|
|
23
24
|
import type { EvalResult } from "../types.ts";
|
|
24
25
|
import type {
|
|
25
26
|
SkippedRunNotice,
|
|
@@ -61,9 +62,9 @@ export interface ViewScan {
|
|
|
61
62
|
|
|
62
63
|
/** view 宿主输入的组合语义(与 show 对齐,docs/feature/reports/architecture.md「Scope 是计算入口」)。 */
|
|
63
64
|
export interface ViewScanOptions {
|
|
64
|
-
/** eval id 前缀(位置参数)
|
|
65
|
+
/** eval id 前缀(位置参数):把根滤成有效根,页面 Scope 与证据(快照明细、artifact 清单)一致收窄。 */
|
|
65
66
|
patterns?: string[];
|
|
66
|
-
/** experiment id 前缀(--
|
|
67
|
+
/** experiment id 前缀(--exp):有效根只留匹配实验。 */
|
|
67
68
|
experiment?: string;
|
|
68
69
|
/** --report 报告文件:相对 cwd 的路径。装载失败抛 ReportLoadError(CLI 打印后退出)。 */
|
|
69
70
|
report?: { path: string; cwd: string };
|
|
@@ -175,10 +176,12 @@ export async function loadLatestResultsPerEval(root = ".niceeval"): Promise<Eval
|
|
|
175
176
|
/**
|
|
176
177
|
* `niceeval view` 的数据装载入口:server 每次请求现读现算,`--out` 导出用同一份。
|
|
177
178
|
* 报告槽 Selection 恒经 selectCurrentResults 合成(现刻水位;与 `niceeval show` 调同一个
|
|
178
|
-
* 函数,裸跑与局部收窄不分叉),位置前缀 / --
|
|
179
|
+
* 函数,裸跑与局部收窄不分叉),位置前缀 / --exp 只作为 scope 传入,不切换选择口径。
|
|
179
180
|
* --report 本身不改挑选——它只换报告槽的填充,注入的 Selection 与裸跑同一份,
|
|
180
181
|
* 「裸跑 ≡ --report <ExperimentComparison>」靠这条成立(docs/feature/reports/architecture.md「Selection 是计算入口」)。
|
|
181
|
-
*
|
|
182
|
+
* 命令行收窄作用在有效根上(docs/feature/reports/view.md 开篇):证据室数据与 artifact 清单
|
|
183
|
+
* 与页面一致地只含收窄后的范围,本地与导出无分叉——收窄导出的站点(烘进 HTML 的数据、
|
|
184
|
+
* 证据文件)只含收窄到的内容。收窄之内、不在现刻水位里的历史 attempt 仍在有效根里,深链可达。
|
|
182
185
|
* 零可读结果一律抛 ViewInputError,不渲染/导出空页面(server 起不来,--out 非零退出)。
|
|
183
186
|
*/
|
|
184
187
|
export async function loadViewScan(input?: string, opts: ViewScanOptions = {}): Promise<ViewScan> {
|
|
@@ -228,6 +231,12 @@ export async function loadViewScan(input?: string, opts: ViewScanOptions = {}):
|
|
|
228
231
|
// 静态渲染成 HTML(en / zh-CN 各一遍,切界面语言不重算数据)。
|
|
229
232
|
const slot = await renderReportSlot(opts.report, opts.page, results, selection, opts.pageFailure ?? "throw");
|
|
230
233
|
|
|
234
|
+
// 有效根:命令行收窄把根滤成只含匹配实验与 attempt(docs/feature/reports/view.md 开篇)。
|
|
235
|
+
// 证据室数据与 artifact 清单从这里取数,与页面 Scope 一致收窄——本地与导出无分叉,
|
|
236
|
+
// 收窄导出的站点(烘进 HTML 的数据、证据文件)只含收窄后的范围。
|
|
237
|
+
const scopedExperiments = filterExperiments(results.experiments, opts.experiment);
|
|
238
|
+
const matchEval = patterns.length > 0 ? evalPrefixPredicate(patterns) : () => true;
|
|
239
|
+
|
|
231
240
|
// 跨快照按身份键去重:--resume 携带的条目在多份落盘里重复,只保留最新快照里的那份
|
|
232
241
|
// (与官方计算函数的聚合口径一致,Runs / Traces 的计数因此不被复印件灌票)。
|
|
233
242
|
const artifactDirs = new Map<string, string>();
|
|
@@ -236,13 +245,15 @@ export async function loadViewScan(input?: string, opts: ViewScanOptions = {}):
|
|
|
236
245
|
// 与报告槽 Selection(现刻水位,可能合成自更早快照)是两个独立概念,不混用。
|
|
237
246
|
const latestSet = new Set(latestPerExperiment.snapshots);
|
|
238
247
|
const allAttempts: AttemptHandle[] = [];
|
|
239
|
-
for (const exp of
|
|
240
|
-
for (const snap of exp.snapshots) allAttempts.push(...snap.attempts);
|
|
248
|
+
for (const exp of scopedExperiments) {
|
|
249
|
+
for (const snap of exp.snapshots) allAttempts.push(...snap.attempts.filter((a) => matchEval(a.evalId)));
|
|
241
250
|
}
|
|
242
251
|
const survivors = new Set(dedupeAttempts(allAttempts).attempts);
|
|
243
252
|
|
|
244
253
|
const snapshots: ViewSnapshot[] = [];
|
|
245
|
-
for (const exp of
|
|
254
|
+
for (const exp of scopedExperiments) {
|
|
255
|
+
// 整个实验没有匹配 eval 时不携带:有效根里没有它,连快照元数据也不烘进页面。
|
|
256
|
+
if (patterns.length > 0 && !exp.evalIds.some((id) => matchEval(id))) continue;
|
|
246
257
|
for (const snap of exp.snapshots) {
|
|
247
258
|
const kept = snap.attempts.filter((a) => survivors.has(a));
|
|
248
259
|
const latest = latestSet.has(snap);
|
|
@@ -267,10 +278,10 @@ export async function loadViewScan(input?: string, opts: ViewScanOptions = {}):
|
|
|
267
278
|
}
|
|
268
279
|
}
|
|
269
280
|
|
|
270
|
-
// 全局最新快照(
|
|
271
|
-
//
|
|
281
|
+
// 全局最新快照(跨有效根内全部实验):viewData.lastRunAt 从这里取。页内 hero 的「最后运行」
|
|
282
|
+
// 显示由 Hero 组件按 heroData(scope) 自己算,不吃这份字段。
|
|
272
283
|
let latestSnapshot: Snapshot | undefined;
|
|
273
|
-
for (const exp of
|
|
284
|
+
for (const exp of scopedExperiments) {
|
|
274
285
|
const candidate = exp.snapshots[0];
|
|
275
286
|
if (!candidate) continue;
|
|
276
287
|
if (!latestSnapshot || candidate.startedAt > latestSnapshot.startedAt) latestSnapshot = candidate;
|
package/src/view/index.ts
CHANGED
|
@@ -80,18 +80,8 @@ export async function buildView(opts: ViewOptions = {}): Promise<string> {
|
|
|
80
80
|
`--out expects a directory, got "${opts.out}". Single-file HTML export was removed: code, transcript and trace views need artifact files next to the page. Export a directory instead (e.g. --out site) and serve it with any static host.`,
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
// attempt 的证据都已出站。按实验收窄发布 = 用 copySnapshots 构建只含它的发布根,再对新根导出。
|
|
86
|
-
if ((opts.scan?.patterns?.length ?? 0) > 0 || opts.scan?.experiment !== undefined) {
|
|
87
|
-
throw new ViewInputError(
|
|
88
|
-
"--out exports the whole results root and cannot be combined with eval prefixes or --experiment.\n" +
|
|
89
|
-
"To publish a site for one experiment, build a narrower results root and export that:\n" +
|
|
90
|
-
' const results = await openResults(".niceeval");\n' +
|
|
91
|
-
' await copySnapshots(results.latest().filter((s) => s.experimentId.startsWith("<prefix>/")), "<publish-root>");\n' +
|
|
92
|
-
"Then: niceeval view --results <publish-root> --out <site>",
|
|
93
|
-
);
|
|
94
|
-
}
|
|
83
|
+
// 位置参数 / --exp 对导出同义于本地:收窄作用在有效根上,出站的页面数据与证据文件
|
|
84
|
+
// 只含收窄后的范围(docs/feature/reports/view.md「静态导出」:出站的就是收窄到的)。
|
|
95
85
|
// 静态导出保持「任一页失败整体失败」(pageFailure 缺省 "throw"),不产出半套站点。
|
|
96
86
|
const plan = await planSite(opts.input, opts.scan);
|
|
97
87
|
await writeSite(plan, out);
|
package/src/view/server.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// HTTP server:把站点管线(site.ts 的 planSite)产出的同一份产物挂在 127.0.0.1 上按路径服务。
|
|
2
2
|
// 这里不携带任何取数或布局知识——查不到清单条目就是 404,与 `--out` 写盘的文件逐字节一致
|
|
3
|
-
// (docs/feature/reports/view.md 开篇;奇偶由 site-parity 测试守护)
|
|
4
|
-
//
|
|
5
|
-
// (pageFailure: "embed")
|
|
3
|
+
// (docs/feature/reports/view.md 开篇;奇偶由 site-parity 测试守护)。宿主语义只有两条,全部
|
|
4
|
+
// 作用在管线之外:打开首页整份重建(数据永远是盘上最新)、单页渲染失败折成页内错误块
|
|
5
|
+
// (pageFailure: "embed")。位置参数 / --exp 收窄是管线输入,不是宿主语义——两宿主同义。
|
|
6
6
|
|
|
7
7
|
import { createServer, type Server } from "node:http";
|
|
8
8
|
import { type ViewScanOptions } from "./data.ts";
|
|
@@ -13,7 +13,7 @@ export interface ViewOptions {
|
|
|
13
13
|
input?: string;
|
|
14
14
|
out?: string;
|
|
15
15
|
port?: number;
|
|
16
|
-
/**
|
|
16
|
+
/** 站点管线的组合语义(位置前缀 / --exp 收窄有效根,--report 换报告槽),透传给管线。 */
|
|
17
17
|
scan?: ViewScanOptions;
|
|
18
18
|
}
|
|
19
19
|
|
package/src/view/shared/types.ts
CHANGED
|
@@ -33,8 +33,9 @@ export interface ViewReportPageMeta {
|
|
|
33
33
|
/**
|
|
34
34
|
* 规范化后的报告外壳声明(docs/feature/reports/library/shell.md):壳(导航 / 页脚)由前端
|
|
35
35
|
* 渲染,页内容消费 <template> 静态块。title 已走完回退链(def.title → 唯一且相同的快照 name →
|
|
36
|
-
* 内置文案「Eval 运行结果 / Eval Results」)
|
|
37
|
-
*
|
|
36
|
+
* 内置文案「Eval 运行结果 / Eval Results」),宿主落点只有浏览器 <title>(文档单例);
|
|
37
|
+
* 页内 hero 标题由 Hero 组件消费同一取值链,品牌是组件、宿主页头不渲染任何品牌位。
|
|
38
|
+
* scripts / styles 是注入资产,不进 viewData。
|
|
38
39
|
* link 的 icon 是内联 SVG 字符串(原样透传、原样内联),不收组件——viewData 就是序列化边界。
|
|
39
40
|
*/
|
|
40
41
|
export interface ViewReportMeta {
|
|
@@ -70,7 +71,11 @@ export interface ViewSnapshot {
|
|
|
70
71
|
results: ViewEvalResult[];
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* 目录扫描里被跳过的 run 的结构化条目;三种原因与 niceeval/results 的 skipped 一致。
|
|
76
|
+
* 页面上的呈现不走它:不可读快照已形成 `unreadable-snapshot` Scope warning,由报告页内的
|
|
77
|
+
* `ScopeWarnings` 组件显示;这里只随 viewData 携带原始事实。
|
|
78
|
+
*/
|
|
74
79
|
export interface SkippedRunNotice {
|
|
75
80
|
/** run 目录,相对 cwd。 */
|
|
76
81
|
dir: string;
|
|
@@ -92,11 +97,11 @@ export interface SkippedRunNotice {
|
|
|
92
97
|
export interface ViewData {
|
|
93
98
|
/** 最近一次 run 的 startedAt(ISO);没有历史 run 时缺省。 */
|
|
94
99
|
lastRunAt?: string;
|
|
95
|
-
/** 报告槽 Selection 合成自几个物理 run
|
|
100
|
+
/** 报告槽 Selection 合成自几个物理 run。 */
|
|
96
101
|
composedRuns: number;
|
|
97
|
-
/** 全部历史快照(跨快照按身份键去重后)
|
|
102
|
+
/** 全部历史快照(跨快照按身份键去重后);attempt 详情路由对这份完整集合解析,不随报告 Scope 收窄。 */
|
|
98
103
|
snapshots: ViewSnapshot[];
|
|
99
|
-
/** 读不了的落盘(三种原因)
|
|
104
|
+
/** 读不了的落盘(三种原因);呈现走报告页内的 ScopeWarnings(unreadable-snapshot warning)。 */
|
|
100
105
|
skippedRuns?: SkippedRunNotice[];
|
|
101
106
|
/** 报告外壳与页导航的声明(规范化后);缺省时前端按单页 `report` 兜底。 */
|
|
102
107
|
report?: ViewReportMeta;
|
package/src/view/styles.css
CHANGED
|
@@ -63,8 +63,8 @@ a { color: inherit; }
|
|
|
63
63
|
align-items: center;
|
|
64
64
|
justify-content: space-between;
|
|
65
65
|
/* space-between 只在有富余空间时才撑开相邻项;.shell-links 的 margin-left:auto 会把富余
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
空间全部吸收到它左侧,导致相邻项贴脸。显式 gap 保证每一对相邻项(导航—shell-links、
|
|
67
|
+
shell-links—语言切换)恒有最小间距,不依赖富余空间。 */
|
|
68
68
|
gap: 28px;
|
|
69
69
|
padding: 0 clamp(20px, 5vw, 80px);
|
|
70
70
|
background: color-mix(in oklch, var(--bg), transparent 4%);
|
|
@@ -73,12 +73,16 @@ a { color: inherit; }
|
|
|
73
73
|
z-index: 10;
|
|
74
74
|
backdrop-filter: blur(10px);
|
|
75
75
|
}
|
|
76
|
+
/* 页头左端的恒定品牌位:NiceEval 字标 + 45° 方块 mark,外链官网(App.tsx 的 .brand)。
|
|
77
|
+
与 hero 下 nre-powered-by 品牌行同族,由宿主渲染、报告定义不能覆盖或移除。 */
|
|
76
78
|
.brand {
|
|
77
79
|
display: flex;
|
|
78
80
|
align-items: baseline;
|
|
79
81
|
gap: 12px;
|
|
80
82
|
font-weight: 690;
|
|
81
83
|
font-size: 20px;
|
|
84
|
+
flex: 0 0 auto;
|
|
85
|
+
text-decoration: none;
|
|
82
86
|
}
|
|
83
87
|
.mark {
|
|
84
88
|
width: 18px;
|
|
@@ -121,219 +125,13 @@ main {
|
|
|
121
125
|
margin: 0 auto;
|
|
122
126
|
padding: clamp(52px, 7vw, 82px) 0 72px;
|
|
123
127
|
}
|
|
124
|
-
.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
margin: 0 auto clamp(38px, 6vw, 58px);
|
|
128
|
-
}
|
|
129
|
-
h1 {
|
|
130
|
-
margin: 0;
|
|
131
|
-
font-size: clamp(42px, 5.6vw, 66px);
|
|
132
|
-
line-height: 0.94;
|
|
133
|
-
font-weight: 760;
|
|
134
|
-
letter-spacing: 0;
|
|
135
|
-
}
|
|
136
|
-
.subtitle {
|
|
137
|
-
margin: 20px auto 0;
|
|
138
|
-
color: color-mix(in oklch, var(--muted), var(--text) 12%);
|
|
139
|
-
font-size: clamp(17px, 2vw, 21px);
|
|
140
|
-
line-height: 1.58;
|
|
141
|
-
max-width: 660px;
|
|
142
|
-
}
|
|
143
|
-
.meta {
|
|
144
|
-
display: flex;
|
|
145
|
-
flex-wrap: wrap;
|
|
146
|
-
justify-content: center;
|
|
147
|
-
gap: 14px;
|
|
148
|
-
margin-top: 24px;
|
|
149
|
-
color: var(--muted);
|
|
150
|
-
font-size: 14px;
|
|
151
|
-
}
|
|
152
|
-
.meta b { color: var(--text); font-weight: 570; }
|
|
153
|
-
/* --report 报告槽:server 侧渲染好的静态报告 HTML(nre-* 类的样式随包 styles.css 注入),
|
|
154
|
-
这里只给槽位留呼吸空间,不覆盖报告自己的样式。 */
|
|
128
|
+
/* 报告槽:server 侧渲染好的静态报告 HTML(nre-* 类的样式随包 styles.css 注入),
|
|
129
|
+
这里只给槽位留呼吸空间,不覆盖报告自己的样式。hero、警告区、批量修复 prompt 都是
|
|
130
|
+
页内组件(nre-hero / nre-warnings / nre-copy-fix-prompt),宿主不再有对应 chrome。 */
|
|
155
131
|
.report-slot {
|
|
156
132
|
margin: 0 auto 36px;
|
|
157
133
|
}
|
|
158
|
-
/* schemaVersion 不匹配等读不了的 run:报告槽不解析它们,这里占位提示。同一原因(且文案
|
|
159
|
-
完全相同)的条目按 SkippedRunsBanner 分组折叠,不逐条重复整句原因 + 命令——那是原实现
|
|
160
|
-
把首屏挤满、警示色又淡到看不出来的根因。 */
|
|
161
|
-
.incompatible-banner {
|
|
162
|
-
border: 1px solid color-mix(in oklch, var(--warn), var(--line) 35%);
|
|
163
|
-
border-left: 3px solid var(--warn);
|
|
164
|
-
border-radius: 8px;
|
|
165
|
-
background: color-mix(in oklch, var(--warn), var(--panel) 85%);
|
|
166
|
-
padding: 12px 16px 14px;
|
|
167
|
-
margin: 0 auto 36px;
|
|
168
|
-
font-size: 13px;
|
|
169
|
-
}
|
|
170
|
-
.ib-head {
|
|
171
|
-
display: flex;
|
|
172
|
-
align-items: center;
|
|
173
|
-
gap: 8px;
|
|
174
|
-
}
|
|
175
|
-
.ib-head b { font-weight: 640; }
|
|
176
|
-
.ib-icon {
|
|
177
|
-
width: 16px;
|
|
178
|
-
height: 16px;
|
|
179
|
-
flex-shrink: 0;
|
|
180
|
-
color: var(--warn);
|
|
181
|
-
stroke-width: 2;
|
|
182
|
-
}
|
|
183
|
-
.ib-groups {
|
|
184
|
-
display: grid;
|
|
185
|
-
gap: 10px;
|
|
186
|
-
margin-top: 10px;
|
|
187
|
-
}
|
|
188
|
-
.ib-group-head {
|
|
189
|
-
display: flex;
|
|
190
|
-
align-items: baseline;
|
|
191
|
-
gap: 8px;
|
|
192
|
-
}
|
|
193
|
-
.ib-group-count {
|
|
194
|
-
display: inline-flex;
|
|
195
|
-
align-items: center;
|
|
196
|
-
justify-content: center;
|
|
197
|
-
min-width: 20px;
|
|
198
|
-
height: 20px;
|
|
199
|
-
padding: 0 6px;
|
|
200
|
-
flex-shrink: 0;
|
|
201
|
-
border-radius: 999px;
|
|
202
|
-
background: color-mix(in oklch, var(--warn), var(--panel) 72%);
|
|
203
|
-
color: var(--text);
|
|
204
|
-
font-size: 11px;
|
|
205
|
-
font-weight: 640;
|
|
206
|
-
font-variant-numeric: tabular-nums;
|
|
207
|
-
}
|
|
208
|
-
.ib-group-desc { color: var(--soft); }
|
|
209
|
-
.ib-group ul {
|
|
210
|
-
margin: 5px 0 0;
|
|
211
|
-
padding: 0;
|
|
212
|
-
list-style: none;
|
|
213
|
-
display: grid;
|
|
214
|
-
gap: 3px;
|
|
215
|
-
}
|
|
216
|
-
.ib-group li {
|
|
217
|
-
display: flex;
|
|
218
|
-
align-items: center;
|
|
219
|
-
gap: 8px;
|
|
220
|
-
min-height: 22px;
|
|
221
|
-
}
|
|
222
|
-
.ib-dir {
|
|
223
|
-
font-family: var(--mono, ui-monospace, monospace);
|
|
224
|
-
font-weight: 560;
|
|
225
|
-
}
|
|
226
|
-
.ib-more {
|
|
227
|
-
color: var(--soft);
|
|
228
|
-
font-size: 12px;
|
|
229
|
-
}
|
|
230
|
-
.ib-copy {
|
|
231
|
-
display: inline-flex;
|
|
232
|
-
align-items: center;
|
|
233
|
-
justify-content: center;
|
|
234
|
-
width: 22px;
|
|
235
|
-
height: 22px;
|
|
236
|
-
flex-shrink: 0;
|
|
237
|
-
border: 1px solid var(--line);
|
|
238
|
-
border-radius: 5px;
|
|
239
|
-
background: var(--panel);
|
|
240
|
-
color: var(--muted);
|
|
241
|
-
cursor: pointer;
|
|
242
|
-
transition: color 0.12s, border-color 0.12s;
|
|
243
|
-
}
|
|
244
|
-
.ib-copy svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
|
|
245
|
-
.ib-copy:hover { color: var(--text); border-color: var(--line-strong); }
|
|
246
|
-
.ib-copy.is-copied { color: var(--good); border-color: color-mix(in oklch, var(--good), var(--line) 40%); }
|
|
247
|
-
.ib-toggle {
|
|
248
|
-
display: inline-flex;
|
|
249
|
-
align-items: center;
|
|
250
|
-
gap: 4px;
|
|
251
|
-
margin-top: 10px;
|
|
252
|
-
border: 0;
|
|
253
|
-
background: none;
|
|
254
|
-
color: var(--muted);
|
|
255
|
-
font: inherit;
|
|
256
|
-
font-size: 12px;
|
|
257
|
-
cursor: pointer;
|
|
258
|
-
padding: 0;
|
|
259
|
-
}
|
|
260
|
-
.ib-toggle svg { width: 12px; height: 12px; transition: transform 0.12s; }
|
|
261
|
-
.ib-toggle svg.is-open { transform: rotate(90deg); }
|
|
262
|
-
.ib-toggle:hover { color: var(--text); }
|
|
263
|
-
|
|
264
|
-
.section-head {
|
|
265
|
-
display: flex;
|
|
266
|
-
align-items: end;
|
|
267
|
-
justify-content: space-between;
|
|
268
|
-
gap: 18px;
|
|
269
|
-
margin-bottom: 16px;
|
|
270
|
-
}
|
|
271
|
-
h2 {
|
|
272
|
-
margin: 0;
|
|
273
|
-
font-size: clamp(24px, 2.6vw, 31px);
|
|
274
|
-
line-height: 1.1;
|
|
275
|
-
font-weight: 720;
|
|
276
|
-
}
|
|
277
|
-
.controls {
|
|
278
|
-
display: flex;
|
|
279
|
-
gap: 8px;
|
|
280
|
-
align-items: center;
|
|
281
|
-
flex-wrap: wrap;
|
|
282
|
-
}
|
|
283
|
-
.search {
|
|
284
|
-
height: 36px;
|
|
285
|
-
min-width: 320px;
|
|
286
|
-
border: 1px solid var(--line);
|
|
287
|
-
border-radius: 7px;
|
|
288
|
-
padding: 0 12px;
|
|
289
|
-
background: var(--panel);
|
|
290
|
-
color: var(--text);
|
|
291
|
-
outline: none;
|
|
292
|
-
}
|
|
293
|
-
.search:focus { border-color: var(--focus); }
|
|
294
|
-
.table-wrap {
|
|
295
|
-
border: 1px solid var(--line);
|
|
296
|
-
border-radius: 8px;
|
|
297
|
-
overflow: auto;
|
|
298
|
-
background: var(--panel);
|
|
299
|
-
}
|
|
300
|
-
table {
|
|
301
|
-
width: 100%;
|
|
302
|
-
border-collapse: collapse;
|
|
303
|
-
min-width: 1040px;
|
|
304
|
-
}
|
|
305
|
-
th, td {
|
|
306
|
-
border-bottom: 1px solid var(--line);
|
|
307
|
-
padding: 0 16px;
|
|
308
|
-
height: 52px;
|
|
309
|
-
text-align: left;
|
|
310
|
-
vertical-align: middle;
|
|
311
|
-
font-size: 14px;
|
|
312
|
-
}
|
|
313
|
-
th {
|
|
314
|
-
color: var(--muted);
|
|
315
|
-
font-weight: 500;
|
|
316
|
-
background: var(--panel);
|
|
317
|
-
position: sticky;
|
|
318
|
-
top: 0;
|
|
319
|
-
z-index: 2;
|
|
320
|
-
}
|
|
321
|
-
tbody tr:last-child td { border-bottom: 0; }
|
|
322
|
-
.section-sub-head {
|
|
323
|
-
display: flex;
|
|
324
|
-
align-items: center;
|
|
325
|
-
justify-content: space-between;
|
|
326
|
-
gap: 18px;
|
|
327
|
-
margin-bottom: 16px;
|
|
328
|
-
min-height: 36px;
|
|
329
|
-
}
|
|
330
|
-
.group-detail-label {
|
|
331
|
-
font-size: 15px;
|
|
332
|
-
font-weight: 680;
|
|
333
|
-
color: var(--text);
|
|
334
|
-
}
|
|
335
134
|
.name { font-weight: 610; }
|
|
336
|
-
.sub { color: var(--muted); font-size: 12px; margin-top: 3px; }
|
|
337
135
|
.num {
|
|
338
136
|
font-variant-numeric: tabular-nums;
|
|
339
137
|
white-space: nowrap;
|
|
@@ -343,12 +141,6 @@ tbody tr:last-child td { border-bottom: 0; }
|
|
|
343
141
|
.bad { color: var(--bad); }
|
|
344
142
|
.warn { color: var(--warn); }
|
|
345
143
|
.infra-err { color: var(--warn); }
|
|
346
|
-
.eval-id {
|
|
347
|
-
display: flex;
|
|
348
|
-
align-items: center;
|
|
349
|
-
overflow-wrap: anywhere;
|
|
350
|
-
font-weight: 560;
|
|
351
|
-
}
|
|
352
144
|
.copy-all-errors {
|
|
353
145
|
height: 36px;
|
|
354
146
|
display: inline-flex;
|
|
@@ -702,41 +494,10 @@ pre {
|
|
|
702
494
|
font-size: 12px;
|
|
703
495
|
line-height: 1.5;
|
|
704
496
|
}
|
|
705
|
-
.empty {
|
|
706
|
-
border: 1px dashed var(--line-strong);
|
|
707
|
-
border-radius: 8px;
|
|
708
|
-
padding: 40px 24px;
|
|
709
|
-
color: var(--muted);
|
|
710
|
-
text-align: center;
|
|
711
|
-
background: var(--panel);
|
|
712
|
-
}
|
|
713
|
-
a.brand { text-decoration: none; color: inherit; }
|
|
714
|
-
a.brand:hover { opacity: 0.75; }
|
|
715
|
-
.traces-entry {
|
|
716
|
-
border: 1px solid var(--line);
|
|
717
|
-
border-radius: 8px;
|
|
718
|
-
background: var(--panel);
|
|
719
|
-
margin-bottom: 12px;
|
|
720
|
-
padding: 14px 18px;
|
|
721
|
-
}
|
|
722
|
-
.traces-entry-head {
|
|
723
|
-
display: flex;
|
|
724
|
-
align-items: baseline;
|
|
725
|
-
gap: 12px;
|
|
726
|
-
margin-bottom: 8px;
|
|
727
|
-
font-size: 13px;
|
|
728
|
-
}
|
|
729
|
-
.traces-verdict { font-weight: 600; min-width: 52px; }
|
|
730
|
-
.traces-exp { color: var(--muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
731
|
-
.traces-dur { color: var(--soft); }
|
|
732
497
|
@media (max-width: 760px) {
|
|
733
498
|
.topbar { padding: 0 20px; }
|
|
734
499
|
.lang-switch button { min-width: 40px; }
|
|
735
500
|
main { width: min(100vw - 28px, 1120px); padding-top: 42px; }
|
|
736
|
-
.hero { text-align: left; margin-left: 0; }
|
|
737
|
-
.meta { justify-content: flex-start; }
|
|
738
|
-
.section-head { align-items: stretch; flex-direction: column; }
|
|
739
|
-
.search { width: 100%; min-width: 0; }
|
|
740
501
|
.detail { padding: 18px 16px 20px; }
|
|
741
502
|
.config-strip { gap: 6px; }
|
|
742
503
|
.detail-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 10px; }
|
|
@@ -1194,8 +955,4 @@ li.tnode-row::before { content: ""; width: 4px; flex-shrink: 0; }
|
|
|
1194
955
|
color: var(--soft);
|
|
1195
956
|
font-size: 12px;
|
|
1196
957
|
}
|
|
1197
|
-
/* 品牌行:hero 之下、品牌蓝,恒带官网链接(shell.md「行为约束」)。 */
|
|
1198
|
-
.hero .powered-by { display: block; margin-top: 16px; font-size: 12px; }
|
|
1199
|
-
.hero .powered-by a { color: var(--blue); text-decoration: none; }
|
|
1200
|
-
.hero .powered-by a:hover { text-decoration: underline; }
|
|
1201
958
|
.nre-page-error pre { white-space: pre-wrap; }
|