niceeval 0.13.3-canary.37 → 0.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/bub.cjs +4 -4
- package/dist/agents/bub.cjs.map +1 -1
- package/dist/agents/bub.d.cts +2 -2
- package/dist/agents/bub.d.mts +2 -2
- package/dist/agents/bub.d.ts +2 -2
- package/dist/agents/codex-app-server.cjs +2 -3
- package/dist/agents/codex-app-server.cjs.map +1 -1
- package/dist/agents/codex.cjs +4 -4
- package/dist/agents/codex.cjs.map +1 -1
- package/dist/agents/codex.d.cts +3 -3
- package/dist/agents/codex.d.mts +3 -3
- package/dist/agents/codex.d.ts +3 -3
- package/dist/agents/sdk-streams.cjs +11 -4
- package/dist/agents/sdk-streams.cjs.map +1 -1
- package/dist/analysis/bindings.cjs +74 -19
- package/dist/analysis/bindings.cjs.map +1 -1
- package/dist/analysis/bindings.d.cts +534 -156
- package/dist/analysis/bindings.d.mts +534 -156
- package/dist/analysis/bindings.d.ts +534 -156
- package/dist/analysis/domain-view.cjs.map +1 -1
- package/dist/analysis/domain-view.d.cts +137 -8
- package/dist/analysis/domain-view.d.mts +137 -8
- package/dist/analysis/domain-view.d.ts +137 -8
- package/dist/analysis/index.cjs.map +1 -1
- package/dist/analysis/index.d.cts +1 -1
- package/dist/analysis/index.d.mts +1 -1
- package/dist/analysis/index.d.ts +1 -1
- package/dist/assertions/api.cjs.map +1 -1
- package/dist/assertions/api.d.cts +62 -0
- package/dist/assertions/api.d.mts +62 -0
- package/dist/assertions/api.d.ts +62 -0
- package/dist/assertions/judge.cjs +56 -5
- package/dist/assertions/judge.cjs.map +1 -1
- package/dist/assertions/match.cjs +66 -42
- package/dist/assertions/match.cjs.map +1 -1
- package/dist/assertions/match.d.cts +13 -0
- package/dist/assertions/match.d.mts +13 -0
- package/dist/assertions/match.d.ts +13 -0
- package/dist/assertions/record/attachment.cjs +104 -33
- package/dist/assertions/record/attachment.cjs.map +1 -1
- package/dist/assertions/record/attachment.d.cts +294 -57
- package/dist/assertions/record/attachment.d.mts +294 -57
- package/dist/assertions/record/attachment.d.ts +294 -57
- package/dist/assertions/record/codec.cjs +91 -17
- package/dist/assertions/record/codec.cjs.map +1 -1
- package/dist/assertions/record/codec.d.cts +280 -52
- package/dist/assertions/record/codec.d.mts +280 -52
- package/dist/assertions/record/codec.d.ts +280 -52
- package/dist/assertions/record/index.js +2 -0
- package/dist/assertions/record/model.cjs +16 -0
- package/dist/assertions/record/model.cjs.map +1 -1
- package/dist/assertions/record/model.d.cts +120 -13
- package/dist/assertions/record/model.d.mts +120 -13
- package/dist/assertions/record/model.d.ts +120 -13
- package/dist/assertions/record/model.js +2 -0
- package/dist/assertions/record/producer.cjs +70 -50
- package/dist/assertions/record/producer.cjs.map +1 -1
- package/dist/assertions/record/producer.d.cts +8 -7
- package/dist/assertions/record/producer.d.mts +8 -7
- package/dist/assertions/record/producer.d.ts +8 -7
- package/dist/assertions/runtime.cjs +49 -7
- package/dist/assertions/runtime.cjs.map +1 -1
- package/dist/cli/application.cjs +40 -0
- package/dist/cli/application.cjs.map +1 -0
- package/dist/cli/application.d.cts +129 -0
- package/dist/cli/application.d.mts +129 -0
- package/dist/cli/application.d.ts +129 -0
- package/dist/cli/application.js +24 -0
- package/dist/cli/application.js.map +1 -0
- package/dist/cli/bootstrap.cjs +10 -4
- package/dist/cli/bootstrap.cjs.map +1 -1
- package/dist/cli/node-application.cjs +123 -0
- package/dist/cli/node-application.cjs.map +1 -0
- package/dist/cli/node-application.d.cts +14 -0
- package/dist/cli/node-application.d.mts +14 -0
- package/dist/cli/node-application.d.ts +14 -0
- package/dist/cli/node-application.js +26 -0
- package/dist/cli/node-application.js.map +1 -0
- package/dist/cli/program.cjs +2807 -0
- package/dist/cli/program.cjs.map +1 -0
- package/dist/cli/program.d.cts +352 -0
- package/dist/cli/program.d.mts +352 -0
- package/dist/cli/program.d.ts +352 -0
- package/dist/cli/program.js +36 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/project-configuration.cjs +134 -0
- package/dist/cli/project-configuration.cjs.map +1 -0
- package/dist/cli/project-configuration.d.cts +64 -0
- package/dist/cli/project-configuration.d.mts +64 -0
- package/dist/cli/project-configuration.d.ts +64 -0
- package/dist/cli/project-configuration.js +22 -0
- package/dist/cli/project-configuration.js.map +1 -0
- package/dist/cli/record.cjs +20 -4
- package/dist/cli/record.cjs.map +1 -1
- package/dist/cli/record.d.cts +3 -3
- package/dist/cli/record.d.mts +3 -3
- package/dist/cli/record.d.ts +3 -3
- package/dist/cli.cjs +19 -3130
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +2 -148
- package/dist/cli.d.mts +2 -148
- package/dist/cli.d.ts +2 -148
- package/dist/cli.js +22 -30
- package/dist/context/assert-first.cjs +20 -15
- package/dist/context/assert-first.cjs.map +1 -1
- package/dist/eval/record/verdict.cjs +3 -2
- package/dist/eval/record/verdict.cjs.map +1 -1
- package/dist/experiment/host/index.cjs +1 -6
- package/dist/experiment/host/index.cjs.map +1 -1
- package/dist/experiment/host/index.d.cts +1 -0
- package/dist/experiment/host/index.d.mts +1 -0
- package/dist/experiment/host/index.d.ts +1 -0
- package/dist/load-config.cjs +13 -4
- package/dist/load-config.cjs.map +1 -1
- package/dist/load-config.d.cts +4 -3
- package/dist/load-config.d.mts +4 -3
- package/dist/load-config.d.ts +4 -3
- package/dist/load-config.js +4 -2
- package/dist/o11y/parsers/codex.cjs +29 -7
- package/dist/o11y/parsers/codex.cjs.map +1 -1
- package/dist/record/codec/core.d.cts +0 -2
- package/dist/record/codec/core.d.mts +0 -2
- package/dist/record/codec/core.d.ts +0 -2
- package/dist/record/codec/identifiers.cjs +2 -3
- package/dist/record/codec/identifiers.cjs.map +1 -1
- package/dist/record/codec/identifiers.d.cts +1 -2
- package/dist/record/codec/identifiers.d.mts +1 -2
- package/dist/record/codec/identifiers.d.ts +1 -2
- package/dist/record/codec/identifiers.js +10 -12
- package/dist/record/codec/index.js +42 -44
- package/dist/record/definition/attachment.cjs +1 -0
- package/dist/record/definition/attachment.cjs.map +1 -1
- package/dist/record/definition/attachment.d.cts +14 -0
- package/dist/record/definition/attachment.d.mts +14 -0
- package/dist/record/definition/attachment.d.ts +14 -0
- package/dist/record/family/assertions-v1.cjs +104 -0
- package/dist/record/family/assertions-v1.cjs.map +1 -0
- package/dist/record/family/assertions-v1.d.cts +2 -0
- package/dist/record/family/assertions-v1.d.mts +2 -0
- package/dist/record/family/assertions-v1.d.ts +2 -0
- package/dist/record/family/assertions-v1.js +6 -0
- package/dist/record/family/assertions-v1.js.map +1 -0
- package/dist/record/family/assertions.cjs +16 -5
- package/dist/record/family/assertions.cjs.map +1 -1
- package/dist/record/family/assertions.d.cts +510 -56
- package/dist/record/family/assertions.d.mts +510 -56
- package/dist/record/family/assertions.d.ts +510 -56
- package/dist/record/family/assertions.js +14 -10
- package/dist/record/family/catalog.cjs +17 -1
- package/dist/record/family/catalog.cjs.map +1 -1
- package/dist/record/family/catalog.d.cts +1292 -104
- package/dist/record/family/catalog.d.mts +1292 -104
- package/dist/record/family/catalog.d.ts +1292 -104
- package/dist/record/family/catalog.js +22 -20
- package/dist/record/family/index.js +144 -138
- package/dist/record/family/observability-v1.cjs +5 -0
- package/dist/record/family/observability-v1.cjs.map +1 -1
- package/dist/record/family/observability.cjs +1 -1
- package/dist/record/family/observability.cjs.map +1 -1
- package/dist/record/host/runtime.cjs +323 -173
- package/dist/record/host/runtime.cjs.map +1 -1
- package/dist/record/host/types.cjs.map +1 -1
- package/dist/record/host/types.d.cts +9 -7
- package/dist/record/host/types.d.mts +9 -7
- package/dist/record/host/types.d.ts +9 -7
- package/dist/record/model/core.cjs.map +1 -1
- package/dist/record/model/core.d.cts +1 -2
- package/dist/record/model/core.d.mts +1 -2
- package/dist/record/model/core.d.ts +1 -2
- package/dist/record/model/definition.cjs +1 -2
- package/dist/record/model/definition.cjs.map +1 -1
- package/dist/record/model/definition.d.cts +1 -7
- package/dist/record/model/definition.d.mts +1 -7
- package/dist/record/model/definition.d.ts +1 -7
- package/dist/record/model/identifiers.cjs +2 -3
- package/dist/record/model/identifiers.cjs.map +1 -1
- package/dist/record/model/identifiers.d.cts +1 -3
- package/dist/record/model/identifiers.d.mts +1 -3
- package/dist/record/model/identifiers.d.ts +1 -3
- package/dist/record/model/identifiers.js +36 -38
- package/dist/record/model/index.js +60 -62
- package/dist/record/platform/node.cjs +17 -7
- package/dist/record/platform/node.cjs.map +1 -1
- package/dist/record/platform/services.cjs.map +1 -1
- package/dist/record/platform/services.d.cts +8 -3
- package/dist/record/platform/services.d.mts +8 -3
- package/dist/record/platform/services.d.ts +8 -3
- package/dist/record/reader/format.cjs +16 -65
- package/dist/record/reader/format.cjs.map +1 -1
- package/dist/record/reader/format.d.cts +5 -9
- package/dist/record/reader/format.d.mts +5 -9
- package/dist/record/reader/format.d.ts +5 -9
- package/dist/record/reader/index.js +10 -8
- package/dist/record/reader/runtime.cjs +63 -32
- package/dist/record/reader/runtime.cjs.map +1 -1
- package/dist/record/reader/runtime.d.cts +40 -4
- package/dist/record/reader/runtime.d.mts +40 -4
- package/dist/record/reader/runtime.d.ts +40 -4
- package/dist/record/reader/runtime.js +6 -4
- package/dist/report/assets/enhance.js +5 -5
- package/dist/report/assets/styles.css +186 -24
- package/dist/report/built-in/result-components.cjs +8 -5
- package/dist/report/built-in/result-components.cjs.map +1 -1
- package/dist/report/built-in/standard.cjs +3 -0
- package/dist/report/built-in/standard.cjs.map +1 -1
- package/dist/report/built-in/standard.d.cts +2 -0
- package/dist/report/built-in/standard.d.mts +2 -0
- package/dist/report/built-in/standard.d.ts +2 -0
- package/dist/report/client-dist/app.js +53 -0
- package/dist/report/components/attempt-detail/compute.cjs +106 -231
- package/dist/report/components/attempt-detail/compute.cjs.map +1 -1
- package/dist/report/components/attempt-detail/compute.d.cts +9 -43
- package/dist/report/components/attempt-detail/compute.d.mts +9 -43
- package/dist/report/components/attempt-detail/compute.d.ts +9 -43
- package/dist/report/components/attempt-detail/compute.js +2 -4
- package/dist/report/components/attempt-detail/content.cjs +3 -4
- package/dist/report/components/attempt-detail/content.cjs.map +1 -1
- package/dist/report/components/attempt-detail/validate.cjs +44 -2
- package/dist/report/components/attempt-detail/validate.cjs.map +1 -1
- package/dist/report/components/entity-lists/compute.cjs +9 -15
- package/dist/report/components/entity-lists/compute.cjs.map +1 -1
- package/dist/report/components/entity-lists/content.cjs +53 -40
- package/dist/report/components/entity-lists/content.cjs.map +1 -1
- package/dist/report/components/entity-lists/index.cjs +1 -3
- package/dist/report/components/entity-lists/index.cjs.map +1 -1
- package/dist/report/components/experiment-detail/compute.cjs +4 -6
- package/dist/report/components/experiment-detail/compute.cjs.map +1 -1
- package/dist/report/definition/cell.cjs +14 -7
- package/dist/report/definition/cell.cjs.map +1 -1
- package/dist/report/definition/cell.d.cts +4 -0
- package/dist/report/definition/cell.d.mts +4 -0
- package/dist/report/definition/cell.d.ts +4 -0
- package/dist/report/definition/primitives/assertion-evidence.cjs +96 -0
- package/dist/report/definition/primitives/assertion-evidence.cjs.map +1 -0
- package/dist/report/definition/primitives/assertion-evidence.d.cts +11 -0
- package/dist/report/definition/primitives/assertion-evidence.d.mts +11 -0
- package/dist/report/definition/primitives/assertion-evidence.d.ts +11 -0
- package/dist/report/definition/primitives/assertion-evidence.js +6 -0
- package/dist/report/definition/primitives/assertion-evidence.js.map +1 -0
- package/dist/report/definition/primitives.cjs +14 -1
- package/dist/report/definition/primitives.cjs.map +1 -1
- package/dist/report/definition/report.cjs +16 -8
- package/dist/report/definition/report.cjs.map +1 -1
- package/dist/report/definition/report.d.cts +6 -0
- package/dist/report/definition/report.d.mts +6 -0
- package/dist/report/definition/report.d.ts +6 -0
- package/dist/report/definition/table-text.cjs +12 -3
- package/dist/report/definition/table-text.cjs.map +1 -1
- package/dist/report/definition/table-text.d.cts +6 -1
- package/dist/report/definition/table-text.d.mts +6 -1
- package/dist/report/definition/table-text.d.ts +6 -1
- package/dist/report/execution/model.cjs +6 -14
- package/dist/report/execution/model.cjs.map +1 -1
- package/dist/report/execution/model.d.cts +5 -10
- package/dist/report/execution/model.d.mts +5 -10
- package/dist/report/execution/model.d.ts +5 -10
- package/dist/report/execution/model.js +6 -6
- package/dist/report/execution/paths.cjs +0 -11
- package/dist/report/execution/paths.cjs.map +1 -1
- package/dist/report/execution/paths.d.cts +0 -1
- package/dist/report/execution/paths.d.mts +0 -1
- package/dist/report/execution/paths.d.ts +0 -1
- package/dist/report/execution/paths.js +6 -8
- package/dist/report/host/execute.cjs +13 -22
- package/dist/report/host/execute.cjs.map +1 -1
- package/dist/report/host/execute.d.cts +1 -4
- package/dist/report/host/execute.d.mts +1 -4
- package/dist/report/host/execute.d.ts +1 -4
- package/dist/report/host/from-record.cjs +3 -0
- package/dist/report/host/from-record.cjs.map +1 -1
- package/dist/report/host/from-record.d.cts +4 -1
- package/dist/report/host/from-record.d.mts +4 -1
- package/dist/report/host/from-record.d.ts +4 -1
- package/dist/report/host/site-assets.cjs +1 -2
- package/dist/report/host/site-assets.cjs.map +1 -1
- package/dist/report/host/site-assets.d.cts +0 -1
- package/dist/report/host/site-assets.d.mts +0 -1
- package/dist/report/host/site-assets.d.ts +0 -1
- package/dist/report/host/site-assets.js +2 -4
- package/dist/report/host/static.cjs +71 -346
- package/dist/report/host/static.cjs.map +1 -1
- package/dist/report/host/static.d.cts +1 -3
- package/dist/report/host/static.d.mts +1 -3
- package/dist/report/host/static.d.ts +1 -3
- package/dist/report/host/static.js +2 -2
- package/dist/report/host/view-session.cjs.map +1 -1
- package/dist/report/host/view-session.d.cts +1 -1
- package/dist/report/host/view-session.d.mts +1 -1
- package/dist/report/host/view-session.d.ts +1 -1
- package/dist/report/model/locale.cjs +1 -1
- package/dist/report/model/locale.cjs.map +1 -1
- package/dist/report/model/locale.d.cts +1 -1
- package/dist/report/model/locale.d.mts +1 -1
- package/dist/report/model/locale.d.ts +1 -1
- package/dist/report/model/pricing.cjs +2 -2
- package/dist/report/model/pricing.cjs.map +1 -1
- package/dist/report/react/enhance.js +5 -5
- package/dist/report/react/styles.css +186 -24
- package/dist/runner/adoption.cjs +4 -7
- package/dist/runner/adoption.cjs.map +1 -1
- package/dist/runner/feedback/failure.cjs +77 -2
- package/dist/runner/feedback/failure.cjs.map +1 -1
- package/dist/runner/feedback/failure.d.cts +2 -1
- package/dist/runner/feedback/failure.d.mts +2 -1
- package/dist/runner/feedback/failure.d.ts +2 -1
- package/dist/runner/project-current.cjs +2 -13
- package/dist/runner/project-current.cjs.map +1 -1
- package/dist/runner/project-current.d.cts +4 -2
- package/dist/runner/project-current.d.mts +4 -2
- package/dist/runner/project-current.d.ts +4 -2
- package/dist/runner/reporters/braintrust.cjs +7 -7
- package/dist/runner/reporters/braintrust.cjs.map +1 -1
- package/dist/runner/reuse-readback.cjs +3 -4
- package/dist/runner/reuse-readback.cjs.map +1 -1
- package/dist/runner/run.cjs +5 -2
- package/dist/runner/run.cjs.map +1 -1
- package/dist/view/server.cjs +2 -37
- package/dist/view/server.cjs.map +1 -1
- package/dist/view/server.d.cts +0 -3
- package/dist/view/server.d.mts +0 -3
- package/dist/view/server.d.ts +0 -3
- package/docs-site/zh/reference/builtin-agents.mdx +7 -7
- package/docs-site/zh/reference/official-adapters.mdx +4 -4
- package/docs-site/zh/reference/report-components.mdx +2 -2
- package/docs-site/zh/tutorials/configuration.mdx +2 -2
- package/docs-site/zh/tutorials/deploy-report-site.mdx +24 -2
- package/docs-site/zh/tutorials/publish-report.mdx +4 -4
- package/docs-site/zh/tutorials/sandbox-agent.mdx +5 -5
- package/docs-site/zh/tutorials/theming.mdx +2 -2
- package/package.json +4 -6
- package/dist/record/migration/index.cjs +0 -5
- package/dist/record/migration/index.cjs.map +0 -1
- package/dist/record/migration/index.d.cts +0 -11
- package/dist/record/migration/index.d.mts +0 -11
- package/dist/record/migration/index.d.ts +0 -11
- package/dist/record/migration/index.js +0 -6
- package/dist/record/migration/index.js.map +0 -1
- package/dist/report/host/site-runtime.cjs +0 -92
- package/dist/report/host/site-runtime.cjs.map +0 -1
- package/dist/report/host/site-runtime.d.cts +0 -9
- package/dist/report/host/site-runtime.d.mts +0 -9
- package/dist/report/host/site-runtime.d.ts +0 -9
- package/dist/report/host/site-runtime.js +0 -10
- package/dist/report/host/site-runtime.js.map +0 -1
- package/dist/view/client-dist/app.css +0 -2
- package/dist/view/client-dist/app.js +0 -49
- package/dist/view/data.cjs +0 -3
- package/dist/view/data.cjs.map +0 -1
- package/dist/view/data.d.cts +0 -9
- package/dist/view/data.d.mts +0 -9
- package/dist/view/data.d.ts +0 -9
- package/dist/view/data.js +0 -4
- package/dist/view/data.js.map +0 -1
- package/dist/view/index.cjs +0 -24
- package/dist/view/index.cjs.map +0 -1
- package/dist/view/index.d.cts +0 -9
- package/dist/view/index.d.mts +0 -9
- package/dist/view/index.d.ts +0 -9
- package/dist/view/index.js +0 -28
- package/dist/view/index.js.map +0 -1
- package/dist/view/report-view-cache.cjs +0 -200
- package/dist/view/report-view-cache.cjs.map +0 -1
- package/dist/view/report-view-cache.d.cts +0 -67
- package/dist/view/report-view-cache.d.mts +0 -67
- package/dist/view/report-view-cache.d.ts +0 -67
- package/dist/view/report-view-cache.js +0 -8
- package/dist/view/report-view-cache.js.map +0 -1
- package/dist/view/shared/types.cjs +0 -3
- package/dist/view/shared/types.cjs.map +0 -1
- package/dist/view/shared/types.d.cts +0 -51
- package/dist/view/shared/types.d.mts +0 -51
- package/dist/view/shared/types.d.ts +0 -51
- package/dist/view/shared/types.js +0 -4
- package/dist/view/shared/types.js.map +0 -1
- package/dist/view/site.cjs +0 -32
- package/dist/view/site.cjs.map +0 -1
- package/dist/view/site.d.cts +0 -24
- package/dist/view/site.d.mts +0 -24
- package/dist/view/site.d.ts +0 -24
- package/dist/view/site.js +0 -8
- package/dist/view/site.js.map +0 -1
- package/dist/view/styles.css +0 -170
- package/dist/view/template.html +0 -17
package/dist/view/server.cjs
CHANGED
|
@@ -237,9 +237,6 @@ function serveRequest(session, request, advertisedAuthorities) {
|
|
|
237
237
|
}));
|
|
238
238
|
}
|
|
239
239
|
const resolved = siteFileForPath(url.pathname, state.current.site);
|
|
240
|
-
if (resolved.state === "redirect") {
|
|
241
|
-
return effect_1.Effect.sync(() => redirect(request.response, resolved.location, headers));
|
|
242
|
-
}
|
|
243
240
|
if (resolved.state === "missing") {
|
|
244
241
|
return effect_1.Effect.sync(() => sendText(request.response, 404, url.pathname.startsWith("/downloads/") ? "download not found" : "page not found", headers));
|
|
245
242
|
}
|
|
@@ -517,42 +514,16 @@ function siteFileForPath(pathname, site) {
|
|
|
517
514
|
return Object.freeze({ state: "missing" });
|
|
518
515
|
}
|
|
519
516
|
const requested = pathname.slice(1);
|
|
517
|
+
// The SPA shell is the revision's sole root document. All business
|
|
518
|
+
// navigation belongs to its hash router, not to host-side path probing.
|
|
520
519
|
const exact = requested === "" ? "index.html" : requested;
|
|
521
520
|
const revision = (0, model_ts_1.closedSiteRevisionData)(site);
|
|
522
521
|
const files = revision.files;
|
|
523
|
-
if (requested === "" && revision.defaultRoute !== undefined && revision.defaultRoute !== "/") {
|
|
524
|
-
const entryFile = staticPageFileForRoute(revision.defaultRoute);
|
|
525
|
-
if (files.some((file) => file.path === entryFile)) {
|
|
526
|
-
return Object.freeze({ state: "redirect", location: revision.defaultRoute });
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
522
|
const direct = files.find((file) => file.path === exact);
|
|
530
523
|
if (direct !== undefined)
|
|
531
524
|
return Object.freeze({ state: "file", file: direct });
|
|
532
|
-
// A report may deliberately declare its first Page at /overview (or another
|
|
533
|
-
// route), so its immutable closure has no root index.html. The advertised
|
|
534
|
-
// root must still land on that revision's canonical entry route rather than
|
|
535
|
-
// becoming a host-generated 404 or re-entering Report execution.
|
|
536
|
-
if (requested === "" && revision.defaultRoute !== undefined) {
|
|
537
|
-
const entryFile = staticPageFileForRoute(revision.defaultRoute);
|
|
538
|
-
if (files.some((file) => file.path === entryFile)) {
|
|
539
|
-
return Object.freeze({ state: "redirect", location: revision.defaultRoute });
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
// Keep direct Page URLs convenient without manufacturing a different body.
|
|
543
|
-
// The redirect selects the exact generated index.html path from this same map.
|
|
544
|
-
const indexPath = requested.endsWith("/")
|
|
545
|
-
? `${requested}index.html`
|
|
546
|
-
: `${requested}/index.html`;
|
|
547
|
-
const page = files.find((file) => file.path === indexPath);
|
|
548
|
-
if (page !== undefined) {
|
|
549
|
-
return Object.freeze({ state: "redirect", location: `/${indexPath}` });
|
|
550
|
-
}
|
|
551
525
|
return Object.freeze({ state: "missing" });
|
|
552
526
|
}
|
|
553
|
-
function staticPageFileForRoute(route) {
|
|
554
|
-
return route === "/" ? "index.html" : `${route.slice(1)}/index.html`;
|
|
555
|
-
}
|
|
556
527
|
function requestUrl(request) {
|
|
557
528
|
try {
|
|
558
529
|
return new URL(request.url ?? "/", "http://127.0.0.1");
|
|
@@ -584,12 +555,6 @@ function send(response, status, body, contentType, headers) {
|
|
|
584
555
|
response.writeHead(status, { "content-type": contentType, ...headers });
|
|
585
556
|
response.end(body);
|
|
586
557
|
}
|
|
587
|
-
function redirect(response, location, headers) {
|
|
588
|
-
if (response.destroyed)
|
|
589
|
-
return;
|
|
590
|
-
response.writeHead(308, { location, ...headers });
|
|
591
|
-
response.end();
|
|
592
|
-
}
|
|
593
558
|
const SAFE_MEDIA_TYPE = /^[A-Za-z0-9!#$%&'*+.^_`|~-]+\/[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;
|
|
594
559
|
function siteContentType(mediaType) {
|
|
595
560
|
const base = mediaType.split(";", 1)[0]?.trim() ?? "";
|
package/dist/view/server.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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","sourcesContent":["// The Node view host owns transport and watch lifetime only. Its caller has\n// already closed Record -> Sample -> Report into a fixed execution rebuild;\n// this module never reopens Record facts.\nimport { readdirSync, statSync, watch, type FSWatcher } from \"node:fs\";\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { Socket } from \"node:net\";\nimport { networkInterfaces } from \"node:os\";\nimport { basename, dirname, resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport type * as Scope from \"effect/Scope\";\nimport { closedSiteRevisionData, type ClosedSiteFile, type ClosedSiteRevision, } from \"../report/execution/model.ts\";\nimport { openReportViewSession, type OpenReportViewSessionInput, type ReportViewOpenError, type ReportViewSessionClosed, type ReportViewSession, } from \"../report/host/view-session.ts\";\nimport type { ViewScanOptions } from \"./data.ts\";\nexport interface NodeViewServerError {\n readonly code: \"report-view-server-failed\";\n readonly operation: \"open\" | \"listen\" | \"watch\";\n readonly reason: string;\n}\nexport interface ViewOptions<Requirements = never> {\n readonly input?: string;\n readonly out?: string;\n readonly port?: number;\n /** Defaults to loopback. An explicit address opts into that network exposure. */\n readonly host?: string;\n /** Retained for the CLI-shaped facade; it is never interpreted as Record data. */\n readonly scan?: ViewScanOptions;\n /**\n * Bootstrap watch inputs when the session/request has none yet. After each\n * successful rebuild the session revision owns the next-round watch set.\n */\n readonly watchInputs?: readonly string[];\n readonly onRebuild?: (completedAt: Date) => void;\n /** An already-open scoped session owned by the caller. */\n readonly session?: ReportViewSession<Requirements>;\n /** Or let this scope open a session from a caller-supplied current rebuild. */\n readonly request?: OpenReportViewSessionInput<Requirements>;\n}\n/** The native Effect-facing server handle. Its resources are also Scope-owned. */\nexport interface ReportViewServer {\n readonly url: string;\n readonly urls: readonly string[];\n readonly close: Effect.Effect<void>;\n}\nexport type RebuildReason = \"records\" | \"modules\";\ninterface InboxClosed {\n readonly code: \"report-view-inbox-closed\";\n}\nconst inboxClosed: InboxClosed = Object.freeze({ code: \"report-view-inbox-closed\" });\ninterface HttpRequest {\n readonly request: IncomingMessage;\n readonly response: ServerResponse;\n}\nconst HTTP_REQUEST_QUEUE_MAX = 128;\n/**\n * A small callback-to-Effect bridge. Node callbacks only enqueue a value; the\n * long-lived scoped Effect performs every session operation, so callbacks do\n * not create private runtimes or invoke `runPromise`/`runSync`.\n */\nclass Inbox<Value> {\n private readonly values: Value[] = [];\n private resume: ((effect: Effect.Effect<Value, InboxClosed>) => void) | undefined;\n private closed = false;\n constructor(private readonly capacity: number) { }\n take(): Effect.Effect<Value, InboxClosed> {\n return Effect.async((resume) => {\n if (this.values.length > 0) {\n resume(Effect.succeed(this.values.shift()!));\n return Effect.void;\n }\n if (this.closed) {\n resume(Effect.fail(inboxClosed));\n return Effect.void;\n }\n this.resume = resume;\n return Effect.sync(() => {\n if (this.resume === resume)\n this.resume = undefined;\n });\n });\n }\n offer(value: Value): boolean {\n if (this.closed)\n return false;\n const resume = this.resume;\n if (resume === undefined) {\n if (this.values.length >= this.capacity)\n return false;\n this.values.push(value);\n return true;\n }\n this.resume = undefined;\n resume(Effect.succeed(value));\n return true;\n }\n close(): void {\n if (this.closed)\n return;\n this.closed = true;\n const resume = this.resume;\n this.resume = undefined;\n resume?.(Effect.fail(inboxClosed));\n }\n}\n/** Coalesces a burst of filesystem events into sequential refresh requests. */\nclass RefreshInbox {\n private pending = false;\n private resume: ((effect: Effect.Effect<void, InboxClosed>) => void) | undefined;\n private closed = false;\n take(): Effect.Effect<void, InboxClosed> {\n return Effect.async((resume) => {\n if (this.pending) {\n this.pending = false;\n resume(Effect.void);\n return Effect.void;\n }\n if (this.closed) {\n resume(Effect.fail(inboxClosed));\n return Effect.void;\n }\n this.resume = resume;\n return Effect.sync(() => {\n if (this.resume === resume)\n this.resume = undefined;\n });\n });\n }\n request(): void {\n if (this.closed)\n return;\n const resume = this.resume;\n if (resume === undefined) {\n this.pending = true;\n return;\n }\n this.resume = undefined;\n resume(Effect.void);\n }\n close(): void {\n if (this.closed)\n return;\n this.closed = true;\n const resume = this.resume;\n this.resume = undefined;\n resume?.(Effect.fail(inboxClosed));\n }\n}\ninterface ServerResources {\n readonly server: Server;\n readonly sockets: Set<Socket>;\n readonly requests: Inbox<HttpRequest>;\n readonly refreshes: RefreshInbox;\n closed: boolean;\n}\ninterface WatchResources {\n /** The one currently published watcher closure. */\n current: WatchSet;\n /** Stable refresh request callback for the current server lifetime. */\n onChange: () => void;\n closed: boolean;\n}\n/**\n * A complete watcher closure. A candidate stays `opening` until every watch\n * for its current directory tree has opened. Callbacks test both this state\n * and the owning resource's current reference, so an old or failed candidate\n * cannot enqueue a late rebuild.\n */\ninterface WatchSet {\n readonly inputs: readonly string[];\n readonly watchers: Map<string, FSWatcher>;\n state: \"opening\" | \"active\" | \"closed\";\n}\n/**\n * Opens a real HTTP server, defaulting to loopback. A watcher event only requests\n * `session.refresh`; the session serializes rebuild and close, preserves the\n * last good immutable execution and recoverable watch set, and publishes a new\n * revision only on success. The Node server then atomically replaces its\n * fs.watch resources from that revision's watchInputs.\n */\nexport function openViewServer<Requirements>(options: ViewOptions<Requirements> = {}): Effect.Effect<ReportViewServer, NodeViewServerError | ReportViewOpenError, Scope.Scope | Requirements> {\n return Effect.gen(function* () {\n const serverScope = yield* Effect.scope;\n if (options.session !== undefined && options.request !== undefined) {\n return yield* Effect.fail(serverError(\"open\", \"provide either session or request, not both\"));\n }\n const host = (options.host ?? \"127.0.0.1\").trim();\n if (host.length === 0) {\n return yield* Effect.fail(serverError(\"open\", \"view host must not be empty\"));\n }\n if (host.includes(\"%\")) {\n return yield* Effect.fail(serverError(\"open\", \"scoped IPv6 view hosts are not supported\"));\n }\n const port = options.port ?? 0;\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n return yield* Effect.fail(serverError(\"open\", `view port must be an integer from 0 through 65535, got ${port}`));\n }\n const session = options.session ?? (options.request === undefined\n ? yield* Effect.fail(serverError(\"open\", \"view needs a scoped ReportViewSession or current rebuild request\"))\n : yield* openReportViewSession({\n ...options.request,\n // Bootstrap the opening revision when the request omitted a watch set.\n watchInputs: options.request.watchInputs ?? optionWatchInputs(options),\n }));\n const opening = yield* session.snapshot.pipe(Effect.mapError(() => serverError(\"open\", \"report view session closed before watchers opened\")));\n const initialWatchInputs = opening.current.watchInputs.length > 0\n ? opening.current.watchInputs\n : optionWatchInputs(options);\n const resources = yield* Effect.acquireRelease(Effect.sync(() => makeResources()), (value) => closeResources(value));\n const address = yield* listen(resources.server, host, port);\n const urls = viewUrls(host, address.port);\n const advertisedAuthorities = Object.freeze(new Set(urls.map((url) => new URL(url).host)));\n const watches = yield* Effect.acquireRelease(openWatchers(initialWatchInputs, () => resources.refreshes.request()), (value) => closeWatchers(value));\n yield* Effect.forkScoped(Effect.forever(Effect.flatMap(resources.requests.take(), (request) => serveRequest(session, request, advertisedAuthorities))).pipe(Effect.catchAll(() => Effect.void)));\n yield* Effect.forkScoped(Effect.forever(Effect.flatMap(resources.refreshes.take(), () => registerRefreshIntent(session, watches, options.onRebuild, serverScope))).pipe(Effect.catchAll(() => Effect.void)));\n const close = Effect.zipRight(closeWatchers(watches), closeResources(resources));\n return Object.freeze({ url: urls[0]!, urls, close });\n });\n}\nfunction makeResources(): ServerResources {\n const requests = new Inbox<HttpRequest>(HTTP_REQUEST_QUEUE_MAX);\n const refreshes = new RefreshInbox();\n const sockets = new Set<Socket>();\n const server = createServer((request, response) => {\n if (!requests.offer(Object.freeze({ request, response }))) {\n sendText(response, 503, \"report view is busy; retry shortly\");\n }\n });\n server.on(\"connection\", (socket) => {\n sockets.add(socket);\n socket.once(\"close\", () => sockets.delete(socket));\n });\n return { server, sockets, requests, refreshes, closed: false };\n}\nfunction listen(server: Server, host: string, port: number): Effect.Effect<{\n readonly host: string;\n readonly port: number;\n}, NodeViewServerError> {\n return Effect.async((resume) => {\n const cleanup = (): void => {\n server.off(\"error\", onError);\n server.off(\"listening\", onListening);\n };\n const onError = (error: Error): void => {\n cleanup();\n resume(Effect.fail(serverError(\"listen\", error.message)));\n };\n const onListening = (): void => {\n cleanup();\n const address = server.address();\n if (address === null || typeof address === \"string\") {\n resume(Effect.fail(serverError(\"listen\", \"server did not expose a TCP address\")));\n return;\n }\n resume(Effect.succeed(Object.freeze({ host: address.address, port: address.port })));\n };\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n try {\n server.listen({ host, port });\n }\n catch (error) {\n onError(asError(error));\n }\n return Effect.sync(() => cleanup());\n });\n}\nfunction serveRequest<Requirements>(session: ReportViewSession<Requirements>, request: HttpRequest, advertisedAuthorities: ReadonlySet<string>): Effect.Effect<void> {\n const authority = requestAuthority(request.request.headers.host);\n if (authority === undefined || !advertisedAuthorities.has(authority)) {\n return Effect.sync(() => sendText(request.response, 421, \"view host is not advertised\"));\n }\n if (request.request.method !== \"GET\" && request.request.method !== \"HEAD\") {\n return Effect.sync(() => sendText(request.response, 405, \"method not allowed\", { allow: \"GET, HEAD\" }));\n }\n const url = requestUrl(request.request);\n if (url === undefined) {\n return Effect.sync(() => sendText(request.response, 400, \"bad request\"));\n }\n if (url.pathname === \"/healthz\") {\n return Effect.sync(() => sendText(request.response, 200, \"ok\"));\n }\n return session.snapshot.pipe(Effect.flatMap((state) => {\n const headers = Object.freeze({\n \"cache-control\": \"no-store\",\n \"x-niceeval-report-revision\": String(state.current.revision),\n \"x-niceeval-report-content-hash\": closedSiteRevisionData(state.current.site).identity.contentHash,\n ...(state.lastProblem === undefined ? {} : { \"x-niceeval-last-rebuild-problem\": \"1\" }),\n });\n // Optional host transport probe. It contains no Report body and does\n // not belong to the content-addressed file mapping. The HTML response\n // below establishes its own served revision through an HttpOnly cookie;\n // after publication this endpoint can report that the browser document\n // is stale without putting revision information into its body bytes.\n if (url.pathname === \"/_niceeval/refresh\") {\n const servedIdentity = reportRevisionCookieValue(request.request.headers.cookie);\n return Effect.sync(() => send(request.response, 204, new Uint8Array(), \"text/plain; charset=utf-8\", {\n ...headers,\n \"x-niceeval-view-stale\": servedIdentity === undefined || servedIdentity === closedSiteRevisionData(state.current.site).identity.contentHash\n ? \"0\"\n : \"1\",\n }));\n }\n const resolved = siteFileForPath(url.pathname, state.current.site);\n if (resolved.state === \"redirect\") {\n return Effect.sync(() => redirect(request.response, resolved.location, headers));\n }\n if (resolved.state === \"missing\") {\n return Effect.sync(() => sendText(request.response, 404, url.pathname.startsWith(\"/downloads/\") ? \"download not found\" : \"page not found\", headers));\n }\n return Effect.sync(() => send(request.response, 200, resolved.file.bytes, siteContentType(resolved.file.mediaType), resolved.file.path.startsWith(\"downloads/\")\n ? { ...headers, \"content-disposition\": \"attachment\", \"x-content-type-options\": \"nosniff\" }\n : resolved.file.mediaType.startsWith(\"text/html;\")\n ? { ...headers, \"set-cookie\": reportRevisionCookie(closedSiteRevisionData(state.current.site).identity.contentHash) }\n : headers));\n }), Effect.catchAll(() => Effect.sync(() => sendText(request.response, 503, \"report view session is closed\"))));\n}\n/**\n * Register immediately, then subscribe in a scoped waiter. The refresh inbox\n * can therefore accept a newer intent while this candidate still performs\n * author work; only a published outcome mutates watcher ownership or emits a\n * browser-facing rebuild notification.\n */\nfunction registerRefreshIntent<Requirements>(session: ReportViewSession<Requirements>, watches: WatchResources, onRebuild: ViewOptions[\"onRebuild\"], serverScope: Scope.Scope): Effect.Effect<void, ReportViewSessionClosed, Requirements> {\n return Effect.gen(function* () {\n const intent = yield* session.refresh;\n yield* Effect.forkIn(intent.outcome.pipe(Effect.flatMap((outcome) => outcome.state !== \"published\"\n ? Effect.void\n : Effect.gen(function* () {\n // One published revision owns its corresponding successful watch set.\n yield* Effect.sync(() => replaceWatchInputs(watches, outcome.revision.watchInputs));\n if (onRebuild !== undefined) {\n yield* Effect.try({\n try: () => onRebuild(new Date()),\n catch: () => undefined,\n }).pipe(Effect.ignore);\n }\n }))), serverScope);\n });\n}\nfunction optionWatchInputs<Requirements>(options: ViewOptions<Requirements>): readonly string[] {\n const values = options.watchInputs ?? [];\n return Object.freeze([...new Set(values.map((value) => resolve(value)))]);\n}\nfunction openWatchers(inputs: readonly string[], onChange: () => void): Effect.Effect<WatchResources, NodeViewServerError> {\n return Effect.try({\n try: () => {\n const resources: WatchResources = {\n current: closedWatchSet(),\n onChange,\n closed: false,\n };\n try {\n const opening = openWatchSet(resources, inputs);\n publishWatchSet(resources, opening);\n return resources;\n }\n catch (error) {\n closeWatchSet(resources.current);\n throw error;\n }\n },\n catch: (error): NodeViewServerError => serverError(\"watch\", asError(error).message),\n });\n}\n/**\n * Atomically swaps the next-round watch set after a successful revision. Failure\n * paths never call this, so last-good entry edges remain recoverable.\n */\nfunction replaceWatchInputs(resources: WatchResources, inputs: readonly string[]): void {\n if (resources.closed)\n return;\n try {\n const opening = openWatchSet(resources, inputs);\n if (resources.closed) {\n closeWatchSet(opening);\n return;\n }\n // No Effect boundary or callback can interleave this publication: the\n // replacement is entirely synchronous after the candidate validated.\n publishWatchSet(resources, opening);\n }\n catch {\n // A transient directory race must not discard the previous recoverable\n // closure. The next filesystem hint retries full reconciliation.\n }\n}\nfunction closedWatchSet(): WatchSet {\n return {\n inputs: Object.freeze([]),\n watchers: new Map(),\n state: \"closed\",\n };\n}\n/**\n * Opens a whole candidate closure without touching the published set. This is\n * also the full reconciliation path for directory-tree changes: fs.watch is a\n * hint, so every event rescans all inputs before requesting a rebuild.\n */\nfunction openWatchSet(resources: WatchResources, inputs: readonly string[]): WatchSet {\n const watchSet: WatchSet = {\n inputs: normalizeWatchInputs(inputs),\n watchers: new Map(),\n state: \"opening\",\n };\n try {\n synchronizeWatchSet(resources, watchSet);\n return watchSet;\n }\n catch (error) {\n closeWatchSet(watchSet);\n throw error;\n }\n}\n/** Watch the Record root and its current Run directories without a polling loop. */\nfunction synchronizeWatchSet(resources: WatchResources, watchSet: WatchSet): void {\n for (const input of watchSet.inputs) {\n let inputIsDirectory: boolean;\n try {\n inputIsDirectory = statSync(input).isDirectory();\n }\n catch (error) {\n if (!isMissingPath(error))\n throw error;\n // A missing config / module / Record root remains observable through its\n // parent directory. It can appear later without restarting the host.\n watchNamedInput(resources, watchSet, dirname(input), basename(input));\n continue;\n }\n if (inputIsDirectory) {\n watchDirectoryTree(resources, watchSet, input, 0);\n }\n else {\n watchNamedInput(resources, watchSet, dirname(input), basename(input));\n }\n }\n}\nfunction normalizeWatchInputs(inputs: readonly string[]): readonly string[] {\n return Object.freeze([...new Set(inputs.map((input) => resolve(input)))].sort());\n}\nconst WATCH_DIRECTORY_DEPTH_MAX = 4;\nfunction watchDirectoryTree(resources: WatchResources, watchSet: WatchSet, directory: string, depth: number): void {\n try {\n watchDirectory(resources, watchSet, directory);\n }\n catch (error) {\n if (!isMissingPath(error))\n throw error;\n watchNamedInput(resources, watchSet, dirname(directory), basename(directory));\n return;\n }\n if (depth >= WATCH_DIRECTORY_DEPTH_MAX)\n return;\n let entries: readonly {\n readonly name: string;\n isDirectory(): boolean;\n }[];\n try {\n entries = readdirSync(directory, { withFileTypes: true });\n }\n catch (error) {\n if (!isMissingPath(error))\n throw error;\n watchNamedInput(resources, watchSet, dirname(directory), basename(directory));\n return;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) {\n watchDirectoryTree(resources, watchSet, resolve(directory, entry.name), depth + 1);\n }\n }\n}\nfunction watchDirectory(resources: WatchResources, watchSet: WatchSet, directory: string): void {\n const key = `directory:${directory}`;\n if (watchSet.watchers.has(key))\n return;\n const watcher = watch(directory, () => watchSetChanged(resources, watchSet));\n watchSet.watchers.set(key, watcher);\n watchFailure(resources, watchSet, key, watcher);\n}\nfunction watchNamedInput(resources: WatchResources, watchSet: WatchSet, directory: string, name: string): void {\n const key = `named:${directory}:${name}`;\n if (watchSet.watchers.has(key))\n return;\n const watcher = watch(directory, (_event, filename) => {\n if (filename === null || filename.toString() === name)\n watchSetChanged(resources, watchSet);\n });\n watchSet.watchers.set(key, watcher);\n watchFailure(resources, watchSet, key, watcher);\n}\nfunction watchFailure(resources: WatchResources, watchSet: WatchSet, key: string, watcher: FSWatcher): void {\n watcher.once(\"error\", () => {\n if (watchSet.watchers.get(key) === watcher) {\n watchSet.watchers.delete(key);\n closeWatcher(watcher);\n }\n watchSetChanged(resources, watchSet);\n });\n}\nfunction watchSetChanged(resources: WatchResources, watchSet: WatchSet): void {\n if (!isCurrentWatchSet(resources, watchSet))\n return;\n // A new Run gets its own directory before its completion marker. Reconcile\n // the whole closure now so the marker change is observed as well as the\n // first incomplete rebuild. Failure leaves this complete old set active.\n replaceWatchInputs(resources, watchSet.inputs);\n if (isCurrentWatchSet(resources, resources.current))\n resources.onChange();\n}\nfunction isCurrentWatchSet(resources: WatchResources, watchSet: WatchSet): boolean {\n return !resources.closed && resources.current === watchSet && watchSet.state === \"active\";\n}\n/** Publishes a fully opened candidate, then retires the old closure synchronously. */\nfunction publishWatchSet(resources: WatchResources, opening: WatchSet): void {\n if (resources.closed) {\n closeWatchSet(opening);\n return;\n }\n const previous = resources.current;\n opening.state = \"active\";\n resources.current = opening;\n closeWatchSet(previous);\n}\nfunction closeWatchSet(watchSet: WatchSet): void {\n if (watchSet.state === \"closed\")\n return;\n watchSet.state = \"closed\";\n const watchers = [...watchSet.watchers.values()];\n watchSet.watchers.clear();\n for (const watcher of watchers)\n closeWatcher(watcher);\n}\nfunction closeWatcher(watcher: FSWatcher): void {\n try {\n watcher.close();\n }\n catch {\n // Closing is best-effort and idempotent at the Node boundary.\n }\n}\nfunction closeResources(resources: ServerResources): Effect.Effect<void> {\n return Effect.suspend(() => {\n if (resources.closed)\n return Effect.void;\n resources.closed = true;\n return Effect.zipRight(Effect.sync(() => {\n resources.requests.close();\n resources.refreshes.close();\n for (const socket of resources.sockets)\n socket.destroy();\n }), closeServer(resources.server));\n });\n}\nfunction closeWatchers(resources: WatchResources): Effect.Effect<void> {\n return Effect.suspend(() => {\n if (resources.closed)\n return Effect.void;\n resources.closed = true;\n return Effect.sync(() => closeWatchSet(resources.current));\n });\n}\nfunction closeServer(server: Server): Effect.Effect<void> {\n return Effect.async((resume) => {\n if (!server.listening) {\n resume(Effect.void);\n return Effect.void;\n }\n try {\n server.close(() => resume(Effect.void));\n }\n catch {\n resume(Effect.void);\n }\n return Effect.void;\n });\n}\ntype SitePathLookup = {\n readonly state: \"file\";\n readonly file: ClosedSiteFile;\n} | {\n readonly state: \"redirect\";\n readonly location: string;\n} | {\n readonly state: \"missing\";\n};\n/**\n * Resolves HTTP paths strictly through the current revision's finished file\n * map. There is intentionally no route callback, renderer, Sample, or Record\n * fallback here, so a request can never splice two revisions together.\n */\nfunction siteFileForPath(pathname: string, site: ClosedSiteRevision): SitePathLookup {\n if (!pathname.startsWith(\"/\") || pathname.includes(\"%\") || pathname.includes(\"\\\\\")) {\n return Object.freeze({ state: \"missing\" as const });\n }\n const requested = pathname.slice(1);\n const exact = requested === \"\" ? \"index.html\" : requested;\n const revision = closedSiteRevisionData(site);\n const files = revision.files;\n if (requested === \"\" && revision.defaultRoute !== undefined && revision.defaultRoute !== \"/\") {\n const entryFile = staticPageFileForRoute(revision.defaultRoute);\n if (files.some((file) => file.path === entryFile)) {\n return Object.freeze({ state: \"redirect\" as const, location: revision.defaultRoute });\n }\n }\n const direct = files.find((file) => file.path === exact);\n if (direct !== undefined)\n return Object.freeze({ state: \"file\" as const, file: direct });\n // A report may deliberately declare its first Page at /overview (or another\n // route), so its immutable closure has no root index.html. The advertised\n // root must still land on that revision's canonical entry route rather than\n // becoming a host-generated 404 or re-entering Report execution.\n if (requested === \"\" && revision.defaultRoute !== undefined) {\n const entryFile = staticPageFileForRoute(revision.defaultRoute);\n if (files.some((file) => file.path === entryFile)) {\n return Object.freeze({ state: \"redirect\" as const, location: revision.defaultRoute });\n }\n }\n // Keep direct Page URLs convenient without manufacturing a different body.\n // The redirect selects the exact generated index.html path from this same map.\n const indexPath = requested.endsWith(\"/\")\n ? `${requested}index.html`\n : `${requested}/index.html`;\n const page = files.find((file) => file.path === indexPath);\n if (page !== undefined) {\n return Object.freeze({ state: \"redirect\" as const, location: `/${indexPath}` });\n }\n return Object.freeze({ state: \"missing\" as const });\n}\nfunction staticPageFileForRoute(route: string): string {\n return route === \"/\" ? \"index.html\" : `${route.slice(1)}/index.html`;\n}\nfunction requestUrl(request: IncomingMessage): URL | undefined {\n try {\n return new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n }\n catch {\n return undefined;\n }\n}\nconst REPORT_REVISION_COOKIE = \"niceeval_report_revision\";\nfunction reportRevisionCookie(contentHash: string): string {\n return `${REPORT_REVISION_COOKIE}=${contentHash}; Path=/; SameSite=Strict; HttpOnly`;\n}\nfunction reportRevisionCookieValue(cookie: string | undefined): string | undefined {\n if (cookie === undefined)\n return undefined;\n for (const entry of cookie.split(\";\")) {\n const [name, ...value] = entry.trim().split(\"=\");\n if (name === REPORT_REVISION_COOKIE)\n return value.join(\"=\");\n }\n return undefined;\n}\nfunction sendText(response: ServerResponse, status: number, body: string, headers: Readonly<Record<string, string>> = {}): void {\n send(response, status, body, \"text/plain; charset=utf-8\", headers);\n}\nfunction send(response: ServerResponse, status: number, body: string | Uint8Array, contentType: string, headers: Readonly<Record<string, string>>): void {\n if (response.destroyed)\n return;\n response.writeHead(status, { \"content-type\": contentType, ...headers });\n response.end(body);\n}\nfunction redirect(response: ServerResponse, location: string, headers: Readonly<Record<string, string>>): void {\n if (response.destroyed)\n return;\n response.writeHead(308, { location, ...headers });\n response.end();\n}\nconst SAFE_MEDIA_TYPE = /^[A-Za-z0-9!#$%&'*+.^_`|~-]+\\/[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;\nfunction siteContentType(mediaType: string): string {\n const base = mediaType.split(\";\", 1)[0]?.trim() ?? \"\";\n return SAFE_MEDIA_TYPE.test(base) ? base : \"application/octet-stream\";\n}\nfunction viewUrls(host: string, port: number): readonly string[] {\n if (host === \"0.0.0.0\") {\n return urlsForAddresses([\n \"127.0.0.1\",\n ...interfaceAddresses(\"IPv4\"),\n ], port);\n }\n if (host === \"::\") {\n return urlsForAddresses([\n \"::1\",\n ...interfaceAddresses(\"IPv6\"),\n ], port);\n }\n return Object.freeze([viewUrl(host, port)]);\n}\nfunction interfaceAddresses(family: \"IPv4\" | \"IPv6\"): readonly string[] {\n const addresses: string[] = [];\n for (const entries of Object.values(networkInterfaces())) {\n for (const entry of entries ?? []) {\n if (entry.family === family &&\n !entry.internal &&\n !entry.address.includes(\"%\") &&\n (family !== \"IPv6\" || entry.scopeid === 0)) {\n addresses.push(entry.address);\n }\n }\n }\n return addresses.sort((left, right) => left.localeCompare(right));\n}\nfunction urlsForAddresses(addresses: readonly string[], port: number): readonly string[] {\n return Object.freeze([...new Set(addresses)].map((address) => viewUrl(address, port)));\n}\nfunction viewUrl(host: string, port: number): string {\n return new URL(`http://${formatHost(host)}:${port}/`).toString();\n}\nfunction requestAuthority(value: string | undefined): string | undefined {\n if (value === undefined)\n return undefined;\n try {\n const url = new URL(`http://${value}`);\n if (url.username.length > 0 || url.password.length > 0)\n return undefined;\n return url.host;\n }\n catch {\n return undefined;\n }\n}\nfunction formatHost(host: string): string {\n return host.includes(\":\") ? `[${host}]` : host;\n}\nfunction serverError(operation: NodeViewServerError[\"operation\"], reason: string): NodeViewServerError {\n return Object.freeze({ code: \"report-view-server-failed\", operation, reason });\n}\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\nfunction isMissingPath(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null)\n return false;\n const code = Reflect.get(error, \"code\");\n return code === \"ENOENT\" || code === \"ENOTDIR\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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","sourcesContent":["// The Node view host owns transport and watch lifetime only. Its caller has\n// already closed Record -> Sample -> Report into a fixed execution rebuild;\n// this module never reopens Record facts.\nimport { readdirSync, statSync, watch, type FSWatcher } from \"node:fs\";\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { Socket } from \"node:net\";\nimport { networkInterfaces } from \"node:os\";\nimport { basename, dirname, resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport type * as Scope from \"effect/Scope\";\nimport { closedSiteRevisionData, type ClosedSiteFile, type ClosedSiteRevision, } from \"../report/execution/model.ts\";\nimport { openReportViewSession, type OpenReportViewSessionInput, type ReportViewOpenError, type ReportViewSessionClosed, type ReportViewSession, } from \"../report/host/view-session.ts\";\nexport interface NodeViewServerError {\n readonly code: \"report-view-server-failed\";\n readonly operation: \"open\" | \"listen\" | \"watch\";\n readonly reason: string;\n}\nexport interface ViewOptions<Requirements = never> {\n readonly input?: string;\n readonly out?: string;\n readonly port?: number;\n /** Defaults to loopback. An explicit address opts into that network exposure. */\n readonly host?: string;\n /**\n * Bootstrap watch inputs when the session/request has none yet. After each\n * successful rebuild the session revision owns the next-round watch set.\n */\n readonly watchInputs?: readonly string[];\n readonly onRebuild?: (completedAt: Date) => void;\n /** An already-open scoped session owned by the caller. */\n readonly session?: ReportViewSession<Requirements>;\n /** Or let this scope open a session from a caller-supplied current rebuild. */\n readonly request?: OpenReportViewSessionInput<Requirements>;\n}\n/** The native Effect-facing server handle. Its resources are also Scope-owned. */\nexport interface ReportViewServer {\n readonly url: string;\n readonly urls: readonly string[];\n readonly close: Effect.Effect<void>;\n}\nexport type RebuildReason = \"records\" | \"modules\";\ninterface InboxClosed {\n readonly code: \"report-view-inbox-closed\";\n}\nconst inboxClosed: InboxClosed = Object.freeze({ code: \"report-view-inbox-closed\" });\ninterface HttpRequest {\n readonly request: IncomingMessage;\n readonly response: ServerResponse;\n}\nconst HTTP_REQUEST_QUEUE_MAX = 128;\n/**\n * A small callback-to-Effect bridge. Node callbacks only enqueue a value; the\n * long-lived scoped Effect performs every session operation, so callbacks do\n * not create private runtimes or invoke `runPromise`/`runSync`.\n */\nclass Inbox<Value> {\n private readonly values: Value[] = [];\n private resume: ((effect: Effect.Effect<Value, InboxClosed>) => void) | undefined;\n private closed = false;\n constructor(private readonly capacity: number) { }\n take(): Effect.Effect<Value, InboxClosed> {\n return Effect.async((resume) => {\n if (this.values.length > 0) {\n resume(Effect.succeed(this.values.shift()!));\n return Effect.void;\n }\n if (this.closed) {\n resume(Effect.fail(inboxClosed));\n return Effect.void;\n }\n this.resume = resume;\n return Effect.sync(() => {\n if (this.resume === resume)\n this.resume = undefined;\n });\n });\n }\n offer(value: Value): boolean {\n if (this.closed)\n return false;\n const resume = this.resume;\n if (resume === undefined) {\n if (this.values.length >= this.capacity)\n return false;\n this.values.push(value);\n return true;\n }\n this.resume = undefined;\n resume(Effect.succeed(value));\n return true;\n }\n close(): void {\n if (this.closed)\n return;\n this.closed = true;\n const resume = this.resume;\n this.resume = undefined;\n resume?.(Effect.fail(inboxClosed));\n }\n}\n/** Coalesces a burst of filesystem events into sequential refresh requests. */\nclass RefreshInbox {\n private pending = false;\n private resume: ((effect: Effect.Effect<void, InboxClosed>) => void) | undefined;\n private closed = false;\n take(): Effect.Effect<void, InboxClosed> {\n return Effect.async((resume) => {\n if (this.pending) {\n this.pending = false;\n resume(Effect.void);\n return Effect.void;\n }\n if (this.closed) {\n resume(Effect.fail(inboxClosed));\n return Effect.void;\n }\n this.resume = resume;\n return Effect.sync(() => {\n if (this.resume === resume)\n this.resume = undefined;\n });\n });\n }\n request(): void {\n if (this.closed)\n return;\n const resume = this.resume;\n if (resume === undefined) {\n this.pending = true;\n return;\n }\n this.resume = undefined;\n resume(Effect.void);\n }\n close(): void {\n if (this.closed)\n return;\n this.closed = true;\n const resume = this.resume;\n this.resume = undefined;\n resume?.(Effect.fail(inboxClosed));\n }\n}\ninterface ServerResources {\n readonly server: Server;\n readonly sockets: Set<Socket>;\n readonly requests: Inbox<HttpRequest>;\n readonly refreshes: RefreshInbox;\n closed: boolean;\n}\ninterface WatchResources {\n /** The one currently published watcher closure. */\n current: WatchSet;\n /** Stable refresh request callback for the current server lifetime. */\n onChange: () => void;\n closed: boolean;\n}\n/**\n * A complete watcher closure. A candidate stays `opening` until every watch\n * for its current directory tree has opened. Callbacks test both this state\n * and the owning resource's current reference, so an old or failed candidate\n * cannot enqueue a late rebuild.\n */\ninterface WatchSet {\n readonly inputs: readonly string[];\n readonly watchers: Map<string, FSWatcher>;\n state: \"opening\" | \"active\" | \"closed\";\n}\n/**\n * Opens a real HTTP server, defaulting to loopback. A watcher event only requests\n * `session.refresh`; the session serializes rebuild and close, preserves the\n * last good immutable execution and recoverable watch set, and publishes a new\n * revision only on success. The Node server then atomically replaces its\n * fs.watch resources from that revision's watchInputs.\n */\nexport function openViewServer<Requirements>(options: ViewOptions<Requirements> = {}): Effect.Effect<ReportViewServer, NodeViewServerError | ReportViewOpenError, Scope.Scope | Requirements> {\n return Effect.gen(function* () {\n const serverScope = yield* Effect.scope;\n if (options.session !== undefined && options.request !== undefined) {\n return yield* Effect.fail(serverError(\"open\", \"provide either session or request, not both\"));\n }\n const host = (options.host ?? \"127.0.0.1\").trim();\n if (host.length === 0) {\n return yield* Effect.fail(serverError(\"open\", \"view host must not be empty\"));\n }\n if (host.includes(\"%\")) {\n return yield* Effect.fail(serverError(\"open\", \"scoped IPv6 view hosts are not supported\"));\n }\n const port = options.port ?? 0;\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n return yield* Effect.fail(serverError(\"open\", `view port must be an integer from 0 through 65535, got ${port}`));\n }\n const session = options.session ?? (options.request === undefined\n ? yield* Effect.fail(serverError(\"open\", \"view needs a scoped ReportViewSession or current rebuild request\"))\n : yield* openReportViewSession({\n ...options.request,\n // Bootstrap the opening revision when the request omitted a watch set.\n watchInputs: options.request.watchInputs ?? optionWatchInputs(options),\n }));\n const opening = yield* session.snapshot.pipe(Effect.mapError(() => serverError(\"open\", \"report view session closed before watchers opened\")));\n const initialWatchInputs = opening.current.watchInputs.length > 0\n ? opening.current.watchInputs\n : optionWatchInputs(options);\n const resources = yield* Effect.acquireRelease(Effect.sync(() => makeResources()), (value) => closeResources(value));\n const address = yield* listen(resources.server, host, port);\n const urls = viewUrls(host, address.port);\n const advertisedAuthorities = Object.freeze(new Set(urls.map((url) => new URL(url).host)));\n const watches = yield* Effect.acquireRelease(openWatchers(initialWatchInputs, () => resources.refreshes.request()), (value) => closeWatchers(value));\n yield* Effect.forkScoped(Effect.forever(Effect.flatMap(resources.requests.take(), (request) => serveRequest(session, request, advertisedAuthorities))).pipe(Effect.catchAll(() => Effect.void)));\n yield* Effect.forkScoped(Effect.forever(Effect.flatMap(resources.refreshes.take(), () => registerRefreshIntent(session, watches, options.onRebuild, serverScope))).pipe(Effect.catchAll(() => Effect.void)));\n const close = Effect.zipRight(closeWatchers(watches), closeResources(resources));\n return Object.freeze({ url: urls[0]!, urls, close });\n });\n}\nfunction makeResources(): ServerResources {\n const requests = new Inbox<HttpRequest>(HTTP_REQUEST_QUEUE_MAX);\n const refreshes = new RefreshInbox();\n const sockets = new Set<Socket>();\n const server = createServer((request, response) => {\n if (!requests.offer(Object.freeze({ request, response }))) {\n sendText(response, 503, \"report view is busy; retry shortly\");\n }\n });\n server.on(\"connection\", (socket) => {\n sockets.add(socket);\n socket.once(\"close\", () => sockets.delete(socket));\n });\n return { server, sockets, requests, refreshes, closed: false };\n}\nfunction listen(server: Server, host: string, port: number): Effect.Effect<{\n readonly host: string;\n readonly port: number;\n}, NodeViewServerError> {\n return Effect.async((resume) => {\n const cleanup = (): void => {\n server.off(\"error\", onError);\n server.off(\"listening\", onListening);\n };\n const onError = (error: Error): void => {\n cleanup();\n resume(Effect.fail(serverError(\"listen\", error.message)));\n };\n const onListening = (): void => {\n cleanup();\n const address = server.address();\n if (address === null || typeof address === \"string\") {\n resume(Effect.fail(serverError(\"listen\", \"server did not expose a TCP address\")));\n return;\n }\n resume(Effect.succeed(Object.freeze({ host: address.address, port: address.port })));\n };\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n try {\n server.listen({ host, port });\n }\n catch (error) {\n onError(asError(error));\n }\n return Effect.sync(() => cleanup());\n });\n}\nfunction serveRequest<Requirements>(session: ReportViewSession<Requirements>, request: HttpRequest, advertisedAuthorities: ReadonlySet<string>): Effect.Effect<void> {\n const authority = requestAuthority(request.request.headers.host);\n if (authority === undefined || !advertisedAuthorities.has(authority)) {\n return Effect.sync(() => sendText(request.response, 421, \"view host is not advertised\"));\n }\n if (request.request.method !== \"GET\" && request.request.method !== \"HEAD\") {\n return Effect.sync(() => sendText(request.response, 405, \"method not allowed\", { allow: \"GET, HEAD\" }));\n }\n const url = requestUrl(request.request);\n if (url === undefined) {\n return Effect.sync(() => sendText(request.response, 400, \"bad request\"));\n }\n if (url.pathname === \"/healthz\") {\n return Effect.sync(() => sendText(request.response, 200, \"ok\"));\n }\n return session.snapshot.pipe(Effect.flatMap((state) => {\n const headers = Object.freeze({\n \"cache-control\": \"no-store\",\n \"x-niceeval-report-revision\": String(state.current.revision),\n \"x-niceeval-report-content-hash\": closedSiteRevisionData(state.current.site).identity.contentHash,\n ...(state.lastProblem === undefined ? {} : { \"x-niceeval-last-rebuild-problem\": \"1\" }),\n });\n // Optional host transport probe. It contains no Report body and does\n // not belong to the content-addressed file mapping. The HTML response\n // below establishes its own served revision through an HttpOnly cookie;\n // after publication this endpoint can report that the browser document\n // is stale without putting revision information into its body bytes.\n if (url.pathname === \"/_niceeval/refresh\") {\n const servedIdentity = reportRevisionCookieValue(request.request.headers.cookie);\n return Effect.sync(() => send(request.response, 204, new Uint8Array(), \"text/plain; charset=utf-8\", {\n ...headers,\n \"x-niceeval-view-stale\": servedIdentity === undefined || servedIdentity === closedSiteRevisionData(state.current.site).identity.contentHash\n ? \"0\"\n : \"1\",\n }));\n }\n const resolved = siteFileForPath(url.pathname, state.current.site);\n if (resolved.state === \"missing\") {\n return Effect.sync(() => sendText(request.response, 404, url.pathname.startsWith(\"/downloads/\") ? \"download not found\" : \"page not found\", headers));\n }\n return Effect.sync(() => send(request.response, 200, resolved.file.bytes, siteContentType(resolved.file.mediaType), resolved.file.path.startsWith(\"downloads/\")\n ? { ...headers, \"content-disposition\": \"attachment\", \"x-content-type-options\": \"nosniff\" }\n : resolved.file.mediaType.startsWith(\"text/html;\")\n ? { ...headers, \"set-cookie\": reportRevisionCookie(closedSiteRevisionData(state.current.site).identity.contentHash) }\n : headers));\n }), Effect.catchAll(() => Effect.sync(() => sendText(request.response, 503, \"report view session is closed\"))));\n}\n/**\n * Register immediately, then subscribe in a scoped waiter. The refresh inbox\n * can therefore accept a newer intent while this candidate still performs\n * author work; only a published outcome mutates watcher ownership or emits a\n * browser-facing rebuild notification.\n */\nfunction registerRefreshIntent<Requirements>(session: ReportViewSession<Requirements>, watches: WatchResources, onRebuild: ViewOptions[\"onRebuild\"], serverScope: Scope.Scope): Effect.Effect<void, ReportViewSessionClosed, Requirements> {\n return Effect.gen(function* () {\n const intent = yield* session.refresh;\n yield* Effect.forkIn(intent.outcome.pipe(Effect.flatMap((outcome) => outcome.state !== \"published\"\n ? Effect.void\n : Effect.gen(function* () {\n // One published revision owns its corresponding successful watch set.\n yield* Effect.sync(() => replaceWatchInputs(watches, outcome.revision.watchInputs));\n if (onRebuild !== undefined) {\n yield* Effect.try({\n try: () => onRebuild(new Date()),\n catch: () => undefined,\n }).pipe(Effect.ignore);\n }\n }))), serverScope);\n });\n}\nfunction optionWatchInputs<Requirements>(options: ViewOptions<Requirements>): readonly string[] {\n const values = options.watchInputs ?? [];\n return Object.freeze([...new Set(values.map((value) => resolve(value)))]);\n}\nfunction openWatchers(inputs: readonly string[], onChange: () => void): Effect.Effect<WatchResources, NodeViewServerError> {\n return Effect.try({\n try: () => {\n const resources: WatchResources = {\n current: closedWatchSet(),\n onChange,\n closed: false,\n };\n try {\n const opening = openWatchSet(resources, inputs);\n publishWatchSet(resources, opening);\n return resources;\n }\n catch (error) {\n closeWatchSet(resources.current);\n throw error;\n }\n },\n catch: (error): NodeViewServerError => serverError(\"watch\", asError(error).message),\n });\n}\n/**\n * Atomically swaps the next-round watch set after a successful revision. Failure\n * paths never call this, so last-good entry edges remain recoverable.\n */\nfunction replaceWatchInputs(resources: WatchResources, inputs: readonly string[]): void {\n if (resources.closed)\n return;\n try {\n const opening = openWatchSet(resources, inputs);\n if (resources.closed) {\n closeWatchSet(opening);\n return;\n }\n // No Effect boundary or callback can interleave this publication: the\n // replacement is entirely synchronous after the candidate validated.\n publishWatchSet(resources, opening);\n }\n catch {\n // A transient directory race must not discard the previous recoverable\n // closure. The next filesystem hint retries full reconciliation.\n }\n}\nfunction closedWatchSet(): WatchSet {\n return {\n inputs: Object.freeze([]),\n watchers: new Map(),\n state: \"closed\",\n };\n}\n/**\n * Opens a whole candidate closure without touching the published set. This is\n * also the full reconciliation path for directory-tree changes: fs.watch is a\n * hint, so every event rescans all inputs before requesting a rebuild.\n */\nfunction openWatchSet(resources: WatchResources, inputs: readonly string[]): WatchSet {\n const watchSet: WatchSet = {\n inputs: normalizeWatchInputs(inputs),\n watchers: new Map(),\n state: \"opening\",\n };\n try {\n synchronizeWatchSet(resources, watchSet);\n return watchSet;\n }\n catch (error) {\n closeWatchSet(watchSet);\n throw error;\n }\n}\n/** Watch the Record root and its current Run directories without a polling loop. */\nfunction synchronizeWatchSet(resources: WatchResources, watchSet: WatchSet): void {\n for (const input of watchSet.inputs) {\n let inputIsDirectory: boolean;\n try {\n inputIsDirectory = statSync(input).isDirectory();\n }\n catch (error) {\n if (!isMissingPath(error))\n throw error;\n // A missing config / module / Record root remains observable through its\n // parent directory. It can appear later without restarting the host.\n watchNamedInput(resources, watchSet, dirname(input), basename(input));\n continue;\n }\n if (inputIsDirectory) {\n watchDirectoryTree(resources, watchSet, input, 0);\n }\n else {\n watchNamedInput(resources, watchSet, dirname(input), basename(input));\n }\n }\n}\nfunction normalizeWatchInputs(inputs: readonly string[]): readonly string[] {\n return Object.freeze([...new Set(inputs.map((input) => resolve(input)))].sort());\n}\nconst WATCH_DIRECTORY_DEPTH_MAX = 4;\nfunction watchDirectoryTree(resources: WatchResources, watchSet: WatchSet, directory: string, depth: number): void {\n try {\n watchDirectory(resources, watchSet, directory);\n }\n catch (error) {\n if (!isMissingPath(error))\n throw error;\n watchNamedInput(resources, watchSet, dirname(directory), basename(directory));\n return;\n }\n if (depth >= WATCH_DIRECTORY_DEPTH_MAX)\n return;\n let entries: readonly {\n readonly name: string;\n isDirectory(): boolean;\n }[];\n try {\n entries = readdirSync(directory, { withFileTypes: true });\n }\n catch (error) {\n if (!isMissingPath(error))\n throw error;\n watchNamedInput(resources, watchSet, dirname(directory), basename(directory));\n return;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) {\n watchDirectoryTree(resources, watchSet, resolve(directory, entry.name), depth + 1);\n }\n }\n}\nfunction watchDirectory(resources: WatchResources, watchSet: WatchSet, directory: string): void {\n const key = `directory:${directory}`;\n if (watchSet.watchers.has(key))\n return;\n const watcher = watch(directory, () => watchSetChanged(resources, watchSet));\n watchSet.watchers.set(key, watcher);\n watchFailure(resources, watchSet, key, watcher);\n}\nfunction watchNamedInput(resources: WatchResources, watchSet: WatchSet, directory: string, name: string): void {\n const key = `named:${directory}:${name}`;\n if (watchSet.watchers.has(key))\n return;\n const watcher = watch(directory, (_event, filename) => {\n if (filename === null || filename.toString() === name)\n watchSetChanged(resources, watchSet);\n });\n watchSet.watchers.set(key, watcher);\n watchFailure(resources, watchSet, key, watcher);\n}\nfunction watchFailure(resources: WatchResources, watchSet: WatchSet, key: string, watcher: FSWatcher): void {\n watcher.once(\"error\", () => {\n if (watchSet.watchers.get(key) === watcher) {\n watchSet.watchers.delete(key);\n closeWatcher(watcher);\n }\n watchSetChanged(resources, watchSet);\n });\n}\nfunction watchSetChanged(resources: WatchResources, watchSet: WatchSet): void {\n if (!isCurrentWatchSet(resources, watchSet))\n return;\n // A new Run gets its own directory before its completion marker. Reconcile\n // the whole closure now so the marker change is observed as well as the\n // first incomplete rebuild. Failure leaves this complete old set active.\n replaceWatchInputs(resources, watchSet.inputs);\n if (isCurrentWatchSet(resources, resources.current))\n resources.onChange();\n}\nfunction isCurrentWatchSet(resources: WatchResources, watchSet: WatchSet): boolean {\n return !resources.closed && resources.current === watchSet && watchSet.state === \"active\";\n}\n/** Publishes a fully opened candidate, then retires the old closure synchronously. */\nfunction publishWatchSet(resources: WatchResources, opening: WatchSet): void {\n if (resources.closed) {\n closeWatchSet(opening);\n return;\n }\n const previous = resources.current;\n opening.state = \"active\";\n resources.current = opening;\n closeWatchSet(previous);\n}\nfunction closeWatchSet(watchSet: WatchSet): void {\n if (watchSet.state === \"closed\")\n return;\n watchSet.state = \"closed\";\n const watchers = [...watchSet.watchers.values()];\n watchSet.watchers.clear();\n for (const watcher of watchers)\n closeWatcher(watcher);\n}\nfunction closeWatcher(watcher: FSWatcher): void {\n try {\n watcher.close();\n }\n catch {\n // Closing is best-effort and idempotent at the Node boundary.\n }\n}\nfunction closeResources(resources: ServerResources): Effect.Effect<void> {\n return Effect.suspend(() => {\n if (resources.closed)\n return Effect.void;\n resources.closed = true;\n return Effect.zipRight(Effect.sync(() => {\n resources.requests.close();\n resources.refreshes.close();\n for (const socket of resources.sockets)\n socket.destroy();\n }), closeServer(resources.server));\n });\n}\nfunction closeWatchers(resources: WatchResources): Effect.Effect<void> {\n return Effect.suspend(() => {\n if (resources.closed)\n return Effect.void;\n resources.closed = true;\n return Effect.sync(() => closeWatchSet(resources.current));\n });\n}\nfunction closeServer(server: Server): Effect.Effect<void> {\n return Effect.async((resume) => {\n if (!server.listening) {\n resume(Effect.void);\n return Effect.void;\n }\n try {\n server.close(() => resume(Effect.void));\n }\n catch {\n resume(Effect.void);\n }\n return Effect.void;\n });\n}\ntype SitePathLookup = {\n readonly state: \"file\";\n readonly file: ClosedSiteFile;\n} | {\n readonly state: \"missing\";\n};\n/**\n * Resolves HTTP paths strictly through the current revision's finished file\n * map. There is intentionally no route callback, renderer, Sample, or Record\n * fallback here, so a request can never splice two revisions together.\n */\nfunction siteFileForPath(pathname: string, site: ClosedSiteRevision): SitePathLookup {\n if (!pathname.startsWith(\"/\") || pathname.includes(\"%\") || pathname.includes(\"\\\\\")) {\n return Object.freeze({ state: \"missing\" as const });\n }\n const requested = pathname.slice(1);\n // The SPA shell is the revision's sole root document. All business\n // navigation belongs to its hash router, not to host-side path probing.\n const exact = requested === \"\" ? \"index.html\" : requested;\n const revision = closedSiteRevisionData(site);\n const files = revision.files;\n const direct = files.find((file) => file.path === exact);\n if (direct !== undefined)\n return Object.freeze({ state: \"file\" as const, file: direct });\n return Object.freeze({ state: \"missing\" as const });\n}\nfunction requestUrl(request: IncomingMessage): URL | undefined {\n try {\n return new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n }\n catch {\n return undefined;\n }\n}\nconst REPORT_REVISION_COOKIE = \"niceeval_report_revision\";\nfunction reportRevisionCookie(contentHash: string): string {\n return `${REPORT_REVISION_COOKIE}=${contentHash}; Path=/; SameSite=Strict; HttpOnly`;\n}\nfunction reportRevisionCookieValue(cookie: string | undefined): string | undefined {\n if (cookie === undefined)\n return undefined;\n for (const entry of cookie.split(\";\")) {\n const [name, ...value] = entry.trim().split(\"=\");\n if (name === REPORT_REVISION_COOKIE)\n return value.join(\"=\");\n }\n return undefined;\n}\nfunction sendText(response: ServerResponse, status: number, body: string, headers: Readonly<Record<string, string>> = {}): void {\n send(response, status, body, \"text/plain; charset=utf-8\", headers);\n}\nfunction send(response: ServerResponse, status: number, body: string | Uint8Array, contentType: string, headers: Readonly<Record<string, string>>): void {\n if (response.destroyed)\n return;\n response.writeHead(status, { \"content-type\": contentType, ...headers });\n response.end(body);\n}\nconst SAFE_MEDIA_TYPE = /^[A-Za-z0-9!#$%&'*+.^_`|~-]+\\/[A-Za-z0-9!#$%&'*+.^_`|~-]+$/;\nfunction siteContentType(mediaType: string): string {\n const base = mediaType.split(\";\", 1)[0]?.trim() ?? \"\";\n return SAFE_MEDIA_TYPE.test(base) ? base : \"application/octet-stream\";\n}\nfunction viewUrls(host: string, port: number): readonly string[] {\n if (host === \"0.0.0.0\") {\n return urlsForAddresses([\n \"127.0.0.1\",\n ...interfaceAddresses(\"IPv4\"),\n ], port);\n }\n if (host === \"::\") {\n return urlsForAddresses([\n \"::1\",\n ...interfaceAddresses(\"IPv6\"),\n ], port);\n }\n return Object.freeze([viewUrl(host, port)]);\n}\nfunction interfaceAddresses(family: \"IPv4\" | \"IPv6\"): readonly string[] {\n const addresses: string[] = [];\n for (const entries of Object.values(networkInterfaces())) {\n for (const entry of entries ?? []) {\n if (entry.family === family &&\n !entry.internal &&\n !entry.address.includes(\"%\") &&\n (family !== \"IPv6\" || entry.scopeid === 0)) {\n addresses.push(entry.address);\n }\n }\n }\n return addresses.sort((left, right) => left.localeCompare(right));\n}\nfunction urlsForAddresses(addresses: readonly string[], port: number): readonly string[] {\n return Object.freeze([...new Set(addresses)].map((address) => viewUrl(address, port)));\n}\nfunction viewUrl(host: string, port: number): string {\n return new URL(`http://${formatHost(host)}:${port}/`).toString();\n}\nfunction requestAuthority(value: string | undefined): string | undefined {\n if (value === undefined)\n return undefined;\n try {\n const url = new URL(`http://${value}`);\n if (url.username.length > 0 || url.password.length > 0)\n return undefined;\n return url.host;\n }\n catch {\n return undefined;\n }\n}\nfunction formatHost(host: string): string {\n return host.includes(\":\") ? `[${host}]` : host;\n}\nfunction serverError(operation: NodeViewServerError[\"operation\"], reason: string): NodeViewServerError {\n return Object.freeze({ code: \"report-view-server-failed\", operation, reason });\n}\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\nfunction isMissingPath(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null)\n return false;\n const code = Reflect.get(error, \"code\");\n return code === \"ENOENT\" || code === \"ENOTDIR\";\n}\n"]}
|
package/dist/view/server.d.cts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type * as Scope from "effect/Scope";
|
|
3
3
|
import { type OpenReportViewSessionInput, type ReportViewOpenError, type ReportViewSession } from "../report/host/view-session.cjs";
|
|
4
|
-
import type { ViewScanOptions } from "./data.cjs";
|
|
5
4
|
export interface NodeViewServerError {
|
|
6
5
|
readonly code: "report-view-server-failed";
|
|
7
6
|
readonly operation: "open" | "listen" | "watch";
|
|
@@ -13,8 +12,6 @@ export interface ViewOptions<Requirements = never> {
|
|
|
13
12
|
readonly port?: number;
|
|
14
13
|
/** Defaults to loopback. An explicit address opts into that network exposure. */
|
|
15
14
|
readonly host?: string;
|
|
16
|
-
/** Retained for the CLI-shaped facade; it is never interpreted as Record data. */
|
|
17
|
-
readonly scan?: ViewScanOptions;
|
|
18
15
|
/**
|
|
19
16
|
* Bootstrap watch inputs when the session/request has none yet. After each
|
|
20
17
|
* successful rebuild the session revision owns the next-round watch set.
|
package/dist/view/server.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type * as Scope from "effect/Scope";
|
|
3
3
|
import { type OpenReportViewSessionInput, type ReportViewOpenError, type ReportViewSession } from "../report/host/view-session.mjs";
|
|
4
|
-
import type { ViewScanOptions } from "./data.mjs";
|
|
5
4
|
export interface NodeViewServerError {
|
|
6
5
|
readonly code: "report-view-server-failed";
|
|
7
6
|
readonly operation: "open" | "listen" | "watch";
|
|
@@ -13,8 +12,6 @@ export interface ViewOptions<Requirements = never> {
|
|
|
13
12
|
readonly port?: number;
|
|
14
13
|
/** Defaults to loopback. An explicit address opts into that network exposure. */
|
|
15
14
|
readonly host?: string;
|
|
16
|
-
/** Retained for the CLI-shaped facade; it is never interpreted as Record data. */
|
|
17
|
-
readonly scan?: ViewScanOptions;
|
|
18
15
|
/**
|
|
19
16
|
* Bootstrap watch inputs when the session/request has none yet. After each
|
|
20
17
|
* successful rebuild the session revision owns the next-round watch set.
|
package/dist/view/server.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type * as Scope from "effect/Scope";
|
|
3
3
|
import { type OpenReportViewSessionInput, type ReportViewOpenError, type ReportViewSession } from "../report/host/view-session.js";
|
|
4
|
-
import type { ViewScanOptions } from "./data.js";
|
|
5
4
|
export interface NodeViewServerError {
|
|
6
5
|
readonly code: "report-view-server-failed";
|
|
7
6
|
readonly operation: "open" | "listen" | "watch";
|
|
@@ -13,8 +12,6 @@ export interface ViewOptions<Requirements = never> {
|
|
|
13
12
|
readonly port?: number;
|
|
14
13
|
/** Defaults to loopback. An explicit address opts into that network exposure. */
|
|
15
14
|
readonly host?: string;
|
|
16
|
-
/** Retained for the CLI-shaped facade; it is never interpreted as Record data. */
|
|
17
|
-
readonly scan?: ViewScanOptions;
|
|
18
15
|
/**
|
|
19
16
|
* Bootstrap watch inputs when the session/request has none yet. After each
|
|
20
17
|
* successful rebuild the session revision owns the next-round watch set.
|
|
@@ -44,13 +44,13 @@ description: "NiceEval 内置的 claude-code、codex、bub 适配器分别做到
|
|
|
44
44
|
### codex
|
|
45
45
|
|
|
46
46
|
- 连接方式:Sandbox 里跑 `codex exec --json`(续接时是 `codex exec resume <id> --json`),stdout JSONL 当 transcript。命令带 `--dangerously-bypass-approvals-and-sandbox` 与 `--dangerously-bypass-hook-trust`:Sandbox 里没人能回答 codex 的交互确认,插件或 `postSetup` 装好的 hook 因此不需要交互授信就能生效。
|
|
47
|
-
- 鉴权:`
|
|
47
|
+
- 鉴权:`CODEX_API_KEY`,可选 `CODEX_BASE_URL` 接 OpenAI 兼容代理。配置项见下方 `CodexConfig`。
|
|
48
48
|
- `tracing` 通过 `~/.codex/config.toml` 的 `[otel.trace_exporter.otlp-http]` 段配置,协议 `http/json`。
|
|
49
49
|
|
|
50
50
|
### bub
|
|
51
51
|
|
|
52
52
|
- 连接方式:Sandbox 里跑 `bub run` + `--session-id`,从 `~/.bub/tapes/<hash>.jsonl` 读 tape 当 transcript。
|
|
53
|
-
- 鉴权:`
|
|
53
|
+
- 鉴权:`BUB_API_KEY` + `BUB_API_BASE`(OpenAI 兼容代理)。配置项见下方 `BubConfig`。
|
|
54
54
|
- `tracing` 通过环境变量注入(`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` 等),协议 `http/protobuf`。
|
|
55
55
|
- 安装走 `uv tool install`(非 npm 包),首次安装带 checkpoint 缓存以加速后续 Sandbox。
|
|
56
56
|
|
|
@@ -168,7 +168,7 @@ preTeardown?: readonly SandboxCommand[];
|
|
|
168
168
|
apiKey?: string;
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
代理 / OpenAI API key。省略时读
|
|
171
|
+
代理 / OpenAI API key。省略时读 CODEX_API_KEY env。
|
|
172
172
|
|
|
173
173
|
#### `baseUrl`
|
|
174
174
|
|
|
@@ -176,7 +176,7 @@ apiKey?: string;
|
|
|
176
176
|
baseUrl?: string;
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
OpenAI 兼容代理 base URL(如 `https://s2a.example.com/v1`)。省略时读
|
|
179
|
+
OpenAI 兼容代理 base URL(如 `https://s2a.example.com/v1`)。省略时读 CODEX_BASE_URL env。
|
|
180
180
|
|
|
181
181
|
#### `env`
|
|
182
182
|
|
|
@@ -187,7 +187,7 @@ env?: Readonly<globalThis.Record<string, string>>;
|
|
|
187
187
|
注入每次 Codex CLI 进程的额外环境变量。首轮 `codex exec` 与续轮 `codex exec resume`
|
|
188
188
|
使用同一份声明;Codex 启动的 lifecycle Hook、MCP 动态 header 与命令子进程都会继承。
|
|
189
189
|
值只经 Sandbox command options 传入,不拼进 shell 文本或写入 setup manifest,并全部按
|
|
190
|
-
潜在敏感值从 timing / execution / error 证据中脱敏。`
|
|
190
|
+
潜在敏感值从 timing / execution / error 证据中脱敏。`CODEX_API_KEY` 仍由 `apiKey` 或
|
|
191
191
|
宿主同名环境变量提供,Adapter 的鉴权值会覆盖这里的同名键。
|
|
192
192
|
env value 不进入 carry 身份。会改变被测行为的非敏感值必须同时声明在 Experiment flags
|
|
193
193
|
或所属 Plugin identity;只轮换凭据不会让旧结果失效。
|
|
@@ -267,7 +267,7 @@ preTeardown?: readonly SandboxCommand[];
|
|
|
267
267
|
apiKey?: string;
|
|
268
268
|
```
|
|
269
269
|
|
|
270
|
-
OpenAI 兼容代理的 API key。省略时读
|
|
270
|
+
OpenAI 兼容代理的 API key。省略时读 BUB_API_KEY env。
|
|
271
271
|
|
|
272
272
|
#### `apiBase`
|
|
273
273
|
|
|
@@ -275,7 +275,7 @@ OpenAI 兼容代理的 API key。省略时读 OPENAI_API_KEY env。
|
|
|
275
275
|
apiBase?: string;
|
|
276
276
|
```
|
|
277
277
|
|
|
278
|
-
OpenAI 兼容代理的 base URL。省略时读
|
|
278
|
+
OpenAI 兼容代理的 base URL。省略时读 BUB_API_BASE env。
|
|
279
279
|
|
|
280
280
|
#### `skills`
|
|
281
281
|
|
|
@@ -64,8 +64,8 @@ export default defineExperiment({
|
|
|
64
64
|
|
|
65
65
|
### codex
|
|
66
66
|
|
|
67
|
-
- **鉴权**:`
|
|
68
|
-
- **Agent 进程环境**:`env` 会注入每次 `codex exec` 与 `codex exec resume`。Codex 启动的 Session 生命周期 Hook、MCP 动态请求头和命令子进程都会继承。值不会拼进 shell 文本或写入安装清单,并按潜在敏感值从 timing、execution 与错误证据中脱敏。`
|
|
67
|
+
- **鉴权**:`CODEX_API_KEY`(工厂参数 `apiKey` 可覆盖),可选 `CODEX_BASE_URL`(工厂参数 `baseUrl`)接 OpenAI 兼容代理。
|
|
68
|
+
- **Agent 进程环境**:`env` 会注入每次 `codex exec` 与 `codex exec resume`。Codex 启动的 Session 生命周期 Hook、MCP 动态请求头和命令子进程都会继承。值不会拼进 shell 文本或写入安装清单,并按潜在敏感值从 timing、execution 与错误证据中脱敏。`CODEX_API_KEY` 仍由 `apiKey` 或宿主环境提供,并覆盖 `env` 里的同名键。`PATH` 是 Sandbox 受管变量,不接受经 `env` 声明——出现即在 `codexAgent()` 调用时报错,改用 Sandbox 的 `pathPrepend`(见 [Sandbox provider](/zh/tutorials/sandbox-providers))。
|
|
69
69
|
- **装 MCP server**:`mcpServers` 配置项,`setup` 阶段追加进 `~/.codex/config.toml` 的 `[mcp_servers.<name>]` 段。两种形态按字段区分:本地 stdio 进程写 `command`(可带 `args` / `env`)。远程 Streamable HTTP 端点写 `url`(可带 `headers`,写成 `[mcp_servers.<name>.http_headers]` 子表)。`url` 要 Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
|
|
70
70
|
|
|
71
71
|
<Warning>
|
|
@@ -120,7 +120,7 @@ export default defineExperiment({
|
|
|
120
120
|
|
|
121
121
|
### bub
|
|
122
122
|
|
|
123
|
-
- **鉴权**:`
|
|
123
|
+
- **鉴权**:`BUB_API_KEY` + `BUB_API_BASE`(OpenAI 兼容代理),工厂参数 `apiKey` / `apiBase` 可覆盖。
|
|
124
124
|
- **装 Skill**:`skills: SkillSpec[]`,与另外两个 Adapter 同一个类型。装进 `.agents/skills/<name>/`,发现指引写进 AGENTS.md。
|
|
125
125
|
- **装插件**:`pythonPlugins: PythonPluginSpec[]`(`{ package }`:PyPI 包、版本约束或 git URL),`setup` 阶段进 `uv tool install … --with <package>`。这个类型只属于 bub。package 集合进安装 checkpoint key,插件不同的两个变体不会复用同一份安装缓存。
|
|
126
126
|
- **预制 Bub**:NiceEval 的 E2B 配方会把 Bub、OTel 插件和 Python 插件集合算成安装指纹。Adapter 只复用指纹完全一致的环境。仅在 PATH 里放一个 `bub` 不足以证明兼容。构建入口见 [Sandbox provider · 从官方基线继续构建以提速](/zh/tutorials/sandbox-providers#从官方基线继续构建以提速)。
|
|
@@ -148,7 +148,7 @@ export default defineExperiment({
|
|
|
148
148
|
|
|
149
149
|
| | claude-code | codex | bub |
|
|
150
150
|
|---|---|---|---|
|
|
151
|
-
| 鉴权环境变量 | `ANTHROPIC_API_KEY` | `
|
|
151
|
+
| 鉴权环境变量 | `ANTHROPIC_API_KEY` | `CODEX_API_KEY` + 可选 `CODEX_BASE_URL` | `BUB_API_KEY` + `BUB_API_BASE` |
|
|
152
152
|
| 额外 Agent 进程环境 | ❌ | ✅ `env` | ❌ |
|
|
153
153
|
| MCP server | ✅ `mcpServers`(stdio + HTTP) | ✅ `mcpServers`(stdio + HTTP) | ❌ |
|
|
154
154
|
| Skill | ✅ `skills: SkillSpec[]`(原生发现) | ✅ `skills: SkillSpec[]`(+ 发现指引) | ✅ `skills: SkillSpec[]`(+ 发现指引) |
|
|
@@ -109,13 +109,13 @@ const MetricCard = defineComponent<
|
|
|
109
109
|
|
|
110
110
|
`show --json` 固定输出英语 JSON。内建 Report 输出 Host 拥有的具名领域文档;自定义 Report 输出一个 Page 的 route、标题、80-column rendered text、下载摘要和问题表。两种 v1 JSON 都在顶层以相同的 `projections` 对象携带该目标 Page 的闭合成本数据;它们不包含作者树、HTML、全站路由或站点 identity。
|
|
111
111
|
|
|
112
|
-
view 与静态导出使用同一份完整站点版本。同一路由的 HTTP body 与导出目录页面 body 逐字节相同。两者都携带同一个
|
|
112
|
+
view 与静态导出使用同一份完整站点版本。同一路由的 HTTP body 与导出目录页面 body 逐字节相同。两者都携带同一个 Host runtime;静态目录找不到 view 的端点时,实时刷新会安静停用。目录不需要网络、源 Record 或 NiceEval 安装,但浏览器必须启用随包交付的 JavaScript。禁用时页面显示可操作的错误,不维护第二套阅读路径。
|
|
113
113
|
|
|
114
114
|
## 样式和资源边界
|
|
115
115
|
|
|
116
116
|
Report CSS 是唯一的产品样式 owner。它负责 reset、基础排版、theme token 与组件样式。View shell 只负责浏览器语言切换、reload 状态和 Host 提示,不重绘 Report 内容。
|
|
117
117
|
|
|
118
|
-
Report 可以在 `head` 中声明结构化 `meta`、`link`、`style` 和 `script`,也可以选择 theme
|
|
118
|
+
Report 可以在 `head` 中声明结构化 `meta`、`link`、`style` 和 `script`,也可以选择 theme。Host runtime 负责报告阅读与导航;作者脚本可以增强作者内容,但不能替代已闭合的正文、Evidence 或机器文档。自定义样式不能建立第二份 reset、theme 或 View shell。
|
|
119
119
|
|
|
120
120
|
## 相关页面
|
|
121
121
|
|
|
@@ -79,8 +79,8 @@ export default defineConfig({
|
|
|
79
79
|
| --- | --- | --- |
|
|
80
80
|
| `ANTHROPIC_API_KEY` | `claudeCodeAgent()` | 工厂参数 `apiKey` 可覆盖 |
|
|
81
81
|
| `ANTHROPIC_BASE_URL` | `claudeCodeAgent()` | 网关地址,工厂参数 `baseUrl` 可覆盖 |
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
82
|
+
| `CODEX_API_KEY` / `CODEX_BASE_URL` | `codexAgent()` | key 必需,代理地址可选;工厂参数 `apiKey` / `baseUrl` 可覆盖 |
|
|
83
|
+
| `BUB_API_KEY` / `BUB_API_BASE` | `bubAgent()` | 两者必需;工厂参数 `apiKey` / `apiBase` 可覆盖 |
|
|
84
84
|
| `OPENCLAW_API_KEY` / `OPENCLAW_BASE_URL` | `openClawAgent()` | key 省略时回落 `ANTHROPIC_API_KEY` |
|
|
85
85
|
| `OPENCODE_API_KEY` / `OPENCODE_BASE_URL` | `openCodeAgent()` | key 省略时回落 `ANTHROPIC_API_KEY` |
|
|
86
86
|
| `HERMES_API_KEY` / `HERMES_API_BASE` | `hermesAgent()` | key 省略时依次回落 `OPENROUTER_API_KEY`、`ANTHROPIC_API_KEY` |
|
|
@@ -38,13 +38,35 @@ GitHub Actions 的构建任务示例:
|
|
|
38
38
|
path: ./report-site
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## 用 Netlify 预览 PR 报告
|
|
42
|
+
|
|
43
|
+
Netlify 的 Git Integration 会为 Pull Request 创建 Deploy Preview。仓库只负责定义构建与输出目录,不需要另写 GitHub Actions 或保存 Netlify token。
|
|
44
|
+
|
|
45
|
+
```toml netlify.toml
|
|
46
|
+
[build]
|
|
47
|
+
publish = "report-site"
|
|
48
|
+
ignore = "exit 0"
|
|
49
|
+
|
|
50
|
+
[context.deploy-preview]
|
|
51
|
+
command = "pnpm install --frozen-lockfile && pnpm exec niceeval --version && pnpm exec niceeval view --out report-site"
|
|
52
|
+
ignore = "exit 1"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
这个默认命令使用项目 lockfile、项目默认 Report 和 project-current Sample。仓库若只想预览某组结果,可以显式加 `--experiment <selector>`。不要加 `--report` 来重复配置里的默认 Report,也不要安装 `niceeval@latest`。
|
|
56
|
+
|
|
57
|
+
在 Netlify 连接 GitHub 仓库后,关闭普通 branch deploy,并保留 Deploy Previews。`ignore` 的退出码 `0` 会跳过 production 与普通 branch build;Deploy Preview 的覆盖值 `1` 让 PR 构建继续。
|
|
58
|
+
|
|
59
|
+
Report 与 `niceeval.config.ts` 是构建期执行的 Node 代码。Deploy Preview 不应获得 Provider、Judge、GitHub 或生产环境 secrets。公开仓库还应把非团队成员的 deploy request 设为必须人工批准,并拒绝 fork 与 Dependabot 的报告预览。这个审批策略属于 Netlify 站点设置,不能交给 PR 可修改的 `netlify.toml`。
|
|
60
|
+
|
|
61
|
+
Deploy Preview URL 可能被转发。不要把含敏感内容的 Record 发布到公开预览;需要限制读者时,在 Netlify 单独配置 Preview 访问保护。PR 关闭也不等于预览已经删除,保留期与删除由站点管理员管理。
|
|
62
|
+
|
|
41
63
|
## 发布前检查
|
|
42
64
|
|
|
43
65
|
导出前,NiceEval 已验证 `pages` 中全部显式声明的普通 Page、参数 Page 实例、链接、资源、下载、`_niceeval/data/projections.json` 和预算;Host 不补建详情 route。成功目录包含 HTML、Report CSS、reload client、作者 asset、下载文件与 projections 文件,后者的 bytes 属于 revision identity;静态目录缺少 reload 端点时,client 安静停用。
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
在部署前断开网络但保持随包交付的 JavaScript 启用,打开首页和至少一个参数详情页。正文、导航、完整度、问题和下载仍应可读;再单独禁用 JavaScript,确认页面显示明确的启用提示。若本机 `view` 使用同一选择和 Report,同一路由的 HTTP body 与目录页面 body 应逐字节一致。
|
|
46
68
|
|
|
47
|
-
`--out`
|
|
69
|
+
`--out` 必须指向不存在的目录。固定 Sample 零选中结果时,命令以 `report-sample-empty` 失败且不创建目录。已选中结果中的 empty MetricValue 仍会正常呈现。更新内容时,选择新的 Sample、导出到新目录,再切换托管平台的发布版本;不要覆盖旧目录。
|
|
48
70
|
|
|
49
71
|
## 下一步
|
|
50
72
|
|
|
@@ -26,7 +26,7 @@ pnpm exec niceeval view --run <run-id> \
|
|
|
26
26
|
|
|
27
27
|
这个站点版本同时是本机 view 与静态导出的来源。同一路由的 HTTP body 和导出目录中的页面 body 逐字节相同。`--out` 不接受 `--page`,因为静态目录始终包含整个站点。
|
|
28
28
|
|
|
29
|
-
Analysis 的 `partial`、`empty`、`unsupported` 与 `failed` 是可显示的数据状态,会带着 samples、total、issues 和 refs
|
|
29
|
+
Analysis 的 `partial`、`empty`、`unsupported` 与 `failed` 是可显示的数据状态,会带着 samples、total、issues 和 refs 一起写入页面。固定 Sample 零选中结果时,导出以 `report-sample-empty` 失败且不创建目录。Page callback 失败、参数实例不合法、路径冲突、资源冲突或预算超限也会阻止导出;它们不会产生一份缺页的目录。
|
|
30
30
|
|
|
31
31
|
## 导出目录的边界
|
|
32
32
|
|
|
@@ -37,9 +37,9 @@ Analysis 的 `partial`、`empty`、`unsupported` 与 `failed` 是可显示的数
|
|
|
37
37
|
- 已关闭的 Source / Diff asset、下载文件和 `_niceeval/data/projections.json`;
|
|
38
38
|
- 站点阅读所需的导航、正文、完整度和问题内容。
|
|
39
39
|
|
|
40
|
-
目录不需要源 Record、NiceEval 安装或网络。`_niceeval/data/projections.json` 的 bytes 与页面、资源一起进入 revision identity。它携带和 view 相同的
|
|
40
|
+
目录不需要源 Record、NiceEval 安装或网络。`_niceeval/data/projections.json` 的 bytes 与页面、资源一起进入 revision identity。它携带和 view 相同的 Host runtime;静态目录不存在 view 端点时,实时刷新安静停用,不显示错误,也不发起新的 Analysis 读取。
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
在断网浏览器中保持随包交付的 JavaScript 启用,打开首页和至少一个参数页。正文、导航、详情、完整度、问题和下载仍应可读;再单独禁用 JavaScript,确认页面显示明确的启用提示而不是局部报告内容。
|
|
43
43
|
|
|
44
44
|
## 目标目录保护
|
|
45
45
|
|
|
@@ -63,4 +63,4 @@ pnpm exec niceeval view --experiment ci --out ./report-site --no-open
|
|
|
63
63
|
|
|
64
64
|
- [部署报告站](/zh/tutorials/deploy-report-site):交给静态托管服务。
|
|
65
65
|
- [查看结果](/zh/tutorials/viewing-results):理解单目标 `show` 与全站 `view` 的边界。
|
|
66
|
-
- [报告 API](/zh/reference/report-components):定义参数 Page
|
|
66
|
+
- [报告 API](/zh/reference/report-components):定义参数 Page、资源与闭合报告内容。
|
|
@@ -13,10 +13,10 @@ Sandbox agent 会在隔离环境中启动 coding-agent CLI,给它 workspace
|
|
|
13
13
|
运行 Anthropic Claude Code CLI,需要 `ANTHROPIC_API_KEY`。
|
|
14
14
|
</Card>
|
|
15
15
|
<Card title="codex" icon="terminal">
|
|
16
|
-
运行 OpenAI Codex CLI,需要 `
|
|
16
|
+
运行 OpenAI Codex CLI,需要 `CODEX_API_KEY`。
|
|
17
17
|
</Card>
|
|
18
18
|
<Card title="bub" icon="robot">
|
|
19
|
-
运行 bub coding agent,需要 `
|
|
19
|
+
运行 bub coding agent,需要 `BUB_API_KEY` 与 `BUB_API_BASE`。
|
|
20
20
|
</Card>
|
|
21
21
|
</CardGroup>
|
|
22
22
|
|
|
@@ -95,10 +95,10 @@ export default defineExperiment({
|
|
|
95
95
|
| Agent | 必需变量 |
|
|
96
96
|
|---|---|
|
|
97
97
|
| `claude-code` | `ANTHROPIC_API_KEY` |
|
|
98
|
-
| `codex` | `
|
|
99
|
-
| `bub` | `
|
|
98
|
+
| `codex` | `CODEX_API_KEY` |
|
|
99
|
+
| `bub` | `BUB_API_KEY`、`BUB_API_BASE` |
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
这些是各 Agent 的官方变量名。CI 可以只保存一组共享凭据,但要在 Experiment 中通过 `apiKey`、`baseUrl` 或 `apiBase` 显式传入,不会改变 Adapter 读取的变量名。
|
|
102
102
|
|
|
103
103
|
## 工作流程
|
|
104
104
|
|