niceeval 0.13.1 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INDEX.md +25 -2
- package/README.md +9 -10
- package/README.zh.md +9 -10
- package/dist/agents/ai-sdk.cjs.map +1 -1
- package/dist/agents/ai-sdk.d.cts +1 -1
- package/dist/agents/ai-sdk.d.mts +1 -1
- package/dist/agents/ai-sdk.d.ts +1 -1
- package/dist/agents/bub-install-spec.cjs +19 -5
- package/dist/agents/bub-install-spec.cjs.map +1 -1
- package/dist/agents/bub-install-spec.d.cts +9 -2
- package/dist/agents/bub-install-spec.d.mts +9 -2
- package/dist/agents/bub-install-spec.d.ts +9 -2
- package/dist/agents/bub-install-spec.js +14 -12
- package/dist/agents/bub.cjs +10 -6
- 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/claude-code.cjs.map +1 -1
- package/dist/agents/claude-code.d.cts +2 -2
- package/dist/agents/claude-code.d.mts +2 -2
- package/dist/agents/claude-code.d.ts +2 -2
- 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/coding-cli-versions.cjs +10 -1
- package/dist/agents/coding-cli-versions.cjs.map +1 -1
- package/dist/agents/coding-cli-versions.d.cts +8 -3
- package/dist/agents/coding-cli-versions.d.mts +8 -3
- package/dist/agents/coding-cli-versions.d.ts +8 -3
- package/dist/agents/coding-cli-versions.js +18 -12
- package/dist/agents/deepseek-harness.cjs +151 -0
- package/dist/agents/deepseek-harness.cjs.map +1 -0
- package/dist/agents/deepseek-harness.d.cts +14 -0
- package/dist/agents/deepseek-harness.d.mts +14 -0
- package/dist/agents/deepseek-harness.d.ts +14 -0
- package/dist/agents/deepseek-harness.js +7 -0
- package/dist/agents/deepseek-harness.js.map +1 -0
- package/dist/agents/exact-npm-plugins.cjs +28 -0
- package/dist/agents/exact-npm-plugins.cjs.map +1 -0
- package/dist/agents/exact-npm-plugins.d.cts +10 -0
- package/dist/agents/exact-npm-plugins.d.mts +10 -0
- package/dist/agents/exact-npm-plugins.d.ts +10 -0
- package/dist/agents/exact-npm-plugins.js +8 -0
- package/dist/agents/exact-npm-plugins.js.map +1 -0
- package/dist/agents/index.cjs +5 -1
- package/dist/agents/index.cjs.map +1 -1
- package/dist/agents/index.d.cts +4 -0
- package/dist/agents/index.d.mts +4 -0
- package/dist/agents/index.d.ts +4 -0
- package/dist/agents/index.js +54 -50
- package/dist/agents/index.mjs +54 -50
- package/dist/agents/omp.cjs +170 -0
- package/dist/agents/omp.cjs.map +1 -0
- package/dist/agents/omp.d.cts +14 -0
- package/dist/agents/omp.d.mts +14 -0
- package/dist/agents/omp.d.ts +14 -0
- package/dist/agents/omp.js +7 -0
- package/dist/agents/omp.js.map +1 -0
- package/dist/agents/openclaw.cjs +51 -2
- package/dist/agents/openclaw.cjs.map +1 -1
- package/dist/agents/openclaw.d.cts +2 -0
- package/dist/agents/openclaw.d.mts +2 -0
- package/dist/agents/openclaw.d.ts +2 -0
- package/dist/agents/types.cjs.map +1 -1
- package/dist/agents/types.d.cts +4 -4
- package/dist/agents/types.d.mts +4 -4
- package/dist/agents/types.d.ts +4 -4
- package/dist/agents/ui-message-stream.cjs +24 -7
- package/dist/agents/ui-message-stream.cjs.map +1 -1
- package/dist/analysis/api.cjs +28 -2
- package/dist/analysis/api.cjs.map +1 -1
- package/dist/analysis/api.d.cts +22 -1
- package/dist/analysis/api.d.mts +22 -1
- package/dist/analysis/api.d.ts +22 -1
- package/dist/analysis/api.js +8 -6
- package/dist/analysis/bindings.cjs +11 -18
- package/dist/analysis/bindings.cjs.map +1 -1
- package/dist/analysis/bindings.d.cts +177 -49
- package/dist/analysis/bindings.d.mts +177 -49
- package/dist/analysis/bindings.d.ts +177 -49
- package/dist/analysis/contracts.cjs +1 -0
- package/dist/analysis/contracts.cjs.map +1 -1
- package/dist/analysis/contracts.d.cts +43 -3
- package/dist/analysis/contracts.d.mts +43 -3
- package/dist/analysis/contracts.d.ts +43 -3
- package/dist/analysis/cost-projection.cjs +2 -1
- package/dist/analysis/cost-projection.cjs.map +1 -1
- package/dist/analysis/cost-projection.d.cts +1 -1
- package/dist/analysis/cost-projection.d.mts +1 -1
- package/dist/analysis/cost-projection.d.ts +1 -1
- package/dist/analysis/cost.cjs +13 -3
- package/dist/analysis/cost.cjs.map +1 -1
- package/dist/analysis/cost.d.cts +10 -3
- package/dist/analysis/cost.d.mts +10 -3
- package/dist/analysis/cost.d.ts +10 -3
- package/dist/analysis/experiment-groups.cjs +96 -0
- package/dist/analysis/experiment-groups.cjs.map +1 -0
- package/dist/analysis/experiment-groups.d.cts +9 -0
- package/dist/analysis/experiment-groups.d.mts +9 -0
- package/dist/analysis/experiment-groups.d.ts +9 -0
- package/dist/analysis/experiment-groups.js +10 -0
- package/dist/analysis/experiment-groups.js.map +1 -0
- package/dist/analysis/index.cjs +4 -1
- package/dist/analysis/index.cjs.map +1 -1
- package/dist/analysis/index.d.cts +4 -2
- package/dist/analysis/index.d.mts +4 -2
- package/dist/analysis/index.d.ts +4 -2
- package/dist/analysis/index.js +40 -36
- package/dist/analysis/index.mjs +40 -36
- package/dist/assertions/limits.cjs +4 -0
- package/dist/assertions/limits.cjs.map +1 -1
- package/dist/assertions/limits.d.cts +4 -0
- package/dist/assertions/limits.d.mts +4 -0
- package/dist/assertions/limits.d.ts +4 -0
- package/dist/assertions/match.cjs +63 -25
- package/dist/assertions/match.cjs.map +1 -1
- package/dist/assertions/match.d.cts +7 -0
- package/dist/assertions/match.d.mts +7 -0
- package/dist/assertions/match.d.ts +7 -0
- package/dist/assertions/record/attachment.cjs +32 -4
- package/dist/assertions/record/attachment.cjs.map +1 -1
- package/dist/assertions/record/diff.cjs +10 -4
- package/dist/assertions/record/diff.cjs.map +1 -1
- package/dist/assertions/record/producer.cjs +101 -4
- package/dist/assertions/record/producer.cjs.map +1 -1
- package/dist/assertions/record/producer.d.cts +4 -1
- package/dist/assertions/record/producer.d.mts +4 -1
- package/dist/assertions/record/producer.d.ts +4 -1
- package/dist/assertions/runtime.cjs +45 -5
- package/dist/assertions/runtime.cjs.map +1 -1
- package/dist/cli/record.cjs +113 -8
- package/dist/cli/record.cjs.map +1 -1
- package/dist/cli/record.d.cts +20 -1
- package/dist/cli/record.d.mts +20 -1
- package/dist/cli/record.d.ts +20 -1
- package/dist/cli/record.js +4 -2
- package/dist/cli.cjs +386 -31
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +10 -2
- package/dist/cli.d.mts +10 -2
- package/dist/cli.d.ts +10 -2
- package/dist/context/send-retry.cjs +4 -4
- package/dist/context/send-retry.cjs.map +1 -1
- package/dist/coordination/host/runtime.cjs +8 -30
- package/dist/coordination/host/runtime.cjs.map +1 -1
- package/dist/coordination/host/runtime.d.cts +3 -3
- package/dist/coordination/host/runtime.d.mts +3 -3
- package/dist/coordination/host/runtime.d.ts +3 -3
- package/dist/coordination/host/types.cjs.map +1 -1
- package/dist/coordination/host/types.d.cts +0 -5
- package/dist/coordination/host/types.d.mts +0 -5
- package/dist/coordination/host/types.d.ts +0 -5
- package/dist/coordination/platform/node.cjs +90 -9
- package/dist/coordination/platform/node.cjs.map +1 -1
- package/dist/define.cjs +25 -1
- package/dist/define.cjs.map +1 -1
- package/dist/experiment/host/index.cjs +1 -0
- package/dist/experiment/host/index.cjs.map +1 -1
- package/dist/i18n/en.cjs +26 -8
- package/dist/i18n/en.cjs.map +1 -1
- package/dist/i18n/en.d.cts +19 -6
- package/dist/i18n/en.d.mts +19 -6
- package/dist/i18n/en.d.ts +19 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/o11y/parsers/hermes.cjs +1 -1
- package/dist/o11y/parsers/hermes.cjs.map +1 -1
- package/dist/o11y/prices.json +1 -1
- package/dist/o11y/record/families.cjs +12 -3
- package/dist/o11y/record/families.cjs.map +1 -1
- package/dist/o11y/record/families.d.cts +8 -8
- package/dist/o11y/record/families.d.mts +8 -8
- package/dist/o11y/record/families.d.ts +8 -8
- package/dist/o11y/record/family-projectors.d.cts +66 -18
- package/dist/o11y/record/family-projectors.d.mts +66 -18
- package/dist/o11y/record/family-projectors.d.ts +66 -18
- package/dist/o11y/record/family-writers.d.cts +11 -3
- package/dist/o11y/record/family-writers.d.mts +11 -3
- package/dist/o11y/record/family-writers.d.ts +11 -3
- package/dist/o11y/record/runner-producer.cjs +14 -4
- package/dist/o11y/record/runner-producer.cjs.map +1 -1
- package/dist/record/codec/core.d.cts +2 -2
- package/dist/record/codec/core.d.mts +2 -2
- package/dist/record/codec/core.d.ts +2 -2
- package/dist/record/family/catalog.d.cts +44 -12
- package/dist/record/family/catalog.d.mts +44 -12
- package/dist/record/family/catalog.d.ts +44 -12
- package/dist/record/family/index.js +128 -124
- package/dist/record/family/observability-v1.cjs +35 -0
- package/dist/record/family/observability-v1.cjs.map +1 -0
- package/dist/record/family/observability-v1.d.cts +3 -0
- package/dist/record/family/observability-v1.d.mts +3 -0
- package/dist/record/family/observability-v1.d.ts +3 -0
- package/dist/record/family/observability-v1.js +6 -0
- package/dist/record/family/observability-v1.js.map +1 -0
- package/dist/record/family/observability.cjs +58 -9
- package/dist/record/family/observability.cjs.map +1 -1
- package/dist/record/family/observability.d.cts +1014 -15
- package/dist/record/family/observability.d.mts +1014 -15
- package/dist/record/family/observability.d.ts +1014 -15
- package/dist/record/family/observability.js +22 -18
- package/dist/record/host/runtime.cjs +600 -31
- 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 +33 -9
- package/dist/record/host/types.d.mts +33 -9
- package/dist/record/host/types.d.ts +33 -9
- package/dist/record/maintenance/runtime.cjs +1 -2
- package/dist/record/maintenance/runtime.cjs.map +1 -1
- package/dist/record/model/core.cjs.map +1 -1
- package/dist/record/model/core.d.cts +1 -1
- package/dist/record/model/core.d.mts +1 -1
- package/dist/record/model/core.d.ts +1 -1
- package/dist/record/model/definition.d.cts +6 -6
- package/dist/record/model/definition.d.mts +6 -6
- package/dist/record/model/definition.d.ts +6 -6
- package/dist/record/model/identifiers.cjs +1 -1
- package/dist/record/model/identifiers.cjs.map +1 -1
- package/dist/record/model/identifiers.d.cts +1 -1
- package/dist/record/model/identifiers.d.mts +1 -1
- package/dist/record/model/identifiers.d.ts +1 -1
- package/dist/record/platform/node.cjs +159 -23
- 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 +15 -2
- package/dist/record/platform/services.d.mts +15 -2
- package/dist/record/platform/services.d.ts +15 -2
- package/dist/record/reader/errors.cjs +37 -1
- package/dist/record/reader/errors.cjs.map +1 -1
- package/dist/record/reader/errors.d.cts +49 -1
- package/dist/record/reader/errors.d.mts +49 -1
- package/dist/record/reader/errors.d.ts +49 -1
- package/dist/record/reader/errors.js +22 -12
- package/dist/record/reader/format.cjs +76 -17
- package/dist/record/reader/format.cjs.map +1 -1
- package/dist/record/reader/format.d.cts +11 -4
- package/dist/record/reader/format.d.mts +11 -4
- package/dist/record/reader/format.d.ts +11 -4
- package/dist/record/reader/format.js +2 -0
- package/dist/record/reader/index.js +32 -18
- package/dist/record/reader/runtime.cjs +64 -0
- package/dist/record/reader/runtime.cjs.map +1 -1
- package/dist/record/reader/runtime.d.cts +15 -0
- package/dist/record/reader/runtime.d.mts +15 -0
- package/dist/record/reader/runtime.d.ts +15 -0
- package/dist/record/reader/runtime.js +2 -0
- package/dist/report/assets/styles.css +53 -29
- package/dist/report/built-in/analysis-values.cjs +21 -13
- package/dist/report/built-in/analysis-values.cjs.map +1 -1
- package/dist/report/built-in/analysis-values.d.cts +11 -22
- package/dist/report/built-in/analysis-values.d.mts +11 -22
- package/dist/report/built-in/analysis-values.d.ts +11 -22
- package/dist/report/built-in/analysis-values.js +4 -6
- package/dist/report/built-in/index.cjs +1 -3
- package/dist/report/built-in/index.cjs.map +1 -1
- package/dist/report/built-in/index.d.cts +1 -1
- package/dist/report/built-in/index.d.mts +1 -1
- package/dist/report/built-in/index.d.ts +1 -1
- package/dist/report/built-in/index.js +4 -8
- package/dist/report/built-in/index.mjs +4 -8
- package/dist/report/built-in/machine.cjs +0 -2
- package/dist/report/built-in/machine.cjs.map +1 -1
- package/dist/report/built-in/machine.d.cts +0 -2
- package/dist/report/built-in/machine.d.mts +0 -2
- package/dist/report/built-in/machine.d.ts +0 -2
- package/dist/report/built-in/result-components.cjs +49 -51
- package/dist/report/built-in/result-components.cjs.map +1 -1
- package/dist/report/built-in/result-components.d.cts +16 -17
- package/dist/report/built-in/result-components.d.mts +16 -17
- package/dist/report/built-in/result-components.d.ts +16 -17
- package/dist/report/built-in/result-components.js +0 -4
- package/dist/report/built-in/run-membership-overview.cjs +126 -17
- package/dist/report/built-in/run-membership-overview.cjs.map +1 -1
- package/dist/report/built-in/run-membership-overview.d.cts +14 -0
- package/dist/report/built-in/run-membership-overview.d.mts +14 -0
- package/dist/report/built-in/run-membership-overview.d.ts +14 -0
- package/dist/report/built-in/run-membership-overview.js +4 -2
- package/dist/report/built-in/standard.cjs +80 -45
- package/dist/report/built-in/standard.cjs.map +1 -1
- package/dist/report/built-in/standard.d.cts +19 -41
- package/dist/report/built-in/standard.d.mts +19 -41
- package/dist/report/built-in/standard.d.ts +19 -41
- package/dist/report/built-in/standard.js +6 -6
- package/dist/report/components/attempt-detail/compute.cjs +78 -2
- package/dist/report/components/attempt-detail/compute.cjs.map +1 -1
- package/dist/report/components/attempt-detail/compute.d.cts +1 -1
- package/dist/report/components/attempt-detail/compute.d.mts +1 -1
- package/dist/report/components/attempt-detail/compute.d.ts +1 -1
- package/dist/report/components/attempt-detail/content.cjs +1 -1
- package/dist/report/components/attempt-detail/content.cjs.map +1 -1
- package/dist/report/components/entity-lists/compute.cjs +42 -5
- package/dist/report/components/entity-lists/compute.cjs.map +1 -1
- package/dist/report/components/entity-lists/compute.d.cts +10 -8
- package/dist/report/components/entity-lists/compute.d.mts +10 -8
- package/dist/report/components/entity-lists/compute.d.ts +10 -8
- package/dist/report/components/entity-lists/content.cjs +31 -6
- package/dist/report/components/entity-lists/content.cjs.map +1 -1
- package/dist/report/components/entity-lists/index.cjs +9 -4
- package/dist/report/components/entity-lists/index.cjs.map +1 -1
- package/dist/report/components/entity-lists/index.d.cts +4 -7
- package/dist/report/components/entity-lists/index.d.mts +4 -7
- package/dist/report/components/entity-lists/index.d.ts +4 -7
- package/dist/report/components/summaries/compute.cjs +8 -1
- package/dist/report/components/summaries/compute.cjs.map +1 -1
- package/dist/report/components/summaries/compute.d.cts +9 -1
- package/dist/report/components/summaries/compute.d.mts +9 -1
- package/dist/report/components/summaries/compute.d.ts +9 -1
- package/dist/report/components/summaries/index.cjs +48 -4
- package/dist/report/components/summaries/index.cjs.map +1 -1
- package/dist/report/components/summaries/index.d.cts +7 -4
- package/dist/report/components/summaries/index.d.mts +7 -4
- package/dist/report/components/summaries/index.d.ts +7 -4
- package/dist/report/definition/cell.cjs +3 -0
- package/dist/report/definition/cell.cjs.map +1 -1
- package/dist/report/definition/cell.d.cts +2 -0
- package/dist/report/definition/cell.d.mts +2 -0
- package/dist/report/definition/cell.d.ts +2 -0
- package/dist/report/definition/primitives/chart.cjs +8 -5
- package/dist/report/definition/primitives/chart.cjs.map +1 -1
- package/dist/report/definition/primitives/points-dataset.cjs +1 -0
- package/dist/report/definition/primitives/points-dataset.cjs.map +1 -1
- package/dist/report/definition/primitives.cjs +15 -2
- package/dist/report/definition/primitives.cjs.map +1 -1
- package/dist/report/definition/report.cjs +27 -3
- package/dist/report/definition/report.cjs.map +1 -1
- package/dist/report/definition/report.d.cts +8 -0
- package/dist/report/definition/report.d.mts +8 -0
- package/dist/report/definition/report.d.ts +8 -0
- package/dist/report/execution/machine.cjs +30 -14
- package/dist/report/execution/machine.cjs.map +1 -1
- package/dist/report/execution/machine.d.cts +20 -10
- package/dist/report/execution/machine.d.mts +20 -10
- package/dist/report/execution/machine.d.ts +20 -10
- package/dist/report/execution/machine.js +6 -6
- package/dist/report/host/execute.cjs +25 -16
- package/dist/report/host/execute.cjs.map +1 -1
- package/dist/report/host/execute.d.cts +4 -0
- package/dist/report/host/execute.d.mts +4 -0
- package/dist/report/host/execute.d.ts +4 -0
- package/dist/report/host/from-record.cjs +22 -5
- package/dist/report/host/from-record.cjs.map +1 -1
- package/dist/report/host/machine.cjs +53 -11
- package/dist/report/host/machine.cjs.map +1 -1
- package/dist/report/host/site-runtime.cjs +9 -8
- package/dist/report/host/site-runtime.cjs.map +1 -1
- package/dist/report/host/site-runtime.d.cts +1 -1
- package/dist/report/host/site-runtime.d.mts +1 -1
- package/dist/report/host/site-runtime.d.ts +1 -1
- package/dist/report/host/static.cjs +56 -9
- package/dist/report/host/static.cjs.map +1 -1
- package/dist/report/index.cjs.map +1 -1
- package/dist/report/index.d.cts +1 -1
- package/dist/report/index.d.mts +1 -1
- package/dist/report/index.d.ts +1 -1
- package/dist/report/model/dataset.cjs +7 -2
- package/dist/report/model/dataset.cjs.map +1 -1
- package/dist/report/model/locale.cjs +2 -0
- package/dist/report/model/locale.cjs.map +1 -1
- package/dist/report/model/locale.d.cts +1 -0
- package/dist/report/model/locale.d.mts +1 -0
- package/dist/report/model/locale.d.ts +1 -0
- package/dist/report/model/metrics.cjs +3 -1
- package/dist/report/model/metrics.cjs.map +1 -1
- package/dist/report/model/pricing.cjs +16 -11
- package/dist/report/model/pricing.cjs.map +1 -1
- package/dist/report/react/styles.css +53 -29
- package/dist/runner/adoption.cjs +1 -0
- package/dist/runner/adoption.cjs.map +1 -1
- package/dist/runner/attempt.cjs +44 -5
- package/dist/runner/attempt.cjs.map +1 -1
- package/dist/runner/attempt.d.cts +13 -1
- package/dist/runner/attempt.d.mts +13 -1
- package/dist/runner/attempt.d.ts +13 -1
- package/dist/runner/config-identity.cjs +10 -2
- package/dist/runner/config-identity.cjs.map +1 -1
- package/dist/runner/config-identity.d.cts +4 -2
- package/dist/runner/config-identity.d.mts +4 -2
- package/dist/runner/config-identity.d.ts +4 -2
- package/dist/runner/feedback/human.cjs +298 -59
- package/dist/runner/feedback/human.cjs.map +1 -1
- package/dist/runner/feedback/json.cjs +14 -6
- package/dist/runner/feedback/json.cjs.map +1 -1
- package/dist/runner/feedback/json.d.cts +3 -2
- package/dist/runner/feedback/json.d.mts +3 -2
- package/dist/runner/feedback/json.d.ts +3 -2
- package/dist/runner/feedback/reducer.cjs +2 -0
- package/dist/runner/feedback/reducer.cjs.map +1 -1
- package/dist/runner/judge-config.cjs +1 -1
- package/dist/runner/judge-config.cjs.map +1 -1
- package/dist/runner/ledger.cjs +124 -12
- package/dist/runner/ledger.cjs.map +1 -1
- package/dist/runner/project-current.cjs +13 -5
- package/dist/runner/project-current.cjs.map +1 -1
- package/dist/runner/run.cjs +564 -256
- package/dist/runner/run.cjs.map +1 -1
- package/dist/runner/sandbox-pool.cjs +161 -30
- package/dist/runner/sandbox-pool.cjs.map +1 -1
- package/dist/runner/sandbox-pool.d.cts +34 -2
- package/dist/runner/sandbox-pool.d.mts +34 -2
- package/dist/runner/sandbox-pool.d.ts +34 -2
- package/dist/runner/shared-state-lease.cjs +803 -0
- package/dist/runner/shared-state-lease.cjs.map +1 -0
- package/dist/runner/shared-state-lease.d.cts +121 -0
- package/dist/runner/shared-state-lease.d.mts +121 -0
- package/dist/runner/shared-state-lease.d.ts +121 -0
- package/dist/runner/shared-state-lease.js +24 -0
- package/dist/runner/shared-state-lease.js.map +1 -0
- package/dist/runner/teardown-registry.cjs +97 -34
- package/dist/runner/teardown-registry.cjs.map +1 -1
- package/dist/runner/teardown-registry.d.cts +27 -1
- package/dist/runner/teardown-registry.d.mts +27 -1
- package/dist/runner/teardown-registry.d.ts +27 -1
- package/dist/runner/teardown-registry.js +20 -16
- package/dist/runner/types.cjs.map +1 -1
- package/dist/runner/types.d.cts +31 -5
- package/dist/runner/types.d.mts +31 -5
- package/dist/runner/types.d.ts +31 -5
- package/dist/sample/analysis.cjs +249 -459
- package/dist/sample/analysis.cjs.map +1 -1
- package/dist/sample/capability.cjs +138 -7
- package/dist/sample/capability.cjs.map +1 -1
- package/dist/sample/capability.d.cts +3 -1
- package/dist/sample/capability.d.mts +3 -1
- package/dist/sample/capability.d.ts +3 -1
- package/dist/sample/capability.js +8 -6
- package/dist/sandbox/docker-agent-image.cjs +5 -1
- package/dist/sandbox/docker-agent-image.cjs.map +1 -1
- package/dist/sandbox/docker-agent-image.d.cts +2 -0
- package/dist/sandbox/docker-agent-image.d.mts +2 -0
- package/dist/sandbox/docker-agent-image.d.ts +2 -0
- package/dist/sandbox/docker-agent-image.js +14 -10
- package/dist/sandbox/docker-profile/schema.cjs +283 -534
- package/dist/sandbox/docker-profile/schema.cjs.map +1 -1
- package/dist/sandbox/docker-profile/schema.d.cts +10 -27
- package/dist/sandbox/docker-profile/schema.d.mts +10 -27
- package/dist/sandbox/docker-profile/schema.d.ts +10 -27
- package/dist/sandbox/e2b-agent-template.cjs +5 -2
- package/dist/sandbox/e2b-agent-template.cjs.map +1 -1
- package/dist/sandbox/index.cjs +4 -2
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.d.cts +1 -1
- package/dist/sandbox/index.d.mts +1 -1
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +120 -116
- package/dist/sandbox/index.mjs +120 -116
- package/dist/sandbox/keep-registry.cjs +28 -66
- package/dist/sandbox/keep-registry.cjs.map +1 -1
- package/dist/sandbox/types.cjs.map +1 -1
- package/dist/sandbox/types.d.cts +1 -1
- package/dist/sandbox/types.d.mts +1 -1
- package/dist/sandbox/types.d.ts +1 -1
- package/dist/shared/aggregate.cjs +16 -6
- package/dist/shared/aggregate.cjs.map +1 -1
- package/dist/shared/aggregate.d.cts +12 -4
- package/dist/shared/aggregate.d.mts +12 -4
- package/dist/shared/aggregate.d.ts +12 -4
- package/dist/shared/turn-label.cjs +20 -2
- package/dist/shared/turn-label.cjs.map +1 -1
- package/dist/shared/turn-label.d.cts +2 -0
- package/dist/shared/turn-label.d.mts +2 -0
- package/dist/shared/turn-label.d.ts +2 -0
- package/dist/shared/turn-label.js +4 -2
- package/dist/vendor/remark/remark-gfm.cjs +7 -7
- package/dist/vendor/remark/remark-gfm.cjs.map +1 -1
- package/dist/vendor/remark/remark-parse.cjs +12 -12
- package/dist/vendor/remark/remark-parse.cjs.map +1 -1
- package/dist/vendor/remark/remark.cjs +13 -13
- package/dist/vendor/remark/remark.cjs.map +1 -1
- package/dist/view/server.cjs +6 -0
- package/dist/view/server.cjs.map +1 -1
- package/docs-site/images/hitl-handshake-zh.svg +3 -3
- package/docs-site/zh/examples/ai-agent-application.mdx +1 -1
- package/docs-site/zh/examples/coding-agent-extensions.mdx +1 -1
- package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +4 -3
- package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
- package/docs-site/zh/examples/integrations/codex-sdk.mdx +5 -5
- package/docs-site/zh/examples/integrations/langgraph.mdx +4 -4
- package/docs-site/zh/examples/integrations/pi-sdk.mdx +5 -5
- package/docs-site/zh/explanation/adapter.mdx +5 -5
- package/docs-site/zh/explanation/assert.mdx +7 -7
- package/docs-site/zh/explanation/drive.mdx +4 -2
- package/docs-site/zh/explanation/evals.mdx +10 -8
- package/docs-site/zh/explanation/experiment.mdx +2 -2
- package/docs-site/zh/explanation/hitl.mdx +9 -9
- package/docs-site/zh/explanation/judge.mdx +5 -5
- package/docs-site/zh/explanation/overview.mdx +3 -3
- package/docs-site/zh/explanation/runner.mdx +1 -1
- package/docs-site/zh/index.mdx +3 -3
- package/docs-site/zh/reference/builtin-agents.mdx +13 -13
- package/docs-site/zh/reference/capabilities.mdx +1 -1
- package/docs-site/zh/reference/cli.mdx +18 -12
- package/docs-site/zh/reference/define-agent.mdx +130 -5
- package/docs-site/zh/reference/define-config.mdx +2 -2
- package/docs-site/zh/reference/define-eval.mdx +4 -4
- package/docs-site/zh/reference/events.mdx +11 -11
- package/docs-site/zh/reference/official-adapters.mdx +6 -6
- package/docs-site/zh/reference/results-data.mdx +6 -0
- package/docs-site/zh/troubleshooting/debugging.mdx +1 -1
- package/docs-site/zh/troubleshooting/recover-after-kill.mdx +37 -5
- package/docs-site/zh/tutorials/accept-results.mdx +72 -0
- package/docs-site/zh/tutorials/agent-onboarding.mdx +6 -6
- package/docs-site/zh/tutorials/authoring.mdx +9 -13
- package/docs-site/zh/tutorials/ci-integration.mdx +6 -6
- package/docs-site/zh/tutorials/compare-runs.mdx +61 -0
- package/docs-site/zh/tutorials/concurrency.mdx +13 -12
- package/docs-site/zh/tutorials/configuration.mdx +4 -6
- package/docs-site/zh/tutorials/connect-your-agent.mdx +1 -1
- package/docs-site/zh/tutorials/control-run-cost.mdx +58 -0
- package/docs-site/zh/tutorials/criteria-files.mdx +2 -2
- package/docs-site/zh/tutorials/custom-reports.mdx +2 -2
- package/docs-site/zh/tutorials/debug-lifecycle-plan.mdx +46 -0
- package/docs-site/zh/tutorials/docker-in-docker.mdx +52 -43
- package/docs-site/zh/tutorials/eval-groups.mdx +6 -6
- package/docs-site/zh/tutorials/evaluation-kinds.mdx +3 -3
- package/docs-site/zh/tutorials/experiments.mdx +2 -3
- package/docs-site/zh/tutorials/handle-execution-failures.mdx +18 -10
- package/docs-site/zh/tutorials/install-custom-sandbox-agent.mdx +16 -8
- package/docs-site/zh/tutorials/nixos-managed-dind.mdx +160 -0
- package/docs-site/zh/tutorials/plugins.mdx +14 -0
- package/docs-site/zh/tutorials/rerun-and-cache.mdx +4 -2
- package/docs-site/zh/tutorials/sandbox-agent.mdx +17 -11
- package/docs-site/zh/tutorials/sandbox-providers.mdx +17 -13
- package/docs-site/zh/tutorials/sandbox-reuse.mdx +12 -19
- package/docs-site/zh/tutorials/select-and-preview.mdx +65 -0
- package/docs-site/zh/tutorials/verify-judge.mdx +78 -0
- package/docs-site/zh/tutorials/viewing-results.mdx +38 -1
- package/docs-site/zh/tutorials/write-experiment.mdx +7 -5
- package/docs-site/zh/tutorials/write-send.mdx +9 -8
- package/package.json +9 -5
- package/dist/report/built-in/overview.cjs +0 -44
- package/dist/report/built-in/overview.cjs.map +0 -1
- package/dist/report/built-in/overview.d.cts +0 -6
- package/dist/report/built-in/overview.d.mts +0 -6
- package/dist/report/built-in/overview.d.ts +0 -6
- package/dist/report/built-in/overview.js +0 -9
- package/dist/report/built-in/overview.js.map +0 -1
- package/dist/runner/gate-lease.cjs +0 -283
- package/dist/runner/gate-lease.cjs.map +0 -1
- package/dist/runner/gate-lease.d.cts +0 -62
- package/dist/runner/gate-lease.d.mts +0 -62
- package/dist/runner/gate-lease.d.ts +0 -62
- package/dist/runner/gate-lease.js +0 -22
- package/dist/runner/gate-lease.js.map +0 -1
|
@@ -4,6 +4,8 @@ exports.teardownsDirOf = teardownsDirOf;
|
|
|
4
4
|
exports.teardownEntryId = teardownEntryId;
|
|
5
5
|
exports.writeTeardownRegistrationEffect = writeTeardownRegistrationEffect;
|
|
6
6
|
exports.readTeardownRegistrationEffect = readTeardownRegistrationEffect;
|
|
7
|
+
exports.readExactTeardownRegistrationEffect = readExactTeardownRegistrationEffect;
|
|
8
|
+
exports.isExactTeardownRegistrationOwnerTerminatedEffect = isExactTeardownRegistrationOwnerTerminatedEffect;
|
|
7
9
|
exports.readTeardownRegistrationsEffect = readTeardownRegistrationsEffect;
|
|
8
10
|
exports.removeTeardownRegistrationIfPresentEffect = removeTeardownRegistrationIfPresentEffect;
|
|
9
11
|
exports.isOrphanedTeardownRegistration = isOrphanedTeardownRegistration;
|
|
@@ -12,41 +14,36 @@ exports.orphanedTeardownReminderEffect = orphanedTeardownReminderEffect;
|
|
|
12
14
|
// (sandbox/keep-registry.ts)同一套原子写纪律,两者都建在 shared/entry-file-store.ts 之上
|
|
13
15
|
// (temp → fsync → rename → fsync 目录)。
|
|
14
16
|
// 契约见 docs/feature/experiments/architecture.md「强杀后的收尾兜底:收尾登记与启动自愈」。
|
|
17
|
+
const node_fs_1 = require("node:fs");
|
|
18
|
+
const promises_1 = require("node:fs/promises");
|
|
15
19
|
const node_path_1 = require("node:path");
|
|
16
20
|
const effect_1 = require("effect");
|
|
17
21
|
const entry_file_store_ts_1 = require("../shared/entry-file-store.cjs");
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
const shared_state_lease_ts_1 = require("./shared-state-lease.cjs");
|
|
23
|
+
const PositiveSafeIntegerSchema = effect_1.Schema.Number.pipe(effect_1.Schema.filter((value) => Number.isSafeInteger(value) && value > 0, { identifier: "PositiveSafeInteger" }));
|
|
24
|
+
const TimestampSchema = effect_1.Schema.String.pipe(effect_1.Schema.filter((value) => Number.isFinite(Date.parse(value)), { identifier: "Timestamp" }));
|
|
25
|
+
const TeardownRegistrationSchema = effect_1.Schema.Struct({
|
|
26
|
+
experimentId: effect_1.Schema.String,
|
|
27
|
+
selectedEvalIds: effect_1.Schema.Array(effect_1.Schema.String),
|
|
28
|
+
pid: PositiveSafeIntegerSchema,
|
|
29
|
+
host: effect_1.Schema.String,
|
|
30
|
+
startedAt: TimestampSchema,
|
|
31
|
+
});
|
|
32
|
+
function errnoCode(cause) {
|
|
33
|
+
return typeof cause === "object" && cause !== null && "code" in cause && typeof cause.code === "string"
|
|
34
|
+
? cause.code
|
|
21
35
|
: undefined;
|
|
22
36
|
}
|
|
23
|
-
function isPositiveInteger(value) {
|
|
24
|
-
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
25
|
-
}
|
|
26
|
-
function isTimestamp(value) {
|
|
27
|
-
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
28
|
-
}
|
|
29
37
|
/** 收尾登记的完整持久形状;单条读取还会核对文件身份。 */
|
|
30
38
|
function decodeTeardownRegistration(value, expected = {}) {
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
33
|
-
typeof record.experimentId !== "string" ||
|
|
34
|
-
!Array.isArray(record.selectedEvalIds) ||
|
|
35
|
-
!record.selectedEvalIds.every((id) => typeof id === "string") ||
|
|
36
|
-
!isPositiveInteger(record.pid) ||
|
|
37
|
-
typeof record.host !== "string" ||
|
|
38
|
-
!isTimestamp(record.startedAt) ||
|
|
39
|
-
(expected.experimentId !== undefined && record.experimentId !== expected.experimentId) ||
|
|
40
|
-
(expected.pid !== undefined && record.pid !== expected.pid)) {
|
|
39
|
+
const decoded = effect_1.Schema.decodeUnknownEither(TeardownRegistrationSchema)(value);
|
|
40
|
+
if (effect_1.Either.isLeft(decoded))
|
|
41
41
|
return undefined;
|
|
42
|
-
|
|
43
|
-
return
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
host: record.host,
|
|
48
|
-
startedAt: record.startedAt,
|
|
49
|
-
};
|
|
42
|
+
const registration = decoded.right;
|
|
43
|
+
return (expected.experimentId !== undefined && registration.experimentId !== expected.experimentId) ||
|
|
44
|
+
(expected.pid !== undefined && registration.pid !== expected.pid)
|
|
45
|
+
? undefined
|
|
46
|
+
: registration;
|
|
50
47
|
}
|
|
51
48
|
function teardownsDirOf(niceevalRoot) {
|
|
52
49
|
return (0, node_path_1.join)(niceevalRoot, "teardowns");
|
|
@@ -64,6 +61,54 @@ function writeTeardownRegistrationEffect(niceevalRoot, entry) {
|
|
|
64
61
|
function readTeardownRegistrationEffect(niceevalRoot, experimentId, pid) {
|
|
65
62
|
return (0, entry_file_store_ts_1.readEntryFileEffect)(teardownsDirOf(niceevalRoot), teardownEntryId(experimentId, pid), (value) => decodeTeardownRegistration(value, { experimentId, pid }));
|
|
66
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Exact recovery cannot treat a malformed or unreadable expected entry as an
|
|
66
|
+
* absent cleanup obligation. Normal registry scans deliberately tolerate
|
|
67
|
+
* damaged historical rows; a recovery is instead about to publish a new
|
|
68
|
+
* sharedState generation, so only a genuinely absent path is safe to accept.
|
|
69
|
+
*/
|
|
70
|
+
function readExactTeardownRegistrationEffect(niceevalRoot, experimentId, pid) {
|
|
71
|
+
const id = teardownEntryId(experimentId, pid);
|
|
72
|
+
const path = (0, node_path_1.join)(teardownsDirOf(niceevalRoot), `${id}.json`);
|
|
73
|
+
return effect_1.Effect.tryPromise({
|
|
74
|
+
try: () => (0, promises_1.readFile)(path, "utf8"),
|
|
75
|
+
catch: (cause) => cause,
|
|
76
|
+
}).pipe(effect_1.Effect.catchAll((cause) => errnoCode(cause) === "ENOENT" ? effect_1.Effect.succeed(undefined) : effect_1.Effect.fail(cause)), effect_1.Effect.flatMap((raw) => raw === undefined ? effect_1.Effect.succeed(undefined) : effect_1.Effect.try({
|
|
77
|
+
try: () => {
|
|
78
|
+
let value;
|
|
79
|
+
try {
|
|
80
|
+
value = JSON.parse(raw);
|
|
81
|
+
}
|
|
82
|
+
catch (cause) {
|
|
83
|
+
throw new Error(`teardown registration ${JSON.stringify(id)} is not valid JSON`, { cause });
|
|
84
|
+
}
|
|
85
|
+
const registration = decodeTeardownRegistration(value, { experimentId, pid });
|
|
86
|
+
if (registration === undefined) {
|
|
87
|
+
throw new Error(`teardown registration ${JSON.stringify(id)} has an invalid identity or shape`);
|
|
88
|
+
}
|
|
89
|
+
return registration;
|
|
90
|
+
},
|
|
91
|
+
catch: (cause) => cause,
|
|
92
|
+
})));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Checks the terminal state of the exact owner recorded by a sharedState
|
|
96
|
+
* generation. On the local host, this uses the same PID + process-identity
|
|
97
|
+
* probe as lease recovery: ENOENT, PID reuse, and Linux Z/X/x are terminal;
|
|
98
|
+
* unreadable or malformed probe evidence fails rather than guessing. Remote
|
|
99
|
+
* termination was already explicitly confirmed by the recovery command.
|
|
100
|
+
*/
|
|
101
|
+
function isExactTeardownRegistrationOwnerTerminatedEffect(input) {
|
|
102
|
+
const { registration, owner, currentHost } = input;
|
|
103
|
+
if (registration.experimentId !== owner.experimentId ||
|
|
104
|
+
registration.pid !== owner.pid ||
|
|
105
|
+
registration.host !== owner.host) {
|
|
106
|
+
return effect_1.Effect.fail(new Error("teardown registration does not match the immutable sharedState owner identity"));
|
|
107
|
+
}
|
|
108
|
+
if (owner.host !== currentHost)
|
|
109
|
+
return effect_1.Effect.succeed(true);
|
|
110
|
+
return (0, shared_state_lease_ts_1.processIdentityForPidEffect)(owner.pid).pipe(effect_1.Effect.map((currentIdentity) => currentIdentity === undefined || currentIdentity !== owner.processIdentity));
|
|
111
|
+
}
|
|
67
112
|
/** 读全部登记项(损坏条目跳过,不整体失败;目录不存在时返回空集合)。 */
|
|
68
113
|
function readTeardownRegistrationsEffect(niceevalRoot) {
|
|
69
114
|
return (0, entry_file_store_ts_1.readAllEntryFilesEffect)(teardownsDirOf(niceevalRoot), decodeTeardownRegistration);
|
|
@@ -76,20 +121,38 @@ function readTeardownRegistrationsEffect(niceevalRoot) {
|
|
|
76
121
|
function removeTeardownRegistrationIfPresentEffect(niceevalRoot, id) {
|
|
77
122
|
return (0, entry_file_store_ts_1.claimEntryFileEffect)(teardownsDirOf(niceevalRoot), id);
|
|
78
123
|
}
|
|
79
|
-
/**
|
|
80
|
-
*
|
|
81
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Normal startup scans only persist PID + host, so they cannot prove PID
|
|
126
|
+
* reuse. They still share lease recovery's terminal Linux process states:
|
|
127
|
+
* a Z/X/x task cannot execute cleanup. Any `/proc` read/parse ambiguity is
|
|
128
|
+
* deliberately treated as live here; the explicit recovery path above has
|
|
129
|
+
* stronger immutable identity evidence and fails closed on that ambiguity.
|
|
130
|
+
*/
|
|
131
|
+
function isPidTerminal(pid) {
|
|
132
|
+
if (process.platform === "linux") {
|
|
133
|
+
try {
|
|
134
|
+
const raw = (0, node_fs_1.readFileSync)(`/proc/${pid}/stat`, "utf8");
|
|
135
|
+
const closing = raw.lastIndexOf(")");
|
|
136
|
+
if (closing < 0 || raw[closing + 1] !== " ")
|
|
137
|
+
return false;
|
|
138
|
+
const state = raw.slice(closing + 2).trim().split(/\s+/u)[0];
|
|
139
|
+
return state === "Z" || state === "X" || state === "x";
|
|
140
|
+
}
|
|
141
|
+
catch (cause) {
|
|
142
|
+
return errnoCode(cause) === "ENOENT";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
82
145
|
try {
|
|
83
146
|
process.kill(pid, 0);
|
|
84
|
-
return
|
|
147
|
+
return false;
|
|
85
148
|
}
|
|
86
149
|
catch (e) {
|
|
87
|
-
return e.code
|
|
150
|
+
return e.code !== "EPERM";
|
|
88
151
|
}
|
|
89
152
|
}
|
|
90
|
-
/** 遗留义务判定:同宿主且
|
|
153
|
+
/** 遗留义务判定:同宿主且 PID 已缺失或处于终态。pid 存活、读取不明或异宿主可能属于并发 run,不触碰。 */
|
|
91
154
|
function isOrphanedTeardownRegistration(entry, currentHost) {
|
|
92
|
-
return entry.host === currentHost &&
|
|
155
|
+
return entry.host === currentHost && isPidTerminal(entry.pid);
|
|
93
156
|
}
|
|
94
157
|
/**
|
|
95
158
|
* `niceeval exp` 启动提醒:遗留义务里「不在本次选择」的那部分,各给一行 `--teardown` 命令。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teardown-registry.js","sourceRoot":"","sources":["teardown-registry.ts"],"names":[],"mappings":"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","sourcesContent":["// 强杀后的收尾登记表:`.niceeval/teardowns/` 下的逐条目文件,与留存注册表\n// (sandbox/keep-registry.ts)同一套原子写纪律,两者都建在 shared/entry-file-store.ts 之上\n// (temp → fsync → rename → fsync 目录)。\n// 契约见 docs/feature/experiments/architecture.md「强杀后的收尾兜底:收尾登记与启动自愈」。\nimport { join } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { claimEntryFileEffect, hashEntryId, readAllEntryFilesEffect, readEntryFileEffect, writeEntryFileEffect, } from \"../shared/entry-file-store.ts\";\n/** 一条收尾登记项(逐条目文件的 JSON 形状)。 */\nexport interface TeardownRegistration {\n experimentId: string;\n selectedEvalIds: readonly string[];\n pid: number;\n host: string;\n startedAt: string;\n}\nfunction recordOf(value: unknown): globalThis.Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value as globalThis.Record<string, unknown>\n : undefined;\n}\nfunction isPositiveInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value > 0;\n}\nfunction isTimestamp(value: unknown): value is string {\n return typeof value === \"string\" && Number.isFinite(Date.parse(value));\n}\n/** 收尾登记的完整持久形状;单条读取还会核对文件身份。 */\nfunction decodeTeardownRegistration(value: unknown, expected: {\n experimentId?: string;\n pid?: number;\n} = {}): TeardownRegistration | undefined {\n const record = recordOf(value);\n if (record === undefined ||\n typeof record.experimentId !== \"string\" ||\n !Array.isArray(record.selectedEvalIds) ||\n !record.selectedEvalIds.every((id) => typeof id === \"string\") ||\n !isPositiveInteger(record.pid) ||\n typeof record.host !== \"string\" ||\n !isTimestamp(record.startedAt) ||\n (expected.experimentId !== undefined && record.experimentId !== expected.experimentId) ||\n (expected.pid !== undefined && record.pid !== expected.pid)) {\n return undefined;\n }\n return {\n experimentId: record.experimentId,\n selectedEvalIds: record.selectedEvalIds,\n pid: record.pid,\n host: record.host,\n startedAt: record.startedAt,\n };\n}\nexport function teardownsDirOf(niceevalRoot: string): string {\n return join(niceevalRoot, \"teardowns\");\n}\n/** entry id:实验身份 + 进程身份的稳定散列。同一实验的并发 run 各有独立收尾义务。 */\nexport function teardownEntryId(experimentId: string, pid: number): string {\n return hashEntryId([experimentId, String(pid)]);\n}\n/** 原子写入一条登记项(委托给共享层的 write-tmp-then-rename 纪律)。 */\nexport function writeTeardownRegistrationEffect(niceevalRoot: string, entry: TeardownRegistration): Effect.Effect<void, unknown> {\n const id = teardownEntryId(entry.experimentId, entry.pid);\n return writeEntryFileEffect(teardownsDirOf(niceevalRoot), id, entry);\n}\n/** 读一条登记项(不存在或损坏都返回 undefined,不抛错)。 */\nexport function readTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown> {\n return readEntryFileEffect(teardownsDirOf(niceevalRoot), teardownEntryId(experimentId, pid), (value) => decodeTeardownRegistration(value, { experimentId, pid }));\n}\n/** 读全部登记项(损坏条目跳过,不整体失败;目录不存在时返回空集合)。 */\nexport function readTeardownRegistrationsEffect(niceevalRoot: string): Effect.Effect<{\n id: string;\n entry: TeardownRegistration;\n}[], unknown> {\n return readAllEntryFilesEffect(teardownsDirOf(niceevalRoot), decodeTeardownRegistration);\n}\n/**\n * 删登记是互斥点:委托给共享层的认领原语(rename-墓碑,见 ../shared/entry-file-store.ts 的\n * `claimEntryFile` 头注释)。成功认领(返回 true)即拿到执行权;登记已被别的进程删除\n * (返回 false)则跳过——同一份遗留义务不会被两个进程双跑。\n */\nexport function removeTeardownRegistrationIfPresentEffect(niceevalRoot: string, id: string): Effect.Effect<boolean, unknown> {\n return claimEntryFileEffect(teardownsDirOf(niceevalRoot), id);\n}\n/** 同宿主 pid 存活探测。runner 已依赖 sandbox 模块;此处保持本地小函数,是因为收尾登记只需\n * `kill(pid, 0)` 这一无副作用的宿主进程事实,不应把 sandbox 身份分类策略带进来。 */\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n }\n catch (e) {\n return (e as NodeJS.ErrnoException).code === \"EPERM\";\n }\n}\n/** 遗留义务判定:同宿主且 pid 不存活。pid 存活或异宿主可能属于并发 run,不触碰。 */\nexport function isOrphanedTeardownRegistration(entry: TeardownRegistration, currentHost: string): boolean {\n return entry.host === currentHost && !isPidAlive(entry.pid);\n}\n/**\n * `niceeval exp` 启动提醒:遗留义务里「不在本次选择」的那部分,各给一行 `--teardown` 命令。\n * 在本次选择且仍声明 teardown 的遗留义务由 run.ts 在调度前自动补执行,不出现在这里\n * (见 docs/feature/experiments/architecture.md「强杀后的收尾兜底」)。\n */\nexport function orphanedTeardownReminderEffect(niceevalRoot: string, recoveringExperimentIds: ReadonlySet<string>, currentHost: string): Effect.Effect<string | undefined, unknown> {\n return readTeardownRegistrationsEffect(niceevalRoot).pipe(Effect.map((registrations) => {\n const lines: string[] = [];\n for (const { entry } of registrations) {\n if (!isOrphanedTeardownRegistration(entry, currentHost))\n continue;\n if (recoveringExperimentIds.has(entry.experimentId))\n continue;\n lines.push(`unfinished experiment teardown for \"${entry.experimentId}\" from a killed run — niceeval exp ${entry.experimentId} --teardown\\n`);\n }\n return lines.length > 0 ? lines.join(\"\") : undefined;\n }));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"teardown-registry.js","sourceRoot":"","sources":["teardown-registry.ts"],"names":[],"mappings":"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","sourcesContent":["// 强杀后的收尾登记表:`.niceeval/teardowns/` 下的逐条目文件,与留存注册表\n// (sandbox/keep-registry.ts)同一套原子写纪律,两者都建在 shared/entry-file-store.ts 之上\n// (temp → fsync → rename → fsync 目录)。\n// 契约见 docs/feature/experiments/architecture.md「强杀后的收尾兜底:收尾登记与启动自愈」。\nimport { readFileSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Effect, Either, Schema } from \"effect\";\nimport { claimEntryFileEffect, hashEntryId, readAllEntryFilesEffect, readEntryFileEffect, writeEntryFileEffect, } from \"../shared/entry-file-store.ts\";\nimport { processIdentityForPidEffect } from \"./shared-state-lease.ts\";\n/** 一条收尾登记项(逐条目文件的 JSON 形状)。 */\nexport interface TeardownRegistration {\n experimentId: string;\n selectedEvalIds: readonly string[];\n pid: number;\n host: string;\n startedAt: string;\n}\nconst PositiveSafeIntegerSchema = Schema.Number.pipe(Schema.filter((value) => Number.isSafeInteger(value) && value > 0, { identifier: \"PositiveSafeInteger\" }));\nconst TimestampSchema = Schema.String.pipe(Schema.filter((value) => Number.isFinite(Date.parse(value)), { identifier: \"Timestamp\" }));\nconst TeardownRegistrationSchema = Schema.Struct({\n experimentId: Schema.String,\n selectedEvalIds: Schema.Array(Schema.String),\n pid: PositiveSafeIntegerSchema,\n host: Schema.String,\n startedAt: TimestampSchema,\n});\nfunction errnoCode(cause: unknown): string | undefined {\n return typeof cause === \"object\" && cause !== null && \"code\" in cause && typeof cause.code === \"string\"\n ? cause.code\n : undefined;\n}\n/** 收尾登记的完整持久形状;单条读取还会核对文件身份。 */\nfunction decodeTeardownRegistration(value: unknown, expected: {\n experimentId?: string;\n pid?: number;\n} = {}): TeardownRegistration | undefined {\n const decoded = Schema.decodeUnknownEither(TeardownRegistrationSchema)(value);\n if (Either.isLeft(decoded))\n return undefined;\n const registration = decoded.right;\n return (expected.experimentId !== undefined && registration.experimentId !== expected.experimentId) ||\n (expected.pid !== undefined && registration.pid !== expected.pid)\n ? undefined\n : registration;\n}\nexport function teardownsDirOf(niceevalRoot: string): string {\n return join(niceevalRoot, \"teardowns\");\n}\n/** entry id:实验身份 + 进程身份的稳定散列。同一实验的并发 run 各有独立收尾义务。 */\nexport function teardownEntryId(experimentId: string, pid: number): string {\n return hashEntryId([experimentId, String(pid)]);\n}\n/** 原子写入一条登记项(委托给共享层的 write-tmp-then-rename 纪律)。 */\nexport function writeTeardownRegistrationEffect(niceevalRoot: string, entry: TeardownRegistration): Effect.Effect<void, unknown> {\n const id = teardownEntryId(entry.experimentId, entry.pid);\n return writeEntryFileEffect(teardownsDirOf(niceevalRoot), id, entry);\n}\n/** 读一条登记项(不存在或损坏都返回 undefined,不抛错)。 */\nexport function readTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown> {\n return readEntryFileEffect(teardownsDirOf(niceevalRoot), teardownEntryId(experimentId, pid), (value) => decodeTeardownRegistration(value, { experimentId, pid }));\n}\n/**\n * Exact recovery cannot treat a malformed or unreadable expected entry as an\n * absent cleanup obligation. Normal registry scans deliberately tolerate\n * damaged historical rows; a recovery is instead about to publish a new\n * sharedState generation, so only a genuinely absent path is safe to accept.\n */\nexport function readExactTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown> {\n const id = teardownEntryId(experimentId, pid);\n const path = join(teardownsDirOf(niceevalRoot), `${id}.json`);\n return Effect.tryPromise({\n try: () => readFile(path, \"utf8\"),\n catch: (cause) => cause,\n }).pipe(Effect.catchAll((cause) => errnoCode(cause) === \"ENOENT\" ? Effect.succeed(undefined) : Effect.fail(cause)), Effect.flatMap((raw) => raw === undefined ? Effect.succeed(undefined) : Effect.try({\n try: () => {\n let value: unknown;\n try {\n value = JSON.parse(raw);\n }\n catch (cause) {\n throw new Error(`teardown registration ${JSON.stringify(id)} is not valid JSON`, { cause });\n }\n const registration = decodeTeardownRegistration(value, { experimentId, pid });\n if (registration === undefined) {\n throw new Error(`teardown registration ${JSON.stringify(id)} has an invalid identity or shape`);\n }\n return registration;\n },\n catch: (cause) => cause,\n })));\n}\n/** Immutable sharedState owner facts that can prove a registry row is old. */\nexport interface ExactTeardownRegistrationOwner {\n readonly experimentId: string;\n readonly pid: number;\n readonly host: string;\n readonly processIdentity: string;\n}\n/**\n * Checks the terminal state of the exact owner recorded by a sharedState\n * generation. On the local host, this uses the same PID + process-identity\n * probe as lease recovery: ENOENT, PID reuse, and Linux Z/X/x are terminal;\n * unreadable or malformed probe evidence fails rather than guessing. Remote\n * termination was already explicitly confirmed by the recovery command.\n */\nexport function isExactTeardownRegistrationOwnerTerminatedEffect(input: {\n readonly registration: TeardownRegistration;\n readonly owner: ExactTeardownRegistrationOwner;\n readonly currentHost: string;\n}): Effect.Effect<boolean, unknown> {\n const { registration, owner, currentHost } = input;\n if (registration.experimentId !== owner.experimentId ||\n registration.pid !== owner.pid ||\n registration.host !== owner.host) {\n return Effect.fail(new Error(\"teardown registration does not match the immutable sharedState owner identity\"));\n }\n if (owner.host !== currentHost)\n return Effect.succeed(true);\n return processIdentityForPidEffect(owner.pid).pipe(Effect.map((currentIdentity) => currentIdentity === undefined || currentIdentity !== owner.processIdentity));\n}\n/** 读全部登记项(损坏条目跳过,不整体失败;目录不存在时返回空集合)。 */\nexport function readTeardownRegistrationsEffect(niceevalRoot: string): Effect.Effect<{\n id: string;\n entry: TeardownRegistration;\n}[], unknown> {\n return readAllEntryFilesEffect(teardownsDirOf(niceevalRoot), decodeTeardownRegistration);\n}\n/**\n * 删登记是互斥点:委托给共享层的认领原语(rename-墓碑,见 ../shared/entry-file-store.ts 的\n * `claimEntryFile` 头注释)。成功认领(返回 true)即拿到执行权;登记已被别的进程删除\n * (返回 false)则跳过——同一份遗留义务不会被两个进程双跑。\n */\nexport function removeTeardownRegistrationIfPresentEffect(niceevalRoot: string, id: string): Effect.Effect<boolean, unknown> {\n return claimEntryFileEffect(teardownsDirOf(niceevalRoot), id);\n}\n/**\n * Normal startup scans only persist PID + host, so they cannot prove PID\n * reuse. They still share lease recovery's terminal Linux process states:\n * a Z/X/x task cannot execute cleanup. Any `/proc` read/parse ambiguity is\n * deliberately treated as live here; the explicit recovery path above has\n * stronger immutable identity evidence and fails closed on that ambiguity.\n */\nfunction isPidTerminal(pid: number): boolean {\n if (process.platform === \"linux\") {\n try {\n const raw = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n const closing = raw.lastIndexOf(\")\");\n if (closing < 0 || raw[closing + 1] !== \" \")\n return false;\n const state = raw.slice(closing + 2).trim().split(/\\s+/u)[0];\n return state === \"Z\" || state === \"X\" || state === \"x\";\n }\n catch (cause) {\n return errnoCode(cause) === \"ENOENT\";\n }\n }\n try {\n process.kill(pid, 0);\n return false;\n }\n catch (e) {\n return (e as NodeJS.ErrnoException).code !== \"EPERM\";\n }\n}\n/** 遗留义务判定:同宿主且 PID 已缺失或处于终态。pid 存活、读取不明或异宿主可能属于并发 run,不触碰。 */\nexport function isOrphanedTeardownRegistration(entry: TeardownRegistration, currentHost: string): boolean {\n return entry.host === currentHost && isPidTerminal(entry.pid);\n}\n/**\n * `niceeval exp` 启动提醒:遗留义务里「不在本次选择」的那部分,各给一行 `--teardown` 命令。\n * 在本次选择且仍声明 teardown 的遗留义务由 run.ts 在调度前自动补执行,不出现在这里\n * (见 docs/feature/experiments/architecture.md「强杀后的收尾兜底」)。\n */\nexport function orphanedTeardownReminderEffect(niceevalRoot: string, recoveringExperimentIds: ReadonlySet<string>, currentHost: string): Effect.Effect<string | undefined, unknown> {\n return readTeardownRegistrationsEffect(niceevalRoot).pipe(Effect.map((registrations) => {\n const lines: string[] = [];\n for (const { entry } of registrations) {\n if (!isOrphanedTeardownRegistration(entry, currentHost))\n continue;\n if (recoveringExperimentIds.has(entry.experimentId))\n continue;\n lines.push(`unfinished experiment teardown for \"${entry.experimentId}\" from a killed run — niceeval exp ${entry.experimentId} --teardown\\n`);\n }\n return lines.length > 0 ? lines.join(\"\") : undefined;\n }));\n}\n"]}
|
|
@@ -14,6 +14,32 @@ export declare function teardownEntryId(experimentId: string, pid: number): stri
|
|
|
14
14
|
export declare function writeTeardownRegistrationEffect(niceevalRoot: string, entry: TeardownRegistration): Effect.Effect<void, unknown>;
|
|
15
15
|
/** 读一条登记项(不存在或损坏都返回 undefined,不抛错)。 */
|
|
16
16
|
export declare function readTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Exact recovery cannot treat a malformed or unreadable expected entry as an
|
|
19
|
+
* absent cleanup obligation. Normal registry scans deliberately tolerate
|
|
20
|
+
* damaged historical rows; a recovery is instead about to publish a new
|
|
21
|
+
* sharedState generation, so only a genuinely absent path is safe to accept.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readExactTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown>;
|
|
24
|
+
/** Immutable sharedState owner facts that can prove a registry row is old. */
|
|
25
|
+
export interface ExactTeardownRegistrationOwner {
|
|
26
|
+
readonly experimentId: string;
|
|
27
|
+
readonly pid: number;
|
|
28
|
+
readonly host: string;
|
|
29
|
+
readonly processIdentity: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Checks the terminal state of the exact owner recorded by a sharedState
|
|
33
|
+
* generation. On the local host, this uses the same PID + process-identity
|
|
34
|
+
* probe as lease recovery: ENOENT, PID reuse, and Linux Z/X/x are terminal;
|
|
35
|
+
* unreadable or malformed probe evidence fails rather than guessing. Remote
|
|
36
|
+
* termination was already explicitly confirmed by the recovery command.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isExactTeardownRegistrationOwnerTerminatedEffect(input: {
|
|
39
|
+
readonly registration: TeardownRegistration;
|
|
40
|
+
readonly owner: ExactTeardownRegistrationOwner;
|
|
41
|
+
readonly currentHost: string;
|
|
42
|
+
}): Effect.Effect<boolean, unknown>;
|
|
17
43
|
/** 读全部登记项(损坏条目跳过,不整体失败;目录不存在时返回空集合)。 */
|
|
18
44
|
export declare function readTeardownRegistrationsEffect(niceevalRoot: string): Effect.Effect<{
|
|
19
45
|
id: string;
|
|
@@ -25,7 +51,7 @@ export declare function readTeardownRegistrationsEffect(niceevalRoot: string): E
|
|
|
25
51
|
* (返回 false)则跳过——同一份遗留义务不会被两个进程双跑。
|
|
26
52
|
*/
|
|
27
53
|
export declare function removeTeardownRegistrationIfPresentEffect(niceevalRoot: string, id: string): Effect.Effect<boolean, unknown>;
|
|
28
|
-
/** 遗留义务判定:同宿主且
|
|
54
|
+
/** 遗留义务判定:同宿主且 PID 已缺失或处于终态。pid 存活、读取不明或异宿主可能属于并发 run,不触碰。 */
|
|
29
55
|
export declare function isOrphanedTeardownRegistration(entry: TeardownRegistration, currentHost: string): boolean;
|
|
30
56
|
/**
|
|
31
57
|
* `niceeval exp` 启动提醒:遗留义务里「不在本次选择」的那部分,各给一行 `--teardown` 命令。
|
|
@@ -14,6 +14,32 @@ export declare function teardownEntryId(experimentId: string, pid: number): stri
|
|
|
14
14
|
export declare function writeTeardownRegistrationEffect(niceevalRoot: string, entry: TeardownRegistration): Effect.Effect<void, unknown>;
|
|
15
15
|
/** 读一条登记项(不存在或损坏都返回 undefined,不抛错)。 */
|
|
16
16
|
export declare function readTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Exact recovery cannot treat a malformed or unreadable expected entry as an
|
|
19
|
+
* absent cleanup obligation. Normal registry scans deliberately tolerate
|
|
20
|
+
* damaged historical rows; a recovery is instead about to publish a new
|
|
21
|
+
* sharedState generation, so only a genuinely absent path is safe to accept.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readExactTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown>;
|
|
24
|
+
/** Immutable sharedState owner facts that can prove a registry row is old. */
|
|
25
|
+
export interface ExactTeardownRegistrationOwner {
|
|
26
|
+
readonly experimentId: string;
|
|
27
|
+
readonly pid: number;
|
|
28
|
+
readonly host: string;
|
|
29
|
+
readonly processIdentity: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Checks the terminal state of the exact owner recorded by a sharedState
|
|
33
|
+
* generation. On the local host, this uses the same PID + process-identity
|
|
34
|
+
* probe as lease recovery: ENOENT, PID reuse, and Linux Z/X/x are terminal;
|
|
35
|
+
* unreadable or malformed probe evidence fails rather than guessing. Remote
|
|
36
|
+
* termination was already explicitly confirmed by the recovery command.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isExactTeardownRegistrationOwnerTerminatedEffect(input: {
|
|
39
|
+
readonly registration: TeardownRegistration;
|
|
40
|
+
readonly owner: ExactTeardownRegistrationOwner;
|
|
41
|
+
readonly currentHost: string;
|
|
42
|
+
}): Effect.Effect<boolean, unknown>;
|
|
17
43
|
/** 读全部登记项(损坏条目跳过,不整体失败;目录不存在时返回空集合)。 */
|
|
18
44
|
export declare function readTeardownRegistrationsEffect(niceevalRoot: string): Effect.Effect<{
|
|
19
45
|
id: string;
|
|
@@ -25,7 +51,7 @@ export declare function readTeardownRegistrationsEffect(niceevalRoot: string): E
|
|
|
25
51
|
* (返回 false)则跳过——同一份遗留义务不会被两个进程双跑。
|
|
26
52
|
*/
|
|
27
53
|
export declare function removeTeardownRegistrationIfPresentEffect(niceevalRoot: string, id: string): Effect.Effect<boolean, unknown>;
|
|
28
|
-
/** 遗留义务判定:同宿主且
|
|
54
|
+
/** 遗留义务判定:同宿主且 PID 已缺失或处于终态。pid 存活、读取不明或异宿主可能属于并发 run,不触碰。 */
|
|
29
55
|
export declare function isOrphanedTeardownRegistration(entry: TeardownRegistration, currentHost: string): boolean;
|
|
30
56
|
/**
|
|
31
57
|
* `niceeval exp` 启动提醒:遗留义务里「不在本次选择」的那部分,各给一行 `--teardown` 命令。
|
|
@@ -14,6 +14,32 @@ export declare function teardownEntryId(experimentId: string, pid: number): stri
|
|
|
14
14
|
export declare function writeTeardownRegistrationEffect(niceevalRoot: string, entry: TeardownRegistration): Effect.Effect<void, unknown>;
|
|
15
15
|
/** 读一条登记项(不存在或损坏都返回 undefined,不抛错)。 */
|
|
16
16
|
export declare function readTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Exact recovery cannot treat a malformed or unreadable expected entry as an
|
|
19
|
+
* absent cleanup obligation. Normal registry scans deliberately tolerate
|
|
20
|
+
* damaged historical rows; a recovery is instead about to publish a new
|
|
21
|
+
* sharedState generation, so only a genuinely absent path is safe to accept.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readExactTeardownRegistrationEffect(niceevalRoot: string, experimentId: string, pid: number): Effect.Effect<TeardownRegistration | undefined, unknown>;
|
|
24
|
+
/** Immutable sharedState owner facts that can prove a registry row is old. */
|
|
25
|
+
export interface ExactTeardownRegistrationOwner {
|
|
26
|
+
readonly experimentId: string;
|
|
27
|
+
readonly pid: number;
|
|
28
|
+
readonly host: string;
|
|
29
|
+
readonly processIdentity: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Checks the terminal state of the exact owner recorded by a sharedState
|
|
33
|
+
* generation. On the local host, this uses the same PID + process-identity
|
|
34
|
+
* probe as lease recovery: ENOENT, PID reuse, and Linux Z/X/x are terminal;
|
|
35
|
+
* unreadable or malformed probe evidence fails rather than guessing. Remote
|
|
36
|
+
* termination was already explicitly confirmed by the recovery command.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isExactTeardownRegistrationOwnerTerminatedEffect(input: {
|
|
39
|
+
readonly registration: TeardownRegistration;
|
|
40
|
+
readonly owner: ExactTeardownRegistrationOwner;
|
|
41
|
+
readonly currentHost: string;
|
|
42
|
+
}): Effect.Effect<boolean, unknown>;
|
|
17
43
|
/** 读全部登记项(损坏条目跳过,不整体失败;目录不存在时返回空集合)。 */
|
|
18
44
|
export declare function readTeardownRegistrationsEffect(niceevalRoot: string): Effect.Effect<{
|
|
19
45
|
id: string;
|
|
@@ -25,7 +51,7 @@ export declare function readTeardownRegistrationsEffect(niceevalRoot: string): E
|
|
|
25
51
|
* (返回 false)则跳过——同一份遗留义务不会被两个进程双跑。
|
|
26
52
|
*/
|
|
27
53
|
export declare function removeTeardownRegistrationIfPresentEffect(niceevalRoot: string, id: string): Effect.Effect<boolean, unknown>;
|
|
28
|
-
/** 遗留义务判定:同宿主且
|
|
54
|
+
/** 遗留义务判定:同宿主且 PID 已缺失或处于终态。pid 存活、读取不明或异宿主可能属于并发 run,不触碰。 */
|
|
29
55
|
export declare function isOrphanedTeardownRegistration(entry: TeardownRegistration, currentHost: string): boolean;
|
|
30
56
|
/**
|
|
31
57
|
* `niceeval exp` 启动提醒:遗留义务里「不在本次选择」的那部分,各给一行 `--teardown` 命令。
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { createRequire as __niceevalCreateRequire } from "node:module";
|
|
2
2
|
const __niceevalRequire = __niceevalCreateRequire(import.meta.url);
|
|
3
3
|
const __niceevalCanonical = __niceevalRequire("./teardown-registry.cjs");
|
|
4
|
-
const __niceevalExport0 = __niceevalCanonical["
|
|
5
|
-
export { __niceevalExport0 as
|
|
6
|
-
const __niceevalExport1 = __niceevalCanonical["
|
|
7
|
-
export { __niceevalExport1 as
|
|
8
|
-
const __niceevalExport2 = __niceevalCanonical["
|
|
9
|
-
export { __niceevalExport2 as
|
|
10
|
-
const __niceevalExport3 = __niceevalCanonical["
|
|
11
|
-
export { __niceevalExport3 as
|
|
12
|
-
const __niceevalExport4 = __niceevalCanonical["
|
|
13
|
-
export { __niceevalExport4 as
|
|
14
|
-
const __niceevalExport5 = __niceevalCanonical["
|
|
15
|
-
export { __niceevalExport5 as
|
|
16
|
-
const __niceevalExport6 = __niceevalCanonical["
|
|
17
|
-
export { __niceevalExport6 as
|
|
18
|
-
const __niceevalExport7 = __niceevalCanonical["
|
|
19
|
-
export { __niceevalExport7 as
|
|
4
|
+
const __niceevalExport0 = __niceevalCanonical["isExactTeardownRegistrationOwnerTerminatedEffect"];
|
|
5
|
+
export { __niceevalExport0 as isExactTeardownRegistrationOwnerTerminatedEffect };
|
|
6
|
+
const __niceevalExport1 = __niceevalCanonical["isOrphanedTeardownRegistration"];
|
|
7
|
+
export { __niceevalExport1 as isOrphanedTeardownRegistration };
|
|
8
|
+
const __niceevalExport2 = __niceevalCanonical["orphanedTeardownReminderEffect"];
|
|
9
|
+
export { __niceevalExport2 as orphanedTeardownReminderEffect };
|
|
10
|
+
const __niceevalExport3 = __niceevalCanonical["readExactTeardownRegistrationEffect"];
|
|
11
|
+
export { __niceevalExport3 as readExactTeardownRegistrationEffect };
|
|
12
|
+
const __niceevalExport4 = __niceevalCanonical["readTeardownRegistrationEffect"];
|
|
13
|
+
export { __niceevalExport4 as readTeardownRegistrationEffect };
|
|
14
|
+
const __niceevalExport5 = __niceevalCanonical["readTeardownRegistrationsEffect"];
|
|
15
|
+
export { __niceevalExport5 as readTeardownRegistrationsEffect };
|
|
16
|
+
const __niceevalExport6 = __niceevalCanonical["removeTeardownRegistrationIfPresentEffect"];
|
|
17
|
+
export { __niceevalExport6 as removeTeardownRegistrationIfPresentEffect };
|
|
18
|
+
const __niceevalExport7 = __niceevalCanonical["teardownEntryId"];
|
|
19
|
+
export { __niceevalExport7 as teardownEntryId };
|
|
20
|
+
const __niceevalExport8 = __niceevalCanonical["teardownsDirOf"];
|
|
21
|
+
export { __niceevalExport8 as teardownsDirOf };
|
|
22
|
+
const __niceevalExport9 = __niceevalCanonical["writeTeardownRegistrationEffect"];
|
|
23
|
+
export { __niceevalExport9 as writeTeardownRegistrationEffect };
|
|
20
24
|
//# sourceMappingURL=teardown-registry.js.map
|