niceeval 0.9.0 → 0.10.0
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 +31 -33
- package/dist/agents/types.d.ts +20 -17
- package/dist/context/types.d.ts +21 -21
- package/dist/i18n/en.d.ts +10 -2
- package/dist/i18n/zh-CN.d.ts +15 -7
- package/dist/o11y/execution-tree.d.ts +103 -0
- package/dist/o11y/otlp/select.d.ts +22 -0
- package/dist/report/{react → assets}/colors.d.ts +8 -0
- package/dist/report/{react → assets}/colors.js +23 -0
- package/dist/report/built-in/index.d.ts +2 -2
- package/dist/report/built-in/index.js +2 -2
- package/dist/report/built-in/standard.d.ts +8 -1
- package/dist/report/built-in/standard.js +17 -7
- package/dist/report/components/attempt-detail/AttemptAssertions.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptAssertions.js +17 -0
- package/dist/report/components/attempt-detail/AttemptConversation.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptConversation.js +34 -0
- package/dist/report/components/attempt-detail/AttemptDiagnostics.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptDiagnostics.js +7 -0
- package/dist/report/components/attempt-detail/AttemptDiff.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptDiff.js +11 -0
- package/dist/report/components/attempt-detail/AttemptError.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptError.js +16 -0
- package/dist/report/components/attempt-detail/AttemptFixPrompt.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptFixPrompt.js +7 -0
- package/dist/report/components/attempt-detail/AttemptSource.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptSource.js +27 -0
- package/dist/report/components/attempt-detail/AttemptSummary.d.ts +8 -0
- package/dist/report/components/attempt-detail/AttemptSummary.js +20 -0
- package/dist/report/components/attempt-detail/AttemptTimeline.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptTimeline.js +28 -0
- package/dist/report/components/attempt-detail/AttemptTrace.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptTrace.js +29 -0
- package/dist/report/components/attempt-detail/AttemptUsage.d.ts +6 -0
- package/dist/report/components/attempt-detail/AttemptUsage.js +20 -0
- package/dist/report/components/attempt-detail/compute.d.ts +24 -0
- package/dist/report/components/attempt-detail/compute.js +254 -0
- package/dist/report/components/attempt-detail/faces.d.ts +14 -0
- package/dist/report/components/attempt-detail/faces.js +235 -0
- package/dist/report/components/attempt-detail/index.d.ts +38 -0
- package/dist/report/components/attempt-detail/index.js +527 -0
- package/dist/report/{react → components}/cell.d.ts +5 -3
- package/dist/report/{react → components}/cell.js +3 -3
- package/dist/report/{react → components/entity-lists}/AttemptList.d.ts +8 -4
- package/dist/report/{react → components/entity-lists}/AttemptList.js +16 -10
- package/dist/report/{react → components/entity-lists}/EvalList.d.ts +3 -3
- package/dist/report/{react → components/entity-lists}/EvalList.js +0 -0
- package/dist/report/{react → components/entity-lists}/ExperimentList.d.ts +3 -3
- package/dist/report/{react → components/entity-lists}/ExperimentList.js +10 -10
- package/dist/report/components/entity-lists/compute.d.ts +23 -0
- package/dist/report/components/entity-lists/compute.js +171 -0
- package/dist/report/components/entity-lists/faces.d.ts +5 -0
- package/dist/report/components/entity-lists/faces.js +174 -0
- package/dist/report/components/entity-lists/index.d.ts +51 -0
- package/dist/report/components/entity-lists/index.js +165 -0
- package/dist/report/{react → components}/fixtures.d.ts +2 -2
- package/dist/report/{react → components}/fixtures.js +1 -1
- package/dist/report/{react → components/metric-views}/DeltaTable.d.ts +2 -2
- package/dist/report/{react → components/metric-views}/DeltaTable.js +4 -4
- package/dist/report/{react → components/metric-views}/MetricBars.d.ts +3 -3
- package/dist/report/{react → components/metric-views}/MetricBars.js +3 -3
- package/dist/report/{react → components/metric-views}/MetricLine.d.ts +2 -2
- package/dist/report/{react → components/metric-views}/MetricLine.js +8 -5
- package/dist/report/{react → components/metric-views}/MetricMatrix.d.ts +3 -3
- package/dist/report/{react → components/metric-views}/MetricMatrix.js +4 -4
- package/dist/report/components/metric-views/MetricScatter.d.ts +11 -0
- package/dist/report/{react → components/metric-views}/MetricScatter.js +26 -23
- package/dist/report/{react → components/metric-views}/MetricTable.d.ts +3 -3
- package/dist/report/{react → components/metric-views}/MetricTable.js +4 -4
- package/dist/report/{react → components/metric-views}/Scoreboard.d.ts +2 -2
- package/dist/report/{react → components/metric-views}/Scoreboard.js +3 -3
- package/dist/report/components/metric-views/compute.d.ts +89 -0
- package/dist/report/{compute.js → components/metric-views/compute.js} +32 -415
- package/dist/report/components/metric-views/faces.d.ts +13 -0
- package/dist/report/components/metric-views/faces.js +381 -0
- package/dist/report/components/metric-views/index.d.ts +50 -0
- package/dist/report/components/metric-views/index.js +273 -0
- package/dist/report/{text → components/metric-views}/plot.js +1 -1
- package/dist/report/components/shared-compute.d.ts +22 -0
- package/dist/report/components/shared-compute.js +47 -0
- package/dist/report/components/shared-faces.d.ts +9 -0
- package/dist/report/components/shared-faces.js +26 -0
- package/dist/report/components/shared.d.ts +68 -0
- package/dist/report/components/shared.js +125 -0
- package/dist/report/{react → components/site-components}/CopyFixPrompt.d.ts +2 -2
- package/dist/report/{react → components/site-components}/CopyFixPrompt.js +2 -2
- package/dist/report/{react → components/site-components}/HeroCard.d.ts +2 -2
- package/dist/report/{react → components/site-components}/HeroCard.js +2 -2
- package/dist/report/{react → components/site-components}/ScopeWarnings.d.ts +2 -2
- package/dist/report/{react → components/site-components}/ScopeWarnings.js +3 -3
- package/dist/report/{react → components/site-components}/TraceWaterfall.d.ts +3 -3
- package/dist/report/{react → components/site-components}/TraceWaterfall.js +5 -5
- package/dist/report/components/site-components/compute.d.ts +28 -0
- package/dist/report/components/site-components/compute.js +132 -0
- package/dist/report/components/site-components/faces.d.ts +21 -0
- package/dist/report/components/site-components/faces.js +75 -0
- package/dist/report/components/site-components/index.d.ts +74 -0
- package/dist/report/components/site-components/index.js +220 -0
- package/dist/report/{scope-warnings.d.ts → components/site-components/scope-warnings.d.ts} +2 -2
- package/dist/report/{scope-warnings.js → components/site-components/scope-warnings.js} +2 -2
- package/dist/report/{react → components/summaries}/ScopeSummary.d.ts +2 -2
- package/dist/report/{react → components/summaries}/ScopeSummary.js +17 -8
- package/dist/report/components/summaries/compute.d.ts +7 -0
- package/dist/report/components/summaries/compute.js +51 -0
- package/dist/report/components/summaries/faces.d.ts +7 -0
- package/dist/report/components/summaries/faces.js +38 -0
- package/dist/report/components/summaries/index.d.ts +27 -0
- package/dist/report/components/summaries/index.js +78 -0
- package/dist/report/definition/grid-layout.d.ts +50 -0
- package/dist/report/definition/grid-layout.js +89 -0
- package/dist/report/{primitives.d.ts → definition/primitives.d.ts} +34 -4
- package/dist/report/{primitives.js → definition/primitives.js} +101 -10
- package/dist/report/{report.d.ts → definition/report.d.ts} +36 -65
- package/dist/report/{report.js → definition/report.js} +58 -90
- package/dist/report/{text/table.d.ts → definition/table-text.d.ts} +2 -2
- package/dist/report/{text/table.js → definition/table-text.js} +2 -2
- package/dist/report/{tree.d.ts → definition/tree.d.ts} +44 -12
- package/dist/report/{tree.js → definition/tree.js} +10 -12
- package/dist/report/index.d.ts +33 -18
- package/dist/report/index.js +23 -14
- package/dist/report/{aggregate.d.ts → model/aggregate.d.ts} +12 -4
- package/dist/report/{aggregate.js → model/aggregate.js} +28 -8
- package/dist/report/{flag.d.ts → model/flag.d.ts} +14 -1
- package/dist/report/{flag.js → model/flag.js} +35 -0
- package/dist/report/{format.d.ts → model/format.d.ts} +11 -5
- package/dist/report/{format.js → model/format.js} +48 -4
- package/dist/report/{locale.d.ts → model/locale.d.ts} +17 -17
- package/dist/report/{locale.js → model/locale.js} +31 -33
- package/dist/report/{metrics.d.ts → model/metrics.d.ts} +2 -2
- package/dist/report/{metrics.js → model/metrics.js} +2 -2
- package/dist/report/{types.d.ts → model/types.d.ts} +140 -20
- package/dist/report/react/index.d.ts +32 -21
- package/dist/report/react/index.js +33 -21
- package/dist/report/{load.d.ts → runtime/load.d.ts} +1 -1
- package/dist/report/{load.js → runtime/load.js} +1 -1
- package/dist/report/runtime/text.d.ts +67 -0
- package/dist/report/runtime/text.js +114 -0
- package/dist/report/runtime/web.d.ts +35 -0
- package/dist/report/runtime/web.js +70 -0
- package/dist/results/annotated-source.d.ts +87 -0
- package/dist/results/attempt-evidence.d.ts +74 -0
- package/dist/results/attempt-source.d.ts +15 -0
- package/dist/results/select.d.ts +12 -2
- package/dist/results/select.js +27 -5
- package/dist/runner/eval-selection.d.ts +26 -0
- package/dist/runner/feedback/sink.d.ts +26 -1
- package/dist/runner/types.d.ts +149 -23
- package/dist/sandbox/docker.d.ts +6 -0
- package/dist/sandbox/types.d.ts +23 -21
- package/dist/scoring/display.d.ts +7 -2
- package/dist/scoring/display.js +42 -4
- package/dist/scoring/types.d.ts +3 -3
- package/dist/shared/aggregate.d.ts +15 -1
- package/dist/shared/aggregate.js +32 -1
- package/dist/shared/types.d.ts +6 -1
- package/docs-site/images/logo-dark.svg +7 -0
- package/docs-site/images/logo.svg +6 -5
- package/docs-site/zh/README.md +8 -7
- package/docs-site/zh/examples/ai-agent-application.mdx +5 -5
- package/docs-site/zh/examples/coding-agent-extensions.mdx +4 -4
- package/docs-site/zh/examples/index.mdx +3 -3
- package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +1 -1
- package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
- package/docs-site/zh/examples/integrations/codex-sdk.mdx +3 -3
- package/docs-site/zh/examples/integrations/langgraph.mdx +3 -3
- package/docs-site/zh/examples/integrations/pi-sdk.mdx +2 -2
- package/docs-site/zh/explanation/adapter.mdx +19 -19
- package/docs-site/zh/explanation/assert.mdx +9 -9
- package/docs-site/zh/explanation/drive.mdx +4 -4
- package/docs-site/zh/explanation/evals.mdx +8 -8
- package/docs-site/zh/explanation/experiment.mdx +8 -8
- package/docs-site/zh/explanation/hitl.mdx +13 -13
- package/docs-site/zh/explanation/judge.mdx +3 -3
- package/docs-site/zh/explanation/overview.mdx +7 -7
- package/docs-site/zh/explanation/runner.mdx +11 -11
- package/docs-site/zh/explanation/tier.mdx +6 -6
- package/docs-site/zh/index.mdx +14 -14
- package/docs-site/zh/introduction.mdx +13 -16
- package/docs-site/zh/reference/builtin-agents.mdx +61 -28
- package/docs-site/zh/reference/capabilities.mdx +7 -27
- package/docs-site/zh/reference/cli.mdx +35 -32
- package/docs-site/zh/reference/define-agent.mdx +32 -31
- package/docs-site/zh/reference/define-config.mdx +6 -6
- package/docs-site/zh/reference/define-eval.mdx +33 -20
- package/docs-site/zh/reference/events.mdx +4 -4
- package/docs-site/zh/reference/expect.mdx +3 -3
- package/docs-site/zh/reference/official-adapters.mdx +17 -17
- package/docs-site/zh/reference/report-components.mdx +193 -121
- package/docs-site/zh/reference/results-data.mdx +13 -13
- package/docs-site/zh/troubleshooting/debug-sandbox.mdx +11 -11
- package/docs-site/zh/troubleshooting/debugging.mdx +43 -19
- package/docs-site/zh/{how-to → tutorials}/agent-feedback-loop.mdx +38 -38
- package/docs-site/zh/tutorials/agent-onboarding.mdx +100 -0
- package/docs-site/zh/tutorials/authoring.mdx +211 -0
- package/docs-site/zh/{how-to → tutorials}/ci-integration.mdx +8 -8
- package/docs-site/zh/{how-to → tutorials}/connect-otel.mdx +22 -22
- package/docs-site/zh/{how-to → tutorials}/connect-your-agent.mdx +58 -63
- package/docs-site/zh/tutorials/custom-reports.mdx +453 -0
- package/docs-site/zh/{how-to → tutorials}/dataset-fanout.mdx +4 -4
- package/docs-site/zh/tutorials/experiments.mdx +103 -0
- package/docs-site/zh/{how-to → tutorials}/fixtures.mdx +9 -9
- package/docs-site/zh/{how-to → tutorials}/publish-report.mdx +11 -5
- package/docs-site/zh/tutorials/quickstart.mdx +18 -18
- package/docs-site/zh/{how-to → tutorials}/reporters.mdx +6 -6
- package/docs-site/zh/{how-to → tutorials}/sandbox-agent.mdx +6 -6
- package/docs-site/zh/{how-to → tutorials}/sandbox-providers.mdx +41 -19
- package/docs-site/zh/{how-to → tutorials}/scoring-guide.mdx +4 -4
- package/docs-site/zh/{how-to → tutorials}/viewing-results.mdx +59 -50
- package/docs-site/zh/tutorials/write-experiment.mdx +355 -0
- package/docs-site/zh/{how-to → tutorials}/write-send.mdx +40 -40
- package/package.json +8 -4
- package/src/agents/bub.ts +21 -8
- package/src/agents/claude-code.ts +23 -10
- package/src/agents/codex.test.ts +22 -7
- package/src/agents/codex.ts +22 -9
- package/src/agents/index.ts +2 -2
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/post-setup.ts +45 -22
- package/src/agents/streaming.ts +1 -1
- package/src/agents/types.ts +20 -17
- package/src/agents/ui-message-stream.test.ts +10 -0
- package/src/agents/ui-message-stream.ts +12 -1
- package/src/cli.ts +77 -64
- package/src/context/types.ts +21 -21
- package/src/define.ts +13 -0
- package/src/i18n/en.ts +30 -15
- package/src/i18n/zh-CN.ts +30 -15
- package/src/index.ts +2 -0
- package/src/report/{react → assets}/colors.ts +22 -0
- package/src/report/{react → assets}/enhance.js +1 -33
- package/src/report/{react → assets}/styles.css +136 -112
- package/src/report/built-in/index.tsx +2 -2
- package/src/report/built-in/standard.tsx +18 -6
- package/src/report/components/attempt-detail/AttemptAssertions.tsx +67 -0
- package/src/report/components/attempt-detail/AttemptConversation.tsx +110 -0
- package/src/report/components/attempt-detail/AttemptDiagnostics.tsx +38 -0
- package/src/report/components/attempt-detail/AttemptDiff.tsx +35 -0
- package/src/report/components/attempt-detail/AttemptError.tsx +31 -0
- package/src/report/components/attempt-detail/AttemptFixPrompt.tsx +26 -0
- package/src/report/components/attempt-detail/AttemptSource.tsx +80 -0
- package/src/report/components/attempt-detail/AttemptSummary.tsx +74 -0
- package/src/report/components/attempt-detail/AttemptTimeline.tsx +108 -0
- package/src/report/components/attempt-detail/AttemptTrace.tsx +63 -0
- package/src/report/components/attempt-detail/AttemptUsage.tsx +29 -0
- package/src/report/components/attempt-detail/attempt-components.test.tsx +680 -0
- package/src/report/components/attempt-detail/compute.ts +287 -0
- package/src/report/components/attempt-detail/faces.ts +257 -0
- package/src/report/components/attempt-detail/index.tsx +583 -0
- package/src/report/components/attempt-detail/validate.test.ts +235 -0
- package/src/report/{react → components}/cell.tsx +6 -3
- package/src/report/{report.test.ts → components/compute.test.ts} +316 -46
- package/src/report/{react → components/entity-lists}/AttemptList.tsx +24 -16
- package/src/report/{react → components/entity-lists}/EvalList.tsx +0 -0
- package/src/report/{react → components/entity-lists}/ExperimentList.tsx +23 -20
- package/src/report/components/entity-lists/compute.ts +196 -0
- package/src/report/components/entity-lists/faces.ts +207 -0
- package/src/report/components/entity-lists/index.tsx +241 -0
- package/src/report/components/entity-lists/validate.test.ts +114 -0
- package/src/report/{react → components}/fixtures.ts +2 -2
- package/src/report/{react → components/metric-views}/DeltaTable.tsx +5 -5
- package/src/report/{react → components/metric-views}/MetricBars.tsx +5 -5
- package/src/report/{react → components/metric-views}/MetricLine.tsx +9 -6
- package/src/report/{react → components/metric-views}/MetricMatrix.tsx +6 -6
- package/src/report/{react → components/metric-views}/MetricScatter.tsx +41 -33
- package/src/report/{react → components/metric-views}/MetricTable.tsx +6 -6
- package/src/report/{react → components/metric-views}/Scoreboard.tsx +4 -4
- package/src/report/{compute.ts → components/metric-views/compute.ts} +51 -477
- package/src/report/components/metric-views/faces.ts +423 -0
- package/src/report/components/metric-views/index.tsx +352 -0
- package/src/report/{text → components/metric-views}/plot.ts +1 -1
- package/src/report/components/metric-views/validate.test.ts +211 -0
- package/src/report/{react → components}/render.test.tsx +47 -17
- package/src/report/components/shared-compute.ts +59 -0
- package/src/report/components/shared-faces.ts +30 -0
- package/src/report/components/shared.ts +192 -0
- package/src/report/{react → components/site-components}/CopyFixPrompt.tsx +3 -3
- package/src/report/{react → components/site-components}/HeroCard.tsx +3 -3
- package/src/report/{react → components/site-components}/ScopeWarnings.tsx +4 -4
- package/src/report/{react → components/site-components}/TraceWaterfall.tsx +13 -10
- package/src/report/components/site-components/compute.ts +144 -0
- package/src/report/components/site-components/faces.ts +80 -0
- package/src/report/components/site-components/index.tsx +265 -0
- package/src/report/{scope-warnings.ts → components/site-components/scope-warnings.ts} +3 -3
- package/src/report/{site-components.test.tsx → components/site-components/site-components.test.tsx} +23 -21
- package/src/report/components/site-components/validate.test.ts +89 -0
- package/src/report/{react → components/summaries}/ScopeSummary.tsx +26 -11
- package/src/report/components/summaries/compute.ts +56 -0
- package/src/report/components/summaries/faces.ts +48 -0
- package/src/report/components/summaries/index.tsx +127 -0
- package/src/report/components/summaries/validate.test.ts +49 -0
- package/src/report/definition/grid-layout.test.ts +124 -0
- package/src/report/definition/grid-layout.ts +146 -0
- package/src/report/{primitives.tsx → definition/primitives.tsx} +168 -18
- package/src/report/{report.ts → definition/report.ts} +98 -165
- package/src/report/{shell-head.test.ts → definition/shell-head.test.ts} +2 -2
- package/src/report/{text/table.ts → definition/table-text.ts} +4 -4
- package/src/report/{tree.ts → definition/tree.ts} +58 -22
- package/src/report/index.ts +126 -66
- package/src/report/{aggregate.ts → model/aggregate.ts} +31 -9
- package/src/report/{flag.ts → model/flag.ts} +39 -1
- package/src/report/{format.ts → model/format.ts} +59 -5
- package/src/report/{locale.ts → model/locale.ts} +34 -36
- package/src/report/{metrics.ts → model/metrics.ts} +3 -3
- package/src/report/{types.ts → model/types.ts} +143 -22
- package/src/report/react/index.tsx +52 -26
- package/src/report/{dual-render.test.tsx → runtime/dual-render.test.tsx} +564 -49
- package/src/report/runtime/host.test.ts +44 -0
- package/src/report/runtime/host.ts +138 -0
- package/src/report/{load.ts → runtime/load.ts} +1 -1
- package/src/report/runtime/text.ts +192 -0
- package/src/report/runtime/web.ts +106 -0
- package/src/results/attempt-evidence.ts +5 -1
- package/src/results/host-equivalence.test.ts +54 -3
- package/src/results/select.ts +30 -6
- package/src/runner/attempt.test.ts +48 -1
- package/src/runner/attempt.ts +62 -42
- package/src/runner/cleanup-timeout.test.ts +16 -0
- package/src/runner/cleanup-timeout.ts +23 -0
- package/src/runner/discover.ts +1 -2
- package/src/runner/eval-selection.test.ts +187 -0
- package/src/runner/eval-selection.ts +109 -0
- package/src/runner/experiment-cleanup-registry.test.ts +89 -0
- package/src/runner/experiment-cleanup-registry.ts +39 -0
- package/src/runner/experiment-labels.test.ts +71 -0
- package/src/runner/feedback/agent.test.ts +33 -1
- package/src/runner/feedback/agent.ts +12 -16
- package/src/runner/feedback/ci.test.ts +35 -1
- package/src/runner/feedback/ci.ts +16 -18
- package/src/runner/feedback/coordinator.ts +28 -0
- package/src/runner/feedback/human.test.ts +108 -1
- package/src/runner/feedback/human.ts +71 -21
- package/src/runner/feedback/reducer.test.ts +64 -0
- package/src/runner/feedback/reducer.ts +26 -0
- package/src/runner/feedback/sink.ts +40 -1
- package/src/runner/fingerprint.ts +2 -1
- package/src/runner/report.test.ts +14 -0
- package/src/runner/report.ts +3 -1
- package/src/runner/run.test.ts +390 -12
- package/src/runner/run.ts +259 -26
- package/src/runner/sandbox-selection.test.ts +13 -3
- package/src/runner/sandbox-selection.ts +4 -2
- package/src/runner/types.ts +158 -23
- package/src/sandbox/docker.ts +7 -0
- package/src/sandbox/e2b.ts +12 -13
- package/src/sandbox/types.ts +23 -21
- package/src/scoring/display.test.ts +28 -2
- package/src/scoring/display.ts +38 -5
- package/src/scoring/types.ts +3 -3
- package/src/shared/aggregate.test.ts +52 -0
- package/src/shared/aggregate.ts +30 -1
- package/src/shared/types.ts +6 -1
- package/src/show/command.test.ts +34 -0
- package/src/show/command.ts +16 -0
- package/src/show/compose.ts +1 -1
- package/src/show/index.ts +58 -22
- package/src/show/render.ts +16 -240
- package/src/show/show.test.ts +128 -35
- package/src/view/app/App.test.tsx +8 -7
- package/src/view/app/App.tsx +135 -51
- package/src/view/app/i18n.ts +7 -147
- package/src/view/app/lib/attempt-dialog.test.ts +65 -0
- package/src/view/app/lib/attempt-dialog.ts +69 -0
- package/src/view/app/main.tsx +0 -1
- package/src/view/app/types.ts +3 -86
- package/src/view/artifact-serving.test.ts +22 -38
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +15 -22
- package/src/view/data.test.ts +48 -36
- package/src/view/data.ts +122 -89
- package/src/view/index.ts +3 -13
- package/src/view/server.ts +36 -6
- package/src/view/shared/types.ts +6 -31
- package/src/view/site-parity.test.ts +24 -1
- package/src/view/site.ts +144 -17
- package/src/view/styles.css +18 -806
- package/src/view/view-report.test.ts +182 -34
- package/dist/report/components.d.ts +0 -179
- package/dist/report/components.js +0 -544
- package/dist/report/compute.d.ts +0 -139
- package/dist/report/react/ExperimentComparison.d.ts +0 -10
- package/dist/report/react/ExperimentComparison.js +0 -12
- package/dist/report/react/MetricScatter.d.ts +0 -9
- package/dist/report/react/format.d.ts +0 -3
- package/dist/report/react/format.js +0 -7
- package/dist/report/text/faces.d.ts +0 -45
- package/dist/report/text/faces.js +0 -671
- package/dist/report/web.d.ts +0 -32
- package/dist/report/web.js +0 -48
- package/docs-site/zh/how-to/authoring.mdx +0 -162
- package/docs-site/zh/how-to/custom-reports.mdx +0 -414
- package/docs-site/zh/how-to/experiments.mdx +0 -86
- package/docs-site/zh/how-to/write-experiment.mdx +0 -164
- package/src/report/components.tsx +0 -925
- package/src/report/react/ExperimentComparison.tsx +0 -73
- package/src/report/react/format.ts +0 -9
- package/src/report/text/faces.ts +0 -767
- package/src/report/web.ts +0 -77
- package/src/show/report-host.test.ts +0 -205
- package/src/show/report-host.ts +0 -389
- package/src/view/app/components/AttemptModal.tsx +0 -496
- package/src/view/app/components/CodeView.test.tsx +0 -142
- package/src/view/app/components/CodeView.tsx +0 -310
- package/src/view/app/components/CopyControls.tsx +0 -106
- package/src/view/app/components/Trace.tsx +0 -100
- package/src/view/app/components/Transcript.tsx +0 -157
- package/src/view/app/components/ui/badge.tsx +0 -21
- package/src/view/app/lib/artifact-url.ts +0 -17
- package/src/view/app/lib/attempt-route.test.ts +0 -80
- package/src/view/app/lib/attempt-route.ts +0 -52
- package/src/view/app/lib/format.ts +0 -70
- package/src/view/app/lib/guards.test.ts +0 -108
- package/src/view/app/lib/guards.ts +0 -71
- package/src/view/app/lib/rows.ts +0 -22
- package/src/view/app/lib/transcript-data.tsx +0 -151
- package/src/view/app/lib/verdict.ts +0 -23
- package/src/view/app/shared.ts +0 -8
- /package/dist/report/{react → components/metric-views}/chart-math.d.ts +0 -0
- /package/dist/report/{react → components/metric-views}/chart-math.js +0 -0
- /package/dist/report/{text → components/metric-views}/plot.d.ts +0 -0
- /package/dist/report/{react → components/site-components}/PoweredBy.d.ts +0 -0
- /package/dist/report/{react → components/site-components}/PoweredBy.js +0 -0
- /package/dist/report/{text/layout.d.ts → model/text-layout.d.ts} +0 -0
- /package/dist/report/{text/layout.js → model/text-layout.js} +0 -0
- /package/dist/report/{types.js → model/types.js} +0 -0
- /package/src/report/{react → components/metric-views}/chart-math.test.ts +0 -0
- /package/src/report/{react → components/metric-views}/chart-math.ts +0 -0
- /package/src/report/{react → components/site-components}/PoweredBy.tsx +0 -0
- /package/src/report/{text/layout.ts → model/text-layout.ts} +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// cases: docs/engineering/unit-tests/experiments-runner/cases.md
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { matchExperimentSelector } from "./aggregate.ts";
|
|
4
|
+
|
|
5
|
+
describe("matchExperimentSelector", () => {
|
|
6
|
+
const ids = [
|
|
7
|
+
"compare/bub-gpt-5.6-luna",
|
|
8
|
+
"compare/codex-gpt-5.6-luna",
|
|
9
|
+
"compare/codex-gpt-5.6-luna--agents-md",
|
|
10
|
+
"compare/codex-gpt-5.6-luna--mempal",
|
|
11
|
+
"dev-e2b/bub-e2b",
|
|
12
|
+
"dev/bub-gpt-5.4-mini",
|
|
13
|
+
"top-level",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
it("selects an entire group by exact directory match", () => {
|
|
17
|
+
expect(matchExperimentSelector(ids, "compare")).toEqual([
|
|
18
|
+
"compare/bub-gpt-5.6-luna",
|
|
19
|
+
"compare/codex-gpt-5.6-luna",
|
|
20
|
+
"compare/codex-gpt-5.6-luna--agents-md",
|
|
21
|
+
"compare/codex-gpt-5.6-luna--mempal",
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("an exact id match wins even when it is a prefix of sibling variants", () => {
|
|
26
|
+
expect(matchExperimentSelector(ids, "compare/codex-gpt-5.6-luna")).toEqual([
|
|
27
|
+
"compare/codex-gpt-5.6-luna",
|
|
28
|
+
]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("falls back to a filename prefix within an exact-matched directory to select a family", () => {
|
|
32
|
+
expect(matchExperimentSelector(ids, "compare/codex")).toEqual([
|
|
33
|
+
"compare/codex-gpt-5.6-luna",
|
|
34
|
+
"compare/codex-gpt-5.6-luna--agents-md",
|
|
35
|
+
"compare/codex-gpt-5.6-luna--mempal",
|
|
36
|
+
]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("requires an exact directory segment; a group-like prefix does not leak across groups", () => {
|
|
40
|
+
expect(matchExperimentSelector(ids, "dev")).toEqual(["dev/bub-gpt-5.4-mini"]);
|
|
41
|
+
expect(matchExperimentSelector(ids, "dev")).not.toContain("dev-e2b/bub-e2b");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("matches a top-level (groupless) experiment by exact id", () => {
|
|
45
|
+
expect(matchExperimentSelector(ids, "top-level")).toEqual(["top-level"]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("returns empty when nothing matches", () => {
|
|
49
|
+
expect(matchExperimentSelector(ids, "dev-e3b")).toEqual([]);
|
|
50
|
+
expect(matchExperimentSelector(ids, "compare/nope")).toEqual([]);
|
|
51
|
+
});
|
|
52
|
+
});
|
package/src/shared/aggregate.ts
CHANGED
|
@@ -47,7 +47,7 @@ export function experimentGroupOf(experimentId: string): string | undefined {
|
|
|
47
47
|
/**
|
|
48
48
|
* eval id 前缀过滤,同 CLI 位置参数语义(docs/feature/reports/show.md「打开与收窄」):
|
|
49
49
|
* eval 位置参数是收窄过滤,按**裸前缀宽松匹配**——"algebra" 命中 "algebra"、"algebra/..."
|
|
50
|
-
* 也命中 "algebra2",多命中正是它的用途(与 `--
|
|
50
|
+
* 也命中 "algebra2",多命中正是它的用途(与 `--exp` 的按路径段匹配有意不同)。
|
|
51
51
|
*/
|
|
52
52
|
export function evalPrefixPredicate(evals?: string | string[]): (id: string) => boolean {
|
|
53
53
|
if (evals === undefined) return () => true;
|
|
@@ -55,6 +55,35 @@ export function evalPrefixPredicate(evals?: string | string[]): (id: string) =>
|
|
|
55
55
|
return (id) => prefixes.some((prefix) => id.startsWith(prefix));
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* 实验选择器解析:`niceeval exp` 位置参数与 `--exp` 共用同一条规则(docs/feature/experiments/cli.md
|
|
60
|
+
* 「实验选择器怎样解析」)。按序:①精确 id 优先,即使它同时是同目录内其它文件名的前缀;
|
|
61
|
+
* ②目录段精确前缀(含更深层目录),选中该目录下全部实验;③以上都不命中且选择器形如
|
|
62
|
+
* `目录/文件名前缀` 时,目录段精确匹配后按文件名段前缀选中一族配置——目录段永远精确,不跨目录
|
|
63
|
+
* 误配,文件名段裸前缀,与 `evalPrefixPredicate` 同一条"共享前缀即家族"的逻辑。
|
|
64
|
+
*/
|
|
65
|
+
export function matchExperimentSelector(ids: readonly string[], selector: string): string[] {
|
|
66
|
+
const exact = ids.find((id) => id === selector);
|
|
67
|
+
if (exact !== undefined) return [exact];
|
|
68
|
+
const dirMatches = ids.filter((id) => id.startsWith(selector + "/"));
|
|
69
|
+
if (dirMatches.length > 0) return dirMatches;
|
|
70
|
+
const lastSlash = selector.lastIndexOf("/");
|
|
71
|
+
if (lastSlash === -1) return [];
|
|
72
|
+
const dir = selector.slice(0, lastSlash);
|
|
73
|
+
const namePrefix = selector.slice(lastSlash + 1);
|
|
74
|
+
if (namePrefix === "") return [];
|
|
75
|
+
return ids.filter((id) => id.startsWith(dir + "/") && id.slice(dir.length + 1).startsWith(namePrefix));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 零命中时展示的可浏览路径清单(docs/feature/experiments/cli.md「零命中」):按 id 的顶层目录段
|
|
80
|
+
* 去重、排序,带尾斜杠;没有目录段的顶层 experiment id 原样列出(它本身就是一个可选择的目标,
|
|
81
|
+
* 不是一段路径)。这是运行选择的展示投影,不是报告分组。
|
|
82
|
+
*/
|
|
83
|
+
export function browsableExperimentPaths(ids: readonly string[]): string[] {
|
|
84
|
+
return [...new Set(ids.map((id) => (id.includes("/") ? `${id.split("/")[0]}/` : id)))].sort();
|
|
85
|
+
}
|
|
86
|
+
|
|
58
87
|
/** 无 experimentId 时的兜底标签。 */
|
|
59
88
|
export function fallbackExperimentLabel(result: {
|
|
60
89
|
experimentId?: string;
|
package/src/shared/types.ts
CHANGED
|
@@ -30,7 +30,12 @@ export interface SourceArtifact {
|
|
|
30
30
|
content: string;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* 内部收尾闭包类型:供运行器内部的清理注册表使用(如 `postSetup` 钩子内部累积待收尾动作),
|
|
35
|
+
* 不出现在任何公开的生命周期钩子签名里——`SandboxHook`/`AgentSetup`/`AgentTeardown` 等公开
|
|
36
|
+
* 钩子一律 `void | Promise<void>`,setup 不返回值,收尾靠成对的 teardown(见
|
|
37
|
+
* docs/runner.md「环境预置不进运行器,但按顺序调它」)。
|
|
38
|
+
*/
|
|
34
39
|
export type Cleanup = () => Promise<void> | void;
|
|
35
40
|
|
|
36
41
|
/** `ScopedFeedback.progress` 的入参:此刻正在做什么(短命状态,可被后续更新覆盖)。 */
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// cases: docs/engineering/unit-tests/reports/cases.md
|
|
2
|
+
// 「外壳、页面与 Tabs」——show 专属的索引命令拼装(showCommand)与其余页索引文案(otherPagesText)。
|
|
3
|
+
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { showCommand } from "./command.ts";
|
|
6
|
+
import { otherPagesText } from "./render.ts";
|
|
7
|
+
|
|
8
|
+
describe("其余页索引与索引命令上下文", () => {
|
|
9
|
+
const pages = [
|
|
10
|
+
{ id: "overview", title: { en: "Overview", "zh-CN": "总览" } },
|
|
11
|
+
{ id: "exam", title: { en: "Exam", "zh-CN": "成绩单" } },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
it("只列未渲染的页,索引命令保留当前 --results / --report 与位置参数,复制即可复现下一层视图", () => {
|
|
15
|
+
// 渲染的是 overview,其余页索引只含 exam 一行——与「渲染初始页 + 尾部附其余页索引」
|
|
16
|
+
// 的行为一致(docs/feature/reports/show/reports.md Case 2)。
|
|
17
|
+
const text = otherPagesText({
|
|
18
|
+
otherPages: pages.filter((p) => p.id !== "overview"),
|
|
19
|
+
command: { patterns: [], results: "tmp/published-results", report: "reports/site.tsx" },
|
|
20
|
+
locale: "zh-CN",
|
|
21
|
+
});
|
|
22
|
+
expect(text).toContain("其余页:");
|
|
23
|
+
expect(text).toContain("niceeval show --results tmp/published-results --report reports/site.tsx --page exam");
|
|
24
|
+
expect(text).toContain("成绩单");
|
|
25
|
+
expect(text).not.toContain("总览");
|
|
26
|
+
expect(text).not.toContain("--page overview");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("showCommand 按序携带位置参数与 --exp / --results / --report / --page", () => {
|
|
30
|
+
expect(
|
|
31
|
+
showCommand({ patterns: ["memory/swelancer"], experiment: "dev-e2b", report: "reports/site.tsx", page: "exam" }),
|
|
32
|
+
).toBe("niceeval show memory/swelancer --exp dev-e2b --report reports/site.tsx --page exam");
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// show 专属的可复制命令拼装:页索引 / 组索引共用的携带规则(docs/feature/reports/show/reports.md
|
|
2
|
+
// 「索引命令携带完整上下文」)。这不是两宿主共用的报告 runtime 部分——view 走网页路由,不生成
|
|
3
|
+
// 终端命令——所以住在 show 自己这一侧,不进 src/report/runtime/host.ts。
|
|
4
|
+
|
|
5
|
+
import type { HostCommandContext } from "../report/runtime/host.ts";
|
|
6
|
+
|
|
7
|
+
/** 按上下文拼一条可复制的 show 命令(页索引 / 组索引共用的携带规则)。 */
|
|
8
|
+
export function showCommand(ctx: HostCommandContext, extra: string[] = []): string {
|
|
9
|
+
const parts = ["niceeval show", ...ctx.patterns];
|
|
10
|
+
if (ctx.experiment !== undefined) parts.push(`--exp ${ctx.experiment}`);
|
|
11
|
+
if (ctx.results !== undefined) parts.push(`--results ${ctx.results}`);
|
|
12
|
+
if (ctx.report !== undefined) parts.push(`--report ${ctx.report}`);
|
|
13
|
+
if (ctx.page !== undefined) parts.push(`--page ${ctx.page}`);
|
|
14
|
+
parts.push(...extra);
|
|
15
|
+
return parts.join(" ");
|
|
16
|
+
}
|
package/src/show/compose.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// 现刻水位 Scope(两个宿主共用)住在 ../results/select.ts;本文件只留 show 独有的时间轴计算。
|
|
7
7
|
// 数据只消费 niceeval/results 的读取面。
|
|
8
8
|
|
|
9
|
-
import { attemptCostUSD } from "../report/metrics.ts";
|
|
9
|
+
import { attemptCostUSD } from "../report/model/metrics.ts";
|
|
10
10
|
import { compactAssertionSummary, primaryAssertionSummary, summaryText } from "../scoring/display.ts";
|
|
11
11
|
import type { EvalResult, Verdict } from "../types.ts";
|
|
12
12
|
import type { AttemptHandle, Experiment } from "../results/index.ts";
|
package/src/show/index.ts
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
// 位置参数 = eval id 前缀,或 `@<locator>`(精确指名单个 attempt,见 results/locator.ts):
|
|
5
5
|
// 裸跑 / 多 eval 前缀 内建报告(niceeval/report/built-in 默认导出)的 text 面(单 eval 前缀仍进入详情)
|
|
6
6
|
// 恰好一个 eval 单 eval 详情(attempt / 断言明细,宿主本体)
|
|
7
|
-
// @<locator> 精确 attempt:无证据 flag →
|
|
7
|
+
// @<locator> 精确 attempt:无证据 flag → 当前 report 的 attempt-input page(内建 standard
|
|
8
|
+
// 或 --report 自定义);带 flag → 对应证据切面(宿主本体,不经报告管线)
|
|
8
9
|
// --source / --execution / --diff[=路径] 证据切面(宿主本体):出现即走证据室,不渲染报告槽
|
|
9
10
|
// --history 执行时间轴(逐 experimentId + evalId 分节),与 --report 互斥
|
|
10
|
-
// --report <文件> 整槽换成用户报告;位置前缀 / --results / --
|
|
11
|
+
// --report <文件> 整槽换成用户报告;位置前缀 / --results / --exp 先收窄 Scope 再注入
|
|
11
12
|
// --page <id> 多页报告选页;未命中列出可用页 id 按用法错误退出
|
|
12
|
-
// --results <目录> 结果根换成该目录;--
|
|
13
|
+
// --results <目录> 结果根换成该目录;--exp 让 Scope 只留该实验
|
|
13
14
|
//
|
|
14
15
|
// 数据全部走 niceeval/results 的读取面(openResults + 合成 Scope + loadAttemptEvidence),
|
|
15
16
|
// 不自己爬目录;证据可用性只由 loadAttemptEvidence 在单 Attempt 页面计算。
|
|
@@ -28,26 +29,25 @@ import {
|
|
|
28
29
|
// against — `instanceof` is keyed by declaration site, so a raw src copy and the compiled
|
|
29
30
|
// dist copy of "the same" class are two different types. The package-owned report runtime
|
|
30
31
|
// ships as precompiled ESM (dist/report/**, built by `pnpm run build:report`); all report
|
|
31
|
-
// loading/rendering goes through
|
|
32
|
-
import { ReportLoadError } from "../../dist/report/load.js";
|
|
32
|
+
// loading/rendering goes through ../report/runtime/host.ts (the shared contact surface).
|
|
33
|
+
import { ReportLoadError } from "../../dist/report/runtime/load.js";
|
|
33
34
|
import { detectLocale, t } from "../i18n/index.ts";
|
|
34
35
|
import { foldEvalVerdict } from "../shared/verdict.ts";
|
|
35
36
|
import { selectCurrentResults, filterExperiments } from "../results/select.ts";
|
|
36
37
|
import { evalPrefixPredicate } from "../shared/aggregate.ts";
|
|
37
38
|
import { attemptHistory } from "./compose.ts";
|
|
38
39
|
import {
|
|
40
|
+
buildHostReportMeta,
|
|
39
41
|
HostReportError,
|
|
40
42
|
loadHostReport,
|
|
41
|
-
reportMetaFor,
|
|
42
43
|
renderHostPageText,
|
|
43
44
|
type HostCommandContext,
|
|
44
|
-
} from "
|
|
45
|
+
} from "../report/runtime/host.ts";
|
|
45
46
|
import {
|
|
46
47
|
attemptArtifactsPath,
|
|
47
48
|
attemptEvidenceHeader,
|
|
48
49
|
attemptHistoryText,
|
|
49
50
|
attemptIndexLine,
|
|
50
|
-
attemptOverviewText,
|
|
51
51
|
attemptsOfEval,
|
|
52
52
|
diffText,
|
|
53
53
|
evalDetailText,
|
|
@@ -96,8 +96,9 @@ function clampWidth(columns: number | undefined): number {
|
|
|
96
96
|
return Math.max(40, Math.min(columns as number, 160));
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
// --report
|
|
100
|
-
|
|
99
|
+
// --report 的装载住在 ../report/runtime/host.ts(两个宿主共用的中性联系面);规范化本身是
|
|
100
|
+
// `defineReport` 自己的职责,不在宿主层重复。
|
|
101
|
+
export { loadHostReport, localizeText } from "../report/runtime/host.ts";
|
|
101
102
|
|
|
102
103
|
export async function runShow(
|
|
103
104
|
cwd: string,
|
|
@@ -163,8 +164,7 @@ async function show(
|
|
|
163
164
|
// `@<locator>` 位置参数:身份直达单个 attempt,与 eval id 前缀匹配完全不同的语义
|
|
164
165
|
// (`@` 打头对 eval id 天然无歧义,见 locator.ts),必须在下面的前缀匹配逻辑之前分流掉,
|
|
165
166
|
// 不然 "@1x7f3q" 会被当成一个谁都匹配不到的 eval id 前缀,报「no eval match」这种文不对题的
|
|
166
|
-
//
|
|
167
|
-
// 三个证据切面)——真正的 `--source`/`--execution`/`--diff` 统一 attempt 全景是后续阶段。
|
|
167
|
+
// 错误。
|
|
168
168
|
const locatorArg = patterns.find((p) => p.startsWith(ATTEMPT_LOCATOR_PREFIX));
|
|
169
169
|
if (locatorArg !== undefined) {
|
|
170
170
|
if (patterns.length !== 1) {
|
|
@@ -199,7 +199,35 @@ async function show(
|
|
|
199
199
|
io.out(blocks.join("\n\n") + "\n");
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
202
|
-
|
|
202
|
+
// 无证据 flag:选中当前 report definition 里唯一的 attempt-input page,注入这份 evidence,
|
|
203
|
+
// 走与其它 page 完全相同的 resolve → validate → render 管线(docs/feature/reports/show/attempt.md;
|
|
204
|
+
// docs/feature/reports/library/attempt-detail.md「在 show 与 view 怎样渲染」)。不带 --report
|
|
205
|
+
// 时装载内建 standard,其中就带这张 page;--report 指向的自定义报告没有声明 attempt-input page
|
|
206
|
+
// 时报完整用户反馈,不回退到内建详情(三条解决路径都在错误文案里给出)。
|
|
207
|
+
const report = await loadHostReport(cwd, flags.report);
|
|
208
|
+
const attemptPage = report.pages.find((p) => p.input === "attempt");
|
|
209
|
+
if (attemptPage === undefined) {
|
|
210
|
+
const sourceLabel = flags.report ?? "the built-in report";
|
|
211
|
+
throw new ShowError(
|
|
212
|
+
`error: ${sourceLabel} has no attempt-input page — "${locatorArg}" cannot be opened without one. ` +
|
|
213
|
+
`Add one: use \`extends: standard\` (inherits its attempt page), import { standardAttemptPage } from ` +
|
|
214
|
+
`"niceeval/report/built-in" and add it to your pages list, or declare your own \`input: "attempt"\` page.\n`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
const locale = detectLocale();
|
|
218
|
+
const selection = selectCurrentResults(results, {});
|
|
219
|
+
const meta = await buildHostReportMeta(report, selection);
|
|
220
|
+
const text = await renderHostPageText(
|
|
221
|
+
attemptPage,
|
|
222
|
+
{
|
|
223
|
+
scope: selection,
|
|
224
|
+
results,
|
|
225
|
+
report: meta,
|
|
226
|
+
page: { id: attemptPage.id, input: "attempt", locator: attempt.locator!, evidence: attemptEvidence },
|
|
227
|
+
},
|
|
228
|
+
{ width: io.width, locale },
|
|
229
|
+
);
|
|
230
|
+
io.out(text + "\n");
|
|
203
231
|
return;
|
|
204
232
|
}
|
|
205
233
|
|
|
@@ -322,16 +350,23 @@ async function show(
|
|
|
322
350
|
};
|
|
323
351
|
const sourceLabel = flags.report ?? "the built-in report";
|
|
324
352
|
|
|
325
|
-
// 初始页 = --page
|
|
326
|
-
//
|
|
327
|
-
// 「行为约束」「本地宿主只 resolve 被打开的页」)。
|
|
328
|
-
|
|
353
|
+
// 初始页 = --page 指定的页,缺省第一张可导航页(docs/feature/reports/show/reports.md
|
|
354
|
+
// Case 2);本地宿主只 resolve 被打开的这一页——其余页只留 id / title,不触发取数(见
|
|
355
|
+
// shell.md「行为约束」「本地宿主只 resolve 被打开的页」)。navigation:false 的页(参数化
|
|
356
|
+
// attempt 详情)不参与缺省选择,也不能被 --page 直接打开——没有 locator 不能拿 Scope 强行
|
|
357
|
+
// resolve(architecture.md「Attempt 详情是一张参数化 page」)。
|
|
358
|
+
let page = report.pages.find((p) => p.navigation !== false) ?? report.pages[0];
|
|
329
359
|
if (flags.page !== undefined) {
|
|
330
360
|
const hit = report.pages.find((p) => p.id === flags.page);
|
|
331
361
|
if (!hit) {
|
|
332
362
|
// 用法错误:列出可用页 id(docs/feature/reports/show/reports.md Case 1/2 的报错样例)。
|
|
333
363
|
throw new ShowError(
|
|
334
|
-
`error: page "${flags.page}" not found in ${sourceLabel}. Available pages: ${report.pages.map((p) => p.id).join(", ")}\n`,
|
|
364
|
+
`error: page "${flags.page}" not found in ${sourceLabel}. Available pages: ${report.pages.filter((p) => p.navigation !== false).map((p) => p.id).join(", ")}\n`,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
if (hit.input === "attempt") {
|
|
368
|
+
throw new ShowError(
|
|
369
|
+
`error: page "${hit.id}" in ${sourceLabel} is an attempt-input page and needs a locator — it cannot be opened with --page directly. Use niceeval show @<locator> instead.\n`,
|
|
335
370
|
);
|
|
336
371
|
}
|
|
337
372
|
page = hit;
|
|
@@ -339,10 +374,10 @@ async function show(
|
|
|
339
374
|
|
|
340
375
|
// attemptCommand 留给渲染管线的默认值:AttemptLocator 已经是可直接 `niceeval show @<locator>`
|
|
341
376
|
// 的真实 CLI 语法,不需要再反查 eval id 拼一条近似命令。
|
|
342
|
-
const meta =
|
|
377
|
+
const meta = await buildHostReportMeta(report, selection);
|
|
343
378
|
const text = await renderHostPageText(
|
|
344
379
|
page,
|
|
345
|
-
{ scope: selection, results, report: meta },
|
|
380
|
+
{ scope: selection, results, report: meta, page: { id: page.id, input: "scope" } },
|
|
346
381
|
{
|
|
347
382
|
width: io.width,
|
|
348
383
|
locale,
|
|
@@ -350,8 +385,9 @@ async function show(
|
|
|
350
385
|
},
|
|
351
386
|
);
|
|
352
387
|
|
|
353
|
-
// 页数大于一时尾部附「其余页」索引(
|
|
354
|
-
|
|
388
|
+
// 页数大于一时尾部附「其余页」索引(只列未渲染、且可导航的页,不倾倒内容);单页定义
|
|
389
|
+
// 没有这段;隐藏的 attempt page 不出现在「其余页」里。
|
|
390
|
+
const remaining = report.pages.filter((p) => p.id !== page.id && p.navigation !== false);
|
|
355
391
|
if (remaining.length === 0) {
|
|
356
392
|
io.out(text + "\n");
|
|
357
393
|
return;
|