@gfdelarue/testkit 0.4.4 → 0.5.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.
Files changed (817) hide show
  1. package/README.md +752 -462
  2. package/bin/testkit-windows-owner-arm64.exe +0 -0
  3. package/bin/testkit-windows-owner-x64.exe +0 -0
  4. package/dist/app/bugs/categories.js +1 -1
  5. package/dist/app/bugs/ci-report.js +2 -2
  6. package/dist/app/bugs/ci-summary.js +3 -3
  7. package/dist/app/bugs/draft.js +4 -4
  8. package/dist/app/bugs/facts.js +2 -2
  9. package/dist/app/bugs/file.js +1 -1
  10. package/dist/app/bugs/gate.js +1 -1
  11. package/dist/app/bugs/guide.js +3 -3
  12. package/dist/app/bugs/issue.js +4 -4
  13. package/dist/app/bugs/known-failures.js +1 -1
  14. package/dist/app/bugs/record.js +2 -2
  15. package/dist/app/bugs/run-reading.js +1 -1
  16. package/dist/app/bugs/supplied-reproduce.js +1 -0
  17. package/dist/app/campaigns/campaign.js +1 -1
  18. package/dist/app/cleanup/index.js +1 -1
  19. package/dist/app/db-schema/prepare.js +1 -1
  20. package/dist/app/destroy/index.js +1 -1
  21. package/dist/app/discover/index.js +2 -2
  22. package/dist/app/doctor/index.js +1 -1
  23. package/dist/app/environments/config-driven.js +1 -0
  24. package/dist/app/environments/environment-file.js +1 -0
  25. package/dist/app/environments/file-setup.js +1 -0
  26. package/dist/app/environments/routing.js +1 -0
  27. package/dist/app/environments/static-values.js +1 -0
  28. package/dist/app/environments/supplied-input.js +1 -0
  29. package/dist/app/environments/supplied.js +1 -0
  30. package/dist/app/environments/task-databases.js +2 -0
  31. package/dist/app/file-selection.js +1 -1
  32. package/dist/app/inspect/artifacts.js +1 -1
  33. package/dist/app/inspect/index.js +1 -1
  34. package/dist/app/lint/index.js +1 -1
  35. package/dist/app/lint/native.js +1 -1
  36. package/dist/app/lint/options.js +1 -1
  37. package/dist/app/lint/rules/data.js +1 -1
  38. package/dist/app/lint/rules/engine-imports.js +1 -1
  39. package/dist/app/lint/rules/syntax.js +1 -1
  40. package/dist/app/lint/rules/unit.js +1 -1
  41. package/dist/app/lint/shared.js +1 -1
  42. package/dist/app/package-inspection.js +1 -1
  43. package/dist/app/reports/files.js +1 -0
  44. package/dist/app/reports/prepare.js +2 -0
  45. package/dist/app/reports/publish.js +1 -0
  46. package/dist/app/run/caller-redaction.js +1 -0
  47. package/dist/app/run/engine-evidence-persistence.js +1 -1
  48. package/dist/app/run/engine-execution-failures.js +1 -1
  49. package/dist/app/run/engine-execution-reporting.js +1 -1
  50. package/dist/app/run/engine-execution.js +1 -1
  51. package/dist/app/run/engine-orchestration.js +1 -1
  52. package/dist/app/run/environment.js +1 -0
  53. package/dist/app/run/failure-details.js +1 -1
  54. package/dist/app/run/live-run.js +1 -1
  55. package/dist/app/run/orchestrator.js +1 -1
  56. package/dist/app/run/planning.js +1 -1
  57. package/dist/app/run/request.js +1 -1
  58. package/dist/app/run/results.js +1 -1
  59. package/dist/app/run/run-events.js +1 -1
  60. package/dist/app/run/run-finalization.js +1 -1
  61. package/dist/app/run/runtime-fixtures.js +1 -1
  62. package/dist/app/run/scheduler/estimates.js +1 -1
  63. package/dist/app/run/scheduler/identity.js +1 -1
  64. package/dist/app/run/scheduler/index.js +1 -1
  65. package/dist/app/run/scheduler/locks.js +1 -0
  66. package/dist/app/run/selection.js +1 -1
  67. package/dist/app/run/setup/runtime-node-setup-protocol.js +1 -1
  68. package/dist/app/run/setup/runtime-node-setup-worker.js +1 -1
  69. package/dist/app/run/setup/runtime-node-setup.js +2 -2
  70. package/dist/app/run/task-batches.js +1 -1
  71. package/dist/app/run/task-leases.js +1 -0
  72. package/dist/app/run/worker-loop.js +1 -1
  73. package/dist/app/status/runs.js +1 -1
  74. package/dist/app/tracker/index.js +1 -1
  75. package/dist/app/typecheck/index.js +4 -4
  76. package/dist/cli/command-catalog.js +1 -1
  77. package/dist/cli/command-flags.js +1 -1
  78. package/dist/cli/command-registry.js +1 -1
  79. package/dist/cli/commands/artifacts.js +2 -2
  80. package/dist/cli/commands/bug/file.js +2 -2
  81. package/dist/cli/commands/bug/record.js +2 -2
  82. package/dist/cli/commands/discover.js +1 -1
  83. package/dist/cli/commands/report/prepare.js +5 -0
  84. package/dist/cli/commands/report/publish.js +2 -0
  85. package/dist/cli/commands/run.js +2 -2
  86. package/dist/cli/commands/typecheck.js +1 -1
  87. package/dist/cli/commands/workspace.js +1 -1
  88. package/dist/cli/framework/errors.js +1 -1
  89. package/dist/cli/framework/execute.js +7 -6
  90. package/dist/cli/framework/parser.js +1 -1
  91. package/dist/cli/json-errors.js +1 -1
  92. package/dist/cli/operations/run/operation.js +2 -2
  93. package/dist/cli/renderers/bug/text.js +1 -1
  94. package/dist/cli/renderers/discover/report.js +1 -1
  95. package/dist/cli/renderers/doctor/text.js +1 -1
  96. package/dist/cli/renderers/run/events.js +2 -2
  97. package/dist/cli/renderers/run/formatting.js +1 -1
  98. package/dist/cli/renderers/run/status.js +1 -1
  99. package/dist/cli/renderers/run/text-reporter.js +24 -22
  100. package/dist/cli/terminal/colors.js +1 -1
  101. package/dist/cli/terminal/layout.js +2 -2
  102. package/dist/config/authoring/http-methods.js +1 -1
  103. package/dist/config/authoring/index.js +1 -1
  104. package/dist/config/authoring/preset-env.js +1 -1
  105. package/dist/config/loader/config-loader.js +1 -1
  106. package/dist/config/loader/database.js +1 -1
  107. package/dist/config/loader/decode-execution.js +1 -1
  108. package/dist/config/loader/dependencies.js +1 -1
  109. package/dist/config/loader/discover-tests.js +1 -1
  110. package/dist/config/loader/discovery-summary.js +1 -1
  111. package/dist/config/loader/discovery.js +2 -2
  112. package/dist/config/loader/env.js +1 -1
  113. package/dist/config/loader/execution-model.js +1 -1
  114. package/dist/config/loader/file-metadata.js +1 -1
  115. package/dist/config/loader/groups.js +1 -0
  116. package/dist/config/loader/index.js +1 -1
  117. package/dist/config/loader/load.js +1 -1
  118. package/dist/config/loader/managed-configs.js +1 -1
  119. package/dist/config/loader/owned-discovery.js +1 -0
  120. package/dist/config/loader/path-policy.js +1 -1
  121. package/dist/config/loader/runtime-isolation.js +1 -1
  122. package/dist/config/loader/runtime.js +1 -1
  123. package/dist/config/loader/skip-config.js +1 -1
  124. package/dist/config/loader/task-policy.js +1 -0
  125. package/dist/config/loader/test-selection.js +1 -1
  126. package/dist/config/loader/validation.js +1 -1
  127. package/dist/database/activity-gate.js +1 -1
  128. package/dist/database/admin.js +2 -2
  129. package/dist/database/bindings.js +1 -0
  130. package/dist/database/cleanup.js +1 -1
  131. package/dist/database/docker-metadata.js +3 -3
  132. package/dist/database/docker.js +3 -3
  133. package/dist/database/index.js +1 -1
  134. package/dist/database/lifecycle-cleanup.js +1 -1
  135. package/dist/database/local-postgres.js +1 -1
  136. package/dist/database/naming.js +1 -1
  137. package/dist/database/postgres/connection-check.js +1 -0
  138. package/dist/database/postgres/protocol.js +2 -0
  139. package/dist/database/schema-operations.js +1 -1
  140. package/dist/database/schema-source.js +3 -3
  141. package/dist/database/source-schema-env.js +1 -0
  142. package/dist/database/source-url.js +2 -2
  143. package/dist/database/state-files.js +1 -1
  144. package/dist/database/state.js +1 -1
  145. package/dist/database/steps.js +3 -3
  146. package/dist/domain/file-timeout.js +1 -1
  147. package/dist/domain/identifiers.js +1 -1
  148. package/dist/domain/operation-display.js +1 -1
  149. package/dist/domain/retired-test-types.js +1 -0
  150. package/dist/domain/runtime-isolation-contract.js +1 -1
  151. package/dist/domain/suite-selection.js +1 -1
  152. package/dist/domain/test-outcomes.js +1 -1
  153. package/dist/domain/test-types.js +1 -1
  154. package/dist/engines/adapters/evidence-files.js +1 -1
  155. package/dist/engines/adapters/evidence-identity.js +1 -1
  156. package/dist/engines/adapters/execution.js +1 -1
  157. package/dist/engines/adapters/json-bounds.js +2 -0
  158. package/dist/engines/adapters/native-report.js +1 -1
  159. package/dist/engines/api/execution-scope.js +1 -1
  160. package/dist/engines/api/execution.js +1 -1
  161. package/dist/engines/api/index.js +1 -1
  162. package/dist/engines/api/runtime-artifact.js +1 -1
  163. package/dist/engines/bundle-cache.js +1 -1
  164. package/dist/engines/catalog.js +1 -1
  165. package/dist/engines/contracts/environment-values.js +1 -0
  166. package/dist/engines/contracts/fixture-manifest.js +1 -1
  167. package/dist/engines/definitions.js +1 -1
  168. package/dist/engines/environment/handles.js +1 -0
  169. package/dist/engines/environment/index.js +1 -0
  170. package/dist/engines/factory.js +1 -1
  171. package/dist/engines/installations/node-vitest.js +1 -1
  172. package/dist/engines/installations/package-resolution.js +1 -1
  173. package/dist/engines/installations/playwright-resolution-child.js +1 -1
  174. package/dist/engines/installations/playwright.js +1 -1
  175. package/dist/engines/managed-module-resolution-policy-input.js +1 -1
  176. package/dist/engines/managed-module-resolution-policy.js +1 -1
  177. package/dist/engines/managed-module-resolution.js +2 -2
  178. package/dist/engines/manager.js +1 -1
  179. package/dist/engines/node-vitest/adapter/adapter.js +1 -1
  180. package/dist/engines/node-vitest/adapter/driver.js +2 -0
  181. package/dist/engines/node-vitest/adapter/evidence.js +2 -2
  182. package/dist/engines/node-vitest/adapter/failure-details.js +4 -2
  183. package/dist/engines/node-vitest/adapter/reporter.js +1 -1
  184. package/dist/engines/node-vitest/adapter/workspace.js +31 -192
  185. package/dist/engines/node-vitest/inventory/index.js +2 -0
  186. package/dist/engines/node-vitest/inventory/list-files.js +3 -0
  187. package/dist/engines/node-vitest/runtime/contract/index.js +1 -1
  188. package/dist/engines/node-vitest/runtime/data/http.js +1 -1
  189. package/dist/engines/node-vitest/runtime/data/index.js +1 -1
  190. package/dist/engines/node-vitest/runtime/data/report.js +5 -6
  191. package/dist/engines/node-vitest/runtime/data/scenario.js +2 -2
  192. package/dist/engines/node-vitest/runtime/runtime-input.js +1 -1
  193. package/dist/engines/node-vitest/selection.js +1 -0
  194. package/dist/engines/playwright/adapter/adapter.js +1 -1
  195. package/dist/engines/playwright/adapter/config.js +4 -4
  196. package/dist/engines/playwright/adapter/evidence-validation.js +1 -1
  197. package/dist/engines/playwright/adapter/evidence.js +1 -1
  198. package/dist/engines/playwright/adapter/reporter.js +1 -1
  199. package/dist/engines/playwright/runtime/config-file.js +1 -1
  200. package/dist/engines/playwright/runtime/config.js +1 -1
  201. package/dist/engines/playwright/runtime/runtime-input.js +43 -20
  202. package/dist/engines/runtime-input-file.js +1 -1
  203. package/dist/environment/lifecycle-artifacts.js +1 -1
  204. package/dist/environment/lifecycle-controller.js +1 -1
  205. package/dist/environment/lifecycle.js +1 -1
  206. package/dist/environment/ports.js +1 -0
  207. package/dist/environment/ready-environment.js +1 -1
  208. package/dist/environment/run-environment.js +1 -1
  209. package/dist/environment/run-stopping.js +1 -1
  210. package/dist/environment/runtime-contexts.js +1 -1
  211. package/dist/environment/runtime-manager.js +1 -1
  212. package/dist/environment/runtime-planning.js +1 -1
  213. package/dist/environment/runtime-preparation.js +1 -1
  214. package/dist/environment/services.js +3 -1
  215. package/dist/environment/state.js +1 -1
  216. package/dist/environment/template.js +1 -1
  217. package/dist/evidence/artifact-config.js +1 -1
  218. package/dist/evidence/artifact-validation.js +1 -1
  219. package/dist/evidence/artifacts.js +2 -2
  220. package/dist/evidence/bundles.js +1 -1
  221. package/dist/evidence/environment-record.js +1 -0
  222. package/dist/evidence/index.js +1 -1
  223. package/dist/evidence/logs.js +2 -2
  224. package/dist/evidence/operation-timings.js +1 -1
  225. package/dist/evidence/read-fields.js +1 -1
  226. package/dist/evidence/read-run.js +1 -1
  227. package/dist/evidence/reading.js +1 -1
  228. package/dist/evidence/redaction.js +4 -0
  229. package/dist/evidence/reporting.js +1 -1
  230. package/dist/evidence/run-model.js +1 -0
  231. package/dist/evidence/storage.js +2 -2
  232. package/dist/evidence/timing.js +1 -1
  233. package/dist/kernel/error-serialization.js +1 -1
  234. package/dist/kernel/redaction-targets.js +1 -0
  235. package/dist/kernel/redaction.js +4 -1
  236. package/dist/kernel/unknown-values.js +1 -1
  237. package/dist/process/environment.js +1 -1
  238. package/dist/process/execa-bundle.json +3 -3
  239. package/dist/process/files/json-file.js +1 -1
  240. package/dist/process/files/paths.js +1 -1
  241. package/dist/process/host/metadata.js +1 -1
  242. package/dist/process/host/platform.js +1 -1
  243. package/dist/process/host-process.js +1 -1
  244. package/dist/process/index.js +1 -1
  245. package/dist/process/lifecycle-fence.js +1 -1
  246. package/dist/process/locks.js +4 -4
  247. package/dist/process/port-listener.js +2 -0
  248. package/dist/process/process-group.js +1 -1
  249. package/dist/process/process-identity.js +1 -1
  250. package/dist/process/process.js +33 -33
  251. package/dist/process/readiness.js +1 -1
  252. package/dist/process/ready-deadline.js +1 -0
  253. package/dist/process/recovery.js +1 -1
  254. package/dist/process/runs/manifest.js +1 -1
  255. package/dist/process/runs/ownership.js +1 -1
  256. package/dist/process/runs/product-state.js +1 -1
  257. package/dist/process/runs/stop.js +1 -1
  258. package/dist/process/service-processes.js +1 -1
  259. package/dist/process/stoppable-settlement.js +1 -0
  260. package/dist/process/url-redaction.js +1 -0
  261. package/dist/process/windows-cli-owner.js +3 -3
  262. package/dist/process/windows-native.js +1 -1
  263. package/dist/repo/ci-environment.js +1 -1
  264. package/dist/repo/fingerprint-policy.js +1 -1
  265. package/dist/repo/managed-git.js +1 -1
  266. package/dist/repo/physical-tree.js +1 -1
  267. package/dist/repo/publish-directory.js +3 -0
  268. package/dist/repo/state.js +4 -4
  269. package/dist/steps/build-config.js +1 -1
  270. package/dist/steps/configured-step-testkit-modules.js +1 -1
  271. package/dist/steps/configured-steps.js +1 -1
  272. package/dist/steps/environment.js +1 -1
  273. package/dist/steps/index.js +1 -1
  274. package/dist/steps/run.js +2 -2
  275. package/dist/toolchains/archive.js +1 -1
  276. package/dist/toolchains/index.js +3 -3
  277. package/dist/toolchains/node-provisioning.js +2 -2
  278. package/dist/toolchains/semver.js +1 -1
  279. package/dist/toolchains/vitest/index.js +1 -1
  280. package/dist/tracker/redaction.js +1 -2
  281. package/dist/{config/runtime/build-assets.d.ts → types/config-build-assets.d.ts} +5 -3
  282. package/dist/{database/steps.d.ts → types/config-database-steps.d.ts} +7 -7
  283. package/dist/{config/runtime/next-runtime-tsconfig.d.ts → types/config-next-runtime-tsconfig.d.ts} +5 -3
  284. package/dist/types/config.d.ts +501 -0
  285. package/dist/types/drizzle.d.ts +13 -0
  286. package/dist/{config/runtime/env/index.d.ts → types/env.d.ts} +22 -20
  287. package/dist/types/environment.d.ts +40 -0
  288. package/dist/types/index.d.ts +21 -0
  289. package/dist/types/node-vitest-contract.d.ts +75 -0
  290. package/dist/types/node-vitest-data.d.ts +407 -0
  291. package/dist/types/playwright.d.ts +130 -0
  292. package/dist/types/tooling-vitest.d.ts +13 -0
  293. package/dist/types/workspace.d.ts +617 -0
  294. package/docs/bug-records.md +83 -81
  295. package/docs/engines.md +213 -0
  296. package/docs/test-types.md +35 -33
  297. package/package.json +22 -29
  298. package/testkit-config-schema.md +403 -171
  299. package/dist/app/bugs/areas.d.ts +0 -38
  300. package/dist/app/bugs/assessment.d.ts +0 -9
  301. package/dist/app/bugs/categories.d.ts +0 -41
  302. package/dist/app/bugs/ci-report.d.ts +0 -21
  303. package/dist/app/bugs/ci-summary.d.ts +0 -13
  304. package/dist/app/bugs/draft.d.ts +0 -70
  305. package/dist/app/bugs/facts.d.ts +0 -48
  306. package/dist/app/bugs/file.d.ts +0 -45
  307. package/dist/app/bugs/gate.d.ts +0 -22
  308. package/dist/app/bugs/guide.d.ts +0 -20
  309. package/dist/app/bugs/issue.d.ts +0 -18
  310. package/dist/app/bugs/known-failures.d.ts +0 -49
  311. package/dist/app/bugs/record.d.ts +0 -14
  312. package/dist/app/bugs/run-reading.d.ts +0 -51
  313. package/dist/app/bugs/store.d.ts +0 -34
  314. package/dist/app/campaigns/brief.d.ts +0 -7
  315. package/dist/app/campaigns/campaign.d.ts +0 -14
  316. package/dist/app/campaigns/index.d.ts +0 -38
  317. package/dist/app/campaigns/store.d.ts +0 -5
  318. package/dist/app/campaigns/summary.d.ts +0 -13
  319. package/dist/app/cleanup/index.d.ts +0 -52
  320. package/dist/app/db-schema/prepare.d.ts +0 -11
  321. package/dist/app/db-schema/refresh.d.ts +0 -17
  322. package/dist/app/db-schema/verify.d.ts +0 -11
  323. package/dist/app/destroy/index.d.ts +0 -16
  324. package/dist/app/discover/index.d.ts +0 -8
  325. package/dist/app/doctor/index.d.ts +0 -17
  326. package/dist/app/file-selection.d.ts +0 -1
  327. package/dist/app/inspect/artifacts.d.ts +0 -30
  328. package/dist/app/inspect/index.d.ts +0 -112
  329. package/dist/app/lint/index.d.ts +0 -28
  330. package/dist/app/lint/native.d.ts +0 -10
  331. package/dist/app/lint/options.d.ts +0 -67
  332. package/dist/app/lint/policy.d.ts +0 -21
  333. package/dist/app/lint/rules/data.d.ts +0 -3
  334. package/dist/app/lint/rules/engine-imports.d.ts +0 -3
  335. package/dist/app/lint/rules/syntax.d.ts +0 -4
  336. package/dist/app/lint/rules/unit.d.ts +0 -3
  337. package/dist/app/lint/shared.d.ts +0 -36
  338. package/dist/app/package-inspection.d.ts +0 -20
  339. package/dist/app/run/endpoint-readiness.d.ts +0 -43
  340. package/dist/app/run/endpoint-readiness.js +0 -1
  341. package/dist/app/run/engine-evidence-persistence.d.ts +0 -39
  342. package/dist/app/run/engine-execution-cleanup.d.ts +0 -8
  343. package/dist/app/run/engine-execution-cleanup.js +0 -1
  344. package/dist/app/run/engine-execution-failures.d.ts +0 -41
  345. package/dist/app/run/engine-execution-observer.d.ts +0 -21
  346. package/dist/app/run/engine-execution-reporting.d.ts +0 -17
  347. package/dist/app/run/engine-execution.d.ts +0 -63
  348. package/dist/app/run/engine-failure-stack.d.ts +0 -1
  349. package/dist/app/run/engine-orchestration.d.ts +0 -49
  350. package/dist/app/run/failure-details.d.ts +0 -37
  351. package/dist/app/run/live-run.d.ts +0 -27
  352. package/dist/app/run/operation-progress.d.ts +0 -13
  353. package/dist/app/run/orchestrator.d.ts +0 -68
  354. package/dist/app/run/planning-types.d.ts +0 -68
  355. package/dist/app/run/planning.d.ts +0 -15
  356. package/dist/app/run/playwright-configuration.d.ts +0 -2
  357. package/dist/app/run/playwright-configuration.js +0 -1
  358. package/dist/app/run/request.d.ts +0 -30
  359. package/dist/app/run/results.d.ts +0 -161
  360. package/dist/app/run/run-events.d.ts +0 -144
  361. package/dist/app/run/run-finalization.d.ts +0 -52
  362. package/dist/app/run/run-guards.d.ts +0 -3
  363. package/dist/app/run/runtime-failures.d.ts +0 -18
  364. package/dist/app/run/runtime-fixtures.d.ts +0 -2
  365. package/dist/app/run/runtime-task-types.d.ts +0 -20
  366. package/dist/app/run/scheduler/estimates.d.ts +0 -32
  367. package/dist/app/run/scheduler/identity.d.ts +0 -9
  368. package/dist/app/run/scheduler/index.d.ts +0 -124
  369. package/dist/app/run/scheduler/observations.d.ts +0 -20
  370. package/dist/app/run/selection.d.ts +0 -10
  371. package/dist/app/run/setup/runtime-node-setup-errors.d.ts +0 -13
  372. package/dist/app/run/setup/runtime-node-setup-protocol.d.ts +0 -85
  373. package/dist/app/run/setup/runtime-node-setup-worker.d.ts +0 -1
  374. package/dist/app/run/setup/runtime-node-setup.d.ts +0 -48
  375. package/dist/app/run/task-batches.d.ts +0 -23
  376. package/dist/app/run/worker-loop.d.ts +0 -57
  377. package/dist/app/setup/playwright.d.ts +0 -22
  378. package/dist/app/status/index.d.ts +0 -9
  379. package/dist/app/status/model.d.ts +0 -29
  380. package/dist/app/status/runs.d.ts +0 -99
  381. package/dist/app/stop/index.d.ts +0 -14
  382. package/dist/app/tracker/index.d.ts +0 -8
  383. package/dist/app/tracker/remote.d.ts +0 -13
  384. package/dist/app/tracker/token.d.ts +0 -7
  385. package/dist/app/typecheck/index.d.ts +0 -63
  386. package/dist/cli/command-catalog.d.ts +0 -137
  387. package/dist/cli/command-flags.d.ts +0 -19
  388. package/dist/cli/command-registry.d.ts +0 -3
  389. package/dist/cli/commands/artifacts.d.ts +0 -48
  390. package/dist/cli/commands/bug/file.d.ts +0 -16
  391. package/dist/cli/commands/bug/guide.d.ts +0 -5
  392. package/dist/cli/commands/bug/record.d.ts +0 -9
  393. package/dist/cli/commands/campaign/finish.d.ts +0 -10
  394. package/dist/cli/commands/campaign/start.d.ts +0 -7
  395. package/dist/cli/commands/campaign/status.d.ts +0 -13
  396. package/dist/cli/commands/ci/report.d.ts +0 -15
  397. package/dist/cli/commands/cleanup.d.ts +0 -13
  398. package/dist/cli/commands/db/schema/refresh.d.ts +0 -2
  399. package/dist/cli/commands/db/schema/verify.d.ts +0 -2
  400. package/dist/cli/commands/destroy.d.ts +0 -9
  401. package/dist/cli/commands/discover.d.ts +0 -2
  402. package/dist/cli/commands/doctor.d.ts +0 -2
  403. package/dist/cli/commands/guard/unsafe-entrypoint.d.ts +0 -2
  404. package/dist/cli/commands/lint.d.ts +0 -2
  405. package/dist/cli/commands/run/status.d.ts +0 -5
  406. package/dist/cli/commands/run/stop.d.ts +0 -7
  407. package/dist/cli/commands/run.d.ts +0 -9
  408. package/dist/cli/commands/setup/playwright.d.ts +0 -2
  409. package/dist/cli/commands/status.d.ts +0 -5
  410. package/dist/cli/commands/stop.d.ts +0 -12
  411. package/dist/cli/commands/typecheck.d.ts +0 -2
  412. package/dist/cli/commands/workspace.d.ts +0 -2
  413. package/dist/cli/entrypoint.d.ts +0 -1
  414. package/dist/cli/framework/command.d.ts +0 -21
  415. package/dist/cli/framework/definitions.d.ts +0 -100
  416. package/dist/cli/framework/errors.d.ts +0 -6
  417. package/dist/cli/framework/execute.d.ts +0 -14
  418. package/dist/cli/framework/help.d.ts +0 -11
  419. package/dist/cli/framework/index.d.ts +0 -3
  420. package/dist/cli/framework/parser.d.ts +0 -6
  421. package/dist/cli/index.d.ts +0 -4
  422. package/dist/cli/json-errors.d.ts +0 -3
  423. package/dist/cli/operations/db/schema/refresh/operation.d.ts +0 -7
  424. package/dist/cli/operations/db/schema/verify/operation.d.ts +0 -7
  425. package/dist/cli/operations/run/operation.d.ts +0 -24
  426. package/dist/cli/process-signal.d.ts +0 -1
  427. package/dist/cli/renderers/bug/text.d.ts +0 -8
  428. package/dist/cli/renderers/campaign/text.d.ts +0 -2
  429. package/dist/cli/renderers/ci/text.d.ts +0 -2
  430. package/dist/cli/renderers/cleanup/format.d.ts +0 -14
  431. package/dist/cli/renderers/db-schema/text.d.ts +0 -4
  432. package/dist/cli/renderers/destroy/text.d.ts +0 -4
  433. package/dist/cli/renderers/discover/report.d.ts +0 -7
  434. package/dist/cli/renderers/discover/text.d.ts +0 -3
  435. package/dist/cli/renderers/doctor/text.d.ts +0 -2
  436. package/dist/cli/renderers/lint/text.d.ts +0 -2
  437. package/dist/cli/renderers/run/events.d.ts +0 -8
  438. package/dist/cli/renderers/run/failure.d.ts +0 -8
  439. package/dist/cli/renderers/run/formatting.d.ts +0 -79
  440. package/dist/cli/renderers/run/status.d.ts +0 -6
  441. package/dist/cli/renderers/run/text-reporter.d.ts +0 -19
  442. package/dist/cli/renderers/status/text.d.ts +0 -2
  443. package/dist/cli/renderers/stop/text.d.ts +0 -7
  444. package/dist/cli/renderers/typecheck/text.d.ts +0 -2
  445. package/dist/cli/terminal/colors.d.ts +0 -10
  446. package/dist/cli/terminal/layout.d.ts +0 -11
  447. package/dist/cli/version-drift.d.ts +0 -25
  448. package/dist/config/authoring/build-config-contract.d.ts +0 -27
  449. package/dist/config/authoring/configured-step-contract.d.ts +0 -18
  450. package/dist/config/authoring/http-execution-contract.d.ts +0 -70
  451. package/dist/config/authoring/http-methods.d.ts +0 -18
  452. package/dist/config/authoring/index.d.ts +0 -381
  453. package/dist/config/authoring/preset-env.d.ts +0 -19
  454. package/dist/config/authoring/runtime.d.ts +0 -64
  455. package/dist/config/loader/bugs.d.ts +0 -15
  456. package/dist/config/loader/config-loader.d.ts +0 -9
  457. package/dist/config/loader/database-materialization.d.ts +0 -19
  458. package/dist/config/loader/database-roles.d.ts +0 -2
  459. package/dist/config/loader/database.d.ts +0 -55
  460. package/dist/config/loader/decode-discovery.d.ts +0 -5
  461. package/dist/config/loader/decode-execution.d.ts +0 -9
  462. package/dist/config/loader/dependencies.d.ts +0 -7
  463. package/dist/config/loader/discover-tests.d.ts +0 -111
  464. package/dist/config/loader/discovery-summary.d.ts +0 -29
  465. package/dist/config/loader/discovery.d.ts +0 -54
  466. package/dist/config/loader/env.d.ts +0 -4
  467. package/dist/config/loader/execution-model.d.ts +0 -16
  468. package/dist/config/loader/file-metadata.d.ts +0 -19
  469. package/dist/config/loader/index.d.ts +0 -10
  470. package/dist/config/loader/load.d.ts +0 -91
  471. package/dist/config/loader/managed-configs.d.ts +0 -23
  472. package/dist/config/loader/path-policy.d.ts +0 -9
  473. package/dist/config/loader/paths.d.ts +0 -5
  474. package/dist/config/loader/runtime-isolation.d.ts +0 -44
  475. package/dist/config/loader/runtime.d.ts +0 -25
  476. package/dist/config/loader/skip-config.d.ts +0 -44
  477. package/dist/config/loader/test-selection.d.ts +0 -15
  478. package/dist/config/loader/validation.d.ts +0 -16
  479. package/dist/config/loader/values.d.ts +0 -4
  480. package/dist/config/loader/values.js +0 -1
  481. package/dist/database/activity-gate.d.ts +0 -22
  482. package/dist/database/admin.d.ts +0 -31
  483. package/dist/database/cleanup.d.ts +0 -36
  484. package/dist/database/configured-steps.d.ts +0 -27
  485. package/dist/database/constants.d.ts +0 -11
  486. package/dist/database/docker-metadata.d.ts +0 -3
  487. package/dist/database/docker.d.ts +0 -65
  488. package/dist/database/drizzle/index.d.ts +0 -13
  489. package/dist/database/fingerprint.d.ts +0 -12
  490. package/dist/database/index.d.ts +0 -39
  491. package/dist/database/lifecycle-cleanup.d.ts +0 -7
  492. package/dist/database/local-postgres.d.ts +0 -71
  493. package/dist/database/naming.d.ts +0 -17
  494. package/dist/database/postgres/index.d.ts +0 -71
  495. package/dist/database/progress.d.ts +0 -6
  496. package/dist/database/roles.d.ts +0 -19
  497. package/dist/database/runtime-config.d.ts +0 -16
  498. package/dist/database/runtime-reservations.d.ts +0 -19
  499. package/dist/database/schema-operations.d.ts +0 -18
  500. package/dist/database/schema-source.d.ts +0 -96
  501. package/dist/database/source-refresh-lock.d.ts +0 -8
  502. package/dist/database/source-url.d.ts +0 -22
  503. package/dist/database/state-files.d.ts +0 -13
  504. package/dist/database/state.d.ts +0 -26
  505. package/dist/database/template-steps.d.ts +0 -39
  506. package/dist/domain/file-timeout.d.ts +0 -28
  507. package/dist/domain/identifiers.d.ts +0 -9
  508. package/dist/domain/operation-display.d.ts +0 -10
  509. package/dist/domain/operation-reason.d.ts +0 -5
  510. package/dist/domain/postgres-route.d.ts +0 -4
  511. package/dist/domain/runtime-identity.d.ts +0 -1
  512. package/dist/domain/runtime-isolation-contract.d.ts +0 -5
  513. package/dist/domain/service-name.d.ts +0 -2
  514. package/dist/domain/suite-selection.d.ts +0 -20
  515. package/dist/domain/test-outcomes.d.ts +0 -3
  516. package/dist/domain/test-types.d.ts +0 -16
  517. package/dist/engines/adapters/evidence-files.d.ts +0 -32
  518. package/dist/engines/adapters/evidence-identity.d.ts +0 -12
  519. package/dist/engines/adapters/execution.d.ts +0 -42
  520. package/dist/engines/adapters/native-report.d.ts +0 -25
  521. package/dist/engines/adapters/node-startup-cache.d.ts +0 -8
  522. package/dist/engines/adapters/workspace.d.ts +0 -4
  523. package/dist/engines/api/capabilities.d.ts +0 -31
  524. package/dist/engines/api/capabilities.js +0 -1
  525. package/dist/engines/api/evidence.d.ts +0 -38
  526. package/dist/engines/api/execution-observer.d.ts +0 -8
  527. package/dist/engines/api/execution-scope.d.ts +0 -17
  528. package/dist/engines/api/execution.d.ts +0 -101
  529. package/dist/engines/api/index.d.ts +0 -5
  530. package/dist/engines/api/k6-runtime-input.d.ts +0 -26
  531. package/dist/engines/api/k6-runtime-input.js +0 -1
  532. package/dist/engines/api/runtime-artifact.d.ts +0 -19
  533. package/dist/engines/bundle-cache.d.ts +0 -32
  534. package/dist/engines/catalog.d.ts +0 -27
  535. package/dist/engines/contracts/fixture-manifest.d.ts +0 -34
  536. package/dist/engines/contracts/json-bounds.d.ts +0 -36
  537. package/dist/engines/contracts/json-bounds.js +0 -2
  538. package/dist/engines/contracts/k6-repository-configuration.d.ts +0 -12
  539. package/dist/engines/contracts/k6-repository-configuration.js +0 -1
  540. package/dist/engines/contracts/test-context.d.ts +0 -15
  541. package/dist/engines/contracts/test-context.js +0 -1
  542. package/dist/engines/definitions.d.ts +0 -22
  543. package/dist/engines/factory.d.ts +0 -6
  544. package/dist/engines/generated-performance.d.ts +0 -1
  545. package/dist/engines/installation-catalog.d.ts +0 -27
  546. package/dist/engines/installation-catalog.js +0 -1
  547. package/dist/engines/installations/k6.d.ts +0 -98
  548. package/dist/engines/installations/k6.js +0 -1
  549. package/dist/engines/installations/node-vitest.d.ts +0 -33
  550. package/dist/engines/installations/package-requirements.d.ts +0 -28
  551. package/dist/engines/installations/package-resolution.d.ts +0 -51
  552. package/dist/engines/installations/playwright-resolution-child.d.ts +0 -1
  553. package/dist/engines/installations/playwright.d.ts +0 -75
  554. package/dist/engines/installations/types.d.ts +0 -10
  555. package/dist/engines/k6/adapter/bundle.d.ts +0 -25
  556. package/dist/engines/k6/adapter/bundle.js +0 -112
  557. package/dist/engines/k6/adapter/evidence.d.ts +0 -15
  558. package/dist/engines/k6/adapter/evidence.js +0 -4
  559. package/dist/engines/k6/adapter/executor.d.ts +0 -13
  560. package/dist/engines/k6/adapter/executor.js +0 -1
  561. package/dist/engines/k6/adapter/index.d.ts +0 -1
  562. package/dist/engines/k6/adapter/index.js +0 -1
  563. package/dist/engines/k6/adapter/input.d.ts +0 -21
  564. package/dist/engines/k6/adapter/input.js +0 -1
  565. package/dist/engines/k6/adapter/native-summary.d.ts +0 -11
  566. package/dist/engines/k6/adapter/native-summary.js +0 -1
  567. package/dist/engines/k6/adapter/repository-configuration.d.ts +0 -2
  568. package/dist/engines/k6/adapter/repository-configuration.js +0 -1
  569. package/dist/engines/k6/authoring-type-paths.d.ts +0 -3
  570. package/dist/engines/k6/authoring-type-paths.js +0 -1
  571. package/dist/engines/k6/runtime/ambient-types/bundle-manifest.json +0 -146
  572. package/dist/engines/k6/runtime/ambient-types/k6/LICENSE +0 -21
  573. package/dist/engines/k6/runtime/ambient-types/k6/browser/index.d.ts +0 -6332
  574. package/dist/engines/k6/runtime/ambient-types/k6/crypto/index.d.ts +0 -218
  575. package/dist/engines/k6/runtime/ambient-types/k6/data/index.d.ts +0 -16
  576. package/dist/engines/k6/runtime/ambient-types/k6/encoding/index.d.ts +0 -46
  577. package/dist/engines/k6/runtime/ambient-types/k6/execution/index.d.ts +0 -127
  578. package/dist/engines/k6/runtime/ambient-types/k6/experimental/csv/index.d.ts +0 -96
  579. package/dist/engines/k6/runtime/ambient-types/k6/experimental/fs/index.d.ts +0 -104
  580. package/dist/engines/k6/runtime/ambient-types/k6/experimental/redis/index.d.ts +0 -821
  581. package/dist/engines/k6/runtime/ambient-types/k6/experimental/streams/index.d.ts +0 -198
  582. package/dist/engines/k6/runtime/ambient-types/k6/global.d.ts +0 -83
  583. package/dist/engines/k6/runtime/ambient-types/k6/html/index.d.ts +0 -1325
  584. package/dist/engines/k6/runtime/ambient-types/k6/http/index.d.ts +0 -806
  585. package/dist/engines/k6/runtime/ambient-types/k6/index.d.ts +0 -126
  586. package/dist/engines/k6/runtime/ambient-types/k6/metrics/index.d.ts +0 -66
  587. package/dist/engines/k6/runtime/ambient-types/k6/net/grpc/index.d.ts +0 -247
  588. package/dist/engines/k6/runtime/ambient-types/k6/options/index.d.ts +0 -459
  589. package/dist/engines/k6/runtime/ambient-types/k6/package.json +0 -79
  590. package/dist/engines/k6/runtime/ambient-types/k6/secrets/index.d.ts +0 -36
  591. package/dist/engines/k6/runtime/ambient-types/k6/timers/index.d.ts +0 -47
  592. package/dist/engines/k6/runtime/ambient-types/k6/websockets/index.d.ts +0 -324
  593. package/dist/engines/k6/runtime/ambient-types/k6/ws/index.d.ts +0 -283
  594. package/dist/engines/k6/runtime/ambient-types/xk6-sql/LICENSE +0 -201
  595. package/dist/engines/k6/runtime/ambient-types/xk6-sql/index.d.ts +0 -397
  596. package/dist/engines/k6/runtime/ambient-types/xk6-sql/package.json +0 -15
  597. package/dist/engines/k6/runtime/artifacts.d.ts +0 -2
  598. package/dist/engines/k6/runtime/artifacts.js +0 -1
  599. package/dist/engines/k6/runtime/checks.d.ts +0 -17
  600. package/dist/engines/k6/runtime/checks.js +0 -1
  601. package/dist/engines/k6/runtime/dal-fixtures.d.ts +0 -24
  602. package/dist/engines/k6/runtime/dal-fixtures.js +0 -1
  603. package/dist/engines/k6/runtime/dal-suite.d.ts +0 -24
  604. package/dist/engines/k6/runtime/dal-suite.js +0 -1
  605. package/dist/engines/k6/runtime/dal.d.ts +0 -10
  606. package/dist/engines/k6/runtime/dal.js +0 -1
  607. package/dist/engines/k6/runtime/fixtures.d.ts +0 -3
  608. package/dist/engines/k6/runtime/fixtures.js +0 -1
  609. package/dist/engines/k6/runtime/http-assertions.d.ts +0 -19
  610. package/dist/engines/k6/runtime/http-assertions.js +0 -1
  611. package/dist/engines/k6/runtime/http-checks.d.ts +0 -19
  612. package/dist/engines/k6/runtime/http-checks.js +0 -1
  613. package/dist/engines/k6/runtime/http-suite-runtime.d.ts +0 -103
  614. package/dist/engines/k6/runtime/http-suite-runtime.js +0 -1
  615. package/dist/engines/k6/runtime/http.d.ts +0 -15
  616. package/dist/engines/k6/runtime/http.js +0 -1
  617. package/dist/engines/k6/runtime/index.d.ts +0 -11
  618. package/dist/engines/k6/runtime/index.js +0 -1
  619. package/dist/engines/k6/runtime/input.d.ts +0 -3
  620. package/dist/engines/k6/runtime/input.js +0 -1
  621. package/dist/engines/k6/runtime/k6-repository-configuration.d.ts +0 -9
  622. package/dist/engines/k6/runtime/k6-repository-configuration.js +0 -1
  623. package/dist/engines/k6/runtime/node-setup.d.ts +0 -13
  624. package/dist/engines/k6/runtime/node-setup.js +0 -1
  625. package/dist/engines/k6/runtime/runtime-globals.d.ts +0 -10
  626. package/dist/engines/k6/runtime/runtime.d.ts +0 -54
  627. package/dist/engines/k6/runtime/runtime.js +0 -1
  628. package/dist/engines/k6/runtime/shared/assertion-details.d.ts +0 -19
  629. package/dist/engines/k6/runtime/shared/assertion-details.js +0 -2
  630. package/dist/engines/k6/runtime/shared/db-normalization.d.ts +0 -19
  631. package/dist/engines/k6/runtime/shared/db-normalization.js +0 -1
  632. package/dist/engines/k6/runtime/shared/error-body.d.ts +0 -3
  633. package/dist/engines/k6/runtime/shared/error-body.js +0 -1
  634. package/dist/engines/k6/runtime/shared/file-data.d.ts +0 -1
  635. package/dist/engines/k6/runtime/shared/file-data.js +0 -1
  636. package/dist/engines/k6/runtime/shared/fixture-engine.d.ts +0 -8
  637. package/dist/engines/k6/runtime/shared/fixture-engine.js +0 -2
  638. package/dist/engines/k6/runtime/shared/http-check-plan.d.ts +0 -29
  639. package/dist/engines/k6/runtime/shared/http-check-plan.js +0 -1
  640. package/dist/engines/k6/runtime/shared/http-parsing.d.ts +0 -10
  641. package/dist/engines/k6/runtime/shared/http-parsing.js +0 -3
  642. package/dist/engines/k6/runtime/shared/ordering.d.ts +0 -2
  643. package/dist/engines/k6/runtime/shared/ordering.js +0 -1
  644. package/dist/engines/k6/runtime/shared/properties.d.ts +0 -1
  645. package/dist/engines/k6/runtime/shared/properties.js +0 -1
  646. package/dist/engines/k6/runtime/suite.d.ts +0 -4
  647. package/dist/engines/k6/runtime/suite.js +0 -1
  648. package/dist/engines/k6/runtime/types.d.ts +0 -244
  649. package/dist/engines/k6/runtime/types.js +0 -1
  650. package/dist/engines/k6/runtime/xk6-sql-driver-postgres.d.ts +0 -7
  651. package/dist/engines/k6/runtime/xk6-sql-driver-postgres.js +0 -1
  652. package/dist/engines/managed-module-resolution-policy-input.d.ts +0 -9
  653. package/dist/engines/managed-module-resolution-policy.d.ts +0 -25
  654. package/dist/engines/managed-module-resolution.d.ts +0 -13
  655. package/dist/engines/manager.d.ts +0 -25
  656. package/dist/engines/node-vitest/adapter/adapter.d.ts +0 -16
  657. package/dist/engines/node-vitest/adapter/consumer-typescript-paths.d.ts +0 -17
  658. package/dist/engines/node-vitest/adapter/consumer-typescript-paths.js +0 -3
  659. package/dist/engines/node-vitest/adapter/evidence.d.ts +0 -33
  660. package/dist/engines/node-vitest/adapter/failure-details.d.ts +0 -3
  661. package/dist/engines/node-vitest/adapter/index.d.ts +0 -1
  662. package/dist/engines/node-vitest/adapter/reporter.d.ts +0 -7
  663. package/dist/engines/node-vitest/adapter/resolution.d.ts +0 -12
  664. package/dist/engines/node-vitest/adapter/resolution.js +0 -1
  665. package/dist/engines/node-vitest/adapter/workspace.d.ts +0 -19
  666. package/dist/engines/node-vitest/runtime/contract/index.d.ts +0 -64
  667. package/dist/engines/node-vitest/runtime/data/http.d.ts +0 -4
  668. package/dist/engines/node-vitest/runtime/data/index.d.ts +0 -8
  669. package/dist/engines/node-vitest/runtime/data/primitives.d.ts +0 -1
  670. package/dist/engines/node-vitest/runtime/data/report.d.ts +0 -3
  671. package/dist/engines/node-vitest/runtime/data/runner.d.ts +0 -4
  672. package/dist/engines/node-vitest/runtime/data/scenario.d.ts +0 -12
  673. package/dist/engines/node-vitest/runtime/data/types.d.ts +0 -412
  674. package/dist/engines/node-vitest/runtime/runtime-input.d.ts +0 -64
  675. package/dist/engines/playwright/adapter/adapter.d.ts +0 -18
  676. package/dist/engines/playwright/adapter/attachments.d.ts +0 -26
  677. package/dist/engines/playwright/adapter/config.d.ts +0 -45
  678. package/dist/engines/playwright/adapter/evidence-validation.d.ts +0 -12
  679. package/dist/engines/playwright/adapter/evidence.d.ts +0 -32
  680. package/dist/engines/playwright/adapter/failure-details.d.ts +0 -2
  681. package/dist/engines/playwright/adapter/index.d.ts +0 -3
  682. package/dist/engines/playwright/adapter/reporter.d.ts +0 -12
  683. package/dist/engines/playwright/runtime/config-file.d.ts +0 -2
  684. package/dist/engines/playwright/runtime/config.d.ts +0 -24
  685. package/dist/engines/playwright/runtime/index.d.ts +0 -4
  686. package/dist/engines/playwright/runtime/runtime-input.d.ts +0 -36
  687. package/dist/engines/playwright/runtime/sandbox.d.ts +0 -84
  688. package/dist/engines/runtime-input-file.d.ts +0 -27
  689. package/dist/environment/lifecycle-artifacts.d.ts +0 -7
  690. package/dist/environment/lifecycle-controller.d.ts +0 -70
  691. package/dist/environment/lifecycle.d.ts +0 -29
  692. package/dist/environment/maintenance.d.ts +0 -68
  693. package/dist/environment/planning-types.d.ts +0 -35
  694. package/dist/environment/readiness.d.ts +0 -12
  695. package/dist/environment/readiness.js +0 -1
  696. package/dist/environment/ready-environment.d.ts +0 -19
  697. package/dist/environment/run-environment.d.ts +0 -38
  698. package/dist/environment/run-stopping.d.ts +0 -13
  699. package/dist/environment/runtime-contexts.d.ts +0 -33
  700. package/dist/environment/runtime-manager.d.ts +0 -95
  701. package/dist/environment/runtime-planning.d.ts +0 -16
  702. package/dist/environment/runtime-preparation.d.ts +0 -30
  703. package/dist/environment/runtime-service.d.ts +0 -18
  704. package/dist/environment/services.d.ts +0 -48
  705. package/dist/environment/state.d.ts +0 -18
  706. package/dist/environment/status-runtime.d.ts +0 -53
  707. package/dist/environment/template.d.ts +0 -180
  708. package/dist/evidence/artifact-config.d.ts +0 -14
  709. package/dist/evidence/artifact-validation.d.ts +0 -5
  710. package/dist/evidence/artifacts.d.ts +0 -75
  711. package/dist/evidence/bundles.d.ts +0 -27
  712. package/dist/evidence/ci-provenance.d.ts +0 -9
  713. package/dist/evidence/contracts.d.ts +0 -154
  714. package/dist/evidence/file-evidence.d.ts +0 -23
  715. package/dist/evidence/finalization.d.ts +0 -9
  716. package/dist/evidence/index.d.ts +0 -8
  717. package/dist/evidence/logs.d.ts +0 -31
  718. package/dist/evidence/operation-timings.d.ts +0 -60
  719. package/dist/evidence/read-bundle.d.ts +0 -4
  720. package/dist/evidence/read-fields.d.ts +0 -22
  721. package/dist/evidence/read-provenance.d.ts +0 -2
  722. package/dist/evidence/read-redaction.d.ts +0 -2
  723. package/dist/evidence/read-retention.d.ts +0 -2
  724. package/dist/evidence/read-run.d.ts +0 -2
  725. package/dist/evidence/reading.d.ts +0 -28
  726. package/dist/evidence/reporting-types.d.ts +0 -330
  727. package/dist/evidence/reporting.d.ts +0 -3
  728. package/dist/evidence/secure-file-copy.d.ts +0 -24
  729. package/dist/evidence/setup-progress.d.ts +0 -63
  730. package/dist/evidence/step-output.d.ts +0 -16
  731. package/dist/evidence/storage-inventory.d.ts +0 -27
  732. package/dist/evidence/storage.d.ts +0 -27
  733. package/dist/evidence/timing.d.ts +0 -23
  734. package/dist/file.d.ts +0 -11
  735. package/dist/index.d.ts +0 -4
  736. package/dist/kernel/error-serialization.d.ts +0 -38
  737. package/dist/kernel/redaction.d.ts +0 -2
  738. package/dist/kernel/unknown-values.d.ts +0 -6
  739. package/dist/kernel/work-metrics.d.ts +0 -6
  740. package/dist/process/capture-output.d.ts +0 -7
  741. package/dist/process/command-shell.d.ts +0 -1
  742. package/dist/process/environment-overlay.d.ts +0 -17
  743. package/dist/process/environment.d.ts +0 -33
  744. package/dist/process/files/contained-path.d.ts +0 -8
  745. package/dist/process/files/directory-status.d.ts +0 -14
  746. package/dist/process/files/dotenv.d.ts +0 -2
  747. package/dist/process/files/file-snapshot.d.ts +0 -34
  748. package/dist/process/files/json-file.d.ts +0 -12
  749. package/dist/process/files/paths.d.ts +0 -1
  750. package/dist/process/files/product-dir.d.ts +0 -1
  751. package/dist/process/files/temp-dir.d.ts +0 -11
  752. package/dist/process/host/metadata.d.ts +0 -6
  753. package/dist/process/host/platform.d.ts +0 -57
  754. package/dist/process/host-command.d.ts +0 -4
  755. package/dist/process/host-inspection-command.d.ts +0 -13
  756. package/dist/process/host-process.d.ts +0 -19
  757. package/dist/process/index.d.ts +0 -9
  758. package/dist/process/lifecycle-fence.d.ts +0 -11
  759. package/dist/process/locks.d.ts +0 -28
  760. package/dist/process/process-contracts.d.ts +0 -78
  761. package/dist/process/process-group.d.ts +0 -12
  762. package/dist/process/process-identity.d.ts +0 -27
  763. package/dist/process/process-limits.d.ts +0 -6
  764. package/dist/process/process.d.ts +0 -12
  765. package/dist/process/readiness.d.ts +0 -37
  766. package/dist/process/recovery.d.ts +0 -3
  767. package/dist/process/runs/inspection.d.ts +0 -5
  768. package/dist/process/runs/manifest.d.ts +0 -86
  769. package/dist/process/runs/ownership.d.ts +0 -11
  770. package/dist/process/runs/product-state.d.ts +0 -2
  771. package/dist/process/runs/schema.d.ts +0 -3
  772. package/dist/process/runs/stop.d.ts +0 -19
  773. package/dist/process/runtime-socket.d.ts +0 -4
  774. package/dist/process/service-processes.d.ts +0 -13
  775. package/dist/process/shutdown.d.ts +0 -10
  776. package/dist/process/windows-cli-owner.d.ts +0 -2
  777. package/dist/process/windows-native.d.ts +0 -6
  778. package/dist/process/windows-process-identity.d.ts +0 -4
  779. package/dist/repo/ci-environment.d.ts +0 -7
  780. package/dist/repo/fingerprint-policy.d.ts +0 -15
  781. package/dist/repo/git-path.d.ts +0 -2
  782. package/dist/repo/history.d.ts +0 -17
  783. package/dist/repo/managed-git.d.ts +0 -10
  784. package/dist/repo/metadata.d.ts +0 -3
  785. package/dist/repo/physical-tree.d.ts +0 -37
  786. package/dist/repo/remote.d.ts +0 -6
  787. package/dist/repo/state.d.ts +0 -26
  788. package/dist/repo/tree-listing.d.ts +0 -10
  789. package/dist/steps/build-config.d.ts +0 -35
  790. package/dist/steps/configured-step-testkit-modules.d.ts +0 -19
  791. package/dist/steps/configured-steps.d.ts +0 -51
  792. package/dist/steps/environment.d.ts +0 -84
  793. package/dist/steps/index.d.ts +0 -2
  794. package/dist/steps/module-runner.d.ts +0 -1
  795. package/dist/steps/run.d.ts +0 -36
  796. package/dist/toolchains/archive.d.ts +0 -53
  797. package/dist/toolchains/esbuild.d.ts +0 -9
  798. package/dist/toolchains/host-node-support.d.ts +0 -3
  799. package/dist/toolchains/index.d.ts +0 -114
  800. package/dist/toolchains/managed-node-releases.d.ts +0 -28
  801. package/dist/toolchains/node-cache.d.ts +0 -20
  802. package/dist/toolchains/node-integrity.d.ts +0 -18
  803. package/dist/toolchains/node-provisioning.d.ts +0 -29
  804. package/dist/toolchains/semver.d.ts +0 -13
  805. package/dist/toolchains/shared-operation.d.ts +0 -11
  806. package/dist/toolchains/timeouts.d.ts +0 -1
  807. package/dist/toolchains/vitest/index.d.ts +0 -13
  808. package/dist/tracker/gitea.d.ts +0 -14
  809. package/dist/tracker/github.d.ts +0 -14
  810. package/dist/tracker/http.d.ts +0 -33
  811. package/dist/tracker/index.d.ts +0 -4
  812. package/dist/tracker/redaction.d.ts +0 -4
  813. package/dist/tracker/requests.d.ts +0 -17
  814. package/dist/tracker/responses.d.ts +0 -24
  815. package/dist/tracker/types.d.ts +0 -51
  816. package/docs/engine-architecture.md +0 -654
  817. /package/dist/engines/{k6/runtime/runtime-globals.js → api/profiles.js} +0 -0
