@gfdelarue/testkit 0.4.5 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +724 -495
- package/bin/testkit-windows-owner-arm64.exe +0 -0
- package/bin/testkit-windows-owner-x64.exe +0 -0
- package/dist/app/bugs/ci-report.js +2 -2
- package/dist/app/bugs/ci-summary.js +3 -3
- package/dist/app/bugs/draft.js +3 -3
- package/dist/app/bugs/file.js +1 -1
- package/dist/app/bugs/gate.js +1 -1
- package/dist/app/bugs/guide.js +3 -3
- package/dist/app/bugs/issue.js +4 -4
- package/dist/app/bugs/known-failures.js +1 -1
- package/dist/app/bugs/record.js +1 -1
- package/dist/app/bugs/run-reading.js +1 -1
- package/dist/app/bugs/supplied-reproduce.js +1 -0
- package/dist/app/campaigns/campaign.js +1 -1
- package/dist/app/campaigns/index.js +2 -2
- package/dist/app/cleanup/index.js +1 -1
- package/dist/app/db-schema/prepare.js +1 -1
- package/dist/app/destroy/index.js +1 -1
- package/dist/app/discover/index.js +2 -2
- package/dist/app/doctor/index.js +1 -1
- package/dist/app/environments/config-driven.js +1 -1
- package/dist/app/environments/environment-file.js +1 -0
- package/dist/app/environments/file-setup.js +1 -0
- package/dist/app/environments/routing.js +1 -1
- package/dist/app/environments/static-values.js +1 -0
- package/dist/app/environments/supplied-input.js +1 -0
- package/dist/app/environments/supplied.js +1 -1
- package/dist/app/environments/task-databases.js +2 -0
- package/dist/app/inspect/artifacts.js +1 -1
- package/dist/app/inspect/index.js +1 -1
- package/dist/app/lint/index.js +1 -1
- package/dist/app/lint/native.js +1 -1
- package/dist/app/lint/options.js +1 -1
- package/dist/app/lint/rules/engine-imports.js +1 -1
- package/dist/app/lint/rules/syntax.js +1 -1
- package/dist/app/lint/rules/unit.js +1 -1
- package/dist/app/reports/prepare.js +1 -1
- package/dist/app/run/caller-redaction.js +1 -0
- package/dist/app/run/engine-execution-failures.js +1 -1
- package/dist/app/run/engine-execution-reporting.js +1 -1
- package/dist/app/run/engine-execution.js +1 -1
- package/dist/app/run/engine-orchestration.js +1 -1
- package/dist/app/run/environment.js +1 -1
- package/dist/app/run/failure-details.js +1 -1
- package/dist/app/run/live-run.js +1 -1
- package/dist/app/run/orchestrator.js +1 -1
- package/dist/app/run/planning.js +1 -1
- package/dist/app/run/request.js +1 -1
- package/dist/app/run/results.js +1 -1
- package/dist/app/run/run-events.js +1 -1
- package/dist/app/run/run-finalization.js +1 -1
- package/dist/app/run/scheduler/estimates.js +1 -1
- package/dist/app/run/scheduler/identity.js +1 -1
- package/dist/app/run/scheduler/index.js +1 -1
- package/dist/app/run/setup/runtime-node-setup-protocol.js +1 -1
- package/dist/app/run/setup/runtime-node-setup-worker.js +1 -1
- package/dist/app/run/setup/runtime-node-setup.js +2 -2
- package/dist/app/run/task-batches.js +1 -1
- package/dist/app/run/worker-loop.js +1 -1
- package/dist/app/status/model.js +1 -1
- package/dist/app/status/runs.js +1 -1
- package/dist/app/typecheck/index.js +4 -4
- package/dist/cli/command-catalog.js +1 -1
- package/dist/cli/command-flags.js +1 -1
- package/dist/cli/commands/artifacts.js +2 -2
- package/dist/cli/commands/bug/file.js +2 -2
- package/dist/cli/commands/bug/record.js +2 -2
- package/dist/cli/commands/discover.js +1 -1
- package/dist/cli/commands/guard/unsafe-entrypoint.js +1 -1
- package/dist/cli/commands/run.js +2 -2
- package/dist/cli/commands/typecheck.js +1 -1
- package/dist/cli/commands/workspace.js +1 -1
- package/dist/cli/framework/errors.js +1 -1
- package/dist/cli/framework/execute.js +7 -6
- package/dist/cli/framework/parser.js +1 -1
- package/dist/cli/operations/run/operation.js +2 -2
- package/dist/cli/renderers/bug/text.js +1 -1
- package/dist/cli/renderers/discover/report.js +1 -1
- package/dist/cli/renderers/run/events.js +2 -2
- package/dist/cli/renderers/run/formatting.js +1 -1
- package/dist/cli/renderers/run/status.js +1 -1
- package/dist/cli/renderers/run/text-reporter.js +24 -22
- package/dist/cli/terminal/colors.js +1 -1
- package/dist/cli/terminal/layout.js +2 -2
- package/dist/config/authoring/database-fixture-discovery.js +1 -0
- package/dist/config/authoring/http-methods.js +1 -1
- package/dist/config/authoring/index.js +1 -1
- package/dist/config/loader/config-loader.js +1 -1
- package/dist/config/loader/decode-discovery.js +1 -1
- package/dist/config/loader/decode-execution.js +1 -1
- package/dist/config/loader/dependencies.js +1 -1
- package/dist/config/loader/discover-tests.js +1 -1
- package/dist/config/loader/discovery-summary.js +1 -1
- package/dist/config/loader/discovery.js +2 -2
- package/dist/config/loader/env.js +1 -1
- package/dist/config/loader/file-metadata.js +1 -1
- package/dist/config/loader/groups.js +2 -1
- package/dist/config/loader/index.js +1 -1
- package/dist/config/loader/load.js +1 -1
- package/dist/config/loader/managed-configs.js +1 -1
- package/dist/config/loader/owned-discovery.js +1 -0
- package/dist/config/loader/path-policy.js +1 -1
- package/dist/config/loader/runtime-isolation.js +1 -1
- package/dist/config/loader/runtime.js +1 -1
- package/dist/config/loader/skip-config.js +1 -1
- package/dist/config/loader/task-policy.js +1 -0
- package/dist/config/loader/test-selection.js +1 -1
- package/dist/config/loader/validation.js +1 -1
- package/dist/database/admin.js +2 -2
- package/dist/database/bindings.js +1 -0
- package/dist/database/cleanup.js +1 -1
- package/dist/database/configured-steps.js +1 -1
- package/dist/database/docker-metadata.js +3 -3
- package/dist/database/docker.js +3 -3
- package/dist/database/index.js +1 -1
- package/dist/database/local-postgres.js +1 -1
- package/dist/database/naming.js +1 -1
- package/dist/database/postgres/connection-check.js +1 -0
- package/dist/database/postgres/protocol.js +2 -0
- package/dist/database/schema-operations.js +1 -1
- package/dist/database/schema-source.js +3 -3
- package/dist/database/source-schema-env.js +1 -0
- package/dist/database/state-files.js +1 -1
- package/dist/database/state.js +1 -1
- package/dist/database/steps.js +3 -3
- package/dist/domain/file-timeout.js +1 -1
- package/dist/domain/identifiers.js +1 -1
- package/dist/domain/retired-test-types.js +1 -0
- package/dist/domain/runtime-isolation-contract.js +1 -1
- package/dist/domain/suite-selection.js +1 -1
- package/dist/domain/test-types.js +1 -1
- package/dist/engines/adapters/evidence-files.js +1 -1
- package/dist/engines/adapters/execution.js +1 -1
- package/dist/engines/adapters/json-bounds.js +2 -0
- package/dist/engines/adapters/native-report.js +1 -1
- package/dist/engines/api/execution.js +1 -1
- package/dist/engines/api/index.js +1 -1
- package/dist/engines/api/runtime-artifact.js +1 -1
- package/dist/engines/catalog.js +1 -1
- package/dist/engines/contracts/environment-values.js +1 -0
- package/dist/engines/definitions.js +1 -1
- package/dist/engines/environment/handles.js +1 -0
- package/dist/engines/environment/index.js +1 -0
- package/dist/engines/factory.js +1 -1
- package/dist/engines/installations/node-vitest.js +1 -1
- package/dist/engines/installations/package-resolution.js +1 -1
- package/dist/engines/installations/playwright.js +1 -1
- package/dist/engines/managed-module-resolution.js +8 -4
- package/dist/engines/manager.js +1 -1
- package/dist/engines/node-vitest/adapter/adapter.js +1 -1
- package/dist/engines/node-vitest/adapter/driver.js +2 -0
- package/dist/engines/node-vitest/adapter/evidence.js +2 -2
- package/dist/engines/node-vitest/adapter/failure-details.js +4 -2
- package/dist/engines/node-vitest/adapter/reporter.js +1 -1
- package/dist/engines/node-vitest/adapter/workspace.js +17 -195
- package/dist/engines/node-vitest/inventory/index.js +2 -0
- package/dist/engines/node-vitest/inventory/list-files.js +3 -0
- package/dist/engines/node-vitest/runtime/data/index.js +1 -1
- package/dist/engines/node-vitest/runtime/data/report.js +5 -6
- package/dist/engines/node-vitest/runtime/data/scenario.js +2 -2
- package/dist/engines/node-vitest/runtime/runtime-input.js +1 -1
- package/dist/engines/node-vitest/selection.js +1 -0
- package/dist/engines/playwright/adapter/adapter.js +1 -1
- package/dist/engines/playwright/adapter/config.js +3 -3
- package/dist/engines/playwright/adapter/evidence-validation.js +1 -1
- package/dist/engines/playwright/adapter/evidence.js +1 -1
- package/dist/engines/playwright/adapter/reporter.js +1 -1
- package/dist/engines/playwright/runtime/config-file.js +1 -1
- package/dist/engines/playwright/runtime/config.js +1 -1
- package/dist/engines/playwright/runtime/managed-test.js +1 -0
- package/dist/engines/playwright/runtime/runtime-input.js +29 -10
- package/dist/engines/runtime-input-file.js +1 -1
- package/dist/environment/lifecycle-controller.js +1 -1
- package/dist/environment/lifecycle.js +1 -1
- package/dist/environment/ready-environment.js +1 -1
- package/dist/environment/run-environment.js +1 -1
- package/dist/environment/run-stopping.js +1 -1
- package/dist/environment/runtime-contexts.js +1 -1
- package/dist/environment/runtime-manager.js +1 -1
- package/dist/environment/runtime-planning.js +1 -1
- package/dist/environment/runtime-preparation.js +1 -1
- package/dist/environment/services.js +3 -3
- package/dist/environment/template.js +1 -1
- package/dist/evidence/artifact-config.js +1 -1
- package/dist/evidence/artifacts.js +2 -2
- package/dist/evidence/bundles.js +1 -1
- package/dist/evidence/environment-record.js +1 -1
- package/dist/evidence/index.js +1 -1
- package/dist/evidence/maintenance.js +1 -0
- package/dist/evidence/read-run.js +1 -1
- package/dist/evidence/reading.js +1 -1
- package/dist/evidence/redaction.js +4 -0
- package/dist/evidence/reporting.js +1 -1
- package/dist/evidence/run-model.js +1 -0
- package/dist/evidence/storage.js +2 -2
- package/dist/evidence/timing.js +1 -1
- package/dist/kernel/error-serialization.js +1 -1
- package/dist/kernel/known-keys.js +1 -0
- package/dist/kernel/redaction-targets.js +1 -0
- package/dist/kernel/redaction.js +4 -1
- package/dist/kernel/unknown-values.js +1 -1
- package/dist/process/environment.js +1 -1
- package/dist/process/execa-bundle.json +3 -3
- package/dist/process/files/json-file.js +1 -1
- package/dist/process/host/platform.js +1 -1
- package/dist/process/host-process.js +1 -1
- package/dist/process/index.js +1 -1
- package/dist/process/locks.js +4 -4
- package/dist/process/port-listener.js +2 -0
- package/dist/process/process-group.js +1 -1
- package/dist/process/process.js +32 -32
- package/dist/process/readiness.js +1 -1
- package/dist/process/ready-deadline.js +1 -0
- package/dist/process/runs/ownership.js +1 -1
- package/dist/process/runs/stop.js +1 -1
- package/dist/process/service-processes.js +1 -1
- package/dist/process/windows-cli-owner.js +3 -3
- package/dist/process/windows-native.js +1 -1
- package/dist/repo/fingerprint-policy.js +1 -1
- package/dist/repo/managed-git.js +1 -1
- package/dist/repo/physical-tree.js +1 -1
- package/dist/repo/state.js +4 -4
- package/dist/steps/build-config.js +1 -1
- package/dist/steps/configured-step-testkit-modules.js +1 -1
- package/dist/steps/configured-steps.js +1 -1
- package/dist/steps/environment.js +1 -1
- package/dist/steps/index.js +1 -1
- package/dist/toolchains/index.js +3 -3
- package/dist/toolchains/semver.js +1 -1
- package/dist/toolchains/vitest/index.js +1 -1
- package/dist/tracker/redaction.js +1 -2
- package/dist/{config/runtime/build-assets.d.ts → types/config-build-assets.d.ts} +5 -3
- package/dist/{database/steps.d.ts → types/config-database-steps.d.ts} +7 -7
- package/dist/{config/runtime/next-runtime-tsconfig.d.ts → types/config-next-runtime-tsconfig.d.ts} +5 -3
- package/dist/types/config.d.ts +422 -0
- package/dist/types/drizzle.d.ts +13 -0
- package/dist/{config/runtime/env/index.d.ts → types/env.d.ts} +22 -20
- package/dist/types/environment.d.ts +46 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/node-vitest-data.d.ts +191 -0
- package/dist/types/playwright.d.ts +130 -0
- package/dist/types/tooling-vitest.d.ts +13 -0
- package/dist/types/workspace.d.ts +633 -0
- package/docs/bug-records.md +35 -40
- package/docs/engines.md +259 -0
- package/docs/release-notes.md +2116 -0
- package/docs/test-types.md +37 -85
- package/package.json +22 -32
- package/testkit-config-schema.md +391 -260
- package/dist/app/bugs/areas.d.ts +0 -38
- package/dist/app/bugs/assessment.d.ts +0 -9
- package/dist/app/bugs/categories.d.ts +0 -41
- package/dist/app/bugs/ci-report.d.ts +0 -21
- package/dist/app/bugs/ci-summary.d.ts +0 -13
- package/dist/app/bugs/draft.d.ts +0 -70
- package/dist/app/bugs/facts.d.ts +0 -49
- package/dist/app/bugs/file.d.ts +0 -45
- package/dist/app/bugs/gate.d.ts +0 -22
- package/dist/app/bugs/guide.d.ts +0 -20
- package/dist/app/bugs/issue.d.ts +0 -18
- package/dist/app/bugs/known-failures.d.ts +0 -49
- package/dist/app/bugs/record.d.ts +0 -14
- package/dist/app/bugs/run-reading.d.ts +0 -51
- package/dist/app/bugs/store.d.ts +0 -34
- package/dist/app/campaigns/brief.d.ts +0 -7
- package/dist/app/campaigns/campaign.d.ts +0 -14
- package/dist/app/campaigns/index.d.ts +0 -38
- package/dist/app/campaigns/store.d.ts +0 -5
- package/dist/app/campaigns/summary.d.ts +0 -13
- package/dist/app/cleanup/index.d.ts +0 -52
- package/dist/app/db-schema/prepare.d.ts +0 -11
- package/dist/app/db-schema/refresh.d.ts +0 -17
- package/dist/app/db-schema/verify.d.ts +0 -11
- package/dist/app/destroy/index.d.ts +0 -16
- package/dist/app/discover/index.d.ts +0 -8
- package/dist/app/doctor/index.d.ts +0 -17
- package/dist/app/environments/config-driven.d.ts +0 -5
- package/dist/app/environments/routing.d.ts +0 -6
- package/dist/app/environments/supplied.d.ts +0 -3
- package/dist/app/file-selection.d.ts +0 -1
- package/dist/app/inspect/artifacts.d.ts +0 -30
- package/dist/app/inspect/index.d.ts +0 -112
- package/dist/app/lint/index.d.ts +0 -28
- package/dist/app/lint/native.d.ts +0 -10
- package/dist/app/lint/options.d.ts +0 -66
- package/dist/app/lint/policy.d.ts +0 -21
- package/dist/app/lint/rules/data.d.ts +0 -3
- package/dist/app/lint/rules/data.js +0 -1
- package/dist/app/lint/rules/engine-imports.d.ts +0 -3
- package/dist/app/lint/rules/syntax.d.ts +0 -4
- package/dist/app/lint/rules/unit.d.ts +0 -3
- package/dist/app/lint/shared.d.ts +0 -34
- package/dist/app/package-inspection.d.ts +0 -20
- package/dist/app/reports/files.d.ts +0 -13
- package/dist/app/reports/prepare.d.ts +0 -20
- package/dist/app/reports/publish.d.ts +0 -21
- package/dist/app/run/endpoint-readiness.d.ts +0 -43
- package/dist/app/run/endpoint-readiness.js +0 -1
- package/dist/app/run/engine-evidence-persistence.d.ts +0 -39
- package/dist/app/run/engine-execution-cleanup.d.ts +0 -8
- package/dist/app/run/engine-execution-cleanup.js +0 -1
- package/dist/app/run/engine-execution-failures.d.ts +0 -41
- package/dist/app/run/engine-execution-observer.d.ts +0 -21
- package/dist/app/run/engine-execution-reporting.d.ts +0 -17
- package/dist/app/run/engine-execution.d.ts +0 -65
- package/dist/app/run/engine-failure-stack.d.ts +0 -1
- package/dist/app/run/engine-orchestration.d.ts +0 -30
- package/dist/app/run/environment.d.ts +0 -33
- package/dist/app/run/failure-details.d.ts +0 -37
- package/dist/app/run/live-run.d.ts +0 -29
- package/dist/app/run/operation-progress.d.ts +0 -13
- package/dist/app/run/orchestrator.d.ts +0 -75
- package/dist/app/run/planning-types.d.ts +0 -68
- package/dist/app/run/planning.d.ts +0 -14
- package/dist/app/run/request.d.ts +0 -30
- package/dist/app/run/results.d.ts +0 -161
- package/dist/app/run/run-events.d.ts +0 -144
- package/dist/app/run/run-finalization.d.ts +0 -56
- package/dist/app/run/run-guards.d.ts +0 -3
- package/dist/app/run/runtime-failures.d.ts +0 -18
- package/dist/app/run/runtime-fixtures.d.ts +0 -2
- package/dist/app/run/runtime-task-types.d.ts +0 -20
- package/dist/app/run/scheduler/estimates.d.ts +0 -32
- package/dist/app/run/scheduler/identity.d.ts +0 -9
- package/dist/app/run/scheduler/index.d.ts +0 -124
- package/dist/app/run/scheduler/locks.d.ts +0 -6
- package/dist/app/run/scheduler/observations.d.ts +0 -20
- package/dist/app/run/selection.d.ts +0 -9
- package/dist/app/run/setup/runtime-node-setup-errors.d.ts +0 -13
- package/dist/app/run/setup/runtime-node-setup-protocol.d.ts +0 -85
- package/dist/app/run/setup/runtime-node-setup-worker.d.ts +0 -1
- package/dist/app/run/setup/runtime-node-setup.d.ts +0 -48
- package/dist/app/run/task-batches.d.ts +0 -23
- package/dist/app/run/task-leases.d.ts +0 -15
- package/dist/app/run/worker-loop.d.ts +0 -66
- package/dist/app/setup/playwright.d.ts +0 -22
- package/dist/app/status/index.d.ts +0 -9
- package/dist/app/status/model.d.ts +0 -29
- package/dist/app/status/runs.d.ts +0 -99
- package/dist/app/stop/index.d.ts +0 -14
- package/dist/app/tracker/index.d.ts +0 -13
- package/dist/app/tracker/remote.d.ts +0 -13
- package/dist/app/tracker/token.d.ts +0 -7
- package/dist/app/typecheck/index.d.ts +0 -63
- package/dist/cli/command-catalog.d.ts +0 -156
- package/dist/cli/command-flags.d.ts +0 -19
- package/dist/cli/command-registry.d.ts +0 -3
- package/dist/cli/commands/artifacts.d.ts +0 -48
- package/dist/cli/commands/bug/file.d.ts +0 -16
- package/dist/cli/commands/bug/guide.d.ts +0 -5
- package/dist/cli/commands/bug/record.d.ts +0 -9
- package/dist/cli/commands/campaign/finish.d.ts +0 -10
- package/dist/cli/commands/campaign/start.d.ts +0 -7
- package/dist/cli/commands/campaign/status.d.ts +0 -13
- package/dist/cli/commands/ci/report.d.ts +0 -15
- package/dist/cli/commands/cleanup.d.ts +0 -13
- package/dist/cli/commands/db/schema/refresh.d.ts +0 -2
- package/dist/cli/commands/db/schema/verify.d.ts +0 -2
- package/dist/cli/commands/destroy.d.ts +0 -9
- package/dist/cli/commands/discover.d.ts +0 -2
- package/dist/cli/commands/doctor.d.ts +0 -2
- package/dist/cli/commands/guard/unsafe-entrypoint.d.ts +0 -2
- package/dist/cli/commands/lint.d.ts +0 -2
- package/dist/cli/commands/report/prepare.d.ts +0 -12
- package/dist/cli/commands/report/publish.d.ts +0 -13
- package/dist/cli/commands/run/status.d.ts +0 -5
- package/dist/cli/commands/run/stop.d.ts +0 -7
- package/dist/cli/commands/run.d.ts +0 -9
- package/dist/cli/commands/setup/playwright.d.ts +0 -2
- package/dist/cli/commands/status.d.ts +0 -5
- package/dist/cli/commands/stop.d.ts +0 -12
- package/dist/cli/commands/typecheck.d.ts +0 -2
- package/dist/cli/commands/workspace.d.ts +0 -2
- package/dist/cli/entrypoint.d.ts +0 -1
- package/dist/cli/framework/command.d.ts +0 -21
- package/dist/cli/framework/definitions.d.ts +0 -100
- package/dist/cli/framework/errors.d.ts +0 -6
- package/dist/cli/framework/execute.d.ts +0 -14
- package/dist/cli/framework/help.d.ts +0 -11
- package/dist/cli/framework/index.d.ts +0 -3
- package/dist/cli/framework/parser.d.ts +0 -6
- package/dist/cli/index.d.ts +0 -4
- package/dist/cli/json-errors.d.ts +0 -3
- package/dist/cli/operations/db/schema/refresh/operation.d.ts +0 -7
- package/dist/cli/operations/db/schema/verify/operation.d.ts +0 -7
- package/dist/cli/operations/run/operation.d.ts +0 -26
- package/dist/cli/process-signal.d.ts +0 -1
- package/dist/cli/renderers/bug/text.d.ts +0 -8
- package/dist/cli/renderers/campaign/text.d.ts +0 -2
- package/dist/cli/renderers/ci/text.d.ts +0 -2
- package/dist/cli/renderers/cleanup/format.d.ts +0 -14
- package/dist/cli/renderers/db-schema/text.d.ts +0 -4
- package/dist/cli/renderers/destroy/text.d.ts +0 -4
- package/dist/cli/renderers/discover/report.d.ts +0 -7
- package/dist/cli/renderers/discover/text.d.ts +0 -3
- package/dist/cli/renderers/doctor/text.d.ts +0 -2
- package/dist/cli/renderers/lint/text.d.ts +0 -2
- package/dist/cli/renderers/run/events.d.ts +0 -8
- package/dist/cli/renderers/run/failure.d.ts +0 -8
- package/dist/cli/renderers/run/formatting.d.ts +0 -79
- package/dist/cli/renderers/run/status.d.ts +0 -6
- package/dist/cli/renderers/run/text-reporter.d.ts +0 -19
- package/dist/cli/renderers/status/text.d.ts +0 -2
- package/dist/cli/renderers/stop/text.d.ts +0 -7
- package/dist/cli/renderers/typecheck/text.d.ts +0 -2
- package/dist/cli/terminal/colors.d.ts +0 -10
- package/dist/cli/terminal/layout.d.ts +0 -11
- package/dist/cli/version-drift.d.ts +0 -25
- package/dist/config/authoring/build-config-contract.d.ts +0 -27
- package/dist/config/authoring/configured-step-contract.d.ts +0 -18
- package/dist/config/authoring/http-execution-contract.d.ts +0 -70
- package/dist/config/authoring/http-methods.d.ts +0 -18
- package/dist/config/authoring/index.d.ts +0 -372
- package/dist/config/authoring/preset-env.d.ts +0 -19
- package/dist/config/authoring/runtime.d.ts +0 -64
- package/dist/config/authoring/runtime.js +0 -1
- package/dist/config/loader/bugs.d.ts +0 -15
- package/dist/config/loader/config-loader.d.ts +0 -9
- package/dist/config/loader/database-materialization.d.ts +0 -19
- package/dist/config/loader/database-roles.d.ts +0 -2
- package/dist/config/loader/database.d.ts +0 -55
- package/dist/config/loader/decode-discovery.d.ts +0 -5
- package/dist/config/loader/decode-execution.d.ts +0 -7
- package/dist/config/loader/dependencies.d.ts +0 -7
- package/dist/config/loader/discover-tests.d.ts +0 -111
- package/dist/config/loader/discovery-summary.d.ts +0 -29
- package/dist/config/loader/discovery.d.ts +0 -53
- package/dist/config/loader/env.d.ts +0 -4
- package/dist/config/loader/execution-model.d.ts +0 -15
- package/dist/config/loader/file-metadata.d.ts +0 -19
- package/dist/config/loader/groups.d.ts +0 -33
- package/dist/config/loader/index.d.ts +0 -10
- package/dist/config/loader/load.d.ts +0 -89
- package/dist/config/loader/managed-configs.d.ts +0 -23
- package/dist/config/loader/path-policy.d.ts +0 -9
- package/dist/config/loader/paths.d.ts +0 -5
- package/dist/config/loader/runtime-isolation.d.ts +0 -44
- package/dist/config/loader/runtime.d.ts +0 -16
- package/dist/config/loader/skip-config.d.ts +0 -44
- package/dist/config/loader/test-selection.d.ts +0 -15
- package/dist/config/loader/validation.d.ts +0 -15
- package/dist/config/loader/values.d.ts +0 -3
- package/dist/config/loader/values.js +0 -1
- package/dist/database/activity-gate.d.ts +0 -22
- package/dist/database/admin.d.ts +0 -31
- package/dist/database/cleanup.d.ts +0 -36
- package/dist/database/configured-steps.d.ts +0 -27
- package/dist/database/constants.d.ts +0 -11
- package/dist/database/docker-metadata.d.ts +0 -3
- package/dist/database/docker.d.ts +0 -65
- package/dist/database/drizzle/index.d.ts +0 -13
- package/dist/database/fingerprint.d.ts +0 -12
- package/dist/database/index.d.ts +0 -39
- package/dist/database/lifecycle-cleanup.d.ts +0 -8
- package/dist/database/local-postgres.d.ts +0 -71
- package/dist/database/naming.d.ts +0 -17
- package/dist/database/postgres/index.d.ts +0 -71
- package/dist/database/progress.d.ts +0 -6
- package/dist/database/roles.d.ts +0 -19
- package/dist/database/runtime-config.d.ts +0 -16
- package/dist/database/runtime-reservations.d.ts +0 -19
- package/dist/database/schema-operations.d.ts +0 -18
- package/dist/database/schema-source.d.ts +0 -96
- package/dist/database/source-refresh-lock.d.ts +0 -8
- package/dist/database/source-url.d.ts +0 -21
- package/dist/database/state-files.d.ts +0 -13
- package/dist/database/state.d.ts +0 -26
- package/dist/database/template-steps.d.ts +0 -39
- package/dist/domain/file-timeout.d.ts +0 -25
- package/dist/domain/identifiers.d.ts +0 -9
- package/dist/domain/operation-display.d.ts +0 -10
- package/dist/domain/operation-reason.d.ts +0 -5
- package/dist/domain/postgres-route.d.ts +0 -4
- package/dist/domain/runtime-identity.d.ts +0 -1
- package/dist/domain/runtime-isolation-contract.d.ts +0 -5
- package/dist/domain/service-name.d.ts +0 -2
- package/dist/domain/suite-selection.d.ts +0 -20
- package/dist/domain/test-outcomes.d.ts +0 -2
- package/dist/domain/test-types.d.ts +0 -16
- package/dist/engines/adapters/evidence-files.d.ts +0 -32
- package/dist/engines/adapters/evidence-identity.d.ts +0 -12
- package/dist/engines/adapters/execution.d.ts +0 -41
- package/dist/engines/adapters/native-report.d.ts +0 -25
- package/dist/engines/adapters/node-startup-cache.d.ts +0 -8
- package/dist/engines/adapters/workspace.d.ts +0 -4
- package/dist/engines/api/capabilities.d.ts +0 -21
- package/dist/engines/api/capabilities.js +0 -1
- package/dist/engines/api/evidence.d.ts +0 -38
- package/dist/engines/api/execution-observer.d.ts +0 -8
- package/dist/engines/api/execution-scope.d.ts +0 -17
- package/dist/engines/api/execution.d.ts +0 -101
- package/dist/engines/api/index.d.ts +0 -5
- package/dist/engines/api/k6-runtime-input.d.ts +0 -26
- package/dist/engines/api/k6-runtime-input.js +0 -1
- package/dist/engines/api/runtime-artifact.d.ts +0 -19
- package/dist/engines/bundle-cache.d.ts +0 -32
- package/dist/engines/catalog.d.ts +0 -27
- package/dist/engines/contracts/fixture-manifest.d.ts +0 -34
- package/dist/engines/contracts/json-bounds.d.ts +0 -36
- package/dist/engines/contracts/json-bounds.js +0 -2
- package/dist/engines/contracts/k6-repository-configuration.d.ts +0 -12
- package/dist/engines/contracts/k6-repository-configuration.js +0 -1
- package/dist/engines/contracts/test-context.d.ts +0 -15
- package/dist/engines/contracts/test-context.js +0 -1
- package/dist/engines/definitions.d.ts +0 -23
- package/dist/engines/factory.d.ts +0 -6
- package/dist/engines/generated-performance.d.ts +0 -1
- package/dist/engines/installation-catalog.d.ts +0 -27
- package/dist/engines/installation-catalog.js +0 -1
- package/dist/engines/installations/k6.d.ts +0 -98
- package/dist/engines/installations/k6.js +0 -1
- package/dist/engines/installations/node-vitest.d.ts +0 -33
- package/dist/engines/installations/package-requirements.d.ts +0 -28
- package/dist/engines/installations/package-resolution.d.ts +0 -51
- package/dist/engines/installations/playwright-resolution-child.d.ts +0 -1
- package/dist/engines/installations/playwright.d.ts +0 -75
- package/dist/engines/installations/types.d.ts +0 -10
- package/dist/engines/k6/adapter/bundle.d.ts +0 -25
- package/dist/engines/k6/adapter/bundle.js +0 -112
- package/dist/engines/k6/adapter/evidence.d.ts +0 -15
- package/dist/engines/k6/adapter/evidence.js +0 -4
- package/dist/engines/k6/adapter/executor.d.ts +0 -13
- package/dist/engines/k6/adapter/executor.js +0 -1
- package/dist/engines/k6/adapter/index.d.ts +0 -1
- package/dist/engines/k6/adapter/index.js +0 -1
- package/dist/engines/k6/adapter/input.d.ts +0 -21
- package/dist/engines/k6/adapter/input.js +0 -1
- package/dist/engines/k6/adapter/native-summary.d.ts +0 -11
- package/dist/engines/k6/adapter/native-summary.js +0 -1
- package/dist/engines/k6/adapter/repository-configuration.d.ts +0 -2
- package/dist/engines/k6/adapter/repository-configuration.js +0 -1
- package/dist/engines/k6/authoring-type-paths.d.ts +0 -3
- package/dist/engines/k6/authoring-type-paths.js +0 -1
- package/dist/engines/k6/runtime/ambient-types/bundle-manifest.json +0 -146
- package/dist/engines/k6/runtime/ambient-types/k6/LICENSE +0 -21
- package/dist/engines/k6/runtime/ambient-types/k6/browser/index.d.ts +0 -6332
- package/dist/engines/k6/runtime/ambient-types/k6/crypto/index.d.ts +0 -218
- package/dist/engines/k6/runtime/ambient-types/k6/data/index.d.ts +0 -16
- package/dist/engines/k6/runtime/ambient-types/k6/encoding/index.d.ts +0 -46
- package/dist/engines/k6/runtime/ambient-types/k6/execution/index.d.ts +0 -127
- package/dist/engines/k6/runtime/ambient-types/k6/experimental/csv/index.d.ts +0 -96
- package/dist/engines/k6/runtime/ambient-types/k6/experimental/fs/index.d.ts +0 -104
- package/dist/engines/k6/runtime/ambient-types/k6/experimental/redis/index.d.ts +0 -821
- package/dist/engines/k6/runtime/ambient-types/k6/experimental/streams/index.d.ts +0 -198
- package/dist/engines/k6/runtime/ambient-types/k6/global.d.ts +0 -83
- package/dist/engines/k6/runtime/ambient-types/k6/html/index.d.ts +0 -1325
- package/dist/engines/k6/runtime/ambient-types/k6/http/index.d.ts +0 -806
- package/dist/engines/k6/runtime/ambient-types/k6/index.d.ts +0 -126
- package/dist/engines/k6/runtime/ambient-types/k6/metrics/index.d.ts +0 -66
- package/dist/engines/k6/runtime/ambient-types/k6/net/grpc/index.d.ts +0 -247
- package/dist/engines/k6/runtime/ambient-types/k6/options/index.d.ts +0 -459
- package/dist/engines/k6/runtime/ambient-types/k6/package.json +0 -79
- package/dist/engines/k6/runtime/ambient-types/k6/secrets/index.d.ts +0 -36
- package/dist/engines/k6/runtime/ambient-types/k6/timers/index.d.ts +0 -47
- package/dist/engines/k6/runtime/ambient-types/k6/websockets/index.d.ts +0 -324
- package/dist/engines/k6/runtime/ambient-types/k6/ws/index.d.ts +0 -283
- package/dist/engines/k6/runtime/ambient-types/xk6-sql/LICENSE +0 -201
- package/dist/engines/k6/runtime/ambient-types/xk6-sql/index.d.ts +0 -397
- package/dist/engines/k6/runtime/ambient-types/xk6-sql/package.json +0 -15
- package/dist/engines/k6/runtime/artifacts.d.ts +0 -2
- package/dist/engines/k6/runtime/artifacts.js +0 -1
- package/dist/engines/k6/runtime/checks.d.ts +0 -17
- package/dist/engines/k6/runtime/checks.js +0 -1
- package/dist/engines/k6/runtime/dal-fixtures.d.ts +0 -24
- package/dist/engines/k6/runtime/dal-fixtures.js +0 -1
- package/dist/engines/k6/runtime/dal-suite.d.ts +0 -24
- package/dist/engines/k6/runtime/dal-suite.js +0 -1
- package/dist/engines/k6/runtime/dal.d.ts +0 -10
- package/dist/engines/k6/runtime/dal.js +0 -1
- package/dist/engines/k6/runtime/fixtures.d.ts +0 -3
- package/dist/engines/k6/runtime/fixtures.js +0 -1
- package/dist/engines/k6/runtime/http-assertions.d.ts +0 -19
- package/dist/engines/k6/runtime/http-assertions.js +0 -1
- package/dist/engines/k6/runtime/http-checks.d.ts +0 -19
- package/dist/engines/k6/runtime/http-checks.js +0 -1
- package/dist/engines/k6/runtime/http-suite-runtime.d.ts +0 -103
- package/dist/engines/k6/runtime/http-suite-runtime.js +0 -1
- package/dist/engines/k6/runtime/http.d.ts +0 -15
- package/dist/engines/k6/runtime/http.js +0 -1
- package/dist/engines/k6/runtime/index.d.ts +0 -11
- package/dist/engines/k6/runtime/index.js +0 -1
- package/dist/engines/k6/runtime/input.d.ts +0 -3
- package/dist/engines/k6/runtime/input.js +0 -1
- package/dist/engines/k6/runtime/k6-repository-configuration.d.ts +0 -9
- package/dist/engines/k6/runtime/k6-repository-configuration.js +0 -1
- package/dist/engines/k6/runtime/node-setup.d.ts +0 -13
- package/dist/engines/k6/runtime/node-setup.js +0 -1
- package/dist/engines/k6/runtime/runtime-globals.d.ts +0 -10
- package/dist/engines/k6/runtime/runtime.d.ts +0 -54
- package/dist/engines/k6/runtime/runtime.js +0 -1
- package/dist/engines/k6/runtime/shared/assertion-details.d.ts +0 -19
- package/dist/engines/k6/runtime/shared/assertion-details.js +0 -2
- package/dist/engines/k6/runtime/shared/db-normalization.d.ts +0 -19
- package/dist/engines/k6/runtime/shared/db-normalization.js +0 -1
- package/dist/engines/k6/runtime/shared/error-body.d.ts +0 -3
- package/dist/engines/k6/runtime/shared/error-body.js +0 -1
- package/dist/engines/k6/runtime/shared/file-data.d.ts +0 -1
- package/dist/engines/k6/runtime/shared/file-data.js +0 -1
- package/dist/engines/k6/runtime/shared/fixture-engine.d.ts +0 -8
- package/dist/engines/k6/runtime/shared/fixture-engine.js +0 -2
- package/dist/engines/k6/runtime/shared/http-check-plan.d.ts +0 -29
- package/dist/engines/k6/runtime/shared/http-check-plan.js +0 -1
- package/dist/engines/k6/runtime/shared/http-parsing.d.ts +0 -10
- package/dist/engines/k6/runtime/shared/http-parsing.js +0 -3
- package/dist/engines/k6/runtime/shared/ordering.d.ts +0 -2
- package/dist/engines/k6/runtime/shared/ordering.js +0 -1
- package/dist/engines/k6/runtime/shared/properties.d.ts +0 -1
- package/dist/engines/k6/runtime/shared/properties.js +0 -1
- package/dist/engines/k6/runtime/suite.d.ts +0 -4
- package/dist/engines/k6/runtime/suite.js +0 -1
- package/dist/engines/k6/runtime/types.d.ts +0 -244
- package/dist/engines/k6/runtime/types.js +0 -1
- package/dist/engines/k6/runtime/xk6-sql-driver-postgres.d.ts +0 -7
- package/dist/engines/k6/runtime/xk6-sql-driver-postgres.js +0 -1
- package/dist/engines/managed-module-resolution-policy-input.d.ts +0 -8
- package/dist/engines/managed-module-resolution-policy.d.ts +0 -25
- package/dist/engines/managed-module-resolution.d.ts +0 -13
- package/dist/engines/manager.d.ts +0 -25
- package/dist/engines/node-vitest/adapter/adapter.d.ts +0 -16
- package/dist/engines/node-vitest/adapter/consumer-typescript-paths.d.ts +0 -17
- package/dist/engines/node-vitest/adapter/consumer-typescript-paths.js +0 -3
- package/dist/engines/node-vitest/adapter/evidence.d.ts +0 -33
- package/dist/engines/node-vitest/adapter/failure-details.d.ts +0 -3
- package/dist/engines/node-vitest/adapter/index.d.ts +0 -1
- package/dist/engines/node-vitest/adapter/reporter.d.ts +0 -7
- package/dist/engines/node-vitest/adapter/resolution.d.ts +0 -12
- package/dist/engines/node-vitest/adapter/resolution.js +0 -1
- package/dist/engines/node-vitest/adapter/workspace.d.ts +0 -19
- package/dist/engines/node-vitest/runtime/contract/index.d.ts +0 -64
- package/dist/engines/node-vitest/runtime/contract/index.js +0 -1
- package/dist/engines/node-vitest/runtime/data/http.d.ts +0 -4
- package/dist/engines/node-vitest/runtime/data/http.js +0 -1
- package/dist/engines/node-vitest/runtime/data/index.d.ts +0 -8
- package/dist/engines/node-vitest/runtime/data/primitives.d.ts +0 -1
- package/dist/engines/node-vitest/runtime/data/report.d.ts +0 -3
- package/dist/engines/node-vitest/runtime/data/runner.d.ts +0 -4
- package/dist/engines/node-vitest/runtime/data/runner.js +0 -1
- package/dist/engines/node-vitest/runtime/data/scenario.d.ts +0 -11
- package/dist/engines/node-vitest/runtime/data/types.d.ts +0 -384
- package/dist/engines/node-vitest/runtime/runtime-input.d.ts +0 -64
- package/dist/engines/playwright/adapter/adapter.d.ts +0 -18
- package/dist/engines/playwright/adapter/attachments.d.ts +0 -26
- package/dist/engines/playwright/adapter/config.d.ts +0 -45
- package/dist/engines/playwright/adapter/evidence-validation.d.ts +0 -9
- package/dist/engines/playwright/adapter/evidence.d.ts +0 -32
- package/dist/engines/playwright/adapter/failure-details.d.ts +0 -2
- package/dist/engines/playwright/adapter/index.d.ts +0 -3
- package/dist/engines/playwright/adapter/reporter.d.ts +0 -12
- package/dist/engines/playwright/runtime/config-file.d.ts +0 -2
- package/dist/engines/playwright/runtime/config.d.ts +0 -24
- package/dist/engines/playwright/runtime/index.d.ts +0 -4
- package/dist/engines/playwright/runtime/runtime-input.d.ts +0 -36
- package/dist/engines/playwright/runtime/sandbox.d.ts +0 -84
- package/dist/engines/runtime-input-file.d.ts +0 -27
- package/dist/environment/lifecycle-artifacts.d.ts +0 -7
- package/dist/environment/lifecycle-controller.d.ts +0 -60
- package/dist/environment/lifecycle.d.ts +0 -32
- package/dist/environment/maintenance.d.ts +0 -68
- package/dist/environment/planning-types.d.ts +0 -33
- package/dist/environment/ports.d.ts +0 -10
- package/dist/environment/ready-environment.d.ts +0 -16
- package/dist/environment/run-environment.d.ts +0 -39
- package/dist/environment/run-stopping.d.ts +0 -13
- package/dist/environment/runtime-contexts.d.ts +0 -37
- package/dist/environment/runtime-manager.d.ts +0 -87
- package/dist/environment/runtime-planning.d.ts +0 -16
- package/dist/environment/runtime-preparation.d.ts +0 -30
- package/dist/environment/runtime-service.d.ts +0 -12
- package/dist/environment/services.d.ts +0 -56
- package/dist/environment/state.d.ts +0 -15
- package/dist/environment/status-runtime.d.ts +0 -53
- package/dist/environment/template.d.ts +0 -164
- package/dist/evidence/artifact-config.d.ts +0 -14
- package/dist/evidence/artifact-validation.d.ts +0 -4
- package/dist/evidence/artifacts.d.ts +0 -75
- package/dist/evidence/bundles.d.ts +0 -27
- package/dist/evidence/ci-provenance.d.ts +0 -9
- package/dist/evidence/contracts.d.ts +0 -154
- package/dist/evidence/environment-record.d.ts +0 -22
- package/dist/evidence/file-evidence.d.ts +0 -23
- package/dist/evidence/finalization.d.ts +0 -9
- package/dist/evidence/index.d.ts +0 -8
- package/dist/evidence/logs.d.ts +0 -31
- package/dist/evidence/operation-timings.d.ts +0 -60
- package/dist/evidence/read-bundle.d.ts +0 -4
- package/dist/evidence/read-fields.d.ts +0 -21
- package/dist/evidence/read-provenance.d.ts +0 -2
- package/dist/evidence/read-redaction.d.ts +0 -2
- package/dist/evidence/read-retention.d.ts +0 -2
- package/dist/evidence/read-run.d.ts +0 -2
- package/dist/evidence/reading.d.ts +0 -28
- package/dist/evidence/reporting-types.d.ts +0 -349
- package/dist/evidence/reporting.d.ts +0 -3
- package/dist/evidence/secure-file-copy.d.ts +0 -24
- package/dist/evidence/setup-progress.d.ts +0 -63
- package/dist/evidence/step-output.d.ts +0 -16
- package/dist/evidence/storage-inventory.d.ts +0 -27
- package/dist/evidence/storage.d.ts +0 -25
- package/dist/evidence/timing.d.ts +0 -23
- package/dist/file.d.ts +0 -11
- package/dist/index.d.ts +0 -4
- package/dist/kernel/error-serialization.d.ts +0 -40
- package/dist/kernel/redaction.d.ts +0 -2
- package/dist/kernel/unknown-values.d.ts +0 -11
- package/dist/kernel/work-metrics.d.ts +0 -6
- package/dist/process/capture-output.d.ts +0 -7
- package/dist/process/command-shell.d.ts +0 -1
- package/dist/process/environment-overlay.d.ts +0 -17
- package/dist/process/environment.d.ts +0 -33
- package/dist/process/files/contained-path.d.ts +0 -8
- package/dist/process/files/directory-status.d.ts +0 -14
- package/dist/process/files/dotenv.d.ts +0 -2
- package/dist/process/files/file-snapshot.d.ts +0 -34
- package/dist/process/files/json-file.d.ts +0 -11
- package/dist/process/files/paths.d.ts +0 -3
- package/dist/process/files/product-dir.d.ts +0 -1
- package/dist/process/files/temp-dir.d.ts +0 -11
- package/dist/process/host/metadata.d.ts +0 -6
- package/dist/process/host/platform.d.ts +0 -57
- package/dist/process/host-command.d.ts +0 -4
- package/dist/process/host-inspection-command.d.ts +0 -13
- package/dist/process/host-process.d.ts +0 -19
- package/dist/process/index.d.ts +0 -9
- package/dist/process/lifecycle-fence.d.ts +0 -10
- package/dist/process/locks.d.ts +0 -28
- package/dist/process/process-contracts.d.ts +0 -78
- package/dist/process/process-group.d.ts +0 -12
- package/dist/process/process-identity.d.ts +0 -27
- package/dist/process/process-limits.d.ts +0 -6
- package/dist/process/process.d.ts +0 -12
- package/dist/process/readiness.d.ts +0 -43
- package/dist/process/recovery.d.ts +0 -3
- package/dist/process/runs/inspection.d.ts +0 -5
- package/dist/process/runs/manifest.d.ts +0 -86
- package/dist/process/runs/ownership.d.ts +0 -11
- package/dist/process/runs/product-state.d.ts +0 -2
- package/dist/process/runs/schema.d.ts +0 -3
- package/dist/process/runs/stop.d.ts +0 -19
- package/dist/process/runtime-socket.d.ts +0 -4
- package/dist/process/service-processes.d.ts +0 -13
- package/dist/process/shutdown.d.ts +0 -10
- package/dist/process/stoppable-settlement.d.ts +0 -26
- package/dist/process/url-redaction.d.ts +0 -1
- package/dist/process/windows-cli-owner.d.ts +0 -2
- package/dist/process/windows-native.d.ts +0 -12
- package/dist/process/windows-process-identity.d.ts +0 -4
- package/dist/repo/ci-environment.d.ts +0 -7
- package/dist/repo/fingerprint-policy.d.ts +0 -13
- package/dist/repo/git-path.d.ts +0 -2
- package/dist/repo/history.d.ts +0 -17
- package/dist/repo/managed-git.d.ts +0 -10
- package/dist/repo/metadata.d.ts +0 -3
- package/dist/repo/physical-tree.d.ts +0 -37
- package/dist/repo/publish-directory.d.ts +0 -20
- package/dist/repo/remote.d.ts +0 -6
- package/dist/repo/state.d.ts +0 -26
- package/dist/repo/tree-listing.d.ts +0 -10
- package/dist/steps/build-config.d.ts +0 -34
- package/dist/steps/configured-step-testkit-modules.d.ts +0 -19
- package/dist/steps/configured-steps.d.ts +0 -51
- package/dist/steps/environment.d.ts +0 -82
- package/dist/steps/index.d.ts +0 -2
- package/dist/steps/module-runner.d.ts +0 -1
- package/dist/steps/run.d.ts +0 -36
- package/dist/toolchains/archive.d.ts +0 -53
- package/dist/toolchains/esbuild.d.ts +0 -9
- package/dist/toolchains/host-node-support.d.ts +0 -3
- package/dist/toolchains/index.d.ts +0 -114
- package/dist/toolchains/managed-node-releases.d.ts +0 -28
- package/dist/toolchains/node-cache.d.ts +0 -20
- package/dist/toolchains/node-integrity.d.ts +0 -18
- package/dist/toolchains/node-provisioning.d.ts +0 -29
- package/dist/toolchains/semver.d.ts +0 -13
- package/dist/toolchains/shared-operation.d.ts +0 -11
- package/dist/toolchains/timeouts.d.ts +0 -1
- package/dist/toolchains/vitest/index.d.ts +0 -13
- package/dist/tracker/gitea.d.ts +0 -14
- package/dist/tracker/github.d.ts +0 -14
- package/dist/tracker/http.d.ts +0 -33
- package/dist/tracker/index.d.ts +0 -4
- package/dist/tracker/redaction.d.ts +0 -4
- package/dist/tracker/requests.d.ts +0 -17
- package/dist/tracker/responses.d.ts +0 -24
- package/dist/tracker/types.d.ts +0 -51
- package/docs/engine-architecture.md +0 -682
- /package/dist/engines/{k6/runtime/runtime-globals.js → api/profiles.js} +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import k from"node:fs";import y from"node:path";import{readBugPolicy as
|
|
2
|
-
`),
|
|
1
|
+
import k from"node:fs";import y from"node:path";import{readBugPolicy as v}from"../../config/loader/bugs.js";import{loadTestkitConfig as g}from"../../config/loader/index.js";import{resolveCiProvenance as T}from"../../evidence/ci-provenance.js";import{loadLatestRun as h}from"../../evidence/reading.js";import{resolveTracker as w}from"../tracker/index.js";import{assessRun as q}from"./assessment.js";import{ciReportMarker as P,readCiContext as b,renderCiSummary as U}from"./ci-summary.js";import{describeRunOutcome as x}from"./known-failures.js";import{readRun as D}from"./run-reading.js";import{resolveBugCheckout as F}from"./store.js";const R="Testkit found no results for this commit";export async function reportCiRun(t){const r=b(t.context),e=await F(t),s=v((await g(e.productDir)).config),a={env:t.env,productDir:e.productDir};let u=null;const l=()=>(u??=w(a),u),{repository:m}=s,o=await q(B(e),m===null?l:()=>w({...a,repository:m})),n=x(o.outcome,s.knownFailures==="allow"),i=e.pullRequestHeadCommit??e.headCommit,c=T(t.env).runUrl,d=U({...o,commit:i,context:r,knownFailuresAllowed:s.knownFailures==="allow",runUrl:c,status:n}),C=I(t.env,d),p=await l();await p.setCommitStatus({...n,context:r,sha:i,targetUrl:c});const S=e.pullRequest===null?null:await p.upsertPullRequestComment({body:d,marker:P(r),pullRequest:e.pullRequest}),f=o.outcome.kind==="tests-failed"?o.outcome.classification:{known:[],new:[]};return{comment:S,commit:i,context:r,description:n.description,known:f.known,new:f.new,pullRequest:e.pullRequest,state:n.state,stepSummary:C,trackerProblem:o.trackerProblem,unreadableIssues:o.unreadableIssues}}function B(t){if(!k.existsSync(y.join(t.productDir,".testkit","results","latest.json")))return{kind:"run-failed",reason:R};const r=h(t.productDir);return r.git.commitSha!==t.headCommit?{kind:"run-failed",reason:R}:D(r,t.productPath)}function I(t,r){const e=t.GITHUB_STEP_SUMMARY?.trim()??"";return e.length===0?null:(k.appendFileSync(e,`${r}
|
|
2
|
+
`),e)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import"./known-failures.js";import{redactBugText as T,redactRunResultText as I}from"../../tracker/redaction.js";export const DEFAULT_CI_CONTEXT="testkit";const k=/^[A-Za-z0-9][A-Za-z0-9 ._/:-]{0,59}$/u,p=12,l=50,b=10,d=160,w=/^https?:\/\/[^\s()<>]+$/u;export function readCiContext(e){if(e===void 0)return DEFAULT_CI_CONTEXT;if(!k.test(e)||e!==e.trim())throw new Error(`--context must be 1 to 60 characters, start with an ASCII letter or a digit, not end with a space, and hold only ASCII letters, digits, spaces, and the characters . _ / : and -. Received ${JSON.stringify(e)}.`);return e}export function ciReportMarker(e){return e===DEFAULT_CI_CONTEXT?"<!-- testkit-ci-report -->":`<!-- testkit-ci-report:${e} -->`}export function renderCiSummary(e){const{context:t,outcome:n}=e,r=[ciReportMarker(t),t===DEFAULT_CI_CONTEXT?"## Testkit":`## Testkit: ${t}`,E(e),`Commit \`${e.commit.slice(0,p)}\`.${h("CI run",e.runUrl," ",".")}`];if(n.kind==="tests-failed"){const{known:a,new:i}=n.classification;if(i.length>0&&r.push("### New failures",f(i.map(s=>`- ${c(s.file)}: ${$(s)}`))),a.length>0&&r.push("### Known failures",f(a.map(({failure:s,issue:o})=>`- ${c(s.file)}: ${$(s)}, ${g(o.issue,o.url)}`))),e.trackerProblem!==null&&r.push(`Testkit could not read the open bugs, so every failure counts as new. ${m(e.trackerProblem,400)}`),e.unreadableIssues.length>0){const s=e.unreadableIssues.slice(0,b).map(u=>g(u.number,u.url)),o=e.unreadableIssues.length-s.length;r.push(`Testkit cannot read the facts block of ${_(e.unreadableIssues.length,"open `testkit` issue")}, so ${e.unreadableIssues.length===1?"it matches":"they match"} no test: ${s.join(", ")}${o>0?`, and ${String(o)} more`:""}.`)}}return`${r.join(`
|
|
2
2
|
|
|
3
3
|
`)}
|
|
4
|
-
`}function
|
|
5
|
-
`)}function h(e,n
|
|
4
|
+
`}function E({knownFailuresAllowed:e,outcome:t,status:n}){return t.kind==="passed"?`${n.description}.`:t.kind==="run-failed"?`The run failed outside its tests. ${c(t.reason,400)}`:t.classification.new.length>0?`${n.description}.`:e?`${n.description}. Every failure is a known bug and \`bugs.knownFailures\` is \`"allow"\`, so the run passes.`:`${n.description}. Every failure is a known bug, and \`bugs.knownFailures\` is \`"fail"\`, so the run fails.`}function f(e){const t=e.length-l;return[...e.slice(0,l),...t>0?[`- and ${String(t)} more`]:[]].join(`
|
|
5
|
+
`)}function h(e,t,n="",r=""){return t!==null&&w.test(t)?`${n}[${e}](${t})${r}`:""}function $(e){return e.title===null?"failed without naming a test":c(e.title)}function g(e,t){const n=`#${String(e)}`;return h(n,t)||n}function _(e,t){return`${String(e)} ${t}${e===1?"":"s"}`}function c(e,t=d){return m(I(e),t)}function m(e,t=d){const n=Array.from(T(e.replace(/\s+/gu," ").trim())),r=n.length>t?`${n.slice(0,t-3).join("")}...`:n.join("");if(r.length===0)return"an empty name";const a=Math.max(0,...[...r.matchAll(/`+/gu)].map(s=>s[0].length)),i="`".repeat(a+1);return r.startsWith("`")||r.endsWith("`")?`${i} ${r} ${i}`:`${i}${r}${i}`}
|
package/dist/app/bugs/draft.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import G from"node:crypto";import
|
|
1
|
+
import G from"node:crypto";import A from"node:path";import{isPublicTestType as j}from"../../domain/identifiers.js";import{isUnknownRecord as g}from"../../kernel/unknown-values.js";import{BUG_CATCHERS as O,BUG_CAUSES as P,BUG_CONFIDENCES as C,BUG_ESCAPES as U,BUG_IMPACTS as F,BUG_SEVERITIES as R,categoryIds as _,isOneOf as E}from"./categories.js";import{BUG_FACTS_TEST_TYPES as z,decodeFaultLines as D,isCommitId as $}from"./facts.js";import{redactBugText as B}from"../../tracker/redaction.js";import{isTimestamp as w}from"../campaigns/campaign.js";export const BUG_DRAFT_SCHEMA_VERSION=1,BUG_TITLE_MAX_LENGTH=200,BUG_SECTION_MAX_LENGTH=12e3;const V=48,L=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;export const CAMPAIGN_ID_MAX_LENGTH=60;export class BugRecordError extends Error{problems;constructor(e,n){super(`${e}:
|
|
2
2
|
${n.map(s=>`- ${s}`).join(`
|
|
3
|
-
`)}`),this.name="BugRecordError",this.problems=n}}export function isCampaignId(t){return typeof t=="string"&&t.length<=CAMPAIGN_ID_MAX_LENGTH&&
|
|
4
|
-
${t.test.title}`).digest("hex");return`${e||"bug"}-${n.slice(0,8)}`}export function isBugDraftId(t){return typeof t=="string"&&/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/u.test(t)}export function namesSameTest(t,e){return t.test.file===e.test.file&&t.test.title===e.test.title}function I(t,e,n){const s=(
|
|
3
|
+
`)}`),this.name="BugRecordError",this.problems=n}}export function isCampaignId(t){return typeof t=="string"&&t.length<=CAMPAIGN_ID_MAX_LENGTH&&L.test(t)}export function testTypeOfFile(t){const e=/\.([a-z0-9]+)\.testkit\.ts$/u.exec(t)?.[1];return j(e)?e:null}function M(t){const e=/\.([a-z0-9]+)\.testkit\.ts$/u.exec(t)?.[1];return z.find(n=>n===e)??null}export function toRepositoryPath(t,e){const n=e.replaceAll("\\","/");if(n.startsWith("/")||/^[a-z]:/iu.test(n))return null;const s=A.posix.normalize(A.posix.join(t,n));return s==="."||s===".."||s.startsWith("../")?null:s}export function toProductPath(t,e){return t===""?e:A.posix.relative(t,e)}export function readBugReport(t,e){if(!g(t))throw new BugRecordError("The bug record is invalid",["it must be a JSON object"]);const n=[],s=[],u=I(t,n,{path:r=>toRepositoryPath(e,r),text:(r,d)=>{const a=B(r);return a!==r&&s.push(d),a}});if(n.length>0)throw new BugRecordError("The bug record is invalid",n);return{redactedFields:s,report:u}}export function createBugDraft(t,e){const n=testTypeOfFile(t.test.file);return{schemaVersion:BUG_DRAFT_SCHEMA_VERSION,id:bugDraftId(t),recordedAt:e.recordedAt.toISOString(),recordedCommit:e.recordedCommit,productPath:e.productPath,caughtBy:e.campaign===null?"manual":"campaign",...e.campaign===null?{}:{campaign:e.campaign},...n===null?{}:{testType:n},...e.vitest===void 0?{}:{vitest:e.vitest},...t}}export function requireOneVitestProject(t,e,n){if(e.length<2||n.project!==null)return;const s=e.map(({project:u})=>JSON.stringify(u)).join(", ");throw new Error(`test.file ${t} runs in the Vitest projects ${s}. Name the one whose run fails with --vitest-project.`)}export function readBugDraft(t){const e="The bug draft is unreadable";if(!g(t))throw new BugRecordError(e,["it must be a JSON object"]);if(t.schemaVersion!==BUG_DRAFT_SCHEMA_VERSION)throw new BugRecordError(e,[`unknown schemaVersion ${JSON.stringify(t.schemaVersion)}`]);const n=[],s=(p,y,b,x)=>y(p)?p:(n.push(x),b),u=I(t,n,{path:p=>toRepositoryPath("",p),text:p=>p}),r=t.testType===void 0&&testTypeOfFile(u.test.file)===null?null:M(u.test.file);t.testType!==(r??void 0)&&n.push(r===null?"testType must be absent for a test file without a type":"testType does not match test.file");const d=s(t.caughtBy,J,"manual","caughtBy must be campaign or manual"),a=s(t.campaign,k,void 0,"campaign must be a campaign id");d==="campaign"!=(a!==void 0)&&n.push("campaign must be present when caughtBy is campaign and absent otherwise");const T={schemaVersion:BUG_DRAFT_SCHEMA_VERSION,id:s(t.id,isBugDraftId,"","id is not a draft id"),recordedAt:s(t.recordedAt,w,"","recordedAt must be a timestamp"),recordedCommit:s(t.recordedCommit,$,"","recordedCommit must be a full commit id"),productPath:s(t.productPath,N,"","productPath must be a string"),caughtBy:d,...a===void 0?{}:{campaign:a},...r===null?{}:{testType:r},...t.vitest===void 0?{}:{vitest:s(t.vitest,X,{},"vitest must hold runner, config and project text")},...u,...t.filed===void 0?{}:{filed:H(t.filed,n)}};if(n.length>0)throw new BugRecordError(e,n);return T}export function bugDraftId(t){const e=t.title.normalize("NFKD").replace(/\p{M}+/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").slice(0,V).replace(/^-+|-+$/gu,""),n=G.createHash("sha256").update(`${t.test.file}
|
|
4
|
+
${t.test.title}`).digest("hex");return`${e||"bug"}-${n.slice(0,8)}`}export function isBugDraftId(t){return typeof t=="string"&&/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/u.test(t)}export function namesSameTest(t,e){return t.test.file===e.test.file&&t.test.title===e.test.title}function I(t,e,n){const s=(i,o,c,f)=>{const m=i[o];if(typeof m!="string"||m.trim().length===0)return e.push(`${c} must be a non-empty string`),"";const h=m.trim(),l=h.length>f?h:n.text(h,c);return l.length>f&&e.push(`${c} must be at most ${String(f)} characters`),l},u=(i,o,c)=>{const f=i[o],m=typeof f=="string"?f.trim():"",h=m.length>0?n.path(m):null;return h===null?e.push(`${c} must be a path inside the repository`):[m,h].some(l=>B(l)!==l)&&e.push(`${c} is a path that holds text Testkit redacts as a secret`),h??""},r=(i,o,c)=>E(i,o)?o:(e.push(`${c} must be one of ${i.join(", ")}`),i[0]),d=i=>{const o=t[i];return g(o)?o:(e.push(`${i} must be an object`),{})},a=(i,o,c)=>{const f=s(i,o,c,BUG_TITLE_MAX_LENGTH);return/[\r\n]/u.test(f)&&e.push(`${c} must be one line`),f},T=a(t,"title","title"),p=d("test"),y=d("fault"),b=d("confidence"),x=u(p,"file","test.file");let S=[1,1];try{S=D(y.lines)}catch(i){e.push(i instanceof Error?i.message:"fault.lines is invalid")}return{title:T,severity:r(R,t.severity,"severity"),expected:s(t,"expected","expected",BUG_SECTION_MAX_LENGTH),authority:s(t,"authority","authority",BUG_SECTION_MAX_LENGTH),observed:s(t,"observed","observed",BUG_SECTION_MAX_LENGTH),rootCause:s(t,"rootCause","rootCause",BUG_SECTION_MAX_LENGTH),test:{file:x,title:a(p,"title","test.title")},fault:{lines:S,path:u(y,"path","fault.path")},cause:r(_(P),t.cause,"cause"),impact:r(_(F),t.impact,"impact"),confidence:{cause:r(C,b.cause,"confidence.cause"),impact:r(C,b.impact,"confidence.impact")},escape:r(_(U),t.escape,"escape")}}function H(t,e){return g(t)&&w(t.filedAt)&&$(t.foundAt)&&typeof t.number=="number"&&Number.isSafeInteger(t.number)&&t.number>=1&&typeof t.url=="string"?{filedAt:t.filedAt,foundAt:t.foundAt,number:t.number,url:t.url}:(e.push("filed must hold filedAt, foundAt, number, and url"),{filedAt:"",foundAt:"",number:0,url:""})}function k(t){return t===void 0||isCampaignId(t)}function J(t){return E(O,t)}function X(t){return g(t)&&Object.values(t).every(N)}function N(t){return typeof t=="string"}
|
package/dist/app/bugs/file.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import b from"node:fs";import p from"node:path";import{readAreaMap as C,readBugPolicy as O}from"../../config/loader/bugs.js";import{loadTestkitConfig as D}from"../../config/loader/index.js";import{findIntroducingCommit as j,listRemoteRefsContaining as x,listUncommittedTrackedFiles as B}from"../../repo/history.js";import{listCommitFiles as N}from"../../repo/tree-listing.js";import{resolveTracker as _}from"../tracker/index.js";import{isTypedTestFile as P}from"../../domain/identifiers.js";import{rejectRetiredTestFile as L}from"../../domain/retired-test-types.js";import{listPlainVitestFiles as M,resolveVitestSelection as J}from"../../engines/catalog.js";import{resolveFaultArea as q}from"./areas.js";import{requireOneVitestProject as K,toProductPath as g}from"./draft.js";import{FACTS_END_MARKER as U,FACTS_START_MARKER as V,readFactsBlock as W,renderFactsBlock as T}from"./facts.js";import{bugFacts as G,bugLabels as H,renderBugIssue as Q,reproduceCommand as y,TESTKIT_LABEL as z}from"./issue.js";import{findKnownTest as X,readKnownTests as Y}from"./known-failures.js";import{holdsRedaction as Z,redactBugText as w}from"../../tracker/redaction.js";import{readEnvironmentFile as E}from"../environments/environment-file.js";import{resolveSuppliedInput as k,suppliedBindings as tt}from"../environments/supplied-input.js";import{suppliedReproduceArgs as et}from"./supplied-reproduce.js";import{bugDraftFile as rt,displayPath as v,readStoredDrafts as it,resolveBugCheckout as st,writeJsonFile as ot}from"./store.js";const nt=12,R=10;export async function prepareBugFiling(t){const i=et(t.supplied??{}),e=await st(t),{draft:r,file:s}=lt(e,t.id);if(r.filed!==void 0)return{draft:r,issue:{number:r.filed.number,url:r.filed.url},status:"already-filed"};L(r.test.file),requireNoSecretInCommand(r),t.supplied!==void 0&&at(t.supplied,e,t.env);const o=I(e.headCommit),a=await N(e.repoRoot,e.headCommit);for(const c of[r.test.file,r.fault.path])if(!a.some(m=>m.path===c))throw new Error(`${c} is not in commit ${o}. Commit it and push the commit, then run this again.`);const l=(await B(e.repoRoot)).filter(c=>!ut(e,c));if(l.length>0)throw new Error(`Tracked files have uncommitted changes: ${ft(l)}. The issue says that the test fails at ${o}, so commit or discard the changes first.`);if((await x(e.repoRoot,e.headCommit)).length===0)throw new Error(`No remote branch contains commit ${o}. Push it, then run this again. The issue points readers to the test at that commit.`);const{config:u}=await D(e.productDir),d=dt(q(C(u),a,r.fault.path),r.fault.path),n=await j(e.repoRoot,e.headCommit,r.fault.path,r.fault.lines),f=await _({env:t.env,productDir:e.productDir,repository:O(u).repository??void 0});return F(await S(f),r.test),{checkout:e,draft:r,draftFile:s,filing:{area:d,foundAt:e.headCommit,introducedBy:n.status==="found"?n.commit:null},reproduceArgs:i,status:"ready",testFile:p.join(e.productDir,g(e.productPath,r.test.file)),tracker:f}}export async function bugRerun(t,i,e={},r=process.env){const{checkout:s,draft:o}=t,a=Object.entries(i).filter(([h,A])=>h.startsWith("vitest-")&&typeof A=="string"),l={...o.vitest,...Object.fromEntries(a)},u=Object.keys(l).length===0?o:{...o,vitest:l};requireNoSecretInCommand(u);const d=e.environmentFile,n=k(e,d===void 0?null:E(d,s.cwd),r),f=J(l,s.productDir,r),c=g(s.productPath,o.test.file),m=P(c)?[]:await M(s.productDir,{...f,host:{...f.host,...tt(n)}}),$=m.filter(h=>h.file===c);return K(o.test.file,$,f),{files:{...r,...n.env}.TESTKIT_REQUIRE_COMPLETE_SUITE==="1"&&$.length>0?[...new Set(m.map(({file:h})=>p.join(s.productDir,h)))]:[t.testFile],ready:{...t,draft:u}}}export async function fileBug(t,i,e={}){const{checkout:r,draft:s,filing:o,reproduceArgs:a,tracker:l}=t,u=requireRecordedFailure(s,i,I(r.headCommit),a);F(await S(l),u);const d=renderReadableBugIssue(s,o,a);await l.ensureLabels(H(s.severity,o.area));const n=await l.createIssue(d),f={...s,filed:{filedAt:(e.at??new Date).toISOString(),foundAt:o.foundAt,number:n.number,url:n.url}};return ot(t.draftFile,f),{area:o.area,covers:"test",draft:f,introducedBy:o.introducedBy,issue:{number:n.number,url:n.url},path:v(r,t.draftFile)}}export function renderReadableBugIssue(t,i,e=[]){const r=Q(t,i,e),s=W(r.body),o=T(G(t,i));if(s.status==="ok"&&T(s.facts)===o)return r;throw new Error(`Testkit cannot read back the facts of the issue it would file, so it files nothing. This happens when test.title, test.file, fault.path, or the area's name holds ${V} or ${U}. Rename the test, the file, or the area, then record the bug again.`)}export function requireNoSecretInCommand(t){const i=y(t);if(w(i)!==i)throw new Error("The command that reproduces this bug holds text that Testkit redacts as a secret, and an issue carries that command. The text is in the path of the product directory, in the test's path from that directory, or in a --vitest-config or --vitest-project selector. Rename what holds it, commit and push the change, then record the bug again.")}function at(t,i,e){const r=t.environmentFile;if(r!==void 0&&!p.isAbsolute(r)&&b.realpathSync.native(i.cwd)!==b.realpathSync.native(i.repoRoot))throw new Error(`The issue's reproduce command runs from the repository root, but --environment-file ${r} is relative to ${i.cwd}. Run testkit bug file from ${i.repoRoot}, or pass the file's absolute path.`);k(t,r===void 0?null:E(r,i.cwd),e)}export function requireRecordedFailure(t,i,e,r=[]){const{file:s,title:o}=t.test,a=`\`${y(t,r)}\``;if(i.kind==="passed")throw new Error(`${s} passed at ${e}, so Testkit has no failure to file. ${a} must fail.`);if(i.kind==="run-failed")throw new Error(`${a} failed outside its tests at ${e}: ${i.reason.replace(/\.?$/u,".")} Testkit files a bug when the test itself fails.`);const l=i.failures.filter(n=>n.file===s);if(l.length===0)throw new Error(`${a} failed at ${e}, but ${s} is not among the files that failed.`);const u=l.flatMap(n=>n.title===null?[]:[n.title]),d=u.filter(n=>!/[\r\n]/u.test(n)&&!Z(n)&&w(n)===n);if(d.includes(o)){if(l.some(n=>n.title===o&&n.ambiguous===!0))throw new Error(`${s} has more than one test titled ${JSON.stringify(o)} at ${e}. An issue names its test by file and title, so it could not say which of them failed. Give each test in the file its own title, commit and push the change, then record the bug again.`);return{file:s,title:o}}if(u.length>0){const n=u.length-d.length;throw new Error([`${s} failed at ${e}, but not under the title ${JSON.stringify(o)}.`,...d.length===0?[]:[`Testkit reported ${d.map(f=>JSON.stringify(f)).join(", ")}. Set test.title to the title Testkit reports, then record the bug again.`],...n===0?[]:[`Testkit ${d.length===0?"":"also "}reported ${n===1?"1 title that spans lines or holds":`${String(n)} titles that span lines or hold`} text it redacts as a secret. It files no bug under such a title. Rename the test, or label the assertion, so that its title is one line and holds no such text.`]].join(" "))}throw new Error(`${s} failed at ${e} without reaching a result, so Testkit cannot tell that ${JSON.stringify(o)} failed. A file fails this way when it crashes, times out, or does not load. Make the test fail on its assertion, then run this again.`)}async function S(t){return Y(await t.listOpenIssues(z)).tests}function F(t,i){const e=X(t,i);if(e===null)return;const r=`Open issue #${String(e.issue)}`;throw new Error(e.title===null?`${r} already covers the whole file ${i.file}: ${e.url}. While it is open, Testkit files no other bug for that file.`:`${r} already covers this test: ${e.url}. Testkit keeps one open bug for each test.`)}function lt(t,i){const e=it(t.productDir),r=e.drafts.find(a=>a.draft.id===i);if(r!==void 0)return r;const s=e.unreadable.find(a=>a.file===rt(t.productDir,i));if(s!==void 0)throw new Error(`Testkit cannot read ${v(t,s.file)}: ${s.problem}. Record the bug again with \`testkit bug record\`.`);const o=e.drafts.filter(a=>a.draft.filed===void 0).map(a=>a.draft.id);throw new Error(o.length===0?`No bug draft has the id ${JSON.stringify(i)}, and this checkout has no unfiled draft. Record the bug with \`testkit bug record\` first.`:`No bug draft has the id ${JSON.stringify(i)}. Unfiled drafts: ${o.join(", ")}.`)}function dt(t,i){if(t.status==="no-map")return null;const e="Fix `areas` in testkit.config.ts, commit and push the change, then run this again.";if(t.status==="resolved"){const{area:r}=t;if(w(r.name)===r.name)return r;throw new Error(`areas.${r.id}.name holds text that Testkit redacts as a secret, and an issue carries its area's name. ${e}`)}throw new Error(t.status==="unclaimed"?`No area claims ${i}. Every bug needs its fault in one area. ${e}`:`The areas ${t.areas.join(" and ")} both claim ${i}. A file belongs to one area. ${e}`)}function ut(t,i){return g(t.productPath,i).startsWith(".testkit/")}function ft(t){const i=t.length-R;return`${t.slice(0,R).join(", ")}${i>0?`, and ${String(i)} more`:""}`}function I(t){return t.slice(0,nt)}
|
package/dist/app/bugs/gate.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readBugPolicy as
|
|
1
|
+
import{readBugPolicy as d}from"../../config/loader/bugs.js";import{loadTestkitConfig as m}from"../../config/loader/index.js";import{resolveTracker as p}from"../tracker/index.js";import{assessRun as w}from"./assessment.js";import{readRunArtifact as k}from"./run-reading.js";import{resolveBugCheckout as g}from"./store.js";const h=1;export async function loadBugPolicy(o){return d((await m(o)).config)}export async function applyKnownFailures(o){const{env:e,exitCode:r,policy:t,productDir:n}=o,i={exitCode:r,knownFailures:null};if(t.knownFailures!=="allow"||r!==h||o.failedOutsideTests)return i;const l=await g({dir:n,env:e}).catch(()=>null),u=k(o.run,l?.productPath??""),{outcome:a,trackerProblem:f}=await w(u,()=>p({env:e,productDir:n,repository:t.repository??void 0}));if(a.kind!=="tests-failed")return i;const{known:s,new:c}=a.classification;return{exitCode:c.length===0&&s.length>0?0:r,knownFailures:{known:s,new:c,trackerProblem:f}}}
|
package/dist/app/bugs/guide.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{BUG_CAUSES as
|
|
1
|
+
import{BUG_CAUSES as i,BUG_CONFIDENCES as u,BUG_ESCAPES as a,BUG_IMPACTS as s,BUG_SEVERITIES as o}from"./categories.js";import{BUG_TITLE_MAX_LENGTH as r}from"./draft.js";import{SEVERITY_LABELS as h}from"./issue.js";export const BUG_RECORD_EXAMPLE={title:"A refund pays out twice when two requests overlap",severity:"high",expected:"A refund pays out once.",authority:'`docs/refunds.md`, "Refunds are idempotent on the order id".',observed:"Two overlapping refund requests for one order both pay out.",rootCause:"`refund()` reads the order's refund state and writes the payout without a lock.",test:{file:"src/checkout/refund.test.ts",title:"a refund pays out once"},fault:{path:"src/checkout/refunds.ts",lines:[41,58]},cause:"race-condition",impact:"financial-error",confidence:{cause:"high",impact:"high"},escape:"no-test"};const c=e=>e.map(t=>`\`${t}\``).join(", "),d=e=>`One of ${c(u)}. How sure you are of the ${e}.`,n=e=>({meaning:`One id from the ${e.field} list below.`,name:e.field});export const BUG_GUIDE={fields:[{name:"title",meaning:`One line of at most ${String(r)} characters that names the broken behaviour. It becomes the issue title.`},{name:"severity",meaning:`One of ${c(o)}. The severities are defined below.`},{name:"expected",meaning:"What the product should do."},{name:"authority",meaning:"The source that says so: documentation, a specification, an API contract, or the code's own stated intent. Name it and quote the part that applies."},{name:"observed",meaning:"What the product does instead."},{name:"rootCause",meaning:"Why the code behaves this way."},{name:"test.file",meaning:"The Testkit test file that fails because of the bug."},{name:"test.title",meaning:`The failure's title. It is one line of at most ${String(r)} characters.`},{name:"fault.path",meaning:"The source file that holds the mistake."},{name:"fault.lines",meaning:"The first and last faulty line as `[start, end]`, counted from 1. One faulty line is `[41, 41]`."},n(i),n(s),{name:"confidence.cause",meaning:d("cause")},{name:"confidence.impact",meaning:d("impact")},n(a)],rules:["Write `test.file` and `fault.path` relative to the product directory, the directory that holds `testkit.config.ts`.","`test.title` must be the failure's title exactly as Testkit reports it. In a Vitest or Playwright file, that is the names of the `describe` blocks around the test and the test's own name, joined by single spaces. When `testkit bug file` rejects the title, its message lists the titles a bug record can use.","Keep credentials, tokens, and passwords out of the record. Testkit redacts the secrets it recognises before it stores the record and again before it files the issue. It files no bug under a failure's title that holds text it redacts, so rename such a test or label such an assertion first."],example:BUG_RECORD_EXAMPLE,severities:o.map(e=>({definition:h[e].description,id:e})),categoryLists:[i,s,a]};export function renderBugGuide(e){return["## Bug record","Write one JSON object for each confirmed bug. Every field is required.",e.fields.map(t=>`- \`${t.name}\`: ${t.meaning}`).join(`
|
|
2
2
|
`),...e.rules,"Example:",["```json",JSON.stringify(e.example,null,2),"```"].join(`
|
|
3
3
|
`),"## Severities",e.severities.map(t=>`- \`${t.id}\`: ${t.definition}`).join(`
|
|
4
|
-
`),...e.categoryLists.flatMap(
|
|
4
|
+
`),...e.categoryLists.flatMap(l)].join(`
|
|
5
5
|
|
|
6
|
-
`)}function
|
|
6
|
+
`)}function l(e){return[`## ${e.field.charAt(0).toUpperCase()}${e.field.slice(1)}`,`The \`${e.field}\` field answers one question. ${e.question}`,e.assignmentRule,e.categories.map(t=>[`- \`${t.id}\`: ${t.definition}`,...t.boundaryRule===""?[]:[` Boundary rule: ${t.boundaryRule}`]].join(`
|
|
7
7
|
`)).join(`
|
|
8
8
|
`)]}
|
package/dist/app/bugs/issue.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{toProductPath as
|
|
2
|
-
`),[
|
|
3
|
-
`),p(bugFacts(o,t
|
|
1
|
+
import{toProductPath as l}from"./draft.js";import{renderFactsBlock as p}from"./facts.js";import{redactBugText as n}from"../../tracker/redaction.js";export const TESTKIT_LABEL="testkit",SEVERITY_LABEL_PREFIX="severity:",AREA_LABEL_PREFIX="area:";const d={color:"0f766e",description:"Filed by Testkit with a regression test.",name:TESTKIT_LABEL};export const SEVERITY_LABELS={critical:{color:"9f1239",description:"The product is unsafe to run or to trust."},high:{color:"e11d48",description:"A core behaviour is broken with no acceptable workaround."},medium:{color:"d97706",description:"A behaviour is broken and a workaround exists, or the reach is limited."},low:{color:"4d7c0f",description:"A minor defect with little consequence."}};const m="475569";export function bugLabels(e,t){return[d,{...SEVERITY_LABELS[e],name:`${SEVERITY_LABEL_PREFIX}${e}`},...t===null?[]:[{color:m,description:t.name,name:`${AREA_LABEL_PREFIX}${t.id}`}]]}export function bugFacts(e,t){return{v:1,cause:e.cause,impact:e.impact,confidence:e.confidence,escape:e.escape,caughtBy:e.caughtBy,...e.campaign===void 0?{}:{campaign:e.campaign},...e.testType===void 0?{}:{testType:e.testType},test:e.test,foundAt:t.foundAt,fault:e.fault,...t.area===null?{}:{area:t.area},...t.introducedBy===null?{}:{introducedBy:t.introducedBy,introducedMethod:"blame"}}}export function renderBugIssue(e,t,r=[]){const o=h(e),[i,c]=o.fault.lines,u=i===c?`line ${String(i)}`:`lines ${String(i)} to ${String(c)}`;return{body:`${["## Expected behaviour",o.expected,"## Authority",o.authority,"## Observed behaviour",o.observed,"## Root cause",o.rootCause,"## Reproduce",["```sh",reproduceCommand(o,r),"```"].join(`
|
|
2
|
+
`),[`Test: \`${o.test.file}\`, "${o.test.title}".`,`Found at \`${t.foundAt}\`.`,`Fault: \`${o.fault.path}\`, ${u}.`].join(`
|
|
3
|
+
`),p(bugFacts(o,t))].join(`
|
|
4
4
|
|
|
5
5
|
`)}
|
|
6
|
-
`,labels:bugLabels(o.severity,t.area).map(
|
|
6
|
+
`,labels:bugLabels(o.severity,t.area).map(a=>a.name),title:o.title}}function h(e){return{...e,title:n(e.title),expected:n(e.expected),authority:n(e.authority),observed:n(e.observed),rootCause:n(e.rootCause),test:{file:e.test.file,title:n(e.test.title)}}}export function reproduceCommand(e,t=[]){const r=l(e.productPath,e.test.file),o=e.productPath===""?`npx testkit run --file ${s(r)}`:`npx testkit run --dir ${s(e.productPath)} --file ${s(r)}`,i=Object.entries(e.vitest??{}).flatMap(([c,u])=>[`--${c}`,u]);return[o,...[...i,...t].map(s)].join(" ")}function s(e){return/^[\w./@:+=-]+$/u.test(e)?e:`'${e.replaceAll("'","'\\''")}'`}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFactsBlock as o}from"./facts.js";import{redactRunResultText as u}from"../../tracker/redaction.js";export const COMMIT_STATUS_DESCRIPTION_MAX_LENGTH=140;export function readKnownTests(n){const
|
|
1
|
+
import{readFactsBlock as o}from"./facts.js";import{redactRunResultText as u}from"../../tracker/redaction.js";export const COMMIT_STATUS_DESCRIPTION_MAX_LENGTH=140;export function readKnownTests(n){const t=[],i=[];for(const e of n){const s=o(e.body);if(s.status==="ok"){const{file:r,title:l}=s.facts.test;t.push({file:r,issue:e.number,title:l??null,url:e.url})}else{const r=s.status==="missing"?"the issue has no facts block":s.reason;i.push({number:e.number,reason:r,url:e.url})}}return{tests:t,unreadable:i}}export function findKnownTest(n,t){const i=n.filter(s=>s.file===t.file),e=i.find(s=>s.title===null)??null;return t.title===null?null:i.find(s=>s.title===t.title)??e}export function classifyFailures(n,t){const i=[],e=[];for(const s of n){const r=t===null?null:findKnownTest(t,s);r===null?e.push(s):i.push({failure:s,issue:r})}return{known:i,new:e}}export function describeRunOutcome(n,t){if(n.kind==="passed")return{description:`${n.passedFiles===1?"1 file":`${String(n.passedFiles)} files`} passed`,state:"success"};if(n.kind==="run-failed"){const s=u(n.reason);return{description:c(`run failed: ${s}`),state:"failure"}}const i=n.classification.known.length,e=n.classification.new.length;return{description:`${String(i+e)} failed: ${String(e)} new, ${String(i)} known`,state:e===0&&t?"success":"failure"}}function c(n){return n.length<=COMMIT_STATUS_DESCRIPTION_MAX_LENGTH?n:`${n.slice(0,COMMIT_STATUS_DESCRIPTION_MAX_LENGTH-3)}...`}
|
package/dist/app/bugs/record.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import c from"node:fs";import h from"node:path";import{text as b}from"node:stream/consumers";import{loadTestkitConfig as D}from"../../config/loader/index.js";import{discoverOwnedTests as k}from"../../config/loader/owned-discovery.js";import{isTypedTestFile as T}from"../../domain/identifiers.js";import{resolveVitestSelection as E}from"../../engines/catalog.js";import{posixPath as P}from"../../process/files/paths.js";import{findActiveCampaign as S,readCampaigns as F}from"../campaigns/store.js";import{BugRecordError as $,createBugDraft as x,namesSameTest as C,readBugReport as R,requireOneVitestProject as j,toProductPath as B}from"./draft.js";import{bugDraftFile as O,displayPath as y,displayUnreadableDrafts as J,readStoredDrafts as N,resolveBugCheckout as A,writeJsonFile as I}from"./store.js";export async function recordBug(o){const t=await A(o),{redactedFields:i,report:e}=U(await q(t.cwd,o.file),t.productPath);for(const[r,g]of[["test.file",e.test.file],["fault.path",e.fault.path]])if(c.statSync(h.join(t.repoRoot,g),{throwIfNoEntry:!1})?.isFile()!==!0)throw new Error(`${r} resolves to ${g} from the repository root, and no file is there. Write the path relative to the product directory.`);const{config:a}=await D(t.productDir),f=E(o.vitest??{},t.productDir),l=B(t.productPath,e.test.file),n=await k(t.productDir,a,{plain:!T(l),selection:f}),m=n.problems.at(0)??n.migration;if(m!==null)throw new Error(m);if(!n.project.files.some(r=>r.filePath===l))throw new Error(`test.file resolves to ${e.test.file}, and Testkit does not discover a test there. Run \`testkit discover\` to list the tests it runs.`);j(e.test.file,n.plainFiles.filter(({file:r})=>r===l),f);const d=x(e,{campaign:S(F(t.productDir))?.id??null,productPath:t.productPath,recordedAt:o.at??new Date,recordedCommit:t.headCommit,vitest:V(o.vitest??{},t.productDir,f)}),u=N(t.productDir),p=u.drafts.filter(r=>C(r.draft,d)),w=p.find(r=>r.draft.filed!==void 0)?.draft.filed;if(w!==void 0)throw new Error(`This test already has a filed bug: ${w.url}. Testkit keeps one bug for each test.`);const s=O(t.productDir,d.id),v=u.unreadable.find(r=>r.file===s);if(v!==void 0)throw new Error(`${y(t,s)} exists and Testkit cannot read it: ${v.problem}. Fix or delete the file, then run this again.`);I(s,d);for(const r of p)r.file!==s&&c.rmSync(r.file,{force:!0});return{draft:d,path:y(t,s),redactedFields:i,replaced:p.length>0,unreadableDrafts:J(t,u.unreadable)}}function V({"vitest-project":o,"vitest-runner":t},i,{config:e}){const a={...t===void 0?{}:{"vitest-runner":t},...e===null?{}:{"vitest-config":P(h.relative(c.realpathSync(i),e))},...o===void 0?{}:{"vitest-project":o}};return Object.keys(a).length===0?void 0:a}async function q(o,t){if(t==="-")return{source:"standard input",text:await b(process.stdin)};try{return{source:t,text:c.readFileSync(h.resolve(o,t),"utf8")}}catch(i){throw new Error(`Testkit cannot read the bug record file ${t}.`,{cause:i})}}function U(o,t){let i;try{i=JSON.parse(o.text)}catch(e){throw new Error(`The bug record in ${o.source} is not valid JSON.`,{cause:e})}try{return R(i,t)}catch(e){throw e instanceof $?new Error(`${e.message}
|
|
2
2
|
Run \`testkit bug guide\` to see the record format.`,{cause:e}):e}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isUnknownRecord as f}from"../../kernel/unknown-values.js";const
|
|
1
|
+
import{runModel as p}from"../../evidence/index.js";import{isUnknownRecord as f}from"../../kernel/unknown-values.js";const k=new Set(["engine-failure","playwright-other-file-spec","vitest-error"]),h=1;export function readRunArtifact(e,r){return readRun(p(e),r)}export function readRun(e,r){if(e.finalizationFailure!==null)return u(e.finalizationFailure.message);if(e.run.status==="interrupted")return u("the run was interrupted");const{cleanup:n,publication:o}=e.archive;if(o?.status==="failed"&&o.required)return u("Testkit could not publish the run's results");if(n?.status==="failed")return u("Testkit could not clean up after the run");const i=e.groups.flatMap(t=>t.errors).at(0);if(i!==void 0)return u(i);const s=e.groups.flatMap(t=>t.suites.flatMap(d=>d.files));if(s.some(t=>t.infraFailed===!0||t.blockedByRuntime===!0))return u("test infrastructure failure");if(s.some(t=>t.status==="not_run"))return u("one or more required test files did not run");if(s.some(t=>t.status==="skipped"))return u("one or more selected test files were skipped");const a=s.find(t=>t.status!=="passed"&&t.status!=="failed");if(a!==void 0)return u(`${a.path} ended as ${a.status}`);const l=s.filter(t=>t.status==="failed");return l.length>0?{failures:l.flatMap(t=>m(t,r)),kind:"tests-failed"}:e.run.status!=="passed"?u(s.length===0?"no runnable test files executed":"the run did not pass"):{kind:"passed",passedFiles:s.length}}function m(e,r){const n=r===""?e.path:`${r}/${e.path}`,o=e.failureDetails??[],i=o.filter(t=>!k.has(t.kind??"")),s=new Set(i.filter(g).map(c)),a=[...new Set(i.map(c))].map(t=>({...s.has(t)?{ambiguous:!0}:{},file:n,title:t}));return o.filter(t=>t.kind==="engine-failure"||t.kind==="vitest-error").map(t=>t.kind==="vitest-error"?"unexplained":F(t,i)).includes("unexplained")||a.length===0?[...a,{file:n,title:null}]:a}function g(e){return e.kind==="vitest-test"&&(e.sharedTitle===!0||typeof e.count=="number"&&e.count>1)}function c(e){const r=e.key?.trim()??"";return r===""?e.title:e.kind==="playwright-spec"?r:e.title}function F(e,r){const n=f(e.actual)&&f(e.actual.details)?e.actual.details:null;if(n===null)return"unexplained";if(e.key==="PLAYWRIGHT_SPECS_FAILED"){const o=y(r.filter(l=>l.kind==="playwright-spec")),i=f(n.stats)?n.stats:{},s=n.failOnFlakyTests!==!1&&i.flaky!==0;return i.unexpected===o&&n.reportErrors===0&&n.attachmentFailures===0&&n.evidenceErrors===0&&n.runStatus==="failed"&&n.exitCode===h&&typeof n.failOnFlakyTests=="boolean"&&!s?"restated":"unexplained"}return"unexplained"}function y(e){return e.reduce((r,n)=>r+(typeof n.count=="number"?n.count:1),0)}function u(e){return{kind:"run-failed",reason:e}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{redactBugText as a}from"../../tracker/redaction.js";const h=/^[A-Za-z_][A-Za-z0-9_]*$/u,d=/^[A-Za-z0-9][A-Za-z0-9._-]*$/u;export function suppliedReproduceArgs(e){if((e.database?.length??0)>0)throw s("--database NAME=URL","Put named databases in an --environment-file, or select the default database's URL from a host variable with --env-from DATABASE_URL=HOST_KEY.");if((e.env?.length??0)>0)throw s("--env NAME=VALUE","Select the value from a host variable with --env-from NAME=HOST_KEY, or put it in an --environment-file.");const r=[];e.baseUrl!==void 0&&r.push("--base-url",i(e.baseUrl,"--base-url"));for(const t of e.endpoint??[]){const n=t.indexOf("="),o=t.slice(0,Math.max(n,0));if(!d.test(o))throw new Error("--endpoint expects NAME=URL, where NAME uses only ASCII letters, digits, dot, underscore or hyphen and starts with a letter or digit");r.push("--endpoint",`${o}=${i(t.slice(n+1),`--endpoint ${o}`)}`)}for(const t of e.envFrom??[]){const n=t.split("=");if(n.length!==2||!n.every(o=>h.test(o)))throw new Error("--env-from expects NAME=HOST_KEY, where both are variable names");r.push("--env-from",t)}if(e.environmentFile!==void 0){if(a(e.environmentFile)!==e.environmentFile)throw new Error("The --environment-file path holds text that Testkit redacts as a secret, and the issue would carry it. Rename the file.");r.push("--environment-file",e.environmentFile)}return r}function i(e,r){let t;try{t=new URL(e)}catch{throw new Error(`${r} is not a valid URL`)}if(t.username!==""||t.password!==""||t.search!==""||t.hash!==""||a(e)!==e)throw new Error(`${r} carries credentials, a query or a fragment, and the issue's reproduce command would hold them. Supply that URL in an --environment-file instead.`);return e}function s(e,r){return new Error(`bug file does not take ${e}, because the issue's reproduce command would hold the raw value. ${r}`)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{redactSensitiveText as
|
|
1
|
+
import{redactSensitiveText as c}from"../../kernel/redaction.js";import{isUnknownRecord as p}from"../../kernel/unknown-values.js";import{CAMPAIGN_ID_MAX_LENGTH as i,isCampaignId as o}from"../bugs/draft.js";import{isCommitId as g}from"../bugs/facts.js";export const CAMPAIGN_SCHEMA_VERSION=1,CAMPAIGN_TARGET_MAX_LENGTH=200;const f=11;export function readCampaignTarget(t){const r=c(t.trim());if(r.length===0||r.length>CAMPAIGN_TARGET_MAX_LENGTH||/[\r\n]/u.test(r))throw new Error(`--target must be one line of 1 to ${String(CAMPAIGN_TARGET_MAX_LENGTH)} characters.`);return r}export function readCampaignId(t){if(o(t))return t;throw new Error(`--id must be lowercase letters, digits, and single hyphens, at most ${String(i)} characters. Got ${JSON.stringify(t)}.`)}export function defaultCampaignId(t,r){return`${t.normalize("NFKD").replace(/\p{M}+/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+/u,"").slice(0,i-f).replace(/-+$/u,"")||"campaign"}-${r.toISOString().slice(0,10)}`}export function readCampaign(t){if(!p(t))throw new Error("it must be a JSON object");if(t.schemaVersion!==CAMPAIGN_SCHEMA_VERSION)throw new Error(`unknown schemaVersion ${JSON.stringify(t.schemaVersion)}`);const r=[],e=(n,a,m)=>a(n)?n:(r.push(m),""),s={schemaVersion:CAMPAIGN_SCHEMA_VERSION,id:e(t.id,o,"id must be a campaign id"),target:e(t.target,d,"target must be one line of text"),startedAt:e(t.startedAt,isTimestamp,"startedAt must be a timestamp"),startCommit:e(t.startCommit,g,"startCommit must be a full commit id"),...t.finishedAt===void 0?{}:{finishedAt:e(t.finishedAt,isTimestamp,"finishedAt must be a timestamp")}};if(r.length>0)throw new Error(r.join(", "));return s}function d(t){return typeof t=="string"&&t.trim().length>0&&!/[\r\n]/u.test(t)}export function isTimestamp(t){return typeof t=="string"&&!Number.isNaN(Date.parse(t))}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
`),
|
|
1
|
+
import A from"node:fs";import c from"node:path";import{readAreaMap as x,readBugPolicy as I}from"../../config/loader/bugs.js";import{PLAIN_TEST_SUFFIX as P}from"../../config/loader/discovery.js";import{loadTestkitConfig as w}from"../../config/loader/index.js";import{listFilesChangedSince as j}from"../../repo/history.js";import{listCommitFiles as T}from"../../repo/tree-listing.js";import{measureAreaMap as E}from"../bugs/areas.js";import{displayPath as D,displayUnreadableDrafts as y,readStoredDrafts as S,resolveBugCheckout as u,writeJsonFile as F,writeTextFile as R}from"../bugs/store.js";import{renderCampaignBrief as B}from"./brief.js";import{defaultCampaignId as $,readCampaignId as L,readCampaignTarget as M}from"./campaign.js";import{campaignDir as k,findActiveCampaign as f,findLastFinishedCampaign as N,readCampaigns as p}from"./store.js";import{renderCampaignSummary as O}from"./summary.js";export async function startCampaign(a){const t=a.at??new Date,r=M(a.target),i=a.id===void 0?$(r,t):L(a.id),e=await u(a),n=f(p(e.productDir));if(n!==null)throw new Error(`Campaign ${n.id} is active in this checkout. Run \`testkit campaign finish\` before you start another.`);const s=k(e.productDir,i);if(A.existsSync(s))throw new Error(`${D(e,s)} already exists. Pass --id to give this campaign another id.`);const m=await v(e),d={schemaVersion:1,id:i,target:r,startedAt:t.toISOString(),startCommit:e.headCommit};return F(c.join(s,"campaign.json"),d),{areas:m,brief:B(d,m,e.productPath),campaign:d}}export async function readCampaignStatus(a){const t=await u(a),r=p(t.productDir),i=f(r),e=S(t.productDir),n=await v(t);return{active:i,areas:{areaCount:n.areas.length,doubleClaimCount:n.doubleClaims.length,unclaimedShare:n.unclaimedShare},drafts:i===null?[]:b(e.drafts,i.id),lastFinished:N(r),unreadableDrafts:y(t,e.unreadable)}}export async function finishCampaign(a){const t=await u(a),r=f(p(t.productDir));if(r===null)throw new Error("No campaign is active in this checkout. Run `testkit campaign start --target <text>` to start one.");const i={...r,finishedAt:(a.at??new Date).toISOString()},e=S(t.productDir),n=b(e.drafts,i.id),s=n.filter(o=>o.filed!==void 0),m=n.filter(o=>o.filed===void 0),{config:d}=await w(t.productDir),l=await j(t.repoRoot,i.startCommit),g=O({campaign:i,filed:s,headCommit:t.headCommit,knownFailures:I(d).knownFailures,testFiles:l===null?null:l.filter(o=>o.endsWith(".testkit.ts")||P.test(o)),unfiled:m,unreadableDrafts:y(t,e.unreadable).map(o=>o.file)}),h=k(t.productDir,i.id),C=c.join(h,"summary.md");return R(C,`${g}
|
|
2
|
+
`),F(c.join(h,"campaign.json"),i),{campaign:i,filed:s,headCommit:t.headCommit,summary:g,summaryPath:D(t,C),unfiled:m}}function b(a,t){return a.map(r=>r.draft).filter(r=>r.campaign===t)}async function v(a){const{config:t}=await w(a.productDir);return E(x(t),await T(a.repoRoot,a.headCommit))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{formatRunSummary as m}from"../../process/runs/manifest.js";import d from"path";import{pruneEmptyDir as p}from"../../process/files/directory-status.js";import f from"fs";import{loadManagedConfigs as v}from"../../config/loader/managed-configs.js";import{collectBundleCleanupTargets as g}from"../../engines/bundle-cache.js";import{createEnvironmentMaintenance as y}from"../../environment/maintenance.js";import{runtimePlanning as h}from"../../environment/runtime-planning.js";export async function cleanupEnvironment(e){const{allConfigs:
|
|
1
|
+
import{formatRunSummary as m}from"../../process/runs/manifest.js";import d from"path";import{pruneEmptyDir as p}from"../../process/files/directory-status.js";import f from"fs";import{loadManagedConfigs as v}from"../../config/loader/managed-configs.js";import{collectBundleCleanupTargets as g}from"../../engines/bundle-cache.js";import{createEnvironmentMaintenance as y}from"../../environment/maintenance.js";import{runtimePlanning as h}from"../../environment/runtime-planning.js";import{resolveProductDir as C}from"../../process/files/product-dir.js";export async function cleanupEnvironment(e){const r=C(process.cwd(),e.dir),{allConfigs:n}=await v({dir:r,service:e.service}),t=await cleanup(r,{allConfigs:n,serviceName:e.service||null,dryRun:e.dryRun,cache:e.cache,resources:e.resources}),a={cleaned:s(t.cleaned),stoppedActive:s(t.stoppedActive),skippedActive:s(t.skippedActive)};return{productDir:r,result:t,runSummaries:a}}export async function cleanup(e,r={}){const n=r.allConfigs??[],t=r.serviceName||null,a=R(r.cache),{environment:c,otherCaches:u}=await y(e).maintain({kind:"cleanup",desiredGraphs:h.collectDesiredRuntimeGraphs(n),serviceName:t,dryRun:!!r.dryRun,resources:!!r.resources},()=>{const i=a.includes("bundles")?g(e,{allConfigs:n,serviceName:t}):[],o=[];return{result:{targets:i,cleaned:o},prune(){for(const l of i)f.rmSync(l.path,{force:!0}),o.push(l);p(d.join(e,".testkit","_bundles"))}}});return{...c,targets:{runtime:c.targets,bundles:u.targets},bundleCleaned:u.cleaned}}function R(e){const n=(Array.isArray(e)?e:e?[e]:[]).filter(Boolean).map(String);return n.includes("all")?["runtime","bundles"]:n}function s(e){return e.map(r=>({runId:r.runId,summary:m(r)}))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import f from"node:path";import{resolveProductDir as g}from"../../config/loader/index.js";import{collectRequiredConfigs as p,loadManagedConfigs as
|
|
1
|
+
import f from"node:path";import{resolveProductDir as g}from"../../config/loader/index.js";import{collectRequiredConfigs as p,loadManagedConfigs as u,resolveTargetConfig as v,topologicallySortConfigs as d}from"../../config/loader/managed-configs.js";import{runtimePlanning as C}from"../../environment/runtime-planning.js";import{withEnvFileValues as w}from"../../config/loader/env.js";import{portsOf as h,releasePorts as P,reservePorts as y}from"../../environment/ports.js";export async function prepareSchemaOperation(o,c){const t=g(process.cwd(),o.dir),{configs:n}=await u({dir:t}),e=v(n,o.service||null),i=p(n,e.name).map(w);return{productDir:t,serviceName:e.name,async resolveConfigs(l){const s=await y(i.filter(r=>r.testkit.local).map(r=>r.name));await P(s.values());const a=C.resolveRuntimeInstanceConfigs(i,"runtime-1",f.join(l,"runtime-1"),{graphDirName:`${c}-${e.name}`,ports:h(s)}),m=a.find(r=>r.name===e.name);if(!m)throw new Error(`Resolved runtime config missing target service "${e.name}"`);return{configs:d(a),target:m}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{filterConfigsByService as
|
|
1
|
+
import{filterConfigsByService as s}from"../../config/loader/managed-configs.js";import{loadConfigContext as n}from"../../config/loader/index.js";import{createEnvironmentMaintenance as i}from"../../environment/maintenance.js";import{hasLocalDatabaseState as d}from"../../database/lifecycle-cleanup.js";export async function destroy(t,e,r={}){await i(t).maintain({kind:"destroy",configs:e,destroyOwnedResources:r.destroyOwnedResources})}export async function destroyEnvironment(t){const e=await n({dir:t.dir,allowUnmigratedServices:!0,plain:!1,retired:[]}),r=s(e.services,t.service||null),o=e.services.some(a=>a.testkit.database!==void 0||a.testkit.databaseFrom!==void 0);return await destroy(e.productDir,r,{destroyOwnedResources:!t.service&&(o||d(e.productDir))}),{ok:!0,productDir:e.productDir,results:r.map(a=>({name:a.name,destroyed:!0}))}}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{resolveRequestedFiles as
|
|
2
|
-
`),
|
|
1
|
+
import{resolveRequestedFiles as u}from"../file-selection.js";import{resolveVitestSelection as f}from"../../engines/catalog.js";import n from"fs";import t from"path";import{loadDiscoveryContext as p,resolveProductDir as v}from"../../config/loader/index.js";export async function executeDiscoverOperation({output:o,vitest:a,...i},l=process.cwd()){const e=v(l,i.dir),m=u(i.file||[],e,l),{discovery:s}=await p({...i,dir:e,file:m,vitest:f(a??{},e)});let c=null;if(o){const r=t.resolve(e,o);n.mkdirSync(t.dirname(r),{recursive:!0}),n.writeFileSync(r,`${JSON.stringify(s,null,2)}
|
|
2
|
+
`),c=(t.relative(e,r)||t.basename(r)).replaceAll("\\","/")}return{...s,outputLabel:c}}
|
package/dist/app/doctor/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import m from"path";import{randomUUID as v}from"node:crypto";import{loadDiscoveryContext as k,loadConfigContext as w}from"../../config/loader/index.js";import{runLintForConfig as D}from"../lint/index.js";import{isUnknownRecord as a}from"../../kernel/unknown-values.js";export async function runDoctor(e={}){const t=[],
|
|
1
|
+
import m from"path";import{randomUUID as v}from"node:crypto";import{loadDiscoveryContext as k,loadConfigContext as w}from"../../config/loader/index.js";import{runLintForConfig as D}from"../lint/index.js";import{isUnknownRecord as a}from"../../kernel/unknown-values.js";import{requireUnknownArray as d}from"../../evidence/read-fields.js";export async function runDoctor(e={}){const t=[],s=e.dir?m.resolve(process.cwd(),e.dir):process.cwd(),r=await w({dir:s,configImportCacheSalt:v(),plain:!1});t.push({code:"config-load",level:"pass",message:"Loaded testkit config and service config"});const l=await k({dir:s,diagnostics:"report"},r),g=l.discovery,f=R(g,"discovery result"),u=d(f.diagnostics,"discovery result diagnostics"),p=d(f.files,"discovery result files"),c=u.filter(S);t.push({code:"discovery",level:c.length===0?"pass":"fail",message:c.length===0?`Discovered ${String(p.length)} testkit files without diagnostics`:`Discovery reported ${String(c.length)} error diagnostics`,details:c});const o=await D(n(r,"config"),{dir:s});if(t.push({code:"lint",level:o.ok?"pass":"fail",message:o.ok?`No Testkit lint violations across ${String(o.summary.testkitFiles)} suite file(s)`:`Found ${String(o.summary.violations)} Testkit lint violation(s)`,details:o.violations}),e.typecheck!==!1)try{const{runTestkitTypecheckForContext:i}=await import("../typecheck/index.js"),y=await i(r,l.discovery,{dir:s}),h=d(n(y,"results"),"typecheck results");t.push({code:"typecheck",level:"pass",message:`Typechecked ${String(h.length)} generated program(s)`})}catch(i){t.push({code:"typecheck",level:"fail",message:C(i)})}return{ok:!t.some(i=>i.level==="fail"),productDir:s,checks:t}}function S(e){return a(e)&&Reflect.get(e,"severity")==="error"}function C(e){const t=n(e,"result"),s=n(t,"stderr");if(typeof s=="string"&&s.length>0)return s;const r=n(t,"stdout");return typeof r=="string"&&r.length>0?r:e instanceof Error?e.message:String(e)}function R(e,t){if(!a(e))throw new Error(`${t} must be an object`);return e}function n(e,t){return a(e)?Reflect.get(e,t):void 0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildTaskExecutionEnv as
|
|
1
|
+
import{createEnvironment as S,environmentTaskIdentities as C,renderSharedEnvironment as k}from"../run/environment.js";import{buildTaskExecutionEnv as R,buildTemplateContext as A,finalizeSerializable as O}from"../../steps/index.js";import{runtimePlanning as j}from"../../environment/runtime-planning.js";import{sourceSchemaCredentialEnvNames as M}from"../../database/source-schema-env.js";import{prepareFileSetup as U}from"./file-setup.js";import{cloneTaskDatabases as T}from"./task-databases.js";import{envRedactionTargets as D,jsonRedactionTargets as N,sensitiveKeyMatcher as E,urlRedactionTargets as x}from"../../kernel/redaction-targets.js";export function planConfiguredCapacity(e){const t=j.buildRuntimeGraphs(e);return{graphs:t,instanceCount:t.reduce((s,a)=>s+a.instanceCount,0),resourceBudgets:I(t)}}function I(e){const t=new Map;for(const s of e)for(const a of s.resourceReservations){const o=t.get(a.key)??{key:a.key,kind:a.kind,scope:a.scope,resourceName:a.resourceName,capacity:a.capacity,reserved:a.reserved,available:a.available,graphs:[]};o.capacity=Math.max(o.capacity,a.capacity),o.reserved=Math.max(o.reserved,a.reserved),o.available=Math.max(0,o.capacity-o.reserved),o.graphs.push({graphKey:s.key,services:a.services,perRuntime:a.perRuntime}),t.set(a.key,o)}return[...t.values()].sort((s,a)=>s.key.localeCompare(a.key))}export function createConfigDrivenEnvironments(e,t,s,a=null){const o=E(a?.redactKeys);return{canAcquire:i=>e.canAcquire(i),getGraph:i=>e.getGraph(i),getGraphFailure:i=>e.getGraphFailure(i),markGraphFailed:(i,d)=>{e.markGraphFailed(i,d)},async acquire(i,d){const p=a?.acquisition({source:"configured",graphKey:i.graphKey,leaseId:d.id,tasks:C(i)});try{const u=c=>{const r=t.get(c);if(r===void 0)throw new Error(`No services are declared for group "${c}"`);return r},h={name:i.targetName,uses:u(i.targetName)},g=await e.acquire({...i,leaseId:d.id},{onRuntimeAssigned:c=>p?.assigned(c)});p?.acquired(K(g));const v=c=>L(p,()=>e.release(g.leaseId,c));try{const c=n=>a?.addRedactionTarget(n),r=k(i,n=>renderEnvironment(g,{name:n,uses:u(n)},d,c,o));return p?.rendered(r),{environment:r,async prepare(n,l){const f={lease:d,productDir:s,record:p,redact:c};if(n.runtimeIsolation!=="resetBefore")return U(n,l,{...f,environment:r});const m=await T(g,r,n,d,l),b=renderEnvironment(m.ready,h,d,c,o);p?.rendered(b);const y=await U(n,l,{...f,environment:b}).catch(async w=>{throw await m.release(),w});return{artifacts:y?.artifacts??[],environment:b,handles:y?.handles??{},setupData:y===null?b.setupData:y.setupData,release:async()=>[...await y?.release()??[],...await m.release()]}},release:v}}catch(c){throw await v({invalidate:!1}),c}}catch(u){throw e.signal.aborted&&u===e.signal.reason?p?.cancelled(u):p?.failed(u),u}}}}function K(e){return{runtimeId:e.runtimeId,services:[...e.services.values()].map(({config:t})=>({serviceName:t.name,runtimeLabel:String(t.runtimeLabel??t.name)}))}}async function L(e,t){try{await t()}catch(s){throw e?.releaseFailed(s),s}e?.released()}const B=new Set(["BASE_URL","DATABASE_URL"]);export function renderEnvironment(e,t,s,a=()=>{},o=E()){const i={leaseDir:s.directory,leaseId:s.id},d=new Map([...e.services].map(([r,n])=>{const l=q(R(n.config,i,{},null,{includeTestkitControls:!1,inheritProcessEnv:!1}));for(const f of[...D(l,o),...[n.baseUrl,n.database?.url].flatMap(m=>m?x(m):[])])a(f);return[r,l]})),p=F(e),u=t.uses.map(r=>{const n=e.services.get(r),l=d.get(r);if(!n||!l)throw new Error(`Runtime instance is missing used service "${r}"`);const f=G(l,p),m=Object.entries(f).find(([b])=>b.toUpperCase()==="DATABASE_URL")?.[1];return{name:r,config:n.config,baseUrl:typeof n.baseUrl=="string"&&n.baseUrl.length>0?n.baseUrl:null,databaseUrl:n.database?.url??(m||null),env:Object.fromEntries(Object.entries(f).filter(([b])=>!B.has(b.toUpperCase())))}}),h={},g=new Set;for(const r of u){const n=Object.entries(r.env).filter(([l])=>!g.has(l.toUpperCase()));for(const[l,f]of n)h[l]=f;for(const[l]of n)g.add(l.toUpperCase())}const v=u.at(0)?.config,c=v?.testkit.ui?_(O(v.testkit.ui,A(v,i))):null;for(const r of N("ui",c,o))a(r);return S({baseUrl:u.find(r=>r.baseUrl!==null)?.baseUrl??null,databaseUrl:u.find(r=>r.databaseUrl!==null)?.databaseUrl??null,databases:Object.fromEntries(u.flatMap(r=>r.databaseUrl===null?[]:[[r.name,r.databaseUrl]])),endpoints:Object.fromEntries(u.flatMap(r=>r.baseUrl===null?[]:[[r.name,r.baseUrl]])),env:h,group:t.name,ui:c})}function F(e){return new Set([...e.services.values()].flatMap(({config:t})=>M(t)).map(t=>t.toUpperCase()))}function G(e,t){return Object.fromEntries(Object.entries(e).filter(([s])=>!t.has(s.toUpperCase())))}function q(e){return Object.fromEntries(Object.entries(e).filter(t=>typeof t[1]=="string"))}function _(e){const t=JSON.stringify(e);if(typeof t!="string")return null;const s=JSON.parse(t);return s!==null&&typeof s=="object"&&!Array.isArray(s)?s:null}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import f from"node:fs";import l from"node:path";import{errorMessage as p}from"../../kernel/error-serialization.js";export const ENVIRONMENT_FILE_VERSION=1;const b=new Set(["version","baseUrl","databaseUrl","endpoints","databases","env","ui","setupData","handles"]);export function readEnvironmentFile(n,o){const r=l.resolve(o,n);let e;try{e=f.readFileSync(r,"utf8")}catch(t){throw new Error(`Environment file ${n} could not be read: ${p(t)}`,{cause:t})}return{content:parseEnvironmentFile(e,n),label:n}}export function parseEnvironmentFile(n,o){const r=h(n);if(!r.ok)throw new Error(`Environment file ${o} is not valid JSON${r.location}`);const e=r.value,t=(s,c)=>{throw new Error(`Environment file ${o}: ${s} ${c}`)};if(!a(e))return t("the document","must be a JSON object");if(e.version!==ENVIRONMENT_FILE_VERSION){const s=`this Testkit reads version ${ENVIRONMENT_FILE_VERSION.toString()}`;return e.version===void 0?t("version",`is missing; ${s}`):t("version",typeof e.version=="number"&&Number.isInteger(e.version)?`${e.version.toString()} is not supported; ${s}`:`must be a whole number; ${s}`)}for(const s of Object.keys(e))b.has(s)||t(s,"is not part of an environment file, which holds values, prepared setup data and handle descriptors, never provider config");const i={databases:d(e.databases,"databases",t),endpoints:d(e.endpoints,"endpoints",t),env:d(e.env,"env",t),handles:m(e.handles,t)};return e.baseUrl!=null&&(i.baseUrl=u(e.baseUrl,"baseUrl",t)),e.databaseUrl!=null&&(i.databaseUrl=u(e.databaseUrl,"databaseUrl",t)),e.ui!=null&&(a(e.ui)||t("ui","must be a JSON object or null"),i.ui=e.ui),e.setupData!==void 0&&(i.setupData=e.setupData),i}function d(n,o,r){if(n===void 0)return{};if(!a(n))return r(o,"must be an object of strings");for(const[e,t]of Object.entries(n))e.length===0&&r(o,"holds an empty name"),u(t,`${o}.${e}`,r);return n}function m(n,o){if(n===void 0)return{};if(!a(n))return o("handles","must be an object of handle descriptors");for(const[r,e]of Object.entries(n)){a(e)||o(`handles.${r}`,"must be a handle descriptor object");const t=e.kind;(typeof t!="string"||t.length===0)&&o(`handles.${r}.kind`,"must be a non-empty string")}return n}function u(n,o,r){return typeof n=="string"?n:r(o,"must be a string")}function a(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function h(n){try{return{ok:!0,value:JSON.parse(n)}}catch(o){const r=/line (\d+) column (\d+)/u.exec(o instanceof Error?o.message:"");return{ok:!1,location:r?` at line ${r[1]}, column ${r[2]}`:""}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import f from"node:path";import{httpCaptureRedactionTargets as E}from"../run/setup/runtime-node-setup-protocol.js";import{classifyRuntimeNodeSetupFailure as M,findRuntimeNodeSetupFile as N,getRuntimeNodeSetupCleanupFailures as S,MAX_RUNTIME_NODE_SETUP_CLEANUP_TIMEOUT_MS as F,runRuntimeNodeSetup as y}from"../run/setup/runtime-node-setup.js";import{defaultEnvironmentValues as T}from"../run/engine-orchestration.js";import{TaskPreparationError as U}from"../run/environment.js";import{toError as d}from"../../kernel/error-serialization.js";import{ambiguousHandleDescriptor as w}from"../../engines/environment/handles.js";export async function prepareFileSetup(e,r,{environment:a,lease:t,productDir:n,record:s,redact:c}){let o,l;try{const i=N(n,e.file);if(i===null)return null;o=s?.setup({module:f.relative(n,i).split(f.sep).join("/"),task:{file:e.file,group:e.targetName,id:e.id}}),l=await y({cleanupTimeoutMs:Math.min(r.timeoutMs,F),deadlineMs:r.deadlineMs,lease:{leaseDir:t.directory,leaseId:t.id},onSidecar:u=>{for(const p of E(u))c(p)},runtimeEnv:T(a),signal:r.signal,targetConfig:{name:e.targetName,productDir:n},task:e})}catch(i){const u=M(i),p=m(i);u==="cancelled"?o?.cancelled(i):o?.failed(i);for(const h of p)o?.releaseFailed(h.error);throw new U(u,d(i),p)}o?.prepared(l.setupData);let g=null;return{artifacts:l.artifacts,handles:_(l.sidecars),setupData:l.setupData,release:()=>g??=R(l.cleanup,o)}}async function R(e,r){try{await e()}catch(a){const t=m(a),n=t.length>0?t:[{error:d(a),owner:"testkit"}];for(const s of n)r?.releaseFailed(s.error);return n}return r?.released(),[]}function _(e){const r={};for(const a of new Set(e.map(t=>t.id))){const t=e.filter(o=>o.id===a),[{requestsUrl:n,resetUrl:s,url:c}]=t;Object.defineProperty(r,a,{enumerable:!0,value:t.length>1?w(t.length):{kind:"http-capture",requestsUrl:n,resetUrl:s,url:c}})}return r}function m(e){return S(e).map(({error:r,owner:a})=>({error:r,owner:a}))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function declaresProvisioning(
|
|
1
|
+
export function declaresProvisioning(n){return n.some(({testkit:r})=>r.local!==void 0||r.database!==void 0||r.databaseFrom!==void 0||r.runtime.build!==null||r.runtime.prepare.steps.length>0||r.runtime.toolchain!==null)}export function declaresValues(n){return n.some(({testkit:r})=>Object.keys(r.serviceEnv).length>0||r.envFiles.length>0||r.ui!=null)}export function routeEnvironments(n){const r=e=>{const a=n.get(e);if(a===void 0)throw new Error(`No environment source for runtime graph "${e}"`);return a};return{acquire:(e,a)=>r(e.graphKey).acquire(e,a),canAcquire:e=>r(e.graphKey).canAcquire(e),getGraph:e=>r(e).getGraph(e),getGraphFailure:e=>r(e).getGraphFailure(e),markGraphFailed:(e,a)=>{r(e).markGraphFailed(e,a)}}}export function holdBeforeRelease(n,r){return{...n,async acquire(e,a){const i=await n.acquire(e,a);let d=null,t=!1;const c=()=>d??=Promise.resolve().then(()=>r(e.targetName,i.environment)).then(()=>({failed:!1}),l=>({error:l,failed:!0}));return{environment:i.environment,async prepare(l,u){const o=await i.prepare(l,u);return o===null?null:{...o,async release(){return await c(),o.release()}}},async release(l){const u=await c(),o=u.failed&&!t;t||=u.failed;try{await i.release(l)}catch(s){if(!o)throw s}if(o)throw u.error}}}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{environmentTaskIdentities as p,PREVIEW_LEASE as h,renderSharedEnvironment as w}from"../run/environment.js";import{withEnvFileValues as g}from"../../config/loader/env.js";import{sensitiveKeyMatcher as y}from"../../kernel/redaction-targets.js";import{renderEnvironment as E}from"./config-driven.js";import{prepareFileSetup as v}from"./file-setup.js";import{resetBeforeRefusal as S}from"./task-databases.js";const I=new Set(["bin","lease","leaseDir","pathList","productDir","service","stateDir"]);export function createStaticValueEnvironments(r,c,a=null){const s=new Map,d=e=>{const t=s.get(e.name);if(t!==void 0)return t;const n=g(e);return T(n),s.set(e.name,n),n},l=(e,t,n,o)=>{const i=r.get(e);if(i===void 0)throw new Error(`No services are declared for group "${e}"`);const m={graphKey:t,leaseId:n.id,runtimeId:t,targetNames:[e],services:new Map(i.map(u=>[u.name,{baseUrl:null,database:null,config:d(u)}]))};return E(m,{name:e,uses:i.map(({name:u})=>u)},n,o,y(a?.redactKeys))};return{canAcquire:()=>!0,getGraph:()=>null,getGraphFailure:()=>null,markGraphFailed:()=>{},preview(e){try{return l(e,"",h,()=>{})}catch{return null}},acquire(e,t){const n=a?.acquisition({source:"static",graphKey:e.graphKey,leaseId:t.id,tasks:p(e)});return Promise.resolve().then(()=>{const o=w(e,i=>l(i,e.graphKey,t,m=>a?.addRedactionTarget(m)));return n?.acquired({runtimeId:null,services:[]}),n?.rendered(o),{environment:o,prepare:async(i,m)=>{if(i.runtimeIsolation==="resetBefore")throw S(i,!1);return v(i,m,{environment:o,lease:t,productDir:c,record:n,redact:u=>a?.addRedactionTarget(u)})},release:()=>(n?.released(),Promise.resolve())}}).catch(o=>{throw n?.failed(o),o})}}}function T(r){const c=[...Object.entries(r.testkit.serviceEnv).map(([a,s])=>[`env.${a}`,s]),["ui",r.testkit.ui]];for(const[a,s]of c)for(const d of f(s))if(!I.has(d))throw new Error(`Service "${r.name}" uses {${d}} in ${a}, which needs a running service, and "${r.name}" starts none`)}function f(r){return typeof r=="string"?[...r.matchAll(/\{([a-zA-Z]+)(?::[^}]+)?\}/gu)].map(c=>c[1]):Array.isArray(r)?r.flatMap(f):r!==null&&typeof r=="object"?Object.values(r).flatMap(f):[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parsePostgresUrl as m}from"../../database/postgres/connection-check.js";import{errorMessage as A}from"../../kernel/error-serialization.js";import{parseHttpUrl as w}from"../../process/readiness.js";const u="BASE_URL",U="DATABASE_URL";export function hasSuppliedInput(e){return e.baseUrl!==void 0||e.environmentFile!==void 0||[e.database,e.endpoint,e.env,e.envFrom].some(a=>(a?.length??0)>0)}export function resolveSuppliedInput(e,a,o){const s=$("the default",!0),d=$("endpoint"),f=$("database"),l=$("env",!0),c=(r,t,n)=>{const i=r.toUpperCase();i===u?s.define(u,b(t,n),n):i===U?s.define(U,h(t,n),n):l.define(r,t,n)};if(a!==null){const{content:r,label:t}=a;if(r.baseUrl!==void 0&&s.define(u,b(r.baseUrl,`${t}: baseUrl`),`${t}: baseUrl`),r.databaseUrl!==void 0){const n=`${t}: databaseUrl`;s.define(U,h(r.databaseUrl,n),n)}for(const[n,i]of Object.entries(r.endpoints))d.define(n,b(i,`${t}: endpoints.${n}`),`${t}: endpoints.${n}`);for(const[n,i]of Object.entries(r.databases))f.define(n,h(i,`${t}: databases.${n}`),`${t}: databases.${n}`);for(const[n,i]of Object.entries(r.env))c(n,i,`${t}: env.${n}`)}e.baseUrl!==void 0&&s.define(u,b(e.baseUrl,"--base-url"),"--base-url");for(const r of e.endpoint??[]){const[t,n]=v(r,"--endpoint","NAME=URL");d.define(t,b(n,`--endpoint ${t}`),`--endpoint ${t}`)}for(const r of e.database??[]){const[t,n]=v(r,"--database","NAME=URL");f.define(t,h(n,`--database ${t}`),`--database ${t}`)}for(const r of e.env??[]){const[t,n]=v(r,"--env","NAME=VALUE");c(t,n,`--env ${t}`)}for(const r of e.envFrom??[]){const[t,n]=v(r,"--env-from","NAME=HOST_KEY"),i=`--env-from ${t}=${n}`,E=o[n];if(E===void 0)throw new Error(`${i}: the host variable ${n} is not set`);c(t,E,i)}const p=s.values();return{baseUrl:p[u]??null,databaseUrl:p[U]??null,databases:Object.fromEntries(Object.entries(f.values()).filter(([,r])=>r.length>0)),endpoints:d.values(),env:l.values(),handles:a?.content.handles??{},...a?.content.setupData===void 0?{}:{setupData:a.content.setupData},ui:a?.content.ui??null}}export function suppliedBindings(e){return{...e.env,...e.baseUrl===null?{}:{BASE_URL:e.baseUrl},...e.databaseUrl===null?{}:{DATABASE_URL:e.databaseUrl}}}export function projectSuppliedEnvironment(e,a){const o=s=>a.filter(d=>Object.hasOwn(s,d)).map(d=>s[d])[0]??null;return{baseUrl:e.baseUrl??o(e.endpoints),databaseUrl:e.databaseUrl??o(e.databases),databases:{...e.databases},endpoints:{...e.endpoints},env:{...e.env},...Object.keys(e.handles).length===0?{}:{handles:{...e.handles}},...e.setupData===void 0?{}:{setupData:e.setupData},ui:e.ui}}function $(e,a=!1){const o=new Map;return{define(s,d,f){const l=a?s.toUpperCase():s,c=o.get(l);if(c===void 0){o.set(l,{label:f,name:s,value:d});return}if(c.value!==d){const p=e==="the default"?`the default ${s}`:`${e} ${c.name}`;throw new Error(`${c.label} and ${f} supply different values for ${p}`)}},values(){return Object.fromEntries([...o.values()].map(({name:s,value:d})=>[s,d]))}}}function v(e,a,o){const s=e.indexOf("=");if(s<=0)throw new Error(`${a} expects ${o}`);return[e.slice(0,s),e.slice(s+1)]}function b(e,a){try{w(e)}catch(o){throw new Error(`${a}: ${o instanceof Error?o.message:String(o)}`,{cause:o})}return e}function h(e,a){if(e.length===0)return e;try{m(e)}catch(o){throw new Error(`${a} ${A(o)}`,{cause:o})}return e}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function createSuppliedEnvironments(
|
|
1
|
+
import{createEnvironment as y,environmentTaskIdentities as O,renderSharedEnvironment as R}from"../run/environment.js";import{httpCaptureRedactionTargets as T}from"../run/setup/runtime-node-setup-protocol.js";import{checkPostgresConnection as E,parsePostgresUrl as M}from"../../database/postgres/connection-check.js";import{errorMessage as l}from"../../kernel/error-serialization.js";import{envRedactionTargets as g,jsonRedactionTargets as f,sensitiveKeyMatcher as j,urlRedactionTargets as q}from"../../kernel/redaction-targets.js";import{parseHttpUrl as D,requireHttpResponse as I}from"../../process/readiness.js";import{prepareFileSetup as P}from"./file-setup.js";import{resetBeforeRefusal as S}from"./task-databases.js";const m=3e4;export function createSuppliedEnvironments(e,{productDir:t,record:a=null,signal:o}){const i=j(a?.redactKeys);return{canAcquire:()=>!0,getGraph:()=>null,getGraphFailure:()=>null,markGraphFailed:()=>{},preview(r){try{return suppliedEnvironment(r,Object.hasOwn(e,r)?e[r]:{})}catch{return null}},async acquire(r,s){const u=Object.hasOwn(e,r.targetName),c=a?.acquisition({source:u?"supplied":"none",graphKey:r.graphKey,leaseId:s.id,tasks:O(r)}),b=u?e[r.targetName]:{};for(const n of $(b,i))a?.addRedactionTarget(n);let d;try{d=R(r,n=>suppliedEnvironment(n,Object.hasOwn(e,n)?e[n]:{})),await C(r.targetName,d,o)}catch(n){throw o?.aborted&&n===o.reason?c?.cancelled(n):c?.failed(n),n}return c?.acquired({runtimeId:null,services:[]}),c?.rendered(d),{environment:d,prepare:async(n,w)=>{if(n.runtimeIsolation==="resetBefore")throw S(n,u);return u?null:P(n,w,{environment:d,lease:s,productDir:t,record:c,redact:U=>a?.addRedactionTarget(U)})},release:()=>(c?.released(),Promise.resolve())}}}}function $(e,t){return[...g(e.env??{},t),...[e.baseUrl,e.databaseUrl,...Object.values(e.databases??{}),...Object.values(e.endpoints??{})].flatMap(a=>a?q(a):[]),...f("handles",e.handles??{},t),...Object.values(e.handles??{}).filter(a=>a.kind==="http-capture").flatMap(T),...f("setupData",e.setupData??{},t),...f("ui",e.ui??{},t)]}async function C(e,t,a){const o=h(t.endpoints),i=h(t.databases);for(const[r,s]of o)await p(e,"endpoint",s,()=>D(r),a);for(const[r,s]of i)await p(e,"database",s,()=>{_(r)},a);for(const[r,s]of o)await p(e,"endpoint",s,()=>I(r,{signal:a,timeoutMs:m}),a);for(const[r,s]of i)await p(e,"database",s,()=>E(r,{signal:a,timeoutMs:m}),a)}function h(e){const t=new Map;for(const[a,o]of Object.entries(e))t.has(o)||t.set(o,a);return t}function _(e){try{M(e)}catch(t){throw new Error(`its URL ${l(t)}`,{cause:t})}}async function p(e,t,a,o,i){try{await o()}catch(r){throw i?.aborted?i.reason:new Error(`Supplied ${t} "${a}" for group "${e}" is not usable: ${l(r)}`,{cause:r})}}export function suppliedEnvironment(e,t){return{...y({baseUrl:t.baseUrl??null,databaseUrl:t.databaseUrl||null,databases:t.databases??{},endpoints:t.endpoints??{},env:t.env??{},group:e,...t.setupData===void 0?{}:{setupData:t.setupData},ui:t.ui??null}),...t.handles===void 0?{}:{handles:{...t.handles}}}}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{TaskPreparationError as g}from"../run/environment.js";import{bindDatabaseUrl as h}from"../../database/bindings.js";import{isEngineTaskDeadlineExceededReason as k}from"../../engines/api/index.js";import{toError as w}from"../../kernel/error-serialization.js";import{withDatabaseBindings as T}from"../../steps/index.js";export function reachedDatabases(e,t){const n=[t.databaseUrl,...Object.values(t.databases),...Object.values(t.env),JSON.stringify(t.ui)].join(`
|
|
2
|
+
`);return[...e].filter(([o])=>n.includes(o))}export async function cloneTaskDatabases(e,t,n,o,l){const d=new Map;for(const a of e.services.values())a.database!==null&&a.config.testkit.database&&d.set(a.database.database,a);const f=reachedDatabases(d,t);if(f.length===0)throw resetBeforeRefusal(n,!1);const c=new Map;try{const{cloneTaskDatabase:a,dropTaskDatabase:s}=await import("../../database/index.js");for(const[r,i]of f){const u={productDir:i.config.productDir,stateDir:i.config.stateDir},b=await a(u,i.config.name,`${o.id}:${String(n.id)}`,{signal:l.signal});c.set(r,{binding:h(b.url),drop:()=>s(u,b.databaseName)})}}catch(a){const s=k(l.signal.reason),r=l.signal.aborted?s?"deadline":"cancelled":"infra";throw new g(r,w(a),await m(c))}const p=a=>c.get(a.database)?.binding??a;let D=null;return{ready:{...e,services:new Map([...e.services].map(([a,s])=>[a,{...s,database:s.database===null?null:p(s.database),config:T(s.config,new Map([...s.config.testkit.templateContext?.databaseBindingsByService??new Map].map(([r,i])=>[r,p(i)])))}]))},release:()=>D??=m(c)}}async function m(e){const t=[];for(const n of e.values())try{await n.drop()}catch(o){t.push({error:w(o),owner:"testkit"})}return t}export function resetBeforeRefusal(e,t){const n=t?`group "${e.targetName}" runs on supplied values, and Testkit resets only a database it provisions`:`group "${e.targetName}" reaches no database Testkit provisions`;return new g("infra",new Error(`${e.file} sets runtimeIsolation "resetBefore", but ${n}`),[])}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import i from"node:path";import{collectArtifactEntries as l,listRunBundles as f,loadRun as t,verifyRunBundle as a}from"../../evidence/index.js";export function inspectArtifacts(r){const e=i.resolve(r.dir||process.cwd());if(r.mode==="runs")return{mode:"runs",runs:f(e,{file:r.file})};const u=r.runId?null:t(e),n=r.runId||u?.run.id||null;if(r.mode==="verify")return{mode:"verify",runId:n,verification:a(e,n)};const d=u??t(e,n),c=l(e,d,r.file,r.group,r.kind,r.includePayload);return{mode:"artifacts",runId:n,entries:c}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{formatTestTypeLabel}from"../../domain/test-types.js";import{readRunDocument as
|
|
1
|
+
export{formatTestTypeLabel}from"../../domain/test-types.js";import{runModel as p}from"../../evidence/index.js";import{readRunDocument as k}from"../../evidence/read-run.js";import m from"fs";import o from"path";import{errorMessage as l}from"../../kernel/error-serialization.js";import{isEngineProfileIdentity as D}from"../../engines/catalog.js";import{loadDiscoveryContext as S,hasDiscoveryErrors as b,buildDiscoveryErrorFromDiagnostics as N,formatDisplayName as $}from"../../config/loader/index.js";import{collectServiceStatus as A,collectConfiguredServiceStatus as M}from"../status/index.js";export{discoverTests,fileDisplayName,formatDisplayName,testTypeContract}from"../../config/loader/index.js";export{listRunBundles,loadRunBundleArtifact,loadRunBundleManifest,verifyRunBundle}from"../../evidence/index.js";const C=3,j=24,x=String;export async function inspectWorkspace(e={}){const t=V(e.targetLimit,j),r=new Date().toISOString(),n=await F(e),a=n.data?.product.directory||o.resolve(process.cwd(),e.dir||"."),[s,i,u]=await Promise.all([e.status===!1?E():P(e,n.context),f(a,"latest"),f(a,"live")]),d=i.data===null?null:p(i.data),c=u.data===null?null:p(u.data),h=g(d,"latest"),I=g(c,"live"),T=L({discovery:n.data,group:e.group||null,latestRun:d,liveRun:c,limit:t}),w=[...n.warnings,...s.warnings,...i.warnings,...u.warnings];return{schemaVersion:C,source:"testkit-workspace",generatedAt:r,product:n.data?.product||{directory:a,name:o.basename(a)},discovery:n.data?{configFile:n.data.configFile||null,diagnostics:n.data.diagnostics,summary:n.data.summary}:null,status:s.data,runs:{latest:h,live:I},targets:T,activity:z(s.data),warnings:w}}async function F(e){try{const{discovery:t,context:r}=await S({diagnostics:"report",dir:e.dir,runnableOnly:!1,group:e.group||null}),n=t.diagnostics.filter(a=>a.severity==="error").map(a=>`Discovery diagnostic: ${a.message}`);return{data:t,warnings:n,context:r}}catch(t){return{data:null,context:null,warnings:[`Discovery unavailable: ${l(t)}`]}}}async function P(e,t){try{if(t&&b(t.discovery.diagnostics))throw N(t.discovery.diagnostics);const r=t?M(t.services):await A({dir:e.dir});return{data:B(r),warnings:[]}}catch(r){return{data:{ok:!1,results:[]},warnings:[`Status unavailable: ${l(r)}`]}}}function E(){return Promise.resolve({data:{ok:!0,results:[]},warnings:[]})}function f(e,t){const r=t==="live"?"live.json":"latest.json",n=o.join(e,".testkit","results",r);if(!m.existsSync(n))return Promise.resolve({data:null,warnings:[]});try{const a=k(JSON.parse(m.readFileSync(n,"utf8")),n);return Promise.resolve({data:a,warnings:[]})}catch(a){return Promise.resolve({data:null,warnings:[`${t} run artifact unavailable: ${l(a)}`]})}}function B(e){return{ok:!0,results:e.map(t=>({caches:t.caches,hasState:t.hasState,name:t.name,product:t.product,runtimeGraphs:t.runtimeGraphs.map(r=>({currentRuntimeDirCount:r.currentRuntimeDirs.length,desired:r.desired,exists:r.exists,name:r.name,orphan:r.orphan,runtimeDirCount:r.runtimeDirCount,staleRuntimeDirCount:r.staleRuntimeDirs.length})),runs:{active:t.runs.active,stale:t.runs.stale,total:t.runs.total},warnings:t.warnings}))}}function g(e,t){if(e===null)return null;const{run:r,summary:n}=e;return{durationMs:r.durationMs,generatedAt:e.generatedAt,id:r.id,startedAt:r.startedAt,status:r.status,types:[...r.types],source:t,files:{failed:n?.files.failed??0,notRun:n?.files.notRun??0,passed:n?.files.passed??0,skipped:n?.files.skipped??0,total:n?.files.total??0},groups:{failed:n?.groups.failed??0,passed:n?.groups.passed??0,skipped:n?.groups.skipped??0,total:n?.groups.total??0},suites:{completed:n?.suites.completed??0,failed:n?.suites.failed??0,passed:n?.suites.passed??0,skipped:n?.suites.skipped??0,total:n?.suites.total??0}}}function L({discovery:e,group:t,latestRun:r,liveRun:n,limit:a}){const s=[O(e),...y(n,"live",t),...y(r,"latest",t),...W(e).slice(0,Math.ceil(a/2)),..._(e).slice(0,a)].filter(i=>i!==null);return G(s).slice(0,a)}function O(e){return e?{detail:e.product.directory,id:"project:all",kind:"project",label:`All tests in ${e.product.name}`,runnable:!0,source:"discovery"}:null}function W(e){return(e?.suites||[]).map(t=>({detail:[t.group,t.testType,t.engineId,t.profileId].filter(Boolean).join(" - "),id:`suite:${t.group}:${t.testType??""}:${t.engineId}:${t.profileId}:${t.name}`,engineId:t.engineId,group:t.group,kind:"suite",label:t.displayName||t.name,profileId:t.profileId,runnable:t.activeFileCount>0,source:"discovery",suiteName:t.name,testType:t.testType??null}))}function _(e){return(e?.files||[]).filter(t=>!t.skipped).map(t=>v(t,"discovery"))}function y(e,t,r){const n=[];for(const a of e?.groups??[])if(!(r!==null&&a.name!==r))for(const s of a.suites)for(const i of s.files)i.status!=="failed"&&!i.error||n.push(v({displayName:R(i.path),engineId:s.engineId,path:i.path,profileId:s.profileId,group:a.name,suiteName:s.name,testType:s.testType},t,"failed"));return n}function v(e,t,r=null){return{detail:[e.group,e.testType,e.engineId,e.profileId,e.suiteName].filter(Boolean).join(" - "),filePath:e.path,engineId:e.engineId,group:e.group||null,id:`file:${e.group||""}:${e.testType??""}:${e.engineId}:${e.profileId}:${e.path}`,kind:"file",label:e.displayName||R(e.path),profileId:e.profileId,runnable:D(e),source:t,status:r||null,suiteName:e.suiteName||null,testType:e.testType??null}}function z(e){return{activeRuns:e.results.reduce((t,r)=>t+r.runs.active,0),staleRuns:e.results.reduce((t,r)=>t+r.runs.stale,0)}}function G(e){const t=new Set,r=[];for(const n of e)t.has(n.id)||(t.add(n.id),r.push(n));return r}function V(e,t){const r=Number(e);return Number.isFinite(r)?Math.max(1,Math.min(100,Math.round(r))):t}function R(e){return $(o.basename(x(e||"test")).replace(/\.testkit\.[cm]?[jt]sx?$/,""))}
|
package/dist/app/lint/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{loadTestkitConfig as
|
|
1
|
+
import{loadTestkitConfig as u,resolveProductDir as m}from"../../config/loader/index.js";export async function executeLintOperation(t={}){const i=m(process.cwd(),t.dir),n=await u(i);return runLintForConfig(p(n),{dir:i})}function p(t){if(!(typeof t!="object"||t===null||Array.isArray(t)))return Reflect.get(t,"config")}import c from"node:fs";import r from"node:path";import{normalizeLintOptions as d,normalizeLintConfig as l}from"./options.js";import{rejectRetiredTestFile as g}from"../../domain/retired-test-types.js";import{collectCurrentFiles as y,collectTrackedFiles as w,isTestkitSuitePath as h}from"./shared.js";export async function runLint(t={}){const{dir:i,...n}=t,o=r.resolve(process.cwd(),i||".");return f(o,d(n))}export async function runLintForConfig(t,i={}){const n=r.resolve(process.cwd(),i.dir||".");return f(n,l(t))}async function f(t,i){const n=await w(t),o=await y(t,n!==null);for(const a of o)g(a);const e=o.length===0?[]:await(await import("./native.js")).lintProject({productDir:t,files:o,options:i,trackedFiles:n}),s={ok:e.length===0,productDir:t,summary:{files:o.length,testkitFiles:o.filter(h).length,violations:e.length},violations:e};return k(t,s),s}export function normalizeLintConfig(t={}){return l(t)}function k(t,i){try{const n=r.join(t,".testkit","lint");c.mkdirSync(n,{recursive:!0}),c.writeFileSync(r.join(n,"latest.json"),`${JSON.stringify(i,null,2)}
|
|
2
2
|
`,"utf8")}catch{}}
|