@@ -1 +1 @@
1
- export{formatTestTypeLabel}from"../../domain/test-types.js";import{readRunDocument as R}from"../../evidence/read-run.js";import c from"fs";import i from"path";import{errorMessage as u}from"../../kernel/error-serialization.js";import{isPublicTestType as w}from"../../domain/identifiers.js";import{loadDiscoveryContext as I,hasDiscoveryErrors as k,buildDiscoveryErrorFromDiagnostics as D,formatDisplayName as S}from"../../config/loader/index.js";import{collectServiceStatus as b,collectConfiguredServiceStatus as A}from"../status/index.js";export{discoverTests,fileDisplayName,formatDisplayName,testTypeContract}from"../../config/loader/index.js";export{listRunBundles,loadRunBundleArtifact,loadRunBundleManifest,verifyRunBundle}from"../../evidence/index.js";const N=2,$=24,C=String;export async function inspectWorkspace(t={}){const e=_(t.targetLimit,$),s=new Date().toISOString(),r=await F(t),a=r.data?.product.directory||i.resolve(process.cwd(),t.dir||"."),[n,o,l]=await Promise.all([t.status===!1?j():M(t,r.context),d(a,"latest"),d(a,"live")]),y=p(o.data,"latest"),g=p(l.data,"live"),T=P({discovery:r.data,latestRunArtifact:o.data,liveRunArtifact:l.data,limit:e}),h=[...r.warnings,...n.warnings,...o.warnings,...l.warnings];return{schemaVersion:N,source:"testkit-workspace",generatedAt:s,product:r.data?.product||{directory:a,name:i.basename(a)},discovery:r.data?{configFile:r.data.configFile||null,diagnostics:r.data.diagnostics,summary:r.data.summary}:null,status:n.data,runs:{latest:y,live:g},targets:T,activity:O(n.data),warnings:h}}async function F(t){try{const{discovery:e,context:s}=await I({diagnostics:"report",dir:t.dir,runnableOnly:!1,service:t.service||null}),r=e.diagnostics.filter(a=>a.severity==="error").map(a=>`Discovery diagnostic: ${a.message}`);return{data:e,warnings:r,context:s}}catch(e){return{data:null,context:null,warnings:[`Discovery unavailable: ${u(e)}`]}}}async function M(t,e){try{if(e&&k(e.discovery.diagnostics))throw D(e.discovery.diagnostics);const s=e?A(e.configs,t.service||null):await b({dir:t.dir,service:t.service||null});return{data:x(s),warnings:[]}}catch(s){return{data:{ok:!1,results:[]},warnings:[`Status unavailable: ${u(s)}`]}}}function j(){return Promise.resolve({data:{ok:!0,results:[]},warnings:[]})}function d(t,e){const s=e==="live"?"live.json":"latest.json",r=i.join(t,".testkit","results",s);if(!c.existsSync(r))return Promise.resolve({data:null,warnings:[]});try{const a=R(JSON.parse(c.readFileSync(r,"utf8")),r);return Promise.resolve({data:a,warnings:[]})}catch(a){return Promise.resolve({data:null,warnings:[`${e} run artifact unavailable: ${u(a)}`]})}}function x(t){return{ok:!0,results:t.map(e=>({caches:e.caches,hasState:e.hasState,name:e.name,product:e.product,runtimeGraphs:e.runtimeGraphs.map(s=>({currentRuntimeDirCount:s.currentRuntimeDirs.length,desired:s.desired,exists:s.exists,name:s.name,orphan:s.orphan,runtimeDirCount:s.runtimeDirCount,staleRuntimeDirCount:s.staleRuntimeDirs.length})),runs:{active:e.runs.active,stale:e.runs.stale,total:e.runs.total},warnings:e.warnings}))}}function p(t,e){if(t===null)return null;const{run:s,summary:r}=t;return{durationMs:s.durationMs??null,generatedAt:t.generatedAt??null,id:s.id,startedAt:s.startedAt,status:s.status,types:s.types??[],source:e,files:{failed:r?.files.failed??0,notRun:r?.files.notRun??0,passed:r?.files.passed??0,skipped:r?.files.skipped??0,total:r?.files.total??0},services:{failed:r?.services.failed??0,passed:r?.services.passed??0,skipped:r?.services.skipped??0,total:r?.services.total??0},suites:{completed:r?.suites.completed??0,failed:r?.suites.failed??0,passed:r?.suites.passed??0,skipped:r?.suites.skipped??0,total:r?.suites.total??0}}}function P({discovery:t,latestRunArtifact:e,liveRunArtifact:s,limit:r}){const a=[E(t),...m(s,"live"),...m(e,"latest"),...B(t).slice(0,Math.ceil(r/2)),...L(t).slice(0,r)].filter(n=>n!==null);return W(a).slice(0,r)}function E(t){return t?{detail:t.product.directory,id:"project:all",kind:"project",label:`All tests in ${t.product.name}`,runnable:!0,source:"discovery"}:null}function B(t){return(t?.suites||[]).map(e=>({detail:[e.service,e.testType,e.engineId,e.profileId].filter(Boolean).join(" - "),id:`suite:${e.service}:${e.testType}:${e.engineId}:${e.profileId}:${e.name}`,engineId:e.engineId,kind:"suite",label:e.displayName||e.name,profileId:e.profileId,runnable:e.activeFileCount>0,service:e.service,source:"discovery",suiteName:e.name,testType:e.testType}))}function L(t){return(t?.files||[]).filter(e=>!e.skipped).map(e=>f(e,"discovery"))}function m(t,e){const s=[];for(const r of t?.services??[])for(const a of r.suites)for(const n of a.files??[])n.status!=="failed"&&!n.error||s.push(f({displayName:v(n.path),engineId:a.engineId,path:n.path,profileId:a.profileId,service:r.name,suiteName:a.name,testType:a.testType},e,"failed"));return s}function f(t,e,s=null){return{detail:[t.service,t.testType,t.engineId,t.profileId,t.suiteName].filter(Boolean).join(" - "),filePath:t.path,engineId:t.engineId,id:`file:${t.service||""}:${t.testType}:${t.engineId}:${t.profileId}:${t.path}`,kind:"file",label:t.displayName||v(t.path),profileId:t.profileId,runnable:w(t.testType),service:t.service||null,source:e,status:s||null,suiteName:t.suiteName||null,testType:t.testType}}function O(t){return{activeRuns:t.results.reduce((e,s)=>e+s.runs.active,0),staleRuns:t.results.reduce((e,s)=>e+s.runs.stale,0)}}function W(t){const e=new Set,s=[];for(const r of t)e.has(r.id)||(e.add(r.id),s.push(r));return s}function _(t,e){const s=Number(t);return Number.isFinite(s)?Math.max(1,Math.min(100,Math.round(s))):e}function v(t){return S(i.basename(C(t||"test")).replace(/\.testkit\.[cm]?[jt]sx?$/,""))}
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,notice:n}=await S({diagnostics:"report",dir:e.dir,runnableOnly:!1,group:e.group||null});n!==null&&e.notice?.(n);const a=t.diagnostics.filter(s=>s.severity==="error").map(s=>`Discovery diagnostic: ${s.message}`);return{data:t,warnings:a,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?$/,""))}
@@ -1,2 +1,2 @@
1
- import{loadTestkitConfig as f,resolveProductDir as u}from"../../config/loader/index.js";export async function executeLintOperation(t={}){const i=u(process.cwd(),t.dir),n=await f(i);return runLintForConfig(m(n),{dir:i})}function m(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 p,normalizeLintConfig as l}from"./options.js";import{collectCurrentFiles as d,collectTrackedFiles as g,isTestkitSuitePath as y}from"./shared.js";export async function runLint(t={}){const{dir:i,...n}=t,o=r.resolve(process.cwd(),i||".");return a(o,p(n))}export async function runLintForConfig(t,i={}){const n=r.resolve(process.cwd(),i.dir||".");return a(n,l(t))}async function a(t,i){const n=await g(t),o=await d(t,n!==null),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(y).length,violations:e.length},violations:e};return w(t,s),s}export function normalizeLintConfig(t={}){return l(t)}function w(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)}
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{}}
@@ -1 +1 @@
1
- import y from"node:path";import{LINT_RULE_NAMES as _}from"./options.js";import{compareFindings as $,findingKey as B,isTypeScriptLikePath as M,matchesAnyPathPattern as h,normalizeFinding as c,normalizePath as E,SOURCE_IGNORES as F}from"./shared.js";import{createSyntaxPolicy as R}from"./rules/syntax.js";import{createDataPolicy as U}from"./rules/data.js";import{createUnitPolicy as z}from"./rules/unit.js";import{createEngineImportPolicy as A}from"./rules/engine-imports.js";export async function lintProject({productDir:i,files:n,trackedFiles:o,options:s}){const x=await K(),[{ESLint:k},v]=x;if(k.version!=="10.7.0"||v.version!=="8.65.0")throw new Error("Testkit lint requires its managed eslint@10.7.0 and @typescript-eslint/parser@8.65.0 installation");const I=new Map,w=[],f=_.filter(e=>s.rules[e].enabled),L=Object.fromEntries(f.filter(e=>e!=="testkitBoundary").map(e=>{const t=s.rules[e],r={meta:{type:"problem",schema:[],messages:{violation:"{{message}}"}},defaultOptions:[],create(l){return(()=>{const S=E(y.relative(i,l.filename)),u={context:l,file:S,report:(a,b,C,g)=>{const O=c({file:S,ruleName:e,ruleId:t.ruleId,kind:b,target:C,message:g,line:a.loc.start.line,snippet:l.sourceCode.getText(a).split(/\r?\n/u)[0]});I.set(T(l.filename,a.loc.start.line,a.loc.start.column+1,g),O),l.report({node:a,messageId:"violation",data:{message:g}})},options:s,literals:w};return e==="engineImports"?A(u):e==="dataSuiteContract"?U(u):e==="unitTestBoundaries"?z(u):R(e,u,n)})()}};return[t.ruleId,r]})),N=new k({cwd:i,overrideConfigFile:!0,allowInlineConfig:!1,errorOnUnmatchedPattern:!1,globInputPaths:!1,warnIgnored:!1,overrideConfig:[{ignores:F},{files:["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}"],languageOptions:{parser:v,ecmaVersion:"latest",sourceType:"module"},plugins:{testkit:{rules:L}}},...f.filter(e=>e!=="testkitBoundary").map(e=>{const t=s.rules[e];return{files:t.include.length?t.include:["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}"],ignores:t.exclude,rules:{[`testkit/${t.ruleId}`]:"error"}}})]}),P=[],j=n.filter(M);if(j.length){const e=j.map(r=>y.join(i,r)),t=await N.lintFiles(e);P.push(...t)}const d=P.flatMap(e=>e.messages.map(t=>{if(t.ruleId===null)return c({file:E(y.relative(i,e.filePath)),line:t.line,ruleName:"syntax",ruleId:"syntax",kind:"parse-error",target:t.message,message:t.message});const r=I.get(T(e.filePath,t.line,t.column,t.message));if(!r)throw new Error(`Missing Testkit finding for ${t.ruleId}: ${t.message}`);return r}));if(f.includes("testkitBoundary")){const e=s.rules.testkitBoundary,t=o&&new Set(o);for(const r of n)e.trackedOnly&&t&&!t.has(r)||!q(r,e)||!r.split("/").some(l=>l.toLowerCase().includes("testkit"))||h(r,e.allowed??[])||d.push(c({file:r,ruleName:"testkitBoundary",ruleId:e.ruleId,kind:"testkit-path",target:r,message:"Tracked Testkit plumbing must live in testkit.config.* or __testkit__/ suites, or move into @gfdelarue/testkit"}))}const p=new Map;for(const e of w){const t=`${e.field}:${e.value}`,r=p.get(t)??[];r.push(e),p.set(t,r)}for(const[e,t]of p)if(!(new Set(t.map(r=>r.file)).size<2))for(const r of t)d.push(c({...r,ruleName:"dalParallelSafety",ruleId:"dal-parallel-safety",kind:"duplicate-literal",target:e,message:`Duplicate ${r.field} literal "${r.value}" appears across DAL specs; use fixture-derived namespaced values`}));const m=new Map;for(const e of d.sort($)){const t=B(e);m.has(t)||m.set(t,e)}return[...m.values()]}function T(i,n,o,s){return[i,n,o,s].join("\0")}function q(i,n){return(!n.include.length||h(i,n.include))&&!h(i,n.exclude)}function K(){return Promise.all([import("eslint"),import("@typescript-eslint/parser")])}
1
+ import m from"node:path";import{posixPath as j}from"../../process/files/paths.js";import{LINT_RULE_NAMES as _}from"./options.js";import{compareFindings as b,findingKey as B,isTypeScriptLikePath as L,matchesAnyPathPattern as p,normalizeFinding as g,SOURCE_IGNORES as M}from"./shared.js";import{createSyntaxPolicy as F}from"./rules/syntax.js";import{createDataPolicy as R}from"./rules/data.js";import{createUnitPolicy as U}from"./rules/unit.js";import{createEngineImportPolicy as $}from"./rules/engine-imports.js";export async function lintProject({productDir:r,files:n,trackedFiles:a,options:s}){const T=await A(),[{ESLint:y},h]=T;if(y.version!=="10.7.0"||h.version!=="8.65.0")throw new Error("Testkit lint requires its managed eslint@10.7.0 and @typescript-eslint/parser@8.65.0 installation");const k=new Map,c=_.filter(t=>s.rules[t].enabled),x=Object.fromEntries(c.filter(t=>t!=="testkitBoundary").map(t=>{const e=s.rules[t],i={meta:{type:"problem",schema:[],messages:{violation:"{{message}}"}},defaultOptions:[],create(o){return(()=>{const P=j(m.relative(r,o.filename)),u={context:o,file:P,report:(l,C,N,d)=>{const O=g({file:P,ruleName:t,ruleId:e.ruleId,kind:C,target:N,message:d,line:l.loc.start.line,snippet:o.sourceCode.getText(l).split(/\r?\n/u)[0]});k.set(E(o.filename,l.loc.start.line,l.loc.start.column+1,d),O),o.report({node:l,messageId:"violation",data:{message:d}})},options:s};return t==="engineImports"?$(u):t==="dataSuiteContract"?R(u):t==="unitTestBoundaries"?U(u):F(t,u,n)})()}};return[e.ruleId,i]})),S=new y({cwd:r,overrideConfigFile:!0,allowInlineConfig:!1,errorOnUnmatchedPattern:!1,globInputPaths:!1,warnIgnored:!1,overrideConfig:[{ignores:M},{files:["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}"],languageOptions:{parser:h,ecmaVersion:"latest",sourceType:"module"},plugins:{testkit:{rules:x}}},...c.filter(t=>t!=="testkitBoundary").map(t=>{const e=s.rules[t];return{files:e.include.length?e.include:["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}"],ignores:e.exclude,rules:{[`testkit/${e.ruleId}`]:"error"}}})]}),I=[],v=n.filter(L);if(v.length){const t=v.map(i=>m.join(r,i)),e=await S.lintFiles(t);I.push(...e)}const w=I.flatMap(t=>t.messages.map(e=>{if(e.ruleId===null)return g({file:j(m.relative(r,t.filePath)),line:e.line,ruleName:"syntax",ruleId:"syntax",kind:"parse-error",target:e.message,message:e.message});const i=k.get(E(t.filePath,e.line,e.column,e.message));if(!i)throw new Error(`Missing Testkit finding for ${e.ruleId}: ${e.message}`);return i}));if(c.includes("testkitBoundary")){const t=s.rules.testkitBoundary,e=a&&new Set(a);for(const i of n)t.trackedOnly&&e&&!e.has(i)||!q(i,t)||!i.split("/").some(o=>o.toLowerCase().includes("testkit"))||p(i,t.allowed??[])||w.push(g({file:i,ruleName:"testkitBoundary",ruleId:t.ruleId,kind:"testkit-path",target:i,message:"Tracked Testkit plumbing must live in testkit.config.* or __testkit__/ suites, or move into @gfdelarue/testkit"}))}const f=new Map;for(const t of w.sort(b)){const e=B(t);f.has(e)||f.set(e,t)}return[...f.values()]}function E(r,n,a,s){return[r,n,a,s].join("\0")}function q(r,n){return(!n.include.length||p(r,n.include))&&!p(r,n.exclude)}function A(){return Promise.all([import("eslint"),import("@typescript-eslint/parser")])}
@@ -1 +1 @@
1
- import{DEFAULT_TESTKIT_BOUNDARY_ALLOWED as a,isObjectRecord as l,normalizePath as y}from"./shared.js";export const LINT_RULE_NAMES=["engineImports","uiSpecShape","dalParallelSafety","dataSuiteContract","configImports","testkitBoundary","unitTestBoundaries"];const b=new Set(LINT_RULE_NAMES),m=new Set(["rules","ui"]),p=new Set(["enabled","exclude","include"]),S=new Set([...p,"allowed","trackedOnly"]),I=new Set(["maxLines","maxTests"]),u="lint levels were removed; set a rule to true or false, or use { enabled: boolean }";export function isLintRuleName(e){return b.has(e)}export const RULES={engineImports:{ruleId:"engine-imports",defaultEnabled:!0},uiSpecShape:{ruleId:"ui-spec-shape",defaultEnabled:!0},dalParallelSafety:{ruleId:"dal-parallel-safety",defaultEnabled:!0},dataSuiteContract:{ruleId:"data-suite-contract",defaultEnabled:!0},configImports:{ruleId:"config-imports",defaultEnabled:!0},testkitBoundary:{ruleId:"testkit-boundary",defaultEnabled:!1},unitTestBoundaries:{ruleId:"unit-test-boundaries",defaultEnabled:!1}};const O=220,T=8;export function normalizeLintConfig(e={}){const n=l(e)?e.lint??{}:{};return normalizeLintOptions(n)}export function normalizeLintOptions(e={}){if(!l(e))throw new Error("lint config must be an object");if(Object.prototype.hasOwnProperty.call(e,"level"))throw new Error(`lint.level was removed; ${u}`);f(e,m,"lint");const n=e.rules??{};if(!l(n))throw new Error("lint.rules must be an object");for(const i of Object.keys(n)){if(i==="missingImports")throw new Error("lint.rules.missingImports was removed; use testkit typecheck for TypeScript import diagnostics");if(!Object.prototype.hasOwnProperty.call(RULES,i))throw new Error(`Unknown lint rule "${i}"`)}const t=i=>{const s=RULES[i];return _({ruleName:i,ruleId:s.ruleId,value:n[i],defaultEnabled:s.defaultEnabled})},r={engineImports:t("engineImports"),configImports:t("configImports"),dalParallelSafety:t("dalParallelSafety"),dataSuiteContract:t("dataSuiteContract"),testkitBoundary:t("testkitBoundary"),uiSpecShape:t("uiSpecShape"),unitTestBoundaries:t("unitTestBoundaries")},o=e.ui===void 0?{}:e.ui;if(!l(o))throw new Error("lint.ui must be an object");return f(o,I,"lint.ui"),{rules:r,ui:{maxLines:w(o.maxLines,O,"lint.ui.maxLines"),maxTests:w(o.maxTests,T,"lint.ui.maxTests")}}}function _({ruleName:e,ruleId:n,value:t,defaultEnabled:r}){if(t===void 0)return d({ruleName:e,ruleId:n,enabled:r});if(typeof t=="boolean")return d({ruleName:e,ruleId:n,enabled:t});if(!l(t))throw new Error(`lint.rules.${e} must be true, false, or a rule config object; ${u}`);if(Object.prototype.hasOwnProperty.call(t,"level"))throw new Error(`lint.rules.${e}.level was removed; ${u}`);return f(t,e==="testkitBoundary"?S:p,`lint.rules.${e}`),d({ruleName:e,ruleId:n,enabled:E(t.enabled,`lint.rules.${e}.enabled`)??!0,include:c(t.include,`lint.rules.${e}.include`),exclude:c(t.exclude,`lint.rules.${e}.exclude`),allowed:e==="testkitBoundary"?h(t.allowed):void 0,trackedOnly:e==="testkitBoundary"?E(t.trackedOnly,`lint.rules.${e}.trackedOnly`):void 0})}function d({ruleName:e,ruleId:n,enabled:t,include:r=[],exclude:o=[],allowed:i,trackedOnly:s}){return{ruleName:e,ruleId:n,enabled:t,include:r,exclude:o,...e==="testkitBoundary"?{allowed:i||a}:{},...e==="testkitBoundary"?{trackedOnly:s!==!1}:{}}}function c(e,n){if(e==null)return[];if(!Array.isArray(e))throw new Error(`${n} must be an array`);return e.map((t,r)=>{const o=typeof t=="string"?t.trim():"";if(!o)throw new Error(`${n}[${String(r)}] must be a non-empty string`);return y(o)})}function h(e){if(e==null)return a;const n=c(e,"lint.rules.testkitBoundary.allowed");return n.length>0?n:a}function w(e,n,t){if(e===void 0)return n;if(typeof e!="number"||!Number.isInteger(e)||e<=0)throw new Error(`${t} must be a positive integer`);return e}function E(e,n){if(e!==void 0){if(typeof e!="boolean")throw new Error(`${n} must be a boolean`);return e}}function f(e,n,t){for(const r of Object.keys(e))if(!n.has(r))throw new Error(`Unknown ${t} option "${r}"`)}
1
+ import{DEFAULT_TESTKIT_BOUNDARY_ALLOWED as u}from"./shared.js";import{posixPath as m}from"../../process/files/paths.js";import{isUnknownRecord as s}from"../../kernel/unknown-values.js";export const LINT_RULE_NAMES=["engineImports","uiSpecShape","dataSuiteContract","configImports","testkitBoundary","unitTestBoundaries"];const b=new Set(["rules","ui"]),p=new Set(["enabled","exclude","include"]),y=new Set([...p,"allowed","trackedOnly"]),I=new Set(["maxLines","maxTests"]),d="lint levels were removed; set a rule to true or false, or use { enabled: boolean }";export const RULES={engineImports:{ruleId:"engine-imports",defaultEnabled:!0},uiSpecShape:{ruleId:"ui-spec-shape",defaultEnabled:!0},dataSuiteContract:{ruleId:"data-suite-contract",defaultEnabled:!0},configImports:{ruleId:"config-imports",defaultEnabled:!0},testkitBoundary:{ruleId:"testkit-boundary",defaultEnabled:!1},unitTestBoundaries:{ruleId:"unit-test-boundaries",defaultEnabled:!1}};const O=220,S=8;export function normalizeLintConfig(t={}){const n=s(t)?t.lint??{}:{};return normalizeLintOptions(n)}export function normalizeLintOptions(t={}){if(!s(t))throw new Error("lint config must be an object");if(Object.prototype.hasOwnProperty.call(t,"level"))throw new Error(`lint.level was removed; ${d}`);f(t,b,"lint");const n=t.rules??{};if(!s(n))throw new Error("lint.rules must be an object");for(const i of Object.keys(n)){if(i==="missingImports")throw new Error("lint.rules.missingImports was removed; use testkit typecheck for TypeScript import diagnostics");if(!Object.prototype.hasOwnProperty.call(RULES,i))throw new Error(`Unknown lint rule "${i}"`)}const e=i=>{const l=RULES[i];return T({ruleName:i,ruleId:l.ruleId,value:n[i],defaultEnabled:l.defaultEnabled})},r={engineImports:e("engineImports"),configImports:e("configImports"),dataSuiteContract:e("dataSuiteContract"),testkitBoundary:e("testkitBoundary"),uiSpecShape:e("uiSpecShape"),unitTestBoundaries:e("unitTestBoundaries")},o=t.ui===void 0?{}:t.ui;if(!s(o))throw new Error("lint.ui must be an object");return f(o,I,"lint.ui"),{rules:r,ui:{maxLines:w(o.maxLines,O,"lint.ui.maxLines"),maxTests:w(o.maxTests,S,"lint.ui.maxTests")}}}function T({ruleName:t,ruleId:n,value:e,defaultEnabled:r}){if(e===void 0)return a({ruleName:t,ruleId:n,enabled:r});if(typeof e=="boolean")return a({ruleName:t,ruleId:n,enabled:e});if(!s(e))throw new Error(`lint.rules.${t} must be true, false, or a rule config object; ${d}`);if(Object.prototype.hasOwnProperty.call(e,"level"))throw new Error(`lint.rules.${t}.level was removed; ${d}`);return f(e,t==="testkitBoundary"?y:p,`lint.rules.${t}`),a({ruleName:t,ruleId:n,enabled:E(e.enabled,`lint.rules.${t}.enabled`)??!0,include:c(e.include,`lint.rules.${t}.include`),exclude:c(e.exclude,`lint.rules.${t}.exclude`),allowed:t==="testkitBoundary"?h(e.allowed):void 0,trackedOnly:t==="testkitBoundary"?E(e.trackedOnly,`lint.rules.${t}.trackedOnly`):void 0})}function a({ruleName:t,ruleId:n,enabled:e,include:r=[],exclude:o=[],allowed:i,trackedOnly:l}){return{ruleName:t,ruleId:n,enabled:e,include:r,exclude:o,...t==="testkitBoundary"?{allowed:i||u}:{},...t==="testkitBoundary"?{trackedOnly:l!==!1}:{}}}function c(t,n){if(t==null)return[];if(!Array.isArray(t))throw new Error(`${n} must be an array`);return t.map((e,r)=>{const o=typeof e=="string"?e.trim():"";if(!o)throw new Error(`${n}[${String(r)}] must be a non-empty string`);return m(o)})}function h(t){if(t==null)return u;const n=c(t,"lint.rules.testkitBoundary.allowed");return n.length>0?n:u}function w(t,n,e){if(t===void 0)return n;if(typeof t!="number"||!Number.isInteger(t)||t<=0)throw new Error(`${e} must be a positive integer`);return t}function E(t,n){if(t!==void 0){if(typeof t!="boolean")throw new Error(`${n} must be a boolean`);return t}}function f(t,n,e){for(const r of Object.keys(t))if(!n.has(r))throw new Error(`Unknown ${e} option "${r}"`)}
@@ -1 +1 @@
1
- import{AST_NODE_TYPES as r}from"@typescript-eslint/types";import{binding as p,memberName as w,stringValue as E}from"../policy.js";const T=new Set(["addFinding","actor","budget","bytes","count","duration","event","externalCall","expectMetric","expectSequence","fixture","finding","http","metric","money","ratio","reconcile","record","recordCache","recordHttpRequest","recordLlmUsage","recordRpc","sequence","sequenceBudget","system","transition"]),N=new Set(["actor","bytes","duration","externalCall","http","money","ratio","reconcile","record","recordCache","recordHttpRequest","recordLlmUsage","recordRpc","sequence","system","transition"]),f=new Set(["bench","describe","it","suite","test","BenchmarkRunner","TestRunner","EvaluatedModules"]);export function createDataPolicy({context:o,file:C,report:n}){if(!C.endsWith(".data.testkit.ts"))return{};const d=new Set,h=new Set,v=new Map,g=new Map;let y=!1,b=!1;const u=(e,t,a="vitest-runner-import")=>{n(e,a,t,`Data suites cannot use ${t} for Vitest case registration; declare cases with dataScenario(...)`)},x=e=>{for(const t of o.sourceCode.getAncestors(e).reverse())if(t.type===r.ArrowFunctionExpression||t.type===r.FunctionExpression){const a=g.get(t);if(a)return a}},m=e=>e.startsWith("vitest/")&&e!=="vitest/package.json"||e==="@gfdelarue/testkit/node-vitest/contract",k=e=>{E(e)?.includes("{serviceContextUrl:")&&n(e,"service-namespace-url","serviceContextUrl","Data suites must not use serviceContextUrl placeholders because they run outside the deployed service namespace")};return{ImportDeclaration(e){const t=e.source.value;if(t==="@playwright/test"&&n(e,"browser-runtime-import",t,"Browser/runtime driving belongs in ui or e2e suites, not data suites"),(t.startsWith("@testing-library/")||t==="jsdom"||t==="happy-dom")&&n(e,"dom-runtime-import","dom-runtime","DOM/rendering tests belong in ui suites, not data suites"),e.importKind==="type")return;const a=e.specifiers.filter(s=>s.type!==r.ImportSpecifier||s.importKind!=="type");if(!(e.specifiers.length&&!a.length)){m(t)&&u(e,t),t==="@gfdelarue/testkit/node-vitest/data"&&(y=!0);for(const s of a){const i=o.sourceCode.getDeclaredVariables(e).find(l=>l.name===s.local.name);if(t==="vitest"&&s.type===r.ImportNamespaceSpecifier&&i&&h.add(i),s.type!==r.ImportSpecifier)continue;const c=s.imported.type===r.Identifier?s.imported.name:s.imported.value;t==="vitest"&&f.has(c)&&u(s,c),t==="@gfdelarue/testkit/node-vitest/data"&&c==="dataScenario"&&i&&d.add(i)}}},ExportNamedDeclaration(e){if(!e.source||e.exportKind==="type")return;const t=e.specifiers.filter(a=>a.exportKind!=="type");if(!(e.specifiers.length&&!t.length)&&(m(e.source.value)&&u(e,e.source.value),e.source.value==="vitest"))for(const a of t){const s=a.local.type===r.Identifier?a.local.name:a.local.value;f.has(s)&&u(a,s)}},ExportAllDeclaration(e){e.exportKind!=="type"&&m(e.source.value)&&u(e,e.source.value)},MemberExpression(e){if(e.object.type!==r.Identifier)return;const t=p(o,e.object),a=w(e);t&&h.has(t)&&a&&f.has(a)&&u(e,a,"vitest-runner-call")},CallExpression(e){const t=e.callee.type===r.Identifier?p(o,e.callee):null;if(t&&d.has(t)){b=!0;const i=e.arguments.at(-1);if(!i||i.type!==r.ArrowFunctionExpression&&i.type!==r.FunctionExpression){n(e,"missing-scenario-callback","dataScenario","dataScenario(...) must provide a callback that receives the Testkit data context");return}const c=i.params[0]?.type===r.AssignmentPattern?i.params[0].left:i.params.at(0),l=c?.type===r.Identifier?o.sourceCode.getDeclaredVariables(i).find(D=>D.name===c.name):null;if(!l){n(e,"missing-data-context","dataScenario","dataScenario callbacks must accept the Testkit data context and record data evidence");return}const S={callback:i,context:l,contextName:l.name,methods:new Set,assertion:!1};v.set(e,S),g.set(i,S);return}const a=o.sourceCode.getText(e.callee);e.callee.type===r.MemberExpression&&a.includes(".serviceContextUrl")&&n(e,"service-namespace-url","serviceContextUrl","Data suites run in the managed Node.js runner, not inside a service namespace; use baseUrl/public endpoints or move service-namespace checks to int/e2e");const s=x(e);if(s&&(/^(expect|assert)(?:\(|\.)/u.test(a)&&(s.assertion=!0),e.callee.type===r.MemberExpression&&e.callee.object.type===r.Identifier&&p(o,e.callee.object)===s.context)){const i=w(e.callee);i&&T.has(i)&&s.methods.add(i)}},"CallExpression:exit"(e){const t=v.get(e);if(!t)return;const{callback:a,contextName:s,methods:i,assertion:c}=t;i.size?[...i].some(l=>N.has(l))||(n(a,"weak-data-evidence",s,"Data scenarios must record product data-flow evidence such as http, bytes, sequence, record, transition, system, externalCall, recordCache, recordLlmUsage, or reconcile; ordinary Node/Vitest-style checks belong in *.contract.testkit.ts with @gfdelarue/testkit/node-vitest/contract"),c&&n(a,"vitest-shaped-data-suite",s,"This dataScenario looks like an ordinary assertion test with weak data bookkeeping; move Node-backed contract checks to *.contract.testkit.ts or model the product data flow with structured evidence")):n(a,"missing-data-evidence",s,"Data scenarios must record Testkit-owned data-flow evidence with the data context, such as http, bytes, sequence, record, transition, system, externalCall, recordCache, recordLlmUsage, or reconcile")},ThrowStatement(e){const t=x(e);t&&(t.assertion=!0)},Literal:k,TemplateLiteral:k,"Program:exit"(e){y?d.size?b||n(e,"missing-data-scenario","dataScenario","Data suites must declare at least one dataScenario(...)"):n(e,"missing-data-scenario-import","dataScenario","Data suites must import dataScenario from @gfdelarue/testkit/node-vitest/data"):n(e,"missing-data-import","@gfdelarue/testkit/node-vitest/data","Data suites must import dataScenario from @gfdelarue/testkit/node-vitest/data")}}}
1
+ import{AST_NODE_TYPES as r}from"@typescript-eslint/types";import{binding as p,memberName as w,stringValue as E}from"../policy.js";const T=new Set(["addFinding","actor","budget","bytes","count","duration","event","externalCall","expectMetric","expectSequence","fixture","finding","http","metric","money","ratio","reconcile","record","recordCache","recordHttpRequest","recordLlmUsage","recordRpc","sequence","sequenceBudget","system","transition"]),N=new Set(["actor","bytes","duration","externalCall","http","money","ratio","reconcile","record","recordCache","recordHttpRequest","recordLlmUsage","recordRpc","sequence","system","transition"]),f=new Set(["bench","describe","it","suite","test","BenchmarkRunner","TestRunner","EvaluatedModules"]);export function createDataPolicy({context:o,file:C,report:n}){if(!C.endsWith(".data.testkit.ts"))return{};const d=new Set,h=new Set,v=new Map,g=new Map;let y=!1,b=!1;const u=(e,t,a="vitest-runner-import")=>{n(e,a,t,`Data suites cannot use ${t} for Vitest case registration; declare cases with dataScenario(...)`)},x=e=>{for(const t of o.sourceCode.getAncestors(e).reverse())if(t.type===r.ArrowFunctionExpression||t.type===r.FunctionExpression){const a=g.get(t);if(a)return a}},m=e=>e.startsWith("vitest/")&&e!=="vitest/package.json"||e==="@gfdelarue/testkit/node-vitest/contract",k=e=>{E(e)?.includes("{serviceContextUrl:")&&n(e,"service-namespace-url","serviceContextUrl","Data suites must not use serviceContextUrl placeholders because they run outside the deployed service namespace")};return{ImportDeclaration(e){const t=e.source.value;if(t==="@playwright/test"&&n(e,"browser-runtime-import",t,"Browser/runtime driving belongs in ui suites, not data suites"),(t.startsWith("@testing-library/")||t==="jsdom"||t==="happy-dom")&&n(e,"dom-runtime-import","dom-runtime","DOM/rendering tests belong in ui suites, not data suites"),e.importKind==="type")return;const a=e.specifiers.filter(s=>s.type!==r.ImportSpecifier||s.importKind!=="type");if(!(e.specifiers.length&&!a.length)){m(t)&&u(e,t),t==="@gfdelarue/testkit/node-vitest/data"&&(y=!0);for(const s of a){const i=o.sourceCode.getDeclaredVariables(e).find(l=>l.name===s.local.name);if(t==="vitest"&&s.type===r.ImportNamespaceSpecifier&&i&&h.add(i),s.type!==r.ImportSpecifier)continue;const c=s.imported.type===r.Identifier?s.imported.name:s.imported.value;t==="vitest"&&f.has(c)&&u(s,c),t==="@gfdelarue/testkit/node-vitest/data"&&c==="dataScenario"&&i&&d.add(i)}}},ExportNamedDeclaration(e){if(!e.source||e.exportKind==="type")return;const t=e.specifiers.filter(a=>a.exportKind!=="type");if(!(e.specifiers.length&&!t.length)&&(m(e.source.value)&&u(e,e.source.value),e.source.value==="vitest"))for(const a of t){const s=a.local.type===r.Identifier?a.local.name:a.local.value;f.has(s)&&u(a,s)}},ExportAllDeclaration(e){e.exportKind!=="type"&&m(e.source.value)&&u(e,e.source.value)},MemberExpression(e){if(e.object.type!==r.Identifier)return;const t=p(o,e.object),a=w(e);t&&h.has(t)&&a&&f.has(a)&&u(e,a,"vitest-runner-call")},CallExpression(e){const t=e.callee.type===r.Identifier?p(o,e.callee):null;if(t&&d.has(t)){b=!0;const i=e.arguments.at(-1);if(!i||i.type!==r.ArrowFunctionExpression&&i.type!==r.FunctionExpression){n(e,"missing-scenario-callback","dataScenario","dataScenario(...) must provide a callback that receives the Testkit data context");return}const c=i.params[0]?.type===r.AssignmentPattern?i.params[0].left:i.params.at(0),l=c?.type===r.Identifier?o.sourceCode.getDeclaredVariables(i).find(D=>D.name===c.name):null;if(!l){n(e,"missing-data-context","dataScenario","dataScenario callbacks must accept the Testkit data context and record data evidence");return}const S={callback:i,context:l,contextName:l.name,methods:new Set,assertion:!1};v.set(e,S),g.set(i,S);return}const a=o.sourceCode.getText(e.callee);e.callee.type===r.MemberExpression&&a.includes(".serviceContextUrl")&&n(e,"service-namespace-url","serviceContextUrl","Data suites run in the managed Node.js runner, not inside a service namespace; use baseUrl/public endpoints or move service-namespace checks to contract");const s=x(e);if(s&&(/^(expect|assert)(?:\(|\.)/u.test(a)&&(s.assertion=!0),e.callee.type===r.MemberExpression&&e.callee.object.type===r.Identifier&&p(o,e.callee.object)===s.context)){const i=w(e.callee);i&&T.has(i)&&s.methods.add(i)}},"CallExpression:exit"(e){const t=v.get(e);if(!t)return;const{callback:a,contextName:s,methods:i,assertion:c}=t;i.size?[...i].some(l=>N.has(l))||(n(a,"weak-data-evidence",s,"Data scenarios must record product data-flow evidence such as http, bytes, sequence, record, transition, system, externalCall, recordCache, recordLlmUsage, or reconcile; ordinary Node/Vitest-style checks belong in *.contract.testkit.ts with @gfdelarue/testkit/node-vitest/contract"),c&&n(a,"vitest-shaped-data-suite",s,"This dataScenario looks like an ordinary assertion test with weak data bookkeeping; move Node-backed contract checks to *.contract.testkit.ts or model the product data flow with structured evidence")):n(a,"missing-data-evidence",s,"Data scenarios must record Testkit-owned data-flow evidence with the data context, such as http, bytes, sequence, record, transition, system, externalCall, recordCache, recordLlmUsage, or reconcile")},ThrowStatement(e){const t=x(e);t&&(t.assertion=!0)},Literal:k,TemplateLiteral:k,"Program:exit"(e){y?d.size?b||n(e,"missing-data-scenario","dataScenario","Data suites must declare at least one dataScenario(...)"):n(e,"missing-data-scenario-import","dataScenario","Data suites must import dataScenario from @gfdelarue/testkit/node-vitest/data"):n(e,"missing-data-import","@gfdelarue/testkit/node-vitest/data","Data suites must import dataScenario from @gfdelarue/testkit/node-vitest/data")}}}
@@ -1 +1 @@
1
- import{AST_NODE_TYPES as l}from"@typescript-eslint/types";import{isPublicTestType as g}from"../../../domain/identifiers.js";import{BUILT_IN_ENGINE_CATALOG as I,expectedEngineAuthoringModule as h,invalidEngineAuthoringImport as E,requireMatchingHostImport as x}from"../../../engines/catalog.js";import{binding as y,stringValue as c}from"../policy.js";export function createEngineImportPolicy({context:u,file:i,report:m}){const n=/\.([^.]+)\.testkit\.ts$/u.exec(i)?.[1];if(!g(n))return{};const p=I.profilesForTestType(n),o=p[0];if(p.length!==1)return{};const a={engineId:o.engineId,profileId:o.id},f=h(o.id),r=(t,e)=>{if(e!==null)try{if(x(i,a,e),e!==f&&(e.startsWith("@gfdelarue/testkit/")||e.startsWith("@gfdelarue/testkit-engine-")))throw E(i,a,e)}catch(s){if(!(s instanceof Error))throw s;m(t,"engine-import",e,s.message)}};return{ImportDeclaration(t){t.importKind!=="type"&&(t.specifiers.length===0||t.specifiers.some(e=>e.type!==l.ImportSpecifier||e.importKind!=="type"))&&r(t,t.source.value)},ExportNamedDeclaration(t){t.source&&t.exportKind!=="type"&&t.specifiers.some(e=>e.exportKind!=="type")&&r(t,t.source.value)},ExportAllDeclaration(t){t.exportKind!=="type"&&r(t,t.source.value)},ImportExpression(t){r(t,c(t.source))},CallExpression(t){t.callee.type===l.Identifier&&t.callee.name==="require"&&!y(u,t.callee)?.defs.length&&r(t,c(t.arguments[0]))}}}
1
+ import{AST_NODE_TYPES as l}from"@typescript-eslint/types";import{isPublicTestType as g}from"../../../domain/identifiers.js";import{allowsEngineAuthoringImport as E,profilesForTestType as h,expectedEngineAuthoringModule as x,invalidEngineAuthoringImport as y,requireMatchingEngineImport as I}from"../../../engines/catalog.js";import{binding as T,stringValue as a}from"../policy.js";export function createEngineImportPolicy({context:m,file:i,report:u}){const p=/\.([^.]+)\.testkit\.ts$/u.exec(i)?.[1];if(!g(p))return{};const s=h(p),o=s[0];if(s.length!==1)return{};const c={engineId:o.engineId,profileId:o.id},f=x(o.id),r=(e,t)=>{if(t!==null)try{if(I(i,c,t),!E(f,t))throw y(i,c,t)}catch(n){if(!(n instanceof Error))throw n;u(e,"engine-import",t,n.message)}};return{ImportDeclaration(e){e.importKind!=="type"&&(e.specifiers.length===0||e.specifiers.some(t=>t.type!==l.ImportSpecifier||t.importKind!=="type"))&&r(e,e.source.value)},ExportNamedDeclaration(e){e.source&&e.exportKind!=="type"&&e.specifiers.some(t=>t.exportKind!=="type")&&r(e,e.source.value)},ExportAllDeclaration(e){e.exportKind!=="type"&&r(e,e.source.value)},ImportExpression(e){r(e,a(e.source))},CallExpression(e){e.callee.type===l.Identifier&&e.callee.name==="require"&&!T(m,e.callee)?.defs.length&&r(e,a(e.arguments[0]))}}}
@@ -1 +1 @@
1
- import{AST_NODE_TYPES as a}from"@typescript-eslint/types";import{memberName as O,stringValue as u}from"../policy.js";export function createSyntaxPolicy(n,{file:s,context:c,report:l,options:r,literals:m},N){if(n==="uiSpecShape"&&s.endsWith(".ui.testkit.ts")){let t=0;return{CallExpression(e){e.callee.type===a.Identifier&&e.callee.name==="test"&&u(e.arguments[0])!==null&&(t+=1)},"Program:exit"(e){const i=c.sourceCode.text.split(/\r?\n/u).length;(i>r.ui.maxLines||t>r.ui.maxTests)&&l(e,"shape-limit",`${String(i)}:${String(t)}`,`UI spec exceeds shape limit (${String(i)}/${String(r.ui.maxLines)} lines, ${String(t)}/${String(r.ui.maxTests)} tests)`)}}}if(n==="configImports"&&s===N.find(t=>/^testkit\.config\.[cm]?[jt]s$/u.test(t)))return{ImportDeclaration(t){const e=t.source.value;(e.startsWith(".")||e.startsWith("/"))&&e.includes("__testkit__")&&l(t,"config-helper-import",e,"testkit.config.ts must not import repo-local __testkit__ helper modules")}};if(n!=="dalParallelSafety")return{};const o=s.endsWith(".dal.testkit.ts"),p=s.split("/").includes("__testkit__")&&s.split("/").includes("helpers")&&s.endsWith(".ts");return{CallExpression(t){if(!o)return;const e=t.callee;(e.type===a.Identifier&&e.name==="truncate"||e.type===a.MemberExpression&&O(e)==="truncate")&&l(t,"truncate","truncate","DAL specs must not truncate shared tables; seed namespaced rows and scope queries instead")},Property(t){if(!o)return;const e=!t.computed&&t.key.type===a.Identifier?t.key.name:u(t.key),i=u(t.value);e&&["slug","email","authProviderId"].includes(e)&&i&&m.push({field:e,value:i,file:s,line:t.loc.start.line,snippet:c.sourceCode.getText(t).split(/\r?\n/u)[0]})},Literal(t){p&&typeof t.value=="string"&&/\bON\s+CONFLICT(?:\s*\([^)]*\))?\s+DO\s+NOTHING\b/iu.test(t.value)&&l(t,"silent-conflict","ON CONFLICT DO NOTHING","Testkit helper seed code must not use ON CONFLICT DO NOTHING; collisions should fail loudly")},TemplateLiteral(t){p&&/\bON\s+CONFLICT(?:\s*\([^)]*\))?\s+DO\s+NOTHING\b/iu.test(t.quasis.map(e=>e.value.cooked??"").join("\0"))&&l(t,"silent-conflict","ON CONFLICT DO NOTHING","Testkit helper seed code must not use ON CONFLICT DO NOTHING; collisions should fail loudly")}}}
1
+ import{AST_NODE_TYPES as c}from"@typescript-eslint/types";import{stringValue as m}from"../policy.js";export function createSyntaxPolicy(r,{file:n,context:a,report:l,options:i},u){if(r==="uiSpecShape"&&n.endsWith(".ui.testkit.ts")){let e=0;return{CallExpression(t){t.callee.type===c.Identifier&&t.callee.name==="test"&&m(t.arguments[0])!==null&&(e+=1)},"Program:exit"(t){const s=a.sourceCode.text.split(/\r?\n/u).length;(s>i.ui.maxLines||e>i.ui.maxTests)&&l(t,"shape-limit",`${String(s)}:${String(e)}`,`UI spec exceeds shape limit (${String(s)}/${String(i.ui.maxLines)} lines, ${String(e)}/${String(i.ui.maxTests)} tests)`)}}}return r==="configImports"&&n===u.find(e=>/^testkit\.config\.[cm]?[jt]s$/u.test(e))?{ImportDeclaration(e){const t=e.source.value;(t.startsWith(".")||t.startsWith("/"))&&t.includes("__testkit__")&&l(e,"config-helper-import",t,"testkit.config.ts must not import repo-local __testkit__ helper modules")}}:{}}
@@ -1 +1 @@
1
- import{AST_NODE_TYPES as o}from"@typescript-eslint/types";import{memberName as a,stringValue as m}from"../policy.js";const u=new Set(["vi.mock","jest.mock","mock.method"]),p=new Set(["vi.fn","vi.spyOn","vi.stubGlobal","vi.useFakeTimers","jest.fn","jest.spyOn","jest.useFakeTimers"]),b=new Set(["sinon","nock","msw","jest-mock"]),f=new Set(["fetch","http.createServer","net.createServer"]),l=new Set(["fs","node:fs","child_process","node:child_process","execa"]);export function createUnitPolicy({file:r,report:s}){if(!/\.(test|spec)\.[cm]?[jt]sx?$/u.test(r)||r.split("/").includes("__testkit__"))return{};const i=(e,t)=>{if(!t)return;const c=t.split("/"),n=t.startsWith("@")?c.slice(0,2).join("/"):c[0];b.has(n)&&s(e,"test-double-library",n,"Unit tests must not use test-double libraries"),(l.has(t)||l.has(n))&&s(e,"io-boundary-import",t,"Unit tests must not import process, network, filesystem, or runtime boundary modules")};return{ImportDeclaration(e){i(e,e.source.value)},ImportExpression(e){i(e,m(e.source))},CallExpression(e){const t=h(e.callee);u.has(t)&&s(e,"module-replacement",t,"Unit tests must not replace modules; move boundary behavior to a Testkit suite"),p.has(t)&&s(e,"function-replacement",t,"Unit tests must not replace collaborators; extract pure logic or move behavior to a Testkit suite"),f.has(t)&&s(e,"io-boundary-call",t,"Unit tests must not cross process, network, filesystem, or runtime boundaries"),t==="require"&&e.arguments.length===1&&i(e,m(e.arguments[0]))},MemberExpression(e){e.object.type===o.Identifier&&e.object.name==="process"&&a(e)==="env"&&s(e,"io-boundary-global","process.env","Unit tests must not read process-global environment state")}}}function h(r){if(r.type===o.Identifier)return r.name;if(r.type!==o.MemberExpression)return"";let s=r.object;for(;s.type===o.MemberExpression;)s=s.object;const i=a(r);return s.type===o.Identifier&&i?`${s.name}.${i}`:""}
1
+ import{AST_NODE_TYPES as n}from"@typescript-eslint/types";import{memberName as m,stringValue as l}from"../policy.js";const u=new Set(["vi.mock","jest.mock","mock.method"]),f=new Set(["vi.fn","vi.spyOn","vi.stubGlobal","vi.useFakeTimers","jest.fn","jest.spyOn","jest.useFakeTimers"]),b=new Set(["sinon","nock","msw","jest-mock"]),h=new Set(["fetch","http.createServer","net.createServer"]),p=new Set(["fs","node:fs","child_process","node:child_process","execa"]),o=r=>`This repository's unitTestBoundaries rule forbids ${r}`;export function createUnitPolicy({file:r,report:s}){if(!/\.(test|spec)\.[cm]?[jt]sx?$/u.test(r)||r.split("/").includes("__testkit__"))return{};const i=(e,t)=>{if(!t)return;const a=t.split("/"),c=t.startsWith("@")?a.slice(0,2).join("/"):a[0];b.has(c)&&s(e,"test-double-library",c,o("test-double libraries")),(p.has(t)||p.has(c))&&s(e,"io-boundary-import",t,o("importing process, network, filesystem, or runtime boundary modules"))};return{ImportDeclaration(e){i(e,e.source.value)},ImportExpression(e){i(e,l(e.source))},CallExpression(e){const t=y(e.callee);u.has(t)&&s(e,"module-replacement",t,o("replacing modules")),f.has(t)&&s(e,"function-replacement",t,o("replacing collaborators")),h.has(t)&&s(e,"io-boundary-call",t,o("crossing process, network, filesystem, or runtime boundaries")),t==="require"&&e.arguments.length===1&&i(e,l(e.arguments[0]))},MemberExpression(e){e.object.type===n.Identifier&&e.object.name==="process"&&m(e)==="env"&&s(e,"io-boundary-global","process.env",o("reading process-global environment state"))}}}function y(r){if(r.type===n.Identifier)return r.name;if(r.type!==n.MemberExpression)return"";let s=r.object;for(;s.type===n.MemberExpression;)s=s.object;const i=m(r);return s.type===n.Identifier&&i?`${s.name}.${i}`:""}
@@ -1 +1 @@
1
- import i from"node:fs";import n from"node:path";import{minimatch as l}from"minimatch";import{glob as p}from"tinyglobby";import{TEST_TYPE_ORDER as u}from"../../domain/test-types.js";import{runManagedGitCommand as a}from"../../repo/managed-git.js";export const DEFAULT_EXCLUDED_DIRS=[".git",".next",".next-testkit",".testkit","coverage","dist","node_modules","playwright-report"],SOURCE_PATTERNS=["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,json}"],SOURCE_IGNORES=DEFAULT_EXCLUDED_DIRS.map(t=>`**/${t}/**`),DEFAULT_TESTKIT_BOUNDARY_ALLOWED=["testkit.config.ts","testkit.config.mts","testkit.config.mjs","testkit.config.js","**/__testkit__/**"];export async function collectCurrentFiles(t,e){const o=e?await a(t,["ls-files","--cached","--others","--exclude-standard","-z"]):void 0,s=o?.exitCode===0?o.stdout.split("\0").filter(r=>r&&i.existsSync(n.join(t,r))):await p(SOURCE_PATTERNS,{cwd:t,ignore:SOURCE_IGNORES,dot:!0,followSymbolicLinks:!1});return[...new Set(s.map(normalizePath))].filter(r=>isSourceLikePath(r)&&!isExcludedRelativePath(r)).sort((r,c)=>r.localeCompare(c))}export async function collectTrackedFiles(t){const e=await a(t,["ls-files","-z"]);return e.exitCode!==0?null:e.stdout.split("\0").map(o=>normalizePath(o)).filter(Boolean).filter(o=>i.existsSync(n.join(t,o))).sort((o,s)=>o.localeCompare(s))}export function normalizePath(t){return t.split(n.sep).join("/")}export function isObjectRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}export function isSourceLikePath(t){return/\.(?:[cm]?[jt]sx?|json)$/u.test(t)}export function isTypeScriptLikePath(t){return/\.[cm]?[jt]sx?$/u.test(t)}export function isTestkitSuitePath(t){return u.some(e=>t.endsWith(`.${e}.testkit.ts`))}export function isExcludedRelativePath(t){return SOURCE_IGNORES.some(e=>l(t,e,{dot:!0}))}export function matchesAnyPathPattern(t,e){return e.some(o=>l(t,o,{dot:!0}))}export function compareFindings(t,e){return t.file.localeCompare(e.file)||t.line-e.line||t.ruleId.localeCompare(e.ruleId)||t.kind.localeCompare(e.kind)||t.target.localeCompare(e.target)}export function normalizeFinding(t){return{ruleName:t.ruleName,ruleId:t.ruleId,kind:t.kind||"violation",target:t.target||"",file:normalizePath(t.file),line:t.line||1,message:t.message,...t.snippet?{snippet:t.snippet}:{}}}export function findingKey(t){return[t.file,String(t.line),t.ruleId,t.kind,t.target].join("\0")}
1
+ import n from"node:fs";import a from"node:path";import{minimatch as l}from"minimatch";import{glob as p}from"tinyglobby";import{TEST_TYPE_ORDER as u}from"../../domain/test-types.js";import{runManagedGitCommand as c}from"../../repo/managed-git.js";import{posixPath as i}from"../../process/files/paths.js";export const DEFAULT_EXCLUDED_DIRS=[".git",".next",".next-testkit",".testkit","coverage","dist","node_modules","playwright-report"],SOURCE_PATTERNS=["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,json}"],SOURCE_IGNORES=DEFAULT_EXCLUDED_DIRS.map(t=>`**/${t}/**`),DEFAULT_TESTKIT_BOUNDARY_ALLOWED=["testkit.config.ts","testkit.config.mts","testkit.config.mjs","testkit.config.js","**/__testkit__/**"];export async function collectCurrentFiles(t,e){const o=e?await c(t,["ls-files","--cached","--others","--exclude-standard","-z"]):void 0,s=o?.exitCode===0?o.stdout.split("\0").filter(r=>r&&n.existsSync(a.join(t,r))):await p(SOURCE_PATTERNS,{cwd:t,ignore:SOURCE_IGNORES,dot:!0,followSymbolicLinks:!1});return[...new Set(s.map(i))].filter(r=>isSourceLikePath(r)&&!isExcludedRelativePath(r)).sort((r,m)=>r.localeCompare(m))}export async function collectTrackedFiles(t){const e=await c(t,["ls-files","-z"]);return e.exitCode!==0?null:e.stdout.split("\0").map(o=>i(o)).filter(Boolean).filter(o=>n.existsSync(a.join(t,o))).sort((o,s)=>o.localeCompare(s))}export function isSourceLikePath(t){return/\.(?:[cm]?[jt]sx?|json)$/u.test(t)}export function isTypeScriptLikePath(t){return/\.[cm]?[jt]sx?$/u.test(t)}export function isTestkitSuitePath(t){return u.some(e=>t.endsWith(`.${e}.testkit.ts`))}export function isExcludedRelativePath(t){return SOURCE_IGNORES.some(e=>l(t,e,{dot:!0}))}export function matchesAnyPathPattern(t,e){return e.some(o=>l(t,o,{dot:!0}))}export function compareFindings(t,e){return t.file.localeCompare(e.file)||t.line-e.line||t.ruleId.localeCompare(e.ruleId)||t.kind.localeCompare(e.kind)||t.target.localeCompare(e.target)}export function normalizeFinding(t){return{ruleName:t.ruleName,ruleId:t.ruleId,kind:t.kind||"violation",target:t.target||"",file:i(t.file),line:t.line||1,message:t.message,...t.snippet?{snippet:t.snippet}:{}}}export function findingKey(t){return[t.file,String(t.line),t.ruleId,t.kind,t.target].join("\0")}
@@ -1 +1 @@
1
- import p from"node:fs";import r from"node:path";import{fileURLToPath as P}from"node:url";import{satisfiesSemver as v}from"../toolchains/semver.js";import{readPackageMetadata as D}from"../process/host/metadata.js";const S=["dependencies","devDependencies","optionalDependencies","peerDependencies"];export function testkitIdentity(){return{description:"Test orchestration platform for product acceptance and QA workflows",name:"@gfdelarue/testkit",version:D().version}}export function inspectPackageVersionDrift(e={}){const n=e.currentPackageRoot||j(e.binUrl||import.meta.url),t=a(r.join(n,"package.json"));if(!t?.version)throw new Error(`Unable to read the current Testkit version from ${n}`);const c=e.cwd||process.cwd(),s=e.dir?r.resolve(c,e.dir):c;if(f(s,n))return null;const g=a(r.join(s,"package.json")),o=R(g),d=r.join(s,"node_modules","@gfdelarue","testkit"),i=a(r.join(d,"package.json"));return!o&&!i||i&&f(d,n)?null:i?.version&&i.version!==t.version?{productDir:s,currentPackageRoot:n,currentVersion:t.version,productPackageRoot:d,productVersion:i.version,declaredSpec:o}:!i&&o&&h(o)&&!v(t.version,l(o))?{productDir:s,currentPackageRoot:n,currentVersion:t.version,productPackageRoot:null,productVersion:null,declaredSpec:o}:null}function j(e){const n=P(e);return y(r.dirname(n))}function y(e){let n=r.resolve(e);for(;;){if(a(r.join(n,"package.json"))?.name==="@gfdelarue/testkit")return n;const c=r.dirname(n);if(c===n)return r.resolve(e);n=c}}function R(e=null){for(const n of S){const t=e?.[n]?.["@gfdelarue/testkit"];if(t?.trim())return t.trim()}return null}function a(e){try{const n=JSON.parse(p.readFileSync(e,"utf8"));return w(n)}catch{return null}}function f(e,n){try{return p.realpathSync(e)===p.realpathSync(n)}catch{return r.resolve(e)===r.resolve(n)}}function h(e){const n=l(e);return/^(?:[<>]=?|[\^~=])?\s*\d/u.test(n)}function l(e){return e.trim().replace(/^workspace:/u,"")}function w(e){return k(e)?{dependencies:u(e.dependencies),devDependencies:u(e.devDependencies),name:m(e.name),optionalDependencies:u(e.optionalDependencies),peerDependencies:u(e.peerDependencies),version:m(e.version)}:null}function u(e){if(!k(e))return;const n=Object.entries(e).filter(t=>typeof t[1]=="string");return Object.fromEntries(n)}function m(e){return typeof e=="string"?e:void 0}function k(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}
1
+ import p from"node:fs";import r from"node:path";import{fileURLToPath as v}from"node:url";import{satisfiesSemver as P}from"../toolchains/semver.js";import{readPackageMetadata as D}from"../process/host/metadata.js";import{isUnknownRecord as f}from"../kernel/unknown-values.js";const S=["dependencies","devDependencies","optionalDependencies","peerDependencies"];export function testkitIdentity(){return{description:"Test orchestration platform for product acceptance and QA workflows",name:"@gfdelarue/testkit",version:D().version}}export function inspectPackageVersionDrift(e={}){const n=e.currentPackageRoot||j(e.binUrl||import.meta.url),t=a(r.join(n,"package.json"));if(!t?.version)throw new Error(`Unable to read the current Testkit version from ${n}`);const c=e.cwd||process.cwd(),s=e.dir?r.resolve(c,e.dir):c;if(l(s,n))return null;const g=a(r.join(s,"package.json")),o=h(g),d=r.join(s,"node_modules","@gfdelarue","testkit"),i=a(r.join(d,"package.json"));return!o&&!i||i&&l(d,n)?null:i?.version&&i.version!==t.version?{productDir:s,currentPackageRoot:n,currentVersion:t.version,productPackageRoot:d,productVersion:i.version,declaredSpec:o}:!i&&o&&w(o)&&!P(t.version,m(o))?{productDir:s,currentPackageRoot:n,currentVersion:t.version,productPackageRoot:null,productVersion:null,declaredSpec:o}:null}function j(e){const n=v(e);return R(r.dirname(n))}function R(e){let n=r.resolve(e);for(;;){if(a(r.join(n,"package.json"))?.name==="@gfdelarue/testkit")return n;const c=r.dirname(n);if(c===n)return r.resolve(e);n=c}}function h(e=null){for(const n of S){const t=e?.[n]?.["@gfdelarue/testkit"];if(t?.trim())return t.trim()}return null}function a(e){try{const n=JSON.parse(p.readFileSync(e,"utf8"));return y(n)}catch{return null}}function l(e,n){try{return p.realpathSync(e)===p.realpathSync(n)}catch{return r.resolve(e)===r.resolve(n)}}function w(e){const n=m(e);return/^(?:[<>]=?|[\^~=])?\s*\d/u.test(n)}function m(e){return e.trim().replace(/^workspace:/u,"")}function y(e){return f(e)?{dependencies:u(e.dependencies),devDependencies:u(e.devDependencies),name:k(e.name),optionalDependencies:u(e.optionalDependencies),peerDependencies:u(e.peerDependencies),version:k(e.version)}:null}function u(e){if(!f(e))return;const n=Object.entries(e).filter(t=>typeof t[1]=="string");return Object.fromEntries(n)}function k(e){return typeof e=="string"?e:void 0}
@@ -0,0 +1 @@
1
+ import o from"node:fs";import c from"node:path";import{copyRegularFileSecurely as g}from"../../evidence/secure-file-copy.js";import{sameFileSnapshot as b}from"../../process/files/file-snapshot.js";export const REPORT_FILE_BYTES=16*1024*1024,REPORT_BYTES=64*1024*1024,REPORT_FILES=1e3,REPORT_TREES=128;export function requireReportPath(t){if(!t||Buffer.byteLength(t)>4096||Buffer.from(t).toString("utf8")!==t||/[\\\0\r\n]/u.test(t)||c.posix.normalize(t)!==t||t.startsWith("/")||t.split("/").some(r=>!r||r==="."||r===".."||r.toLowerCase()===".git"))throw new Error("Use a relative report path without traversal, Git metadata, backslashes, or line breaks.");return t}export function copyReportFile(t,r,f){return o.mkdirSync(c.dirname(r),{recursive:!0}),g(t,r,{maxBytes:REPORT_FILE_BYTES,sizeLimitDescription:"16 MiB report file limit",sourceRoot:f}).sizeBytes}export function snapshotReport(t,r,f=REPORT_TREES){const i=[],R=o.realpathSync(t);let l=0,d=0;function y(e,n,w){const p=o.lstatSync(e,{bigint:!0});if(!p.isDirectory()||p.isSymbolicLink())throw new Error("Reports must contain ordinary directories and files, not links.");if(w>32||++d>f)throw new Error("The report exceeds its directory traversal limit.");for(const s of o.readdirSync(e,{withFileTypes:!0,encoding:"buffer"})){const m=s.name.toString("utf8");if(!Buffer.from(m).equals(s.name))throw new Error("Report filenames must be UTF-8.");const a=requireReportPath(n+m),h=c.join(e,m);if(s.isDirectory()){y(h,a+"/",w+1);continue}if(!s.isFile())throw new Error(`Report entry ${JSON.stringify(a)} is not an ordinary file.`);if(i.length>=REPORT_FILES)throw new Error("A report may contain at most 1000 files.");const S=o.lstatSync(h).mode,u=c.join(r,a),E=copyReportFile(h,u,R);if(l+=E,l>REPORT_BYTES)throw new Error("A report may contain at most 64 MiB of files.");i.push({path:a,absolutePath:u,executable:(S&73)!==0,size:E})}if(!b(p,o.lstatSync(e,{bigint:!0})))throw new Error("The report directory changed while it was being read. Try again with a stable directory.")}if(y(t,"",0),i.length===0)throw new Error("The report directory contains no files. Git does not store empty directories.");return i.sort((e,n)=>e.path<n.path?-1:e.path>n.path?1:0)}
@@ -0,0 +1,2 @@
1
+ import{createHash as x}from"node:crypto";import c from"node:fs";import a from"node:path";import{loadRunBundleManifest as R}from"../../evidence/bundles.js";import{makeTempDir as k,removeTempDir as T}from"../../process/files/temp-dir.js";import{readStoredDrafts as P}from"../bugs/store.js";import{inspectArtifacts as S}from"../inspect/artifacts.js";import{copyReportFile as v,REPORT_BYTES as j,REPORT_FILE_BYTES as B,REPORT_FILES as F,requireReportPath as O}from"./files.js";export function prepareReport(e){const r=e.cwd??process.cwd(),u=a.resolve(r,e.dir??"."),n=a.resolve(r,e.directory),f=[...new Set(e.bug??[])],w=f.length?P(u):{drafts:[],unreadable:[]},y=f.map(o=>{const s=w.drafts.find(m=>m.draft.id===o)?.draft;if(!s)throw new Error(`No readable recorded bug ${JSON.stringify(o)}. Use an ID from testkit bug record or campaign status.`);return s}),l=[...new Set(e.artifact??[])];if(l.length&&!e.run)throw new Error("Select an immutable --run when copying --artifact evidence.");if(e.run&&!l.length)throw new Error("Choose at least one --artifact from the run. Reports never copy all evidence implicitly.");const i=D(u,e.run,l),h=k("testkit-report-prepare-");let d=!1;try{let o=null;if(e.instructions){const t=a.join(h,"instructions");v(a.resolve(r,e.instructions),t),o={path:e.instructions,text:c.readFileSync(t,"utf8")}}c.mkdirSync(a.dirname(n),{recursive:!0});try{c.mkdirSync(n)}catch(t){throw new Error("Choose a new report directory. Preparation never overwrites an existing path.",{cause:t})}d=!0;const s=a.join(n,"report.md");let m=e.template?v(a.resolve(r,e.template),s):0;e.template||c.writeFileSync(s,"",{flag:"wx",mode:384});for(const t of i){const p=a.join(n,t.destination);if(m+=v(t.absolutePath,p,a.join(u,".testkit","results")),x("sha256").update(c.readFileSync(p)).digest("hex")!==t.sha256)throw new Error("Selected evidence changed after verification. The report was not prepared.")}const g=["report.md",...i.map(t=>t.destination)];if(y.length||i.length){const t=JSON.stringify({bugs:y,run:e.run??null,evidence:i.map(({source:E,destination:b})=>({source:E,destination:b}))},null,2)+`
2
+ `,p=Buffer.byteLength(t);if(p>B)throw new Error("The bug context exceeds 16 MiB. Select fewer bugs.");m+=p,c.writeFileSync(a.join(n,"context.json"),t,{flag:"wx",mode:384}),g.push("context.json")}if(m>j||g.length>F)throw new Error("The prepared report exceeds 64 MiB or 1000 files. Select fewer artifacts.");return{directory:n,files:g,bugs:f,run:e.run??null,instructions:o}}catch(o){throw d&&c.rmSync(n,{recursive:!0,force:!0}),o}finally{T(h)}}function D(e,r,u){if(!r)return[];const n={dir:e,runId:r,file:null,group:null},f=S({...n,mode:"verify"});if(f.mode!=="verify"||!f.verification.ok)throw new Error("The selected run failed integrity verification. Run testkit artifacts --verify for details.");const w=S({...n,mode:"artifacts",includePayload:!1});if(w.mode!=="artifacts")throw new Error("Could not inspect selected run artifacts.");const y=R(e,r),l=`.testkit/results/runs/${r}/`;return u.map(i=>{const h=w.entries.find(s=>s.artifactRef.path===i),d=i.startsWith(l)?i.slice(l.length):"",o=y.files.find(s=>s.path===d);if(!h||!o||!d.startsWith("files/"))throw new Error(`Artifact ${JSON.stringify(i)} is not an artifact in the selected immutable run. Use ref.path from testkit artifacts --run ${r} --json.`);return{source:i,destination:"evidence/"+O(d.slice(6)),absolutePath:h.absolutePath,sha256:o.sha256}})}
@@ -0,0 +1 @@
1
+ import n from"node:path";import{makeTempDir as u,removeTempDir as w}from"../../process/files/temp-dir.js";import{publishDirectory as $}from"../../repo/publish-directory.js";import{resolveRepositoryConnection as f}from"../tracker/index.js";import{REPORT_TREES as b,requireReportPath as g,snapshotReport as v}from"./files.js";export async function publishReport(e){const s=e.cwd??process.cwd(),a=e.env??process.env;if(!e.repository.trim())throw new Error("Name an explicit destination --repository.");const t=g(e.path);if(t.split("/").length>32)throw new Error("The destination path is too deeply nested.");const o=u("testkit-report-publish-");try{const i=v(n.resolve(s,e.directory),n.join(o,"files"),b-t.split("/").length),{location:r,target:c}=await f({repository:e.repository,productDir:n.resolve(s,e.dir??"."),env:a}),m=`${r.origin}/${r.owner}/${r.name}.git`,p=await $({workspace:o,remote:m,files:i,branch:e.branch,destination:t,message:e.message??`Publish report bundle ${t}`,token:c.token,env:a,maxFetchBytes:256*1024*1024}),l=c.provider==="github"?"tree":"src/commit",h=`${r.origin}/${r.owner}/${r.name}/${l}/${p.revision}/${t.split("/").map(encodeURIComponent).join("/")}`;return{...p,repository:`${r.origin}/${r.owner}/${r.name}`,branch:e.branch,path:t,url:h,files:i.length,bytes:i.reduce((d,y)=>d+y.size,0)}}finally{w(o)}}
@@ -0,0 +1 @@
1
+ import{redactedRunValue as o,runRedaction as u}from"../../evidence/redaction.js";export function createCallerRedaction(a=process.env,c=[]){let n=()=>[],e=null;return{useSourceTargets(t){n=t,e=null},redact(t){const r=n();return e?.count!==r.length&&(e={count:r.length,targets:u({env:a,redactKeys:c,redactionTargets:r}).targets}),o(t,e.targets)}}}
@@ -1 +1 @@
1
- import{persistFileEvidence as m,fileEvidenceBudgetError as g}from"../../evidence/file-evidence.js";import{MAX_PERSISTED_FILE_ARTIFACT_BYTES as y,persistTaskArtifacts as p,persistTaskOutputArtifacts as E}from"../../evidence/index.js";export const MAX_ENGINE_FILE_EVIDENCE_BYTES=y;export function persistEngineEvidence({artifactRoot:e,evidence:t,productDir:i,scope:r,task:n,fileEvidenceBudget:a}){const o={engineId:n.engineId,file:n.file,id:n.id,profileId:n.profileId,serviceName:n.serviceName,suiteKey:n.suiteKey,suiteName:n.suiteName,testType:n.testType},u=m({artifactRoot:e,artifacts:t.artifacts,productDir:i,task:o,fileEvidenceBudget:a}),f=E(i,o,t.logs.map((c,d)=>({name:`${r}-engine-${c.stream}-${d.toString()}`,kind:`engine.${r}.log`,stream:c.stream,text:c.text}))),s=[...t.metrics.map((c,d)=>v(c,d,r)),...t.native===void 0?[]:[{name:`${r}-engine-native`,kind:`engine.${r}.native`,contentType:"application/json",summary:`${r} engine-native evidence`,emittedAt:new Date().toISOString(),data:t.native}]];return[...u,...f,...p(i,o,s)]}export function persistTrackedEngineEvidence(e,t){const i=[...e.artifacts.map(n=>({category:"artifacts",evidence:{artifacts:[n],logs:[],metrics:[]},value:n})),...e.logs.map(n=>({category:"logs",evidence:{artifacts:[],logs:[n],metrics:[]},value:n})),...e.metrics.map(n=>({category:"metrics",evidence:{artifacts:[],logs:[],metrics:[n]},value:n})),...e.native===void 0?[]:[{category:"native",evidence:{artifacts:[],logs:[],metrics:[],native:e.native},value:e.native}]],r=new Map;for(const n of i){let a;try{a=l(n.value)}catch(s){t.errors.push(contextualError(`Could not identify ${t.scope} engine ${n.category} evidence`,s));continue}const o=`${n.category}:${a}`,u=(r.get(o)??0)+1;r.set(o,u);const f=t.ledger.countsByCategory[n.category].get(a)??0;if(!(t.mode==="reconcile"&&u<=f))try{const s=persistEngineEvidence({artifactRoot:t.artifactRoot,evidence:n.evidence,productDir:t.productDir,scope:t.scope,task:t.task,...n.category==="artifacts"?{fileEvidenceBudget:$(t.ledger)}:{}});if(s.length===0)throw new Error("Evidence did not produce a persisted artifact");t.references.push(...s),t.ledger.countsByCategory[n.category].set(a,f+1)}catch(s){t.errors.push(contextualError(`Could not persist ${t.scope} engine ${n.category} evidence`,s))}}}export function createEvidenceLedger(e=MAX_ENGINE_FILE_EVIDENCE_BYTES){return{countsByCategory:{artifacts:new Map,logs:new Map,metrics:new Map,native:new Map},fileEvidence:{maximumBytes:Math.min(e,MAX_ENGINE_FILE_EVIDENCE_BYTES),persistedBytes:0}}}export function requireTaskArtifacts(e,t){const i=e.get(t);if(!i)throw new Error(`Artifact state is missing engine task ${t}`);return i}export function requireTaskEvidenceLedger(e,t){const i=e.get(t);if(!i)throw new Error(`Evidence state is missing engine task ${t}`);return i}export function contextualError(e,t){return new Error(`${e}: ${B(t).message}`,{cause:t})}function l(e){const t=JSON.stringify(e);if(typeof t!="string")throw new TypeError("Engine evidence entry must be JSON-serializable");return t}function v(e,t,i){return{name:`${i}-engine-metric-${t.toString()}`,kind:`engine.${i}.metric`,contentType:"application/json",summary:`${e.name}=${e.value.toString()}${e.unit?` ${e.unit}`:""}`,emittedAt:new Date().toISOString(),data:{name:e.name,value:e.value,...e.unit===void 0?{}:{unit:e.unit},...e.dimensions===void 0?{}:{dimensions:e.dimensions}}}}function $(e){return{consume(t){const i=e.fileEvidence.persistedBytes+t;if(i>e.fileEvidence.maximumBytes)throw g(e.fileEvidence.maximumBytes);e.fileEvidence.persistedBytes=i},maximumBytes(){return e.fileEvidence.maximumBytes},remainingBytes(){return e.fileEvidence.maximumBytes-e.fileEvidence.persistedBytes}}}function B(e){return e instanceof Error?e:new Error(String(e))}
1
+ import{persistFileEvidence as m,fileEvidenceBudgetError as g}from"../../evidence/file-evidence.js";import{MAX_PERSISTED_FILE_ARTIFACT_BYTES as p,persistTaskArtifacts as y,persistTaskOutputArtifacts as E}from"../../evidence/index.js";import{toError as l}from"../../kernel/error-serialization.js";export const MAX_ENGINE_FILE_EVIDENCE_BYTES=p;export function persistEngineEvidence({artifactRoot:e,evidence:t,productDir:i,scope:r,task:n,fileEvidenceBudget:a}){const o={engineId:n.engineId,file:n.file,id:n.id,profileId:n.profileId,serviceName:n.serviceName,suiteKey:n.suiteKey,suiteName:n.suiteName,testType:n.testType},u=m({artifactRoot:e,artifacts:t.artifacts,productDir:i,task:o,fileEvidenceBudget:a}),f=E(i,o,t.logs.map((c,d)=>({name:`${r}-engine-${c.stream}-${d.toString()}`,kind:`engine.${r}.log`,stream:c.stream,text:c.text}))),s=[...t.metrics.map((c,d)=>$(c,d,r)),...t.native===void 0?[]:[{name:`${r}-engine-native`,kind:`engine.${r}.native`,contentType:"application/json",summary:`${r} engine-native evidence`,emittedAt:new Date().toISOString(),data:t.native}]];return[...u,...f,...y(i,o,s)]}export function persistTrackedEngineEvidence(e,t){const i=[...e.artifacts.map(n=>({category:"artifacts",evidence:{artifacts:[n],logs:[],metrics:[]},value:n})),...e.logs.map(n=>({category:"logs",evidence:{artifacts:[],logs:[n],metrics:[]},value:n})),...e.metrics.map(n=>({category:"metrics",evidence:{artifacts:[],logs:[],metrics:[n]},value:n})),...e.native===void 0?[]:[{category:"native",evidence:{artifacts:[],logs:[],metrics:[],native:e.native},value:e.native}]],r=new Map;for(const n of i){let a;try{a=v(n.value)}catch(s){t.errors.push(contextualError(`Could not identify ${t.scope} engine ${n.category} evidence`,s));continue}const o=`${n.category}:${a}`,u=(r.get(o)??0)+1;r.set(o,u);const f=t.ledger.countsByCategory[n.category].get(a)??0;if(!(t.mode==="reconcile"&&u<=f))try{const s=persistEngineEvidence({artifactRoot:t.artifactRoot,evidence:n.evidence,productDir:t.productDir,scope:t.scope,task:t.task,...n.category==="artifacts"?{fileEvidenceBudget:B(t.ledger)}:{}});if(s.length===0)throw new Error("Evidence did not produce a persisted artifact");t.references.push(...s),t.ledger.countsByCategory[n.category].set(a,f+1)}catch(s){t.errors.push(contextualError(`Could not persist ${t.scope} engine ${n.category} evidence`,s))}}}export function createEvidenceLedger(e=MAX_ENGINE_FILE_EVIDENCE_BYTES){return{countsByCategory:{artifacts:new Map,logs:new Map,metrics:new Map,native:new Map},fileEvidence:{maximumBytes:Math.min(e,MAX_ENGINE_FILE_EVIDENCE_BYTES),persistedBytes:0}}}export function requireTaskArtifacts(e,t){const i=e.get(t);if(!i)throw new Error(`Artifact state is missing engine task ${t}`);return i}export function requireTaskEvidenceLedger(e,t){const i=e.get(t);if(!i)throw new Error(`Evidence state is missing engine task ${t}`);return i}export function contextualError(e,t){return new Error(`${e}: ${l(t).message}`,{cause:t})}function v(e){const t=JSON.stringify(e);if(typeof t!="string")throw new TypeError("Engine evidence entry must be JSON-serializable");return t}function $(e,t,i){return{name:`${i}-engine-metric-${t.toString()}`,kind:`engine.${i}.metric`,contentType:"application/json",summary:`${e.name}=${e.value.toString()}${e.unit?` ${e.unit}`:""}`,emittedAt:new Date().toISOString(),data:{name:e.name,value:e.value,...e.unit===void 0?{}:{unit:e.unit},...e.dimensions===void 0?{}:{dimensions:e.dimensions}}}}function B(e){return{consume(t){const i=e.fileEvidence.persistedBytes+t;if(i>e.fileEvidence.maximumBytes)throw g(e.fileEvidence.maximumBytes);e.fileEvidence.persistedBytes=i},maximumBytes(){return e.fileEvidence.maximumBytes},remainingBytes(){return e.fileEvidence.maximumBytes-e.fileEvidence.persistedBytes}}}
@@ -1 +1 @@
1
- import{isEngineTaskDeadlineExceededReason as g}from"../../engines/api/index.js";import{classifyRuntimeNodeSetupFailure as p,getRuntimeNodeSetupCleanupFailures as m}from"./setup/runtime-node-setup.js";export const ENGINE_REPORTER_CALLBACK_CANCELLED_CODE="TESTKIT_ENGINE_REPORTER_CALLBACK_CANCELLED";export class EngineExecutionBridgeError extends Error{artifactReferencesByTaskId;completedOutcomesByTaskId;disposition;failingTaskId;cause;constructor(n,t,i,r,o=new Map,a=null){super(n,{cause:t}),this.name="EngineExecutionBridgeError",this.cause=t,this.disposition=Object.freeze({...i}),this.failingTaskId=a,this.artifactReferencesByTaskId=r,this.completedOutcomesByTaskId=o}}export class EngineExecutionReporterCallbackError extends Error{cancelled;cause;constructor(n,t){const i=E(t);super(`Engine reporter ${n} callback failed: ${i.message}`,{cause:t}),this.name="EngineExecutionReporterCallbackError",this.cancelled=x(i)===ENGINE_REPORTER_CALLBACK_CANCELLED_CODE,this.cause=t}}export async function executeManagedEngineRequest(e,n){return await e.execute(n)}export function buildBridgeError(e,n,t,i,r,o){const a=n.map(s=>s.error),c=[...e,...a],u=e.map(s=>s.message).join("; "),f=a.map(s=>s.message).join("; "),l=e.length===0?`Engine node setup cleanup failed: ${f}`:a.length===0?u:`${u}; node setup cleanup also failed: ${f}`,d=c.length===1?c[0]:new AggregateError(c,"Engine execution bridge failed");return new EngineExecutionBridgeError(l,d,t,i,r,n[0]?.taskId??o)}export function resolveBridgeDisposition(e,n,t,i){return n.length>0?i.classification==="infra"&&i.runtimeImpact==="fail-graph"?infraBridgeDisposition("fail-graph"):n.some(r=>r.owner==="testkit")?infraBridgeDisposition("invalidate-lease"):e.length>0&&e.every(r=>r instanceof EngineExecutionReporterCallbackError)?e.every(r=>r instanceof EngineExecutionReporterCallbackError&&r.cancelled)?productBridgeDisposition("invalidate-lease"):reporterBridgeDisposition("invalidate-lease"):t||e.length>0&&i.classification==="infra"?infraBridgeDisposition(i.runtimeImpact==="fail-graph"?"fail-graph":"invalidate-lease"):productBridgeDisposition("invalidate-lease"):e.length>0&&e.every(r=>r instanceof EngineExecutionReporterCallbackError)?e.every(r=>r instanceof EngineExecutionReporterCallbackError&&r.cancelled)?cancelledBridgeDisposition():reporterBridgeDisposition(i.runtimeImpact):t&&i.classification!=="infra"?infraBridgeDisposition("none"):{...i}}export function managerFailureBridgeDisposition(e,n,t){return!n.aborted||t!==n.reason?infraBridgeDisposition("none"):e.aborted&&t===e.reason?cancelledBridgeDisposition():g(n.reason)?productBridgeDisposition():infraBridgeDisposition("none")}export function runtimeNodeSetupBridgeDisposition(e){const n=p(e),t=m(e).length>0?"invalidate-lease":"none";return n==="cancelled"?cancelledBridgeDisposition():n==="infra"?infraBridgeDisposition("invalidate-lease"):productBridgeDisposition(t)}export function cancelledBridgeDisposition(){return{classification:void 0,notifyRuntimeError:!1,runtimeImpact:"none",status:"cancelled"}}export function infraBridgeDisposition(e="none"){return{classification:"infra",notifyRuntimeError:!0,runtimeImpact:e,status:"not_run"}}export function reporterBridgeDisposition(e="none"){return{classification:"infra",notifyRuntimeError:!1,runtimeImpact:e,status:"not_run"}}export function productBridgeDisposition(e="none"){return{classification:"product",notifyRuntimeError:!1,runtimeImpact:e,status:"failed"}}function E(e){return e instanceof Error?e:new Error(String(e))}function x(e){return e.code}
1
+ import{isEngineTaskDeadlineExceededReason as k}from"../../engines/api/index.js";import{TaskPreparationError as g}from"./environment.js";import{toError as m}from"../../kernel/error-serialization.js";export const ENGINE_REPORTER_CALLBACK_CANCELLED_CODE="TESTKIT_ENGINE_REPORTER_CALLBACK_CANCELLED";export class EngineExecutionBridgeError extends Error{artifactReferencesByTaskId;completedOutcomesByTaskId;disposition;failingTaskId;state;cause;constructor(r,n,a,t,i=new Map,c=null,s={activeDisposition:a,observedInfraOperationFailure:!1,operationErrors:[]}){super(r,{cause:n}),this.name="EngineExecutionBridgeError",this.cause=n,this.disposition=Object.freeze({...a}),this.failingTaskId=c,this.artifactReferencesByTaskId=t,this.completedOutcomesByTaskId=i,this.state=s}}export class EngineExecutionReporterCallbackError extends Error{cancelled;cause;constructor(r,n){const a=m(n);super(`Engine reporter ${r} callback failed: ${a.message}`,{cause:n}),this.name="EngineExecutionReporterCallbackError",this.cancelled=y(a)===ENGINE_REPORTER_CALLBACK_CANCELLED_CODE,this.cause=n}}export async function executeManagedEngineRequest(e,r){return await e.execute(r)}export function buildBridgeError(e,r,n,a,t,i){const{operationErrors:c}=e,s=r.map(u=>u.error),l=[...c,...s],d=c.map(u=>u.message).join("; "),f=s.map(u=>u.message).join("; "),p=c.length===0?`Engine node setup cleanup failed: ${f}`:s.length===0?d:`${d}; node setup cleanup also failed: ${f}`,o=l.length===1?l[0]:new AggregateError(l,"Engine execution bridge failed");return new EngineExecutionBridgeError(p,o,n,a,t,r[0]?.taskId??i,e)}export function preparationFailure(e,r){const n=e instanceof g?e.cause:e;return E(n,x(e),r)}export function taskStartedFailure(e,r){return E(e,reporterBridgeDisposition(),r)}function E(e,r,n){const a={activeDisposition:r,observedInfraOperationFailure:r.classification==="infra",operationErrors:[m(e)]};return buildBridgeError(a,[],resolveBridgeDisposition(a,[]),new Map,new Map,n)}export async function settlePreparedTask(e,r,n,a){const t=r.map(o=>({...o,taskId:n})),i="error"in e?e.error:null,c="outcomes"in e?e.outcomes:[];let s=i instanceof EngineExecutionBridgeError?i.state:i!==null?{activeDisposition:infraBridgeDisposition(),observedInfraOperationFailure:!0,operationErrors:[m(i)]}:{activeDisposition:infraBridgeDisposition(c.some(o=>o.infraFailed&&o.blockedByRuntime)?"fail-graph":"none"),observedInfraOperationFailure:!1,operationErrors:[]};const l=new Map(i instanceof EngineExecutionBridgeError?i.completedOutcomesByTaskId:c.map(o=>[String(o.task.id),o])),d=i instanceof EngineExecutionBridgeError?i.artifactReferencesByTaskId:new Map(c.map(o=>[String(o.task.id),o.artifacts]));h(l,t);const f=l.get(n);let p=!1;if(f!==void 0)try{await a(f)}catch(o){p=!0;const u=i===null&&t.length===0;s={activeDisposition:u?reporterBridgeDisposition():s.activeDisposition,observedInfraOperationFailure:u||s.observedInfraOperationFailure,operationErrors:[...s.operationErrors,m(o)]}}return t.length===0&&!p?null:buildBridgeError(s,t,resolveBridgeDisposition(s,t),d,l,n)}function h(e,r){const n=new Map;for(const a of r){if(a.owner!=="consumer")continue;const t=n.get(a.taskId)??[];t.push(a.error),n.set(a.taskId,t)}for(const[a,t]of n){const i=e.get(a);if(i===void 0)continue;const c=`Runtime node setup consumer cleanup failed: ${t.map(s=>s.message).join("; ")}`;e.set(a,{...i,error:i.error===null?c:`${i.error}; ${c}`,failureDetails:[...i.failureDetails,...t.map(I)],reason:null,status:"failed"})}}function I(e){return{actual:{owner:"consumer"},classification:"product",count:1,key:"runtime_node_setup_consumer_cleanup_failed",kind:"runtime-node-setup-cleanup",message:e.message,...e.stack===void 0?{}:{stack:e.stack},title:"Runtime node setup consumer cleanup failed"}}export function resolveBridgeDisposition({activeDisposition:e,observedInfraOperationFailure:r,operationErrors:n},a){return a.length>0?e.classification==="infra"&&e.runtimeImpact==="fail-graph"?infraBridgeDisposition("fail-graph"):a.some(t=>t.owner==="testkit")?infraBridgeDisposition("invalidate-lease"):n.length>0&&n.every(t=>t instanceof EngineExecutionReporterCallbackError)?n.every(t=>t instanceof EngineExecutionReporterCallbackError&&t.cancelled)?productBridgeDisposition("invalidate-lease"):reporterBridgeDisposition("invalidate-lease"):r||n.length>0&&e.classification==="infra"?infraBridgeDisposition(e.runtimeImpact==="fail-graph"?"fail-graph":"invalidate-lease"):productBridgeDisposition("invalidate-lease"):n.length>0&&n.every(t=>t instanceof EngineExecutionReporterCallbackError)?n.every(t=>t instanceof EngineExecutionReporterCallbackError&&t.cancelled)?cancelledBridgeDisposition():reporterBridgeDisposition(e.runtimeImpact):r&&e.classification!=="infra"?infraBridgeDisposition("none"):{...e}}export function managerFailureBridgeDisposition(e,r,n){return!r.aborted||n!==r.reason?infraBridgeDisposition("none"):e.aborted&&n===e.reason?cancelledBridgeDisposition():k(r.reason)?productBridgeDisposition():infraBridgeDisposition("none")}function x(e){return e instanceof g?e.kind==="cancelled"?cancelledBridgeDisposition():e.kind==="infra"?infraBridgeDisposition("invalidate-lease"):productBridgeDisposition(e.cleanupFailures.length>0?"invalidate-lease":"none"):infraBridgeDisposition("invalidate-lease")}export function cancelledBridgeDisposition(){return{classification:void 0,notifyRuntimeError:!1,runtimeImpact:"none",status:"cancelled"}}export function infraBridgeDisposition(e="none"){return{classification:"infra",notifyRuntimeError:!0,runtimeImpact:e,status:"not_run"}}export function reporterBridgeDisposition(e="none"){return{classification:"infra",notifyRuntimeError:!1,runtimeImpact:e,status:"not_run"}}export function productBridgeDisposition(e="none"){return{classification:"product",notifyRuntimeError:!1,runtimeImpact:e,status:"failed"}}function y(e){return e.code}
@@ -1 +1 @@
1
- import{ENGINE_REPORTER_CALLBACK_CANCELLED_CODE as c,EngineExecutionReporterCallbackError as l}from"./engine-execution-failures.js";export const DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS=5e3;export class EngineReporterCallbackTimeoutError extends Error{timeoutMs;constructor(n,e){super(`${n} exceeded ${e.toString()} milliseconds`),this.name="EngineReporterCallbackTimeoutError",this.timeoutMs=e}}export class EngineReporterCallbackCancelledError extends Error{code=c;cause;constructor(n,e){const t=e instanceof Error?e:new Error(String(e));super(`${n} was cancelled: ${t.message}`,{cause:e}),this.name="EngineReporterCallbackCancelledError",this.cause=e}}export async function invokeBoundedReporterCallback(r,n,e){const t=Promise.resolve(n());let o,i;const a=new Promise((E,s)=>{e.signal?.aborted?s(new EngineReporterCallbackCancelledError(r,e.signal.reason)):e.signal!==void 0&&(i=()=>{s(new EngineReporterCallbackCancelledError(r,e.signal?.reason))},e.signal.addEventListener("abort",i,{once:!0})),o=setTimeout(()=>{s(new EngineReporterCallbackTimeoutError(r,e.timeoutMs))},e.timeoutMs)});try{await Promise.race([t,a])}finally{o!==void 0&&clearTimeout(o),i!==void 0&&e.signal!==void 0&&e.signal.removeEventListener("abort",i)}}export async function invokeEngineReporterCallback(r,n,e){try{await invokeBoundedReporterCallback(`Engine reporter ${r} callback`,n,e)}catch(t){throw new l(r,t)}}export async function captureEngineReporterCallback(r,n,e,t){try{await invokeEngineReporterCallback(n,e,t)}catch(o){r.push(o instanceof Error?o:new Error(String(o)))}}
1
+ import{ENGINE_REPORTER_CALLBACK_CANCELLED_CODE as l,EngineExecutionReporterCallbackError as c}from"./engine-execution-failures.js";export const DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS=5e3;export class EngineReporterCallbackTimeoutError extends Error{timeoutMs;constructor(n,e){super(`${n} exceeded ${e.toString()} milliseconds`),this.name="EngineReporterCallbackTimeoutError",this.timeoutMs=e}}export class EngineReporterCallbackCancelledError extends Error{code=l;cause;constructor(n,e){const t=e instanceof Error?e:new Error(String(e));super(`${n} was cancelled: ${t.message}`,{cause:e}),this.name="EngineReporterCallbackCancelledError",this.cause=e}}export async function invokeBoundedReporterCallback(r,n,e){const t=Promise.resolve(n());let i,o;const a=new Promise((E,s)=>{e.signal?.aborted?s(new EngineReporterCallbackCancelledError(r,e.signal.reason)):e.signal!==void 0&&(o=()=>{s(new EngineReporterCallbackCancelledError(r,e.signal?.reason))},e.signal.addEventListener("abort",o,{once:!0})),i=setTimeout(()=>{s(new EngineReporterCallbackTimeoutError(r,e.timeoutMs))},e.timeoutMs)});try{await Promise.race([t,a])}finally{i!==void 0&&clearTimeout(i),o!==void 0&&e.signal!==void 0&&e.signal.removeEventListener("abort",o)}}export async function invokeEngineReporterCallback(r,n,e){try{await invokeBoundedReporterCallback(`Engine reporter ${r} callback`,n,e)}catch(t){throw new c(r,t)}}
@@ -1 +1 @@
1
- import U from"node:fs";import F from"node:path";import{EngineTaskDeadlineExceededError as Se}from"../../engines/api/index.js";import"../../domain/identifiers.js";import"../../domain/test-outcomes.js";import{resolveEngineProfile as Ie}from"../../engines/catalog.js";import{BUILT_IN_ENGINE_ORCHESTRATION as Me}from"./engine-orchestration.js";import{persistTaskArtifacts as be}from"../../evidence/index.js";import{createEvidenceLedger as se,persistTrackedEngineEvidence as ae,requireTaskArtifacts as Oe,requireTaskEvidenceLedger as Ne}from"./engine-evidence-persistence.js";import{applyConsumerNodeSetupCleanupFailures as ce,cleanupPreparedNodeSetups as ue}from"./engine-execution-cleanup.js";import{buildBridgeError as _e,EngineExecutionBridgeError as Re,executeManagedEngineRequest as Fe,infraBridgeDisposition as q,managerFailureBridgeDisposition as Ae,productBridgeDisposition as z,reporterBridgeDisposition as V,resolveBridgeDisposition as de,runtimeNodeSetupBridgeDisposition as Ce}from"./engine-execution-failures.js";import{captureEngineReporterCallback as fe,DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS as Be,invokeEngineReporterCallback as le}from"./engine-execution-reporting.js";import{createEngineExecutionObserver as xe}from"./engine-execution-observer.js";export{EngineExecutionBridgeError}from"./engine-execution-failures.js";import{waitForEndpointReadinessPreflight as Pe}from"./endpoint-readiness.js";import{collectCheckDetailsFromRuntimeArtifacts as $e,collectFailureDetailsFromRuntimeArtifacts as Le}from"./failure-details.js";import{buildRuntimeFixtureManifest as je}from"./runtime-fixtures.js";import{MAX_RUNTIME_NODE_SETUP_CLEANUP_TIMEOUT_MS as Je,runRuntimeNodeSetup as Ue}from"./setup/runtime-node-setup.js";export async function executeEngineTask(e,t,n,r,s=null){const i=t,u={signal:r.signal,timeoutMs:Be},m="batchTasks"in n?n.batchTasks:[n],w=m[0],S=t.services.get(w.targetName);if(!S)throw new Error(`Runtime instance is missing target config "${w.targetName}"`);const d=S.config;he(d.productDir,"product directory"),he(i.leaseDir,"runtime lease directory");const T=Ie(w.testType,w.engineId),I=Me.resolve(T),O=We(d.testkit.execution.fileTimeoutSeconds),we=Date.now(),K=pe(we,O),C=ze(t),N=Object.hasOwn(C,w.serviceName)?C[w.serviceName]:null;if(I.endpointReadinessOwner==="orchestrator-http"){if(N===null)throw new Error(`Service "${d.name}" requires local.baseUrl for ${T.id} suites`);const B=Date.now(),D=G(r.signal,K);let y;try{y=await Pe({baseUrl:N,serviceName:d.name,lifecycle:r,signal:D.signal,options:Qe(Xe(K))})}finally{D.dispose()}if(!y.ok){const M=r.isStopRequested()||r.signal.aborted,k=Date.now(),c=buildEndpointReadinessOutcomes(m,n,y,M,B,k),a=[];let g=null;for(const E of c){const l=a.length;await fe(a,"taskStarted",()=>s?.taskStarted?.(E.task,d),u),g===null&&a.length>l&&(g=String(E.task.id)),await fe(a,"taskFinished",()=>s?.taskFinished?.(E.task,E),u),g===null&&a.length>l&&(g=String(E.task.id))}if(a.length>0){const E=a.length===1?a[0]:new AggregateError(a,"Engine readiness reporting failed");throw new Re(`${y.reason}; ${a.map(l=>l.message).join("; ")}`,E,de(a,[],!1,M?{classification:void 0,notifyRuntimeError:!1,runtimeImpact:"none",status:"cancelled"}:V("fail-graph")),new Map(m.map(l=>[String(l.id),[]])),new Map(c.map(l=>[String(l.task.id),l])),g)}return{outcomes:c}}}return e.withEngine(T.engineId,r.signal,async B=>{const D=Ve(i,d.productDir);U.mkdirSync(D.temporaryDirectory,{recursive:!0}),U.mkdirSync(D.artifactDirectory,{recursive:!0});const y=new Map(m.map(p=>[String(p.id),[]])),M=new Map(m.map(p=>[String(p.id),se()])),k=new Map,c=[];let a=z(),g=!1;const E=[],l=[],W=[];let X=null;const Q=new Set,x=async(p,o)=>{const f=String(p.id);Q.has(f)||(Q.add(f),await le("taskFinished",()=>s?.taskFinished?.(p,o),u))};try{for(const[p,o]of m.entries()){a=V();const f=String(o.id);X=f,await le("taskStarted",()=>s?.taskStarted?.(o,d),u),a=z();const Z=I.buildRuntimeEnvironment({baseUrl:N,database:S.database,targetConfig:d,task:o}),_=pe(Date.now(),O),ee=G(r.signal,_);let b;try{b=await Ue({cleanupTimeoutMs:Math.min(O,Je),deadlineMs:_,targetConfig:d,task:o,lease:i,runtimeEnv:Z,signal:ee.signal})}catch(h){throw a=Ce(h),h}finally{ee.dispose()}E.push({cleanup:b.cleanup,taskId:f}),a=q();for(const h of b.artifacts){const v=be(d.productDir,o,[h]);y.get(String(o.id))?.push(...v)}a=z();const R={baseUrl:N,lease:i,profile:T,runtimeEnvironment:Z,targetConfig:d,task:o},te=I.resolveConfiguration(R),ke={...te===void 0?{}:{configuration:te},environment:I.buildEnvironment(R),fixtures:nt(je(d.productDir,o.file),`fixture manifest for ${o.file}`),setupData:Ee(b.setupData,`node setup data for ${o.file}`),supportModules:I.resolveSupportModules(R)},De=qe(R);a=q();const ye=c.length,ne=se(),Te=xe({artifactReferencesByTaskId:y,completedOutcomesByTaskId:k,errors:c,executableTask:n,invocationEvidenceLedger:ne,productDir:d.productDir,taskBatchIndex:p,taskEvidenceLedgers:M,tasks:[o],tasksById:new Map([[f,o]]),workspaceArtifactDirectory:D.artifactDirectory},mapEngineOutcome),P=G(r.signal,_);try{const h={invocationId:He(r,i,o),observer:Te,profile:T,signal:P.signal,target:{endpoints:C,inputs:Ge()},tasks:[{deadlineMs:_,id:f,file:o.file,serviceName:o.serviceName,suiteName:o.suiteName,testType:o.testType,timeoutMs:O,inputs:ke,orchestration:De}],workspace:D};let v;try{v=await Fe(B,h)}catch(oe){throw a=Ae(r.signal,P.signal,oe),oe}const re=mapEngineOutcomes([o],v)[0],j=Oe(y,f),ve=Ne(M,f);ae(re.outcome.evidence,{artifactRoot:D.artifactDirectory,errors:c,ledger:ve,mode:"reconcile",productDir:d.productDir,references:j,scope:"task",task:o});const J=mapEngineOutcome(re.outcome,o,j,n,p);k.set(f,J),J.infraFailed&&J.blockedByRuntime&&(a=q("fail-graph"));const ie=et(v);tt(ie)&&ae(ie,{artifactRoot:D.artifactDirectory,errors:c,ledger:ne,mode:"reconcile",productDir:d.productDir,references:j,scope:"invocation",task:o})}finally{P.dispose()}c.length>ye&&(g=!0),E.pop();const $=await ue([{cleanup:b.cleanup,taskId:f}]);if($.length>0){l.push(...$),ce(k,$);const h=k.get(f);if(h!==void 0)try{await x(o,h)}catch(v){c.push(A(v))}break}if(c.length>0)break;const L=k.get(f);if(L===void 0){c.push(new Error(`Engine task ${f} completed without a mapped outcome`)),g=!0;break}W.push(L),a=V();try{await x(o,L)}catch(h){c.push(A(h)),g=!0;break}}}catch(p){const o=c.length;c.push(A(p)),(o>0||a.classification==="infra")&&(g=!0)}const Y=await ue(E);l.push(...Y),ce(k,Y);for(const p of m){const o=k.get(String(p.id));if(o!==void 0)try{await x(p,o)}catch(f){c.push(A(f))}}if(c.length>0||l.length>0)throw _e(c,l,de(c,l,g,a),y,k,X);return{outcomes:W}})}function qe(e){const t=e.targetConfig.testkit.mode;if(t!==void 0&&(typeof t!="string"||t.trim().length===0))throw new Error("Testkit execution mode must be a non-empty string");const n=e.targetConfig.runtimeId;return{lease:{directory:e.lease.leaseDir,id:String(e.lease.leaseId)},mode:t??"test",...n==null?{}:{runtimeId:String(n)}}}export function mapEngineOutcomes(e,t){const n=new Map(e.map(i=>[String(i.id),i])),r=new Map;for(const i of t.outcomes){const u=n.get(i.taskId);if(!u)throw new Error(`Engine manager returned an outcome for unknown task ${i.taskId}`);if(r.has(i.taskId))throw new Error(`Engine manager returned duplicate outcomes for task ${i.taskId}`);r.set(i.taskId,{task:u,outcome:i})}const s=e.map(i=>String(i.id)).filter(i=>!r.has(i));if(s.length>0)throw new Error(`Engine manager did not return outcomes for task(s): ${s.join(", ")}`);return e.map(i=>{const u=r.get(String(i.id));if(!u)throw new Error("Engine outcome mapping invariant failed");return u})}export function buildEndpointReadinessOutcomes(e,t,n,r,s,i){const u=Math.max(0,i-s);return e.map((m,w)=>({task:m,status:r?"cancelled":"not_run",error:null,reason:n.reason,infraFailed:!r,blockedByRuntime:!r,durationMs:w===0?u:0,startedAt:s,finishedAt:i,artifacts:[],failureDetails:r?[]:[...n.failureDetails],checkDetails:[],...ge(t,m)}))}function ze(e){return Object.freeze(Object.fromEntries([...e.services.values()].flatMap(({config:t,baseUrl:n})=>typeof n=="string"&&n.length>0?[[t.name,n]]:[])))}function Ve(e,t){const n=e.engineWorkspaceDirectory??F.join(e.leaseDir,"engine-execution");return{rootDirectory:t,...e.engineCacheDirectory===void 0?{}:{cacheDirectory:e.engineCacheDirectory},temporaryDirectory:F.join(n,"temporary"),artifactDirectory:F.join(n,"artifacts")}}function Ge(){return{environment:{},fixtures:{},supportModules:{}}}function He(e,t,n){return[e.runId,t.leaseId,Ke(n)].join(":")}function Ke(e){return"batchId"in e?e.batchId:String(e.id)}function We(e){const t=e*1e3;if(!Number.isSafeInteger(t)||t<=0)throw new Error("Engine task timeout must be a positive safe integer");return t}function pe(e,t){const n=e+t;if(!Number.isSafeInteger(n)||n<=e)throw new Error("Engine task deadline must be a positive safe integer");return n}function Xe(e){return Math.max(1,e-Date.now())}function Qe(e){const t=me(process.env.TESTKIT_HTTP_ENDPOINT_PREFLIGHT_TIMEOUT_MS,3e4),n=me(process.env.TESTKIT_HTTP_ENDPOINT_PREFLIGHT_ATTEMPT_TIMEOUT_MS,5e3);return{timeoutMs:Math.min(t,e),attemptTimeoutMs:Math.min(n,e)}}function me(e,t){const n=Number(e);return Number.isInteger(n)&&n>0?n:t}function G(e,t){const n=new AbortController;let r=null;const s=()=>{n.abort(e.reason)},i=()=>{const u=t-Date.now();if(u<=0){n.abort(new Se(t));return}r=setTimeout(i,Math.min(u,2147483647)),r.unref()};return e.aborted?s():(e.addEventListener("abort",s,{once:!0}),i()),{signal:n.signal,dispose(){r!==null&&clearTimeout(r),e.removeEventListener("abort",s)}}}export function mapEngineOutcome(e,t,n,r,s){const i=Le(e.evidence.artifacts),u=t.engineId==="node-vitest"&&i.some(T=>T.kind==="vitest-test")&&e.failure!==null&&Ye(e.failure),m=[...e.failure&&!u?[Ze(e.failure)]:[],...i],w=$e(e.evidence.artifacts),S=e.status==="not_run",d=S||e.failure?.classification==="infra";return{task:t,status:e.status,error:e.status==="failed"?e.failure?.message??"Engine task failed without a message":null,reason:e.status==="failed"||e.status==="passed"?null:e.failure?.message??`Engine task ${e.status}`,infraFailed:d,blockedByRuntime:S,durationMs:e.durationMs,startedAt:e.startedAtMs,finishedAt:e.finishedAtMs,artifacts:n,failureDetails:m,checkDetails:w,...ge(r,t,s)}}function ge(e,t,n){if(!("batchTasks"in e))return{};const r=n??e.batchTasks.findIndex(s=>s.id===t.id&&s.file===t.file);if(r<0)throw new Error(`Task ${String(t.id)} is missing from its engine batch`);return{runtimeBatch:{id:e.batchId,index:r,fileCount:e.batchTasks.length,files:e.batchTasks.map(s=>s.file)}}}function Ye(e){return e.code==="NODE_VITEST_REPORT_FAILED"?!0:e.code==="NODE_VITEST_PROCESS_FAILED"&&e.details?.exitCode===1}function Ze(e){const t=e.code??"ENGINE_TASK_FAILED",n={code:t,details:e.details===void 0?null:rt(e.details)};return{kind:"engine-failure",key:t,title:t,...e.classification===void 0?{}:{classification:e.classification},count:1,message:e.message,actual:n,...e.stack===void 0?{}:{stack:e.stack}}}function et(e){return{artifacts:H(e.evidence.artifacts,e.outcomes.flatMap(t=>t.evidence.artifacts)),logs:H(e.evidence.logs,e.outcomes.flatMap(t=>t.evidence.logs)),metrics:H(e.evidence.metrics,e.outcomes.flatMap(t=>t.evidence.metrics)),...e.evidence.native===void 0?{}:{native:e.evidence.native}}}function H(e,t){const n=new Map;for(const r of t){const s=JSON.stringify(r);n.set(s,(n.get(s)??0)+1)}return e.filter(r=>{const s=JSON.stringify(r),i=n.get(s)??0;return i===0?!0:(n.set(s,i-1),!1)})}function tt(e){return e.artifacts.length>0||e.logs.length>0||e.metrics.length>0||e.native!==void 0}function nt(e,t){const n=Ee(e,t);if(n===null||Array.isArray(n)||typeof n!="object")throw new TypeError(`${t} must contain a JSON object`);return n}function Ee(e,t){try{const n=JSON.stringify(e);if(typeof n!="string")throw new TypeError(`${t} must be JSON-serializable`);return JSON.parse(n)}catch(n){throw new TypeError(`${t} must be JSON-serializable`,{cause:n})}}function rt(e){return JSON.parse(JSON.stringify(e))}function he(e,t){if(!F.isAbsolute(e))throw new Error(`Engine execution ${t} must be absolute`);if(!U.statSync(e).isDirectory())throw new Error(`Engine execution ${t} must be a directory`)}function A(e){return e instanceof Error?e:new Error(String(e))}
1
+ import B from"node:fs";import _ from"node:path";import{EngineTaskDeadlineExceededError as oe}from"../../engines/api/index.js";import"../../domain/identifiers.js";import"../../domain/test-outcomes.js";import{resolveExecutionProfile as se}from"../../engines/catalog.js";import{engineSupportInputs as ae,defaultEnvironmentValues as ce,engineInputEnvironment as de}from"./engine-orchestration.js";import{persistTaskArtifacts as ue}from"../../evidence/index.js";import{createEvidenceLedger as K,persistTrackedEngineEvidence as H,requireTaskArtifacts as Q,requireTaskEvidenceLedger as fe}from"./engine-evidence-persistence.js";import{buildBridgeError as le,executeManagedEngineRequest as pe,infraBridgeDisposition as R,managerFailureBridgeDisposition as ge,productBridgeDisposition as X,reporterBridgeDisposition as Y,resolveBridgeDisposition as me}from"./engine-execution-failures.js";import{DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS as Ee,invokeEngineReporterCallback as Z}from"./engine-execution-reporting.js";import{createEngineExecutionObserver as he}from"./engine-execution-observer.js";import{toError as $}from"../../kernel/error-serialization.js";export{EngineExecutionBridgeError}from"./engine-execution-failures.js";import{collectFailureDetailsFromRuntimeArtifacts as ke}from"./failure-details.js";import{buildRuntimeFixtureManifest as ye}from"./runtime-fixtures.js";import{readEnvironmentValueMissingFailure as we}from"../../engines/contracts/environment-values.js";export async function executeEngineTask(e,{environment:t,lease:n,request:o,started:r,task:i},c,y=null){const T={signal:c.signal,timeoutMs:Ee},g="batchTasks"in i?i.batchTasks:[i],M=g[0],x={name:M.targetName},k=o.productDir;te(k,"product directory"),te(n.directory,"runtime lease directory");const O=se(M),ne=normalizeTimeoutMs(o.fileTimeoutSeconds);if(e.engineId!==O.engineId)throw new Error(`Engine session ${e.engineId} cannot execute ${O.engineId} tasks`);const w=ve(n,k),I=new Map(g.map(a=>[String(a.id),[]])),J=new Map(g.map(a=>[String(a.id),K()])),b=new Map,d=[];let m=X(),D=!1;const C=[];let F=null;const V=new Set,j=async(a,h)=>{const u=String(a.id);u===r?.taskId&&r.prepared!==null||V.has(u)||(V.add(u),await Z("taskFinished",()=>y?.taskFinished?.(a,h),T))};try{m=R();const a=g.find(u=>String(u.id)===r?.taskId);if(r!==null&&r.prepared!==null&&a!==void 0){F=r.taskId;for(const u of r.prepared.artifacts){const f=ue(k,a,[u]);I.get(r.taskId)?.push(...f)}}B.mkdirSync(w.temporaryDirectory,{recursive:!0}),B.mkdirSync(w.artifactDirectory,{recursive:!0});const h=O.taskBatching==="selection"?[g]:g.map(u=>[u]);for(const[u,f]of h.entries()){const P=ne*f.length,q=[];for(const s of f){m=Y();const l=String(s.id);F=l;const E=r?.taskId===l?r:null;E===null&&await Z("taskStarted",()=>y?.taskStarted?.(s,x),T),m=X();const p={environment:t,request:o,runtimeEnvironment:ce(t),task:s},{configuration:v,supportModules:S}=ae(p);q.push({id:l,file:s.file,serviceName:s.serviceName,suiteName:s.suiteName,...s.testType===void 0?{}:{testType:s.testType},timeoutMs:P,inputs:{...v===void 0?{}:{configuration:v},environment:de(p),fixtures:xe(ye(k,s.file),`fixture manifest for ${s.file}`),setupData:ee(E!==null&&E.prepared!==null?E.prepared.setupData:t.setupData,`node setup data for ${s.file}`),supportModules:S},orchestration:{lease:{directory:n.directory,id:n.id},mode:"test"}})}const z=r?.deadlineMs??buildTaskDeadline(Date.now(),P);m=R();const re=d.length,U=K(),W=f.length===1?u:void 0,ie=he({artifactReferencesByTaskId:I,completedOutcomesByTaskId:b,errors:d,executableTask:i,invocationEvidenceLedger:U,productDir:k,taskBatchIndex:W,taskEvidenceLedgers:J,tasks:f,tasksById:new Map(f.map(s=>[String(s.id),s])),workspaceArtifactDirectory:w.artifactDirectory},mapEngineOutcome),N=createDeadlineSignal(c.signal,z);try{const s={invocationId:[c.runId,n.id,be(f[0])].join(":"),observer:ie,profile:O,signal:N.signal,target:{baseUrl:t.baseUrl,databases:t.databases,endpoints:t.endpoints,handles:{...t.handles,...r===null||r.prepared===null?{}:r.prepared.handles},inputs:Ie()},tasks:q.map(p=>({...p,deadlineMs:z})),workspace:w};let l;try{l=await pe(e,s);for(const p of l.runErrors??[])c.recordRunError?.(p)}catch(p){throw m=ge(c.signal,N.signal,p),p}for(const{outcome:p,task:v}of mapEngineOutcomes(f,l)){const S=String(v.id),G=Q(I,S);H(p.evidence,{artifactRoot:w.artifactDirectory,errors:d,ledger:fe(J,S),mode:"reconcile",productDir:k,references:G,scope:"task",task:v});const A=mapEngineOutcome(p,v,G,i,W);b.set(S,A),A.infraFailed&&A.blockedByRuntime&&(m=R("fail-graph"))}const E=Me(l);Oe(E)&&H(E,{artifactRoot:w.artifactDirectory,errors:d,ledger:U,mode:"reconcile",productDir:k,references:Q(I,String(f[0].id)),scope:"invocation",task:f[0]})}finally{N.dispose()}if(d.length>re&&(D=!0),d.length>0)break;for(const s of f){const l=b.get(String(s.id));if(l===void 0){d.push(new Error(`Engine task ${String(s.id)} completed without a mapped outcome`)),D=!0;break}C.push(l),m=Y();try{await j(s,l)}catch(E){d.push($(E)),D=!0;break}}if(d.length>0)break}}catch(a){const h=d.length;d.push($(a)),(h>0||m.classification==="infra")&&(D=!0)}for(const a of g){const h=b.get(String(a.id));if(h!==void 0)try{await j(a,h)}catch(u){d.push($(u))}}if(d.length>0){const a={activeDisposition:m,observedInfraOperationFailure:D,operationErrors:d};throw le(a,[],me(a,[]),I,b,F)}return{outcomes:C}}export function mapEngineOutcomes(e,t){const n=new Map(e.map(i=>[String(i.id),i])),o=new Map;for(const i of t.outcomes){const c=n.get(i.taskId);if(!c)throw new Error(`Engine manager returned an outcome for unknown task ${i.taskId}`);if(o.has(i.taskId))throw new Error(`Engine manager returned duplicate outcomes for task ${i.taskId}`);o.set(i.taskId,{task:c,outcome:i})}const r=e.map(i=>String(i.id)).filter(i=>!o.has(i));if(r.length>0)throw new Error(`Engine manager did not return outcomes for task(s): ${r.join(", ")}`);return e.map(i=>{const c=o.get(String(i.id));if(!c)throw new Error("Engine outcome mapping invariant failed");return c})}function ve(e,t){return{rootDirectory:t,cacheDirectory:e.engineCacheDirectory,temporaryDirectory:_.join(e.engineWorkspaceDirectory,"temporary"),artifactDirectory:_.join(e.engineWorkspaceDirectory,"artifacts")}}function Ie(){return{environment:{},fixtures:{},supportModules:{}}}function be(e){return"batchId"in e?e.batchId:String(e.id)}export function normalizeTimeoutMs(e){const t=e*1e3;if(!Number.isSafeInteger(t)||t<=0)throw new Error("Engine task timeout must be a positive safe integer");return t}export function buildTaskDeadline(e,t){const n=e+t;if(!Number.isSafeInteger(n)||n<=e)throw new Error("Engine task deadline must be a positive safe integer");return n}export function createDeadlineSignal(e,t){const n=new AbortController;let o=null;const r=()=>{n.abort(e.reason)},i=()=>{const c=t-Date.now();if(c<=0){n.abort(new oe(t));return}o=setTimeout(i,Math.min(c,2147483647)),o.unref()};return e.aborted?r():(e.addEventListener("abort",r,{once:!0}),i()),{signal:n.signal,dispose(){o!==null&&clearTimeout(o),e.removeEventListener("abort",r)}}}export function mapEngineOutcome(e,t,n,o,r){const i=ke(e.evidence.artifacts),c=t.engineId==="node-vitest"&&i.some(x=>x.kind==="vitest-test")&&e.failure!==null&&Se(e.failure),y=we(e.failure),T=[...e.failure&&!c?[Te(e.failure,y===null)]:[],...i],g=e.status==="not_run",M=g||e.failure?.classification==="infra";return{task:t,status:e.status,error:e.status==="failed"?e.failure?.message??"Engine task failed without a message":null,reason:e.status==="failed"||e.status==="passed"?null:e.failure?.message??`Engine task ${e.status}`,infraFailed:M,blockedByRuntime:g,durationMs:e.durationMs,startedAt:e.startedAtMs,finishedAt:e.finishedAtMs,artifacts:n,failureDetails:T,...y===null?{}:{environmentValuesMissing:y},...De(o,t,r)}}function De(e,t,n){if(!("batchTasks"in e))return{};const o=n??e.batchTasks.findIndex(r=>r.id===t.id&&r.file===t.file);if(o<0)throw new Error(`Task ${String(t.id)} is missing from its engine batch`);return{runtimeBatch:{id:e.batchId,index:o,fileCount:e.batchTasks.length,files:e.batchTasks.map(r=>r.file)}}}function Se(e){return e.code==="NODE_VITEST_REPORT_FAILED"?!0:e.code==="NODE_VITEST_PROCESS_FAILED"&&e.details?.exitCode===1}function Te(e,t){const n=e.code??"ENGINE_TASK_FAILED",o={code:n,details:!t||e.details===void 0?null:Fe(e.details)};return{kind:"engine-failure",key:n,title:n,...e.classification===void 0?{}:{classification:e.classification},count:1,message:e.message,actual:o,...e.stack===void 0?{}:{stack:e.stack}}}function Me(e){return{artifacts:L(e.evidence.artifacts,e.outcomes.flatMap(t=>t.evidence.artifacts)),logs:L(e.evidence.logs,e.outcomes.flatMap(t=>t.evidence.logs)),metrics:L(e.evidence.metrics,e.outcomes.flatMap(t=>t.evidence.metrics)),...e.evidence.native===void 0?{}:{native:e.evidence.native}}}function L(e,t){const n=new Map;for(const o of t){const r=JSON.stringify(o);n.set(r,(n.get(r)??0)+1)}return e.filter(o=>{const r=JSON.stringify(o),i=n.get(r)??0;return i===0?!0:(n.set(r,i-1),!1)})}function Oe(e){return e.artifacts.length>0||e.logs.length>0||e.metrics.length>0||e.native!==void 0}function xe(e,t){const n=ee(e,t);if(n===null||Array.isArray(n)||typeof n!="object")throw new TypeError(`${t} must contain a JSON object`);return n}function ee(e,t){try{const n=JSON.stringify(e);if(typeof n!="string")throw new TypeError(`${t} must be JSON-serializable`);return JSON.parse(n)}catch(n){throw new TypeError(`${t} must be JSON-serializable`,{cause:n})}}function Fe(e){return JSON.parse(JSON.stringify(e))}function te(e,t){if(!_.isAbsolute(e))throw new Error(`Engine execution ${t} must be absolute`);if(!B.statSync(e).isDirectory())throw new Error(`Engine execution ${t} must be a directory`)}
@@ -1 +1 @@
1
- import{BUILT_IN_RUNNER_PROFILES as a}from"../../engines/definitions.js";import u from"node:fs";import f from"node:path";import"../../engines/api/index.js";import"../../domain/identifiers.js";import{findConfigFile as c,resolveServiceCwd as g}from"../../config/loader/index.js";import{buildPlaywrightUiConfig as l}from"./playwright-configuration.js";import{buildTaskExecutionEnv as d}from"../../steps/index.js";import{findPlaywrightConfigFile as m}from"../../engines/playwright/runtime/config-file.js";const E=Object.freeze(["tsconfig.json","tsconfig.build.json"]),o=Object.freeze(a.map(n=>Object.freeze({engineId:n.engineId,profileId:n.id,endpointReadinessOwner:n.endpointReadinessOwner,buildEnvironment:w,buildRuntimeEnvironment:n.capabilities.databaseRuntime==="required"?p:S,resolveConfiguration:n.engineId==="k6"?y:n.engineId==="playwright"?I:U,resolveSupportModules:n.engineId==="node-vitest"?C:n.engineId==="playwright"?b:_})));export const BUILT_IN_ENGINE_ORCHESTRATION=Object.freeze({integrations:o,resolve(n){const e=o.find(r=>r.profileId===n.id&&r.engineId===n.engineId);if(!e)throw new Error(`No engine orchestration integration for ${n.engineId}/${n.id}`);return e}});function p(n){const e=n.database?.url;if(!e)throw new Error(`Service "${n.targetConfig.name}" requires a database for k6-dal suites`);return{DATABASE_URL:e}}function C(n){const e=c(n.targetConfig.productDir),r=T(n.targetConfig.productDir,E);return{...e===null?{}:{testkitConfig:e},...r===null?{}:{tsconfig:r}}}function b(n){const e=m(g(n.targetConfig.productDir,n.targetConfig.testkit.local?.cwd));return s(e===null?{}:{playwrightConfig:e})}function S(n){return n.baseUrl===null?{}:{BASE_URL:n.baseUrl}}function w(n){const e=s(d(n.targetConfig,n.lease,h(n),null,{includeTestkitControls:!1,inheritProcessEnv:!1}));return O(e,n.targetConfig.name)}function O(n,e){const r=`TESTKIT_${e.toUpperCase().replace(/[^A-Z0-9]+/g,"_")}_SCHEMA_SOURCE_DATABASE_URL`,t=new Set(["TESTKIT_SCHEMA_SOURCE_DATABASE_URL",r]);return Object.fromEntries(Object.entries(n).filter(([i])=>!t.has(i.toUpperCase())))}function h(n){return Object.fromEntries(Object.entries(n.runtimeEnvironment).filter(([e])=>e.toUpperCase()!=="BASE_URL"))}function y(n){return n.targetConfig.engineConfigurations?.k6}function I(n){if(n.baseUrl===null)throw new Error(`Service "${n.targetConfig.name}" requires local.baseUrl for Playwright suites`);return R(l(n.targetConfig,n.baseUrl,n.lease),`Playwright configuration for ${n.task.file}`)}function R(n,e){try{const r=JSON.stringify(n);if(typeof r!="string")throw new TypeError(`${e} must be JSON-serializable`);const t=JSON.parse(r);if(t===null||Array.isArray(t)||typeof t!="object")throw new TypeError(`${e} must contain a JSON object`);return t}catch(r){throw new TypeError(`${e} must be a JSON object`,{cause:r})}}function U(){}function _(){return{}}function T(n,e){for(const r of e){const t=f.join(n,r);try{if(u.statSync(t).isFile())return t}catch(i){if(v(i,"ENOENT"))continue;throw new Error(`Could not inspect optional support module ${t}`,{cause:i})}}return null}function s(n){return Object.fromEntries(Object.entries(n).filter(e=>typeof e[1]=="string"))}function v(n,e){return typeof n=="object"&&n!==null&&Reflect.get(n,"code")===e}
1
+ import"../../engines/api/index.js";import{findConfigFile as o}from"../../config/loader/index.js";import{findNearestPlaywrightConfigFile as i}from"../../engines/playwright/runtime/config-file.js";export function engineSupportInputs(e){switch(e.task.engineId){case"node-vitest":return{configuration:e.request.vitest,supportModules:s(e)};case"playwright":return{configuration:l(e),supportModules:u(e)}}}export function defaultEnvironmentValues(e){return{...e.baseUrl===null?{}:{BASE_URL:e.baseUrl},...e.databaseUrl===null?{}:{DATABASE_URL:e.databaseUrl}}}export function engineInputEnvironment(e){const t=Object.entries(e.runtimeEnvironment).filter(([r])=>r.toUpperCase()!=="BASE_URL"),n=new Set(t.map(([r])=>r.toUpperCase()));return{...Object.fromEntries(Object.entries(e.environment.env).filter(([r])=>!n.has(r.toUpperCase()))),...Object.fromEntries(t)}}function s(e){const t=o(e.request.productDir);return t===null?{}:{testkitConfig:t}}function u(e){const t=i(e.request.productDir,e.request.ownerRoots[e.task.serviceName]??[]);return t===null?{}:{playwrightConfig:t}}function l(e){const t=e.environment.baseUrl;return t!==null&&a(t)?{...e.environment.ui,allowRemote:!0}:{...e.environment.ui}}function a(e){try{return!p(new URL(e).hostname)}catch{return!1}}function p(e){const t=e.toLowerCase();return t==="localhost"||t==="::1"||t==="0.0.0.0"||t==="127.0.0.1"||t.endsWith(".localhost")||t.startsWith("127.")}
@@ -0,0 +1 @@
1
+ import{isDeepStrictEqual as c}from"node:util";import{isUnknownRecord as f}from"../../kernel/unknown-values.js";export function createEnvironment({group:n,setupData:t={},...e}){return{...e,databases:p(e.databases,n,e.databaseUrl,"database"),endpoints:p(e.endpoints,n,e.baseUrl,"endpoint"),env:{...e.env},setupData:t}}export class GroupDefaultConflictError extends Error{}function p(n,t,e,r){if(e===null)return{...n};if(Object.hasOwn(n,t)&&n[t]!==e)throw new GroupDefaultConflictError(`Group "${t}" has a default ${r} and a different ${r} named "${t}"; a group's default ${r} is also named after the group`);return{...n,[t]:e}}export class TaskPreparationError extends Error{cleanupFailures;kind;cause;constructor(t,e,r){super(e.message,{cause:e}),this.name="TaskPreparationError",this.cause=e,this.cleanupFailures=r,this.kind=t}}export function environmentTaskIdentities(n){return("batchTasks"in n?n.batchTasks:[n]).map(environmentTaskIdentity)}const b={baseUrl:"base URL",databaseUrl:"database URL",databases:"database",endpoints:"endpoint",env:"environment value",handles:"handle",setupData:"setup data",ui:"UI values"};export function renderSharedEnvironment(n,t){const[e,...r]=[...new Set(environmentTaskIdentities(n).map(({group:a})=>a))],s=t(e);for(const a of r){const i=t(a),o=Object.keys(b).find(u=>!c(s[u],i[u]));if(o===void 0)continue;const d=h(s[o],i[o]);throw new Error(`Plain Vitest files run in one Vitest invocation, but groups ${e} and ${a} give them a different ${b[o]}${d===void 0?"":` ${d}`}; select one group with --group`)}return s}function h(n,t){if(!(!f(n)||!f(t)))return Object.keys({...n,...t}).find(e=>!c(n[e],t[e]))}export function environmentTaskIdentity({file:n,id:t,targetName:e}){return{id:t,file:n,group:e}}
@@ -1 +1 @@
1
- export function normalizeFailureDetail(e){const t=a(e);if(!t)return null;const n=s(t.kind),r=typeof t.key=="string"&&t.key.trim().length>0?t.key:null,o=s(t.title);if(!n||!r||!o)return null;const i={kind:n,key:r,title:o,count:J(t.count)??1},c=s(t.classification);c&&(i.classification=c);const l=Array.isArray(t.groupPath)?t.groupPath.filter(S=>typeof S=="string"):[];l.length>0&&(i.groupPath=l),typeof t.labelled=="boolean"&&(i.labelled=t.labelled);const u=s(t.checkName);u&&(i.checkName=u);const f=N(t.suitePath);f.length>0&&(i.suitePath=f);const m=s(t.phase);m&&(i.phase=m);const h=s(t.message);h&&(i.message=h),t.expected!==void 0&&(i.expected=p(t.expected)),t.actual!==void 0&&(i.actual=p(t.actual));const g=s(t.traceId);g&&(i.traceId=g);const k=d(t.request);k&&(i.request=k);const A=d(t.response);A&&(i.response=A);const b=d(t.location);b&&(i.location=b);const z=s(t.stack);return z&&(i.stack=z),i}export function mergeFailureDetails(e){const t=new Map;for(const n of e){const r=JSON.stringify([n.kind,n.labelled??null,n.key,n.title]),o=t.get(r);if(!o){t.set(r,{...n});continue}o.count+=n.count,!o.message&&n.message&&(o.message=n.message)}return[...t.values()].sort((n,r)=>n.kind.localeCompare(r.kind)||n.key.localeCompare(r.key)||n.title.localeCompare(r.title))}export function collectFailureDetailsFromRuntimeArtifacts(e){const t=[];for(const n of Array.isArray(e)?e:[]){const r=a(n);if(!r||r.kind!=="testkit.failure-details")continue;const o=a(r.data);if(!o)continue;const i=s(o.phase);for(const c of Array.isArray(o.failures)?o.failures:[]){const l=a(c);if(!l)continue;const u=normalizeFailureDetail({...l,phase:l.phase||i||null});u&&t.push(u)}}return mergeFailureDetails(t)}export function collectCheckDetailsFromRuntimeArtifacts(e){const t=[];for(const n of Array.isArray(e)?e:[]){const r=a(n);if(!r||r.kind!=="testkit.checks")continue;const o=a(r.data);if(o)for(const i of Array.isArray(o.checks)?o.checks:[]){const c=a(i);if(!c)continue;const l=s(c.name)??"unnamed",u=x(c.passes),f=x(c.fails);t.push({name:l,path:N(c.path),passes:u,fails:f,passed:u>0&&f===0})}}return t}function a(e){return F(e)?e:null}function F(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function N(e){if(!Array.isArray(e))return[];const t=[];for(const n of e){const r=s(n);r&&t.push(r)}return t}function s(e){if(typeof e!="string")return null;const t=e.trim();return t.length>0?t:null}function J(e){return typeof e!="number"||!Number.isInteger(e)||e<=0?null:e}function x(e){try{return Math.max(0,Number(e)||0)}catch{return 0}}function d(e){if(!a(e))return null;const t=p(e);return P(t)?t:null}function p(e){try{const t=JSON.stringify(e);if(typeof t!="string")return String(e);const n=JSON.parse(t);return y(n)?n:String(e)}catch{return String(e)}}function y(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"?!0:Array.isArray(e)?e.every(y):P(e)}function P(e){const t=a(e);return t!==null&&Object.values(t).every(y)}
1
+ import{normalizeOptionalString as s,asUnknownRecord as c}from"../../kernel/unknown-values.js";export function normalizeFailureDetail(t){const e=c(t);if(!e)return null;const n=s(e.kind),i=typeof e.key=="string"&&e.key.trim().length>0?e.key:null,o=s(e.title);if(!n||!i||!o)return null;const r={kind:n,key:i,title:o,count:A(e.count)??1},u=s(e.classification);u&&(r.classification=u);const a=Array.isArray(e.groupPath)?e.groupPath.filter(h=>typeof h=="string"):[];a.length>0&&(r.groupPath=a),e.sharedTitle===!0&&(r.sharedTitle=!0);const l=s(e.checkName);l&&(r.checkName=l);const p=s(e.phase);p&&(r.phase=p);const m=s(e.message);m&&(r.message=m),e.expected!==void 0&&(r.expected=f(e.expected)),e.actual!==void 0&&(r.actual=f(e.actual));const y=z(e.location);y&&(r.location=y);const g=s(e.stack);return g&&(r.stack=g),r}export function mergeFailureDetails(t){const e=new Map;for(const n of t){const i=JSON.stringify([n.kind,n.key,n.title]),o=e.get(i);if(!o){e.set(i,{...n});continue}o.count+=n.count,!o.message&&n.message&&(o.message=n.message)}return[...e.values()].sort((n,i)=>n.kind.localeCompare(i.kind)||n.key.localeCompare(i.key)||n.title.localeCompare(i.title))}export function collectFailureDetailsFromRuntimeArtifacts(t){const e=[];for(const n of Array.isArray(t)?t:[]){const i=c(n);if(!i||i.kind!=="testkit.failure-details")continue;const o=c(i.data);if(!o)continue;const r=s(o.phase);for(const u of Array.isArray(o.failures)?o.failures:[]){const a=c(u);if(!a)continue;const l=normalizeFailureDetail({...a,phase:a.phase||r||null});l&&e.push(l)}}return mergeFailureDetails(e)}function A(t){return typeof t!="number"||!Number.isInteger(t)||t<=0?null:t}function z(t){if(!c(t))return null;const e=f(t);return k(e)?e:null}function f(t){try{const e=JSON.stringify(t);if(typeof e!="string")return String(t);const n=JSON.parse(e);return d(n)?n:String(t)}catch{return String(t)}}function d(t){return t===null||typeof t=="boolean"||typeof t=="number"||typeof t=="string"?!0:Array.isArray(t)?t.every(d):k(t)}function k(t){const e=c(t);return e!==null&&Object.values(e).every(d)}
@@ -1 +1 @@
1
- import{finalizeServiceResult as S,summarizeDbBackend as w}from"./results.js";import{buildLiveRunArtifact as b}from"../../evidence/reporting.js";import{writeLiveRunArtifact as C}from"../../evidence/index.js";export function createLiveSnapshotWriter({productDir:e,runId:s,configs:o,trackers:l,startedAt:r,execution:p,workerState:n,selection:t,archiveConfig:m=null,declaredEnvironmentKeys:c=[],metadata:f,logRegistry:a,setupRegistry:g,operationTimingRegistry:v=null,reporter:y=null}){return()=>{const u=Date.now(),L=o.map(i=>S(l.get(i.name),r,u));try{C(e,b({productDir:e,runId:s,results:L,startedAt:r,updatedAt:u,execution:p,workerCount:n.workerCount,runtimeInstanceCount:n.runtimeInstanceCount,runtimeStats:n.runtimeStats,typeValues:t.typeValues,suiteSelectors:t.suiteSelectors,fileNames:t.fileNames,serviceFilter:t.serviceFilter,planning:t.planning||null,archiveConfig:m,declaredEnvironmentKeys:c,metadata:f,summarizeDbBackend:w,serviceLogs:a.listServiceLogs(),setupLogs:a.listSetupLogs(),setupOperations:g.listOperations(),operationTimings:v?.listOperations()||[]}))}catch(i){y?.warning?.(`Live run artifact update skipped: ${O(d(i))}`)}}}function d(e){return(typeof e=="object"&&e!==null||typeof e=="function")&&Reflect.get(e,"message")||e}function O(e){if(typeof e=="symbol")throw new TypeError("Cannot convert a Symbol value to a string");return String(e)}
1
+ import{finalizeServiceResult as v}from"./results.js";import{buildLiveRunArtifact as S}from"../../evidence/reporting.js";import{writeLiveRunArtifact as R}from"../../evidence/index.js";export function createLiveSnapshotWriter({productDir:e,runId:i,configs:o,trackers:u,startedAt:r,execution:l,workerState:s,selection:t,archiveConfig:p=null,declaredEnvironmentKeys:f=[],metadata:m,environmentRecord:g,operationTimingRegistry:c=null,reporter:y=null}){return()=>{const a=Date.now(),w=o.map(n=>v(u.get(n.name),r,a));try{R(e,S({productDir:e,runId:i,results:w,startedAt:r,updatedAt:a,execution:l,workerCount:s.workerCount,typeValues:t.typeValues,suiteSelectors:t.suiteSelectors,fileNames:t.fileNames,groupFilter:t.groupFilter,planning:t.planning||null,archiveConfig:p,declaredEnvironmentKeys:f,metadata:m,environment:g.snapshot(),operationTimings:c?.listOperations()||[]}))}catch(n){y?.warning?.(`Live run artifact update skipped: ${h(b(n))}`)}}}function b(e){return(typeof e=="object"&&e!==null||typeof e=="function")&&Reflect.get(e,"message")||e}function h(e){if(typeof e=="symbol")throw new TypeError("Cannot convert a Symbol value to a string");return String(e)}
@@ -1 +1 @@
1
- import{resolveRuntimeConfigs as re}from"../../config/loader/dependencies.js";import{buildRuntimeGraphs as ne,claimNextTask as ie,collectSuites as ae}from"./planning.js";import{buildRunPlanningMetadata as se,buildScheduledQueue as oe}from"./scheduler/index.js";import{addTrackerError as B,buildServiceTrackers as ue,finalizeServiceResult as _,recordGraphError as le,recordTaskOutcome as ce,summarizeDbBackend as me}from"./results.js";import{loadTimings as fe,saveTimings as de,writeRunArtifact as pe}from"../../evidence/index.js";import{createRunLogRegistry as ge}from"../../evidence/logs.js";import{createOperationTimingRegistry as ke,timeOperation as L}from"../../evidence/operation-timings.js";import{createRunReporterFromListener as he}from"./run-events.js";import{createSetupOperationRegistry as Se}from"../../evidence/setup-progress.js";import{createLocalRunEnvironment as ve}from"../../environment/run-environment.js";import{readPackageMetadata as Re,safeHostname as ye,safeUsername as Ce}from"../../process/host/metadata.js";import{collectGitMetadata as we}from"../../repo/metadata.js";import{resolveExecutionConfig as Fe}from"../../config/loader/decode-execution.js";import"../../environment/run-environment.js";import{createEngineManager as Ae}from"../../engines/factory.js";import{createWorker as xe,runWorker as Ie}from"./worker-loop.js";import{ensureRequestedFilesMatch as Ee}from"./run-guards.js";import{createLiveSnapshotWriter as Te}from"./live-run.js";import{finalizeRunArtifacts as be}from"./run-finalization.js";import{buildRunArtifact as ze}from"../../evidence/reporting.js";import{createOperationReporterBridge as Me}from"./operation-progress.js";import{formatError as $,serializeError as J}from"../../kernel/error-serialization.js";export async function runAll(e,l,g,t,p=e){const k=t.fileNames||[];Ee(e,l,g,k);const a=e[0]?.productDir||process.cwd(),m=ve(a),I=Ae(a),w=new Map(p.map(n=>[n.name,n])),h=Date.now(),f=e[0]?.artifacts??null,z=[...new Set(e.flatMap(n=>Object.keys(n.testkit.serviceEnv)))].sort(),Q={git:await we(a),host:{hostname:ye(),username:Ce()},testkitVersion:Re().version},S=t.onEvent?he(t.onEvent,{debug:t.debug}):null,F=ge(a),v={workerCount:0,runtimeInstanceCount:0,runtimeStats:[]},q=resolveRunExecutionConfig(e[0],t),N=collectServicePlans(e,w,l,g,t,q,S);S?.setServicePlans?.(N);const A=ue(N,h),Y=g.map(n=>({...n})),D={typeValues:l,suiteSelectors:Y,fileNames:k,serviceFilter:t.serviceFilter||null,planning:null};let d=()=>{};const Z=Me(S),x=ke({onChange:n=>{Z(n),d()}}),P=Se({logRegistry:F,onChange:()=>{d()}}),O=N.filter(n=>!n.skipped);let o;const r=await m.start({keepAlive:!0,resetResultsBeforePublish:!0});d=Te({productDir:a,runId:r.runId,configs:e,trackers:A,startedAt:h,execution:q,workerState:v,selection:D,archiveConfig:f,declaredEnvironmentKeys:z,metadata:Q,logRegistry:F,setupRegistry:P,operationTimingRegistry:x,reporter:S});const M={artifacts:null},ee=async(n,c)=>(r.beginFinalization(),await r.finish(n,u=>{const i=c(u);return M.artifacts={runArtifact:i.runArtifact},i},"normal"));let R,E;const U=(n,c,s)=>({productDir:a,runId:r.runId,results:n,startedAt:h,finishedAt:c,execution:q,workerCount:v.workerCount,runtimeInstanceCount:v.runtimeInstanceCount,runtimeStats:v.runtimeStats,selection:D,archiveConfig:f,declaredEnvironmentKeys:z,metadata:Q,logRegistry:F,setupRegistry:P,operationTimingRegistry:x,reporter:S,runInterruptReason:r.getInterruptReason(),runStatus:s,publishRunFinalization:ee});d();let y=null;try{try{if(O.length>0){const s=fe(a),{graphs:u,queue:i}=await L(x,{name:"testkit.plan",kind:"planning",summary:"plan test execution",scope:{serviceCount:O.length}},()=>{const T=ne(O),C=oe(O,T,{timings:s});return{graphs:T,queue:C}});D.planning=se(i,u),d(),S?.setTotalFileCount?.(i.length),v.workerCount=Math.max(1,Math.min(q.taskConcurrency,i.length)),v.runtimeInstanceCount=u.reduce((T,C)=>T+C.instanceCount,0);const V=Array.from({length:v.workerCount},(T,C)=>xe(C+1,a));r.provision(u,{reporter:S,logRegistry:F,setupRegistry:P,operationTimingRegistry:x,skipSchemaSourceVerify:t.skipSchemaSourceVerify});const H=[];try{const C=(await L(x,{name:"testkit.execute",kind:"execution",summary:"execute local worker queue",scope:{workerCount:V.length,taskCount:i.length}},async()=>Promise.allSettled(V.map(j=>Ie(j,i,r,I,A,H,ie,(b,G,K,W)=>{ce(b,G,K,W),d()},(b,G,K,W,te)=>{le(b,G,K,W,te),d()},S))))).flatMap(workerResultErrorsForOrchestrator);for(const j of C)for(const b of A.values())b.skipped||B(b,j);C.length>0&&d(),v.runtimeStats=r.getStats(),d()}finally{await L(x,{name:"testkit.cleanup",kind:"cleanup",summary:"stop managed runtimes and services"},()=>r.cleanupAll())}de(a,s,H)}}catch(s){y=J(s);const u=y.message||$(s);for(const i of A.values())i.skipped||B(i,u);d()}o=y===null?0:r.isStopRequested()?130:1,E=Date.now(),R=e.map(s=>_(A.get(s.name),h,E));const n=resolveRunGateFailure(R,t.allowEmpty===!0);await L(x,{name:"testkit.collect",kind:"collection",summary:"close and collect run logs"},()=>F.closeAll());const c=await be(U(R,E,r.isStopRequested()?"interrupted":y===null&&n===null?null:"failed"));return y!==null&&(o=1),R.some(s=>s.failed||s.infraFailed)&&(o=1),n!==null&&(o=1),c.shouldFailArchivePublication&&(o=1),c.shouldFailArchiveCleanup&&(o=1),(c.runArtifact.run.status==="interrupted"||r.isStopRequested()||r.committedFinalization?.artifactStatus==="interrupted")&&(o=Math.max(o,130)),{runArtifact:c.runArtifact,results:R,exitCode:o,...y===null?{}:{failure:y}}}catch(n){const c=J(n),s=c.message||$(n);for(const i of A.values())i.skipped||B(i,s);d(),r.beginFinalization(),o=r.isStopRequested()||r.committedFinalization?.artifactStatus==="interrupted"?130:1,E=Date.now(),R=e.map(i=>_(A.get(i.name),h,E)),await X(F);let u=M.artifacts;if(u===null)try{u=await qe(U(R,E,r.isStopRequested()?"interrupted":"failed"),r,M,c)}catch{if(M.artifacts===null)throw n;u=M.artifacts}return(u.runArtifact.run.status==="interrupted"||r.isStopRequested()||r.committedFinalization?.artifactStatus==="interrupted")&&(o=Math.max(o,130)),{runArtifact:u.runArtifact,results:R,exitCode:o,failure:y??c}}finally{r.dispose(),await X(F)}}async function qe(e,l,g,t){return l.finish("failed",p=>{const k=p.artifactStatus==="interrupted"?p:{artifactStatus:"failed",interruptReason:null},a=e.declaredEnvironmentKeys??[],m=ze({productDir:e.productDir,runId:e.runId,results:e.results,startedAt:e.startedAt,finishedAt:e.finishedAt,execution:e.execution,workerCount:e.workerCount,runtimeInstanceCount:e.runtimeInstanceCount,runtimeStats:e.runtimeStats,typeValues:e.selection.typeValues,suiteSelectors:e.selection.suiteSelectors,fileNames:e.selection.fileNames,serviceFilter:e.selection.serviceFilter,planning:e.selection.planning??null,archiveConfig:e.archiveConfig,declaredEnvironmentKeys:a,metadata:e.metadata,summarizeDbBackend:me,serviceLogs:e.logRegistry.listServiceLogs(),setupLogs:e.logRegistry.listSetupLogs(),setupOperations:e.setupRegistry.listOperations(),operationTimings:e.operationTimingRegistry?.listOperations()??[],runInterruptReason:k.interruptReason,runStatus:k.artifactStatus});m.finalizationFailure={...t};const w={runArtifact:pe(e.productDir,m,{archiveConfig:e.archiveConfig,declaredEnvironmentKeys:a})};return g.artifacts=w,w},"recovery")}async function X(e){try{await e.closeAll()}catch{}}export function workerResultErrorsForOrchestrator(e){return e.status==="rejected"?[$(e.reason)]:[...new Set(e.value.unpersistedErrors)]}export function resolveRunGateFailure(e,l=!1){return e.some(t=>t.failed)?"test failure":e.some(t=>t.infraFailed)?"test infrastructure failure":e.some(t=>t.notRunFileCount>0)?"one or more required test files did not run":e.some(t=>t.skippedFileCount>0)?"one or more selected test files were skipped":e.reduce((t,p)=>t+p.completedFileCount,0)===0&&!l?"no runnable test files executed":null}export function resolveRunExecutionConfig(e,l){return Fe({cli:{fileTimeoutSeconds:l.fileTimeoutSeconds,taskConcurrency:l.taskConcurrency},repo:e?{fileTimeoutSeconds:e.testkit.execution.fileTimeoutSeconds,taskConcurrency:e.testkit.execution.taskConcurrency}:void 0})}export function collectServicePlans(e,l,g,t,p,k,a=null){return e.map(m=>{const I=ae(m,g,t,p.fileNames||[],p);if(I.length===0)return a?.serviceSkipped?.(m,`no matching files (types=${g.join(",")||"all"} suites=${t.map(f=>f.raw).join(",")||"all"} files=${(p.fileNames||[]).join(",")||"all"})`),{config:m,execution:k,skipped:!0,suites:[],runtimeConfigs:[],runtimeNames:[],runtimeKey:null};for(const f of I)for(const z of f.skippedFiles)a?.plannedSkip?.({serviceName:m.name,testType:f.testType,engineId:f.engineId,profileId:f.profileId,file:z.path,reason:z.reason});const w=re(m,l),h=w.map(f=>f.name).sort();return{config:m,execution:k,skipped:!1,suites:I,runtimeConfigs:w,runtimeNames:h,runtimeKey:h.join("|")}})}
1
+ import{resolveRuntimeClosure as he}from"../../config/loader/dependencies.js";import{claimNextTask as ve,collectSuites as ye}from"./planning.js";import{buildRunPlanningMetadata as ke,buildScheduledQueue as Re}from"./scheduler/index.js";import{requireCompatibleSelection as Se}from"./task-batches.js";import{addTrackerError as we,buildServiceTrackers as Ce,finalizeServiceResult as ie,recordGraphError as Fe,recordTaskOutcome as Ee}from"./results.js";import{loadTimings as Ae,saveTimings as Te,writeRunArtifact as be}from"../../evidence/index.js";import{createRunEnvironmentRecord as Ke}from"../../evidence/environment-record.js";import{createRunLogRegistry as xe}from"../../evidence/logs.js";import{createOperationTimingRegistry as Me,timeOperation as B}from"../../evidence/operation-timings.js";import{createRunReporterFromListener as qe}from"./run-events.js";import{createCallerRedaction as Ie}from"./caller-redaction.js";import{createSetupOperationRegistry as ze}from"../../evidence/setup-progress.js";import{createLocalRunEnvironment as Oe}from"../../environment/run-environment.js";import{createConfigDrivenEnvironments as Pe,planConfiguredCapacity as Ne}from"../environments/config-driven.js";import{declaresProvisioning as je,declaresValues as ae,holdBeforeRelease as De,routeEnvironments as Le}from"../environments/routing.js";import{createStaticValueEnvironments as Ge}from"../environments/static-values.js";import{findRuntimeNodeSetupFile as Ve}from"./setup/runtime-node-setup.js";import{createSuppliedEnvironments as Be}from"../environments/supplied.js";import{environmentTaskIdentity as $e}from"./environment.js";import{createTaskLeases as We}from"./task-leases.js";import{createTaskLocks as Ue}from"./scheduler/locks.js";import{readPackageMetadata as He,safeHostname as Qe,safeUsername as _e}from"../../process/host/metadata.js";import{collectGitMetadata as Je}from"../../repo/metadata.js";import{resolveExecutionConfig as Xe}from"../../config/loader/decode-execution.js";import{resolveTaskPolicy as Ye}from"../../config/loader/task-policy.js";import"../../environment/run-environment.js";import{createEngineManager as Ze}from"../../engines/factory.js";import{createWorker as et,runWorker as tt}from"./worker-loop.js";import{ensureRequestedFilesMatch as rt}from"./run-guards.js";import{createLiveSnapshotWriter as nt}from"./live-run.js";import{finalizeRunArtifacts as it}from"./run-finalization.js";import{buildRunArtifact as at}from"../../evidence/reporting.js";import{createOperationReporterBridge as ot}from"./operation-progress.js";import{formatError as $,serializeError as oe}from"../../kernel/error-serialization.js";export async function runAll(e,n,a,r,c=[]){const h=r.fileNames||[];rt(e,n,a,h);const{productDir:s}=r,p=Oe(s),R=Ze(s),v=new Map(c.map(i=>[i.name,i])),t=Date.now(),C=e[0]?.artifacts??null,q=[...new Set(e.flatMap(i=>i.uses.flatMap(m=>Object.keys(v.get(m)?.testkit.serviceEnv??{}))))].sort(),f={git:await Je(s),host:{hostname:Qe(),username:_e()},testkitVersion:He().version},S=e[0]?.redact??[],b=Ie(process.env,S),Y=r.onEvent,y=Y?qe(i=>{Y(b.redact(i))},{debug:r.debug}):null,K=xe(s),j={workerCount:0},I=resolveRunExecutionConfig(e[0],r),D=collectServicePlans(e,v,n,a,r,I,y);y?.setServicePlans?.(D);const z=Ce(D,t),L=i=>{for(const m of z.values())m.skipped||we(m,i);y?.runError?.(i)},ce=a.map(i=>({...i})),W={typeValues:n,suiteSelectors:ce,fileNames:h,groupFilter:r.serviceFilter||null,planning:null};let k=()=>{};const ue=ot(y),T=Me({onChange:i=>{ue(i),k()}}),Z=ze({logRegistry:K,onChange:()=>{k()}}),d=Ke({logRegistry:K,redactKeys:S,setupRegistry:Z,onPublishedChange:()=>{k()}});b.useSourceTargets(()=>d.redactionTargets()),d.recordGroups(D.map(i=>({dbBackend:i.dbBackend,name:i.config.name})));const U=D.filter(i=>!i.skipped),H=r.environments?.supplied??{},{plans:O,provisionedGraphKeys:G,staticGraphKeys:Q}=assignRuntimeGraphs(U,new Set(Object.keys(H)));let g;const o=await p.start({keepAlive:!0,localInfrastructure:G.size>0,redactKeys:S,redactionTargets:()=>d.redactionTargets(),resetResultsBeforePublish:!0});k=nt({productDir:s,runId:o.runId,configs:e,trackers:z,startedAt:t,execution:I,workerState:j,selection:W,archiveConfig:C,declaredEnvironmentKeys:q,metadata:f,environmentRecord:d,operationTimingRegistry:T,reporter:y});const P={artifacts:null},le=async(i,m)=>(o.beginFinalization(),await o.finish(i,A=>{const w=m(A);return P.artifacts={runArtifact:w.runArtifact},w},"normal"));let F,x;const ee=(i,m,u)=>({productDir:s,runId:o.runId,results:i,startedAt:t,finishedAt:m,execution:I,workerCount:j.workerCount,selection:W,archiveConfig:C,declaredEnvironmentKeys:q,metadata:f,environmentRecord:d,operationTimingRegistry:T,reporter:y,runInterruptReason:o.getInterruptReason(),runStatus:u,publishRunFinalization:le});k();let E=null;try{try{if(U.length>0){const u=Ae(s),{capacity:A,queue:w}=await B(T,{name:"testkit.plan",kind:"planning",summary:"plan test execution",scope:{serviceCount:U.length}},()=>({capacity:Ne(O.filter(l=>G.has(l.runtimeKey))),queue:Re(O.map(l=>prepareSchedulerPlan(l,Object.hasOwn(H,l.config.name)?()=>!1:M=>Ve(s,M)!==null)),{timings:u})}));Se(w,{provisioned:G,static:Q}),W.planning=ke(w),d.recordCapacity(A),y?.setTotalFileCount?.(w.length),j.workerCount=Math.max(1,Math.min(I.taskConcurrency,w.length));const te=Array.from({length:j.workerCount},(l,M)=>et(M+1,s));A.graphs.length>0&&o.provision(A.graphs,{reporter:y,environmentRecord:d,logRegistry:K,setupRegistry:Z,operationTimingRegistry:T,skipSchemaSourceVerify:r.skipSchemaSourceVerify});const me=Pe(o,new Map(O.map(l=>[l.config.name,l.config.uses])),s,d),fe=Ge(new Map(O.filter(l=>Q.has(l.runtimeKey)).map(l=>[l.config.name,l.uses])),s,d),de=Be(H,{productDir:s,record:d,signal:o.signal}),re=We(s),pe={recordRunError:L,runId:o.runId,signal:o.signal,isStopRequested:()=>o.isStopRequested(),environments:mt(Le(new Map(O.map(({runtimeKey:l})=>[l,G.has(l)?me:Q.has(l)?fe:de]))),r.environments?.hold),leases:ut(re,d),locks:Ue(),request:ft(s,e,I,r.vitest)},ne=[];try{const M=(await B(T,{name:"testkit.execute",kind:"execution",summary:"execute local worker queue",scope:{workerCount:te.length,taskCount:w.length}},async()=>Promise.allSettled(te.map(_=>tt(_,w,pe,R,z,ne,ve,(J,V,N,X)=>{Ee(J,V,N,X),N.environmentValuesMissing!==void 0&&d.recordMissingValues($e(V),N.environmentValuesMissing),k()},(J,V,N,X,ge)=>{Fe(J,V,N,X,ge),k()},y))))).flatMap(workerResultErrorsForOrchestrator);for(const _ of M)L(_);M.length>0&&k(),d.recordRuntimeStats(o.getStats())}finally{A.graphs.length>0&&await B(T,{name:"testkit.cleanup",kind:"cleanup",summary:"stop managed runtimes and services"},()=>lt(d,()=>o.cleanupAll())),re.close()}Te(s,u,ne)}}catch(u){E=oe(u),L(E.message||$(u)),k()}g=E===null?0:o.isStopRequested()?130:1,x=Date.now(),F=e.map(u=>ie(z.get(u.name),t,x));const i=resolveRunGateFailure(F,r.allowEmpty===!0);await B(T,{name:"testkit.collect",kind:"collection",summary:"close and collect run logs"},()=>K.closeAll());const m=await it(ee(F,x,o.isStopRequested()?"interrupted":E===null&&i===null?null:"failed"));return E!==null&&(g=1),F.some(u=>u.failed||u.infraFailed)&&(g=1),i!==null&&(g=1),m.shouldFailArchivePublication&&(g=1),m.shouldFailArchiveCleanup&&(g=1),(m.runArtifact.run.status==="interrupted"||o.isStopRequested()||o.committedFinalization?.artifactStatus==="interrupted")&&(g=Math.max(g,130)),{runArtifact:m.runArtifact,results:b.redact(F),exitCode:g,...E===null?{}:{failure:b.redact(E)}}}catch(i){const m=oe(i);L(m.message||$(i)),k(),o.beginFinalization(),g=o.isStopRequested()||o.committedFinalization?.artifactStatus==="interrupted"?130:1,x=Date.now(),F=e.map(A=>ie(z.get(A.name),t,x)),await se(K);let u=P.artifacts;if(u===null)try{u=await st(ee(F,x,o.isStopRequested()?"interrupted":"failed"),o,P,m)}catch{if(P.artifacts===null)throw i;u=P.artifacts}return(u.runArtifact.run.status==="interrupted"||o.isStopRequested()||o.committedFinalization?.artifactStatus==="interrupted")&&(g=Math.max(g,130)),{runArtifact:u.runArtifact,results:b.redact(F),exitCode:g,failure:b.redact(E??m)}}finally{o.dispose(),await se(K),ct(d,r.environments?.observeRecord,y)}}async function st(e,n,a,r){return n.finish("failed",c=>{const h=c.artifactStatus==="interrupted"?c:{artifactStatus:"failed",interruptReason:null},s=e.declaredEnvironmentKeys??[],p=at({productDir:e.productDir,runId:e.runId,results:e.results,startedAt:e.startedAt,finishedAt:e.finishedAt,execution:e.execution,workerCount:e.workerCount,typeValues:e.selection.typeValues,suiteSelectors:e.selection.suiteSelectors,fileNames:e.selection.fileNames,groupFilter:e.selection.groupFilter,planning:e.selection.planning??null,archiveConfig:e.archiveConfig,declaredEnvironmentKeys:s,metadata:e.metadata,environment:e.environmentRecord.snapshot(),operationTimings:e.operationTimingRegistry?.listOperations()??[],runInterruptReason:h.interruptReason,runStatus:h.artifactStatus});p.finalizationFailure={...r};const v={runArtifact:be(e.productDir,p,{archiveConfig:e.archiveConfig,declaredEnvironmentKeys:s,redactKeys:e.environmentRecord.redactKeys,redactionTargets:e.environmentRecord.redactionTargets()})};return a.artifacts=v,v},"recovery")}function ct(e,n,a){if(n!==void 0)try{n(e.snapshot())}catch(r){try{a?.warning?.(`Environment record observer failed: ${$(r)}`)}catch{}}}function ut(e,n){return{...e,remove(a){const r=n.releaseFor(a.id);try{e.remove(a)}catch(c){throw r?.releaseFailed(c),c}r?.released()}}}async function lt(e,n){try{await n()}catch(a){throw e.recordCleanup(a),a}e.recordCleanup(null)}async function se(e){try{await e.closeAll()}catch{}}export function workerResultErrorsForOrchestrator(e){return e.status==="rejected"?[$(e.reason)]:[...new Set(e.value.unpersistedErrors)]}export function resolveRunGateFailure(e,n=!1){return e.some(r=>r.failed)?"test failure":e.some(r=>r.infraFailed)?"test infrastructure failure":e.some(r=>r.notRunFileCount>0)?"one or more required test files did not run":e.some(r=>r.skippedFileCount>0)?"one or more selected test files were skipped":e.reduce((r,c)=>r+c.completedFileCount,0)===0&&!n?"no runnable test files executed":null}function mt(e,n){return n===void 0?e:De(e,n)}function ft(e,n,a,r){return{vitest:r,productDir:e,fileTimeoutSeconds:a.fileTimeoutSeconds,ownerRoots:Object.fromEntries(n.map(c=>[c.name,c.roots]))}}export function resolveRunExecutionConfig(e,n){return Xe({cli:{fileTimeoutSeconds:n.fileTimeoutSeconds,taskConcurrency:n.taskConcurrency},repo:e?{fileTimeoutSeconds:e.testkit.execution.fileTimeoutSeconds,taskConcurrency:e.testkit.execution.taskConcurrency}:void 0})}export function assignRuntimeGraphs(e,n){const a=e.filter(t=>t.suites.some(C=>C.files.length>0)),r=new Set(a.filter(t=>!n.has(t.config.name)&&je(t.runtimeConfigs))),c=new Set([...r].map(t=>t.runtimeKey)),h=t=>!r.has(t)&&!n.has(t.config.name)&&ae(t.runtimeConfigs),s=new Set(a.filter(t=>h(t)&&t.runtimeKey!=="").map(t=>t.runtimeKey)),p=new Set(a.map(t=>t.runtimeKey)),R=t=>t.runtimeKey!==""&&!c.has(t.runtimeKey)&&(h(t)||!s.has(t.runtimeKey))?t.runtimeKey:p.has(t.config.name)?`group:${t.config.name}`:t.config.name,v=a.map(t=>r.has(t)?t:{...t,runtimeKey:R(t)});return{plans:v,provisionedGraphKeys:c,staticGraphKeys:new Set(v.filter(t=>!c.has(t.runtimeKey)&&!n.has(t.config.name)&&ae(t.runtimeConfigs)).map(t=>t.runtimeKey))}}export function prepareSchedulerPlan(e,n){return{graphKey:e.runtimeKey,owner:e.config.name,suites:e.suites.map(a=>({...a,tasks:a.files.map(r=>({file:r,hasSetup:n(r),...Ye(e.config.testkit,a,r)}))}))}}export function collectServicePlans(e,n,a,r,c,h,s=null){return e.map(p=>{const R=p.uses.map(f=>{const S=n.get(f);if(S===void 0)throw new Error(`Group "${p.name}" uses unknown service "${f}"`);return S}),v=R.some(f=>f.testkit.database!==void 0)?"local":null,t=ye(p,a,r,c.fileNames||[],c);if(t.length===0)return s?.serviceSkipped?.(p,`no matching files (types=${a.join(",")||"all"} suites=${r.map(f=>f.raw).join(",")||"all"} files=${(c.fileNames||[]).join(",")||"all"})`),{config:p,dbBackend:v,execution:h,skipped:!0,suites:[],runtimeConfigs:[],runtimeNames:[],runtimeKey:null,uses:R};for(const f of t)for(const S of f.skippedFiles)s?.plannedSkip?.({serviceName:p.name,testType:f.testType,engineId:f.engineId,profileId:f.profileId,file:S.path,reason:S.reason});const C=he(R,n),q=C.map(f=>f.name).sort();return{config:p,dbBackend:v,execution:h,skipped:!1,suites:t,runtimeConfigs:C,runtimeNames:q,runtimeKey:q.join("|"),uses:R}})}
@@ -1 +1 @@
1
- import{runtimePlanning as x}from"../../environment/runtime-planning.js";import{matchesSelectedTypes as y,matchesSuiteSelectors as k}from"../../domain/suite-selection.js";import{isPublicTestType as w}from"../../domain/identifiers.js";import{resolveEngineProfile as R}from"../../engines/catalog.js";const S=["ui","e2e","int","contract","data","dal","load"];export function taskNeedsLocalRuntime(e){return g(e).capabilities.applicationRuntime==="required"}export function collectSuites(e,t,s,o=[],c={}){const n=new Set(o.map(h)),u=[];let d=0;for(const r of orderedTypes(Object.keys(e.suites)))for(const i of e.suites[r]||[]){if(i.testType!==r)throw new Error(`Suite ${e.name}/${r}:${i.name} declares conflicting test type ${i.testType}`);const p=g(i),l=n.size===0?i.files:i.files.filter(f=>n.has(h(f)));if(!y(r,t)||!k(r,i.name,s)||l.length===0)continue;const{files:a,skippedFiles:m}=P(e,r,i.name,l,c);u.push({...i,files:a,skippedFiles:m,orderIndex:d,sortKey:`${r}:${i.name}`,weight:i.testkit?.weight||(p.capabilities.taskBatching==="compatible"?Math.max(2,Math.max(1,a.length)):Math.max(1,a.length)),totalFileCount:l.length}),d+=1}return u}export function orderedTypes(e){const t=e.filter(o=>!w(o));if(t.length>0)throw new Error(`Unknown test types in suite collection: ${t.join(", ")}`);const s=[];for(const o of S)e.includes(o)&&s.push(o);return s}export function claimNextTask(e,t,s=()=>!0){if(e.length===0)return null;const o=[],c=[];for(let n=0;n<e.length;n+=1)t&&e[n].graphKey===t?o.push(n):c.push(n);for(const n of[...o,...c])if(s(e[n]))return e.splice(n,1)[0];return null}function P(e,t,s,o,c={}){if(c.ignoreSkipRules)return{files:o,skippedFiles:[]};const n=e.testkit.skip,u=e.testkit.fileMetadataByPath||null;if(!n&&!u)return{files:o,skippedFiles:[]};const r=(n?.suites||[]).filter(l=>k(t,s,[l.selector]))[0]?.reason||null,i=[],p=[];for(const l of o){const a=h(l),f=(e.testkit.fileMetadataByPath?.get(a)||null)?.skipReason||n?.fileReasonByPath?.get(a)||r;if(f){p.push({path:a,reason:f});continue}i.push(l)}return{files:i,skippedFiles:p}}function g(e){const t=R(e.testType,e.engineId);if(t.id!==e.profileId)throw new Error(`Execution identity ${e.testType}/${e.engineId}/${e.profileId} conflicts with catalog profile ${t.id}`);return t}function h(e){return String(e).split("\\").join("/")}export function buildRuntimeGraphs(e){const t=e.filter(s=>!s.skipped);for(const s of t)s.assignedGraphKey=s.runtimeKey;return x.buildRuntimeGraphs(t)}
1
+ import{matchesSelectedTypes as x,matchesSuiteSelectors as d}from"../../domain/suite-selection.js";import{PUBLIC_TEST_TYPES as m}from"../../domain/identifiers.js";import{resolveExecutionProfile as S}from"../../engines/catalog.js";export function collectSuites(e,l,a,o=[],r={}){const t=new Set(o.map(h)),f=[];let c=0;for(const n of[...e.suites].sort((i,s)=>k(i.testType)-k(s.testType))){const i=S(n),s=t.size===0?n.files:n.files.filter(g=>t.has(h(g)));if(!x(n.testType,l)||!d(n.testType,n.name,a)||s.length===0)continue;const{files:p,skippedFiles:u}=y(e,n.testType,n.name,s,r);f.push({...n,files:p,skippedFiles:u,orderIndex:c,weight:n.testkit?.weight||(i.taskBatching==="compatible"?Math.max(2,Math.max(1,p.length)):Math.max(1,p.length)),totalFileCount:s.length}),c+=1}return f}function k(e){return e===void 0?m.length:m.indexOf(e)}export function claimNextTask(e,l,a=()=>!0){if(e.length===0)return null;const o=[],r=[];for(let t=0;t<e.length;t+=1)l&&e[t].graphKey===l?o.push(t):r.push(t);for(const t of[...o,...r])if(a(e[t]))return e.splice(t,1)[0];return null}function y(e,l,a,o,r={}){if(r.ignoreSkipRules)return{files:o,skippedFiles:[]};const t=e.testkit.skip,f=(t?.suites||[]).find(i=>d(l,a,[i.selector]))?.reason||null,c=[],n=[];for(const i of o){const s=h(i),u=(e.testkit.fileMetadataByPath?.get(s)||null)?.skipReason||t?.fileReasonByPath?.get(s)||f;if(u){n.push({path:s,reason:u});continue}c.push(i)}return{files:c,skippedFiles:n}}function h(e){return String(e).split("\\").join("/")}
@@ -1 +1 @@
1
- import{resolveProductDir as u}from"../../process/files/product-dir.js";import{loadManagedConfigs as d}from"../../config/loader/managed-configs.js";import{parseFileTimeoutOption as S}from"../../domain/file-timeout.js";import{parseSuiteOption as y,parseTypeOption as k}from"../../domain/suite-selection.js";import{resolveRequestedFiles as v}from"../file-selection.js";import{parseTaskConcurrencyOptions as w}from"../../config/loader/decode-execution.js";export async function buildRunRequest(e,c=null,l=process.cwd(),t=process.cwd()){const n=w(e.taskConcurrency,e.workers),a=e.fileTimeoutSeconds==null?null:S(e.fileTimeoutSeconds),r=k(e.type,c),s=y(e.suite),m=e.file??[],o=u(l,e.dir),i=v(m,o,t),{allConfigs:f,configs:p}=await d({dir:o,service:e.service,testSelection:{service:e.service,fileNames:i,typeValues:r,suiteSelectors:s}});return{allConfigs:f,configs:p,productDir:o,typeValues:r,suiteSelectors:s,runOptions:{allowEmpty:e.allowEmpty,fileNames:i,taskConcurrency:n,fileTimeoutSeconds:a,serviceFilter:e.service||null,ignoreSkipRules:e.ignoreSkipRules,skipSchemaSourceVerify:e.skipSchemaSourceVerify}}}
1
+ import{resolveProductDir as g}from"../../process/files/product-dir.js";import{loadRunConfigs as k}from"../../config/loader/managed-configs.js";import{parseFileTimeoutOption as F}from"../../domain/file-timeout.js";import{parseSuiteOption as w,parseTypeOption as O}from"../../domain/suite-selection.js";import{resolveRequestedFiles as R}from"../file-selection.js";import{parseTaskConcurrencyOptions as T}from"../../config/loader/decode-execution.js";import{readEnvironmentFile as h}from"../environments/environment-file.js";import{hasSuppliedInput as E,projectSuppliedEnvironment as V,resolveSuppliedInput as j,suppliedBindings as C}from"../environments/supplied-input.js";import{resolveVitestSelection as I}from"../../engines/catalog.js";export async function buildRunRequest(e,l=null,o=process.cwd(),n=process.cwd(),p=process.env){const a=T(e.taskConcurrency,e.workers),f=e.fileTimeoutSeconds==null?null:F(e.fileTimeoutSeconds),c=O(e.type,l),u=w(e.suite),S=e.file??[],r=g(o,e.dir),m=R(S,r,n),s=e.supplied??{},i=E(s)?j(s,s.environmentFile===void 0?null:h(s.environmentFile,n),p):null,t=I(e.vitest??{},r,p),{groups:d,ownershipNotice:v,services:y}=await k({dir:r,group:e.group,testSelection:{group:e.group,fileNames:m,typeValues:c,suiteSelectors:u},vitest:i===null?t:{...t,host:{...t.host,...C(i)}}});return{groups:d,ownershipNotice:v,services:y,productDir:r,supplied:i===null?null:N(i,d),typeValues:c,suiteSelectors:u,runOptions:{vitest:t,allowEmpty:e.allowEmpty,fileNames:m,taskConcurrency:a,fileTimeoutSeconds:f,serviceFilter:e.group||null,ignoreSkipRules:e.ignoreSkipRules,skipSchemaSourceVerify:e.skipSchemaSourceVerify}}}function N(e,l){return Object.fromEntries(l.map(o=>[o.name,V(e,o.uses)]))}