@gfdelarue/testkit 0.4.5 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (787) hide show
  1. package/README.md +724 -495
  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/ci-report.js +2 -2
  5. package/dist/app/bugs/ci-summary.js +3 -3
  6. package/dist/app/bugs/draft.js +3 -3
  7. package/dist/app/bugs/file.js +1 -1
  8. package/dist/app/bugs/gate.js +1 -1
  9. package/dist/app/bugs/guide.js +3 -3
  10. package/dist/app/bugs/issue.js +4 -4
  11. package/dist/app/bugs/known-failures.js +1 -1
  12. package/dist/app/bugs/record.js +1 -1
  13. package/dist/app/bugs/run-reading.js +1 -1
  14. package/dist/app/bugs/supplied-reproduce.js +1 -0
  15. package/dist/app/campaigns/campaign.js +1 -1
  16. package/dist/app/campaigns/index.js +2 -2
  17. package/dist/app/cleanup/index.js +1 -1
  18. package/dist/app/db-schema/prepare.js +1 -1
  19. package/dist/app/destroy/index.js +1 -1
  20. package/dist/app/discover/index.js +2 -2
  21. package/dist/app/doctor/index.js +1 -1
  22. package/dist/app/environments/config-driven.js +1 -1
  23. package/dist/app/environments/environment-file.js +1 -0
  24. package/dist/app/environments/file-setup.js +1 -0
  25. package/dist/app/environments/routing.js +1 -1
  26. package/dist/app/environments/static-values.js +1 -0
  27. package/dist/app/environments/supplied-input.js +1 -0
  28. package/dist/app/environments/supplied.js +1 -1
  29. package/dist/app/environments/task-databases.js +2 -0
  30. package/dist/app/inspect/artifacts.js +1 -1
  31. package/dist/app/inspect/index.js +1 -1
  32. package/dist/app/lint/index.js +1 -1
  33. package/dist/app/lint/native.js +1 -1
  34. package/dist/app/lint/options.js +1 -1
  35. package/dist/app/lint/rules/engine-imports.js +1 -1
  36. package/dist/app/lint/rules/syntax.js +1 -1
  37. package/dist/app/lint/rules/unit.js +1 -1
  38. package/dist/app/reports/prepare.js +1 -1
  39. package/dist/app/run/caller-redaction.js +1 -0
  40. package/dist/app/run/engine-execution-failures.js +1 -1
  41. package/dist/app/run/engine-execution-reporting.js +1 -1
  42. package/dist/app/run/engine-execution.js +1 -1
  43. package/dist/app/run/engine-orchestration.js +1 -1
  44. package/dist/app/run/environment.js +1 -1
  45. package/dist/app/run/failure-details.js +1 -1
  46. package/dist/app/run/live-run.js +1 -1
  47. package/dist/app/run/orchestrator.js +1 -1
  48. package/dist/app/run/planning.js +1 -1
  49. package/dist/app/run/request.js +1 -1
  50. package/dist/app/run/results.js +1 -1
  51. package/dist/app/run/run-events.js +1 -1
  52. package/dist/app/run/run-finalization.js +1 -1
  53. package/dist/app/run/scheduler/estimates.js +1 -1
  54. package/dist/app/run/scheduler/identity.js +1 -1
  55. package/dist/app/run/scheduler/index.js +1 -1
  56. package/dist/app/run/setup/runtime-node-setup-protocol.js +1 -1
  57. package/dist/app/run/setup/runtime-node-setup-worker.js +1 -1
  58. package/dist/app/run/setup/runtime-node-setup.js +2 -2
  59. package/dist/app/run/task-batches.js +1 -1
  60. package/dist/app/run/worker-loop.js +1 -1
  61. package/dist/app/status/model.js +1 -1
  62. package/dist/app/status/runs.js +1 -1
  63. package/dist/app/typecheck/index.js +4 -4
  64. package/dist/cli/command-catalog.js +1 -1
  65. package/dist/cli/command-flags.js +1 -1
  66. package/dist/cli/commands/artifacts.js +2 -2
  67. package/dist/cli/commands/bug/file.js +2 -2
  68. package/dist/cli/commands/bug/record.js +2 -2
  69. package/dist/cli/commands/discover.js +1 -1
  70. package/dist/cli/commands/guard/unsafe-entrypoint.js +1 -1
  71. package/dist/cli/commands/run.js +2 -2
  72. package/dist/cli/commands/typecheck.js +1 -1
  73. package/dist/cli/commands/workspace.js +1 -1
  74. package/dist/cli/framework/errors.js +1 -1
  75. package/dist/cli/framework/execute.js +7 -6
  76. package/dist/cli/framework/parser.js +1 -1
  77. package/dist/cli/operations/run/operation.js +2 -2
  78. package/dist/cli/renderers/bug/text.js +1 -1
  79. package/dist/cli/renderers/discover/report.js +1 -1
  80. package/dist/cli/renderers/run/events.js +2 -2
  81. package/dist/cli/renderers/run/formatting.js +1 -1
  82. package/dist/cli/renderers/run/status.js +1 -1
  83. package/dist/cli/renderers/run/text-reporter.js +24 -22
  84. package/dist/cli/terminal/colors.js +1 -1
  85. package/dist/cli/terminal/layout.js +2 -2
  86. package/dist/config/authoring/database-fixture-discovery.js +1 -0
  87. package/dist/config/authoring/http-methods.js +1 -1
  88. package/dist/config/authoring/index.js +1 -1
  89. package/dist/config/loader/config-loader.js +1 -1
  90. package/dist/config/loader/decode-discovery.js +1 -1
  91. package/dist/config/loader/decode-execution.js +1 -1
  92. package/dist/config/loader/dependencies.js +1 -1
  93. package/dist/config/loader/discover-tests.js +1 -1
  94. package/dist/config/loader/discovery-summary.js +1 -1
  95. package/dist/config/loader/discovery.js +2 -2
  96. package/dist/config/loader/env.js +1 -1
  97. package/dist/config/loader/file-metadata.js +1 -1
  98. package/dist/config/loader/groups.js +2 -1
  99. package/dist/config/loader/index.js +1 -1
  100. package/dist/config/loader/load.js +1 -1
  101. package/dist/config/loader/managed-configs.js +1 -1
  102. package/dist/config/loader/owned-discovery.js +1 -0
  103. package/dist/config/loader/path-policy.js +1 -1
  104. package/dist/config/loader/runtime-isolation.js +1 -1
  105. package/dist/config/loader/runtime.js +1 -1
  106. package/dist/config/loader/skip-config.js +1 -1
  107. package/dist/config/loader/task-policy.js +1 -0
  108. package/dist/config/loader/test-selection.js +1 -1
  109. package/dist/config/loader/validation.js +1 -1
  110. package/dist/database/admin.js +2 -2
  111. package/dist/database/bindings.js +1 -0
  112. package/dist/database/cleanup.js +1 -1
  113. package/dist/database/configured-steps.js +1 -1
  114. package/dist/database/docker-metadata.js +3 -3
  115. package/dist/database/docker.js +3 -3
  116. package/dist/database/index.js +1 -1
  117. package/dist/database/local-postgres.js +1 -1
  118. package/dist/database/naming.js +1 -1
  119. package/dist/database/postgres/connection-check.js +1 -0
  120. package/dist/database/postgres/protocol.js +2 -0
  121. package/dist/database/schema-operations.js +1 -1
  122. package/dist/database/schema-source.js +3 -3
  123. package/dist/database/source-schema-env.js +1 -0
  124. package/dist/database/state-files.js +1 -1
  125. package/dist/database/state.js +1 -1
  126. package/dist/database/steps.js +3 -3
  127. package/dist/domain/file-timeout.js +1 -1
  128. package/dist/domain/identifiers.js +1 -1
  129. package/dist/domain/retired-test-types.js +1 -0
  130. package/dist/domain/runtime-isolation-contract.js +1 -1
  131. package/dist/domain/suite-selection.js +1 -1
  132. package/dist/domain/test-types.js +1 -1
  133. package/dist/engines/adapters/evidence-files.js +1 -1
  134. package/dist/engines/adapters/execution.js +1 -1
  135. package/dist/engines/adapters/json-bounds.js +2 -0
  136. package/dist/engines/adapters/native-report.js +1 -1
  137. package/dist/engines/api/execution.js +1 -1
  138. package/dist/engines/api/index.js +1 -1
  139. package/dist/engines/api/runtime-artifact.js +1 -1
  140. package/dist/engines/catalog.js +1 -1
  141. package/dist/engines/contracts/environment-values.js +1 -0
  142. package/dist/engines/definitions.js +1 -1
  143. package/dist/engines/environment/handles.js +1 -0
  144. package/dist/engines/environment/index.js +1 -0
  145. package/dist/engines/factory.js +1 -1
  146. package/dist/engines/installations/node-vitest.js +1 -1
  147. package/dist/engines/installations/package-resolution.js +1 -1
  148. package/dist/engines/installations/playwright.js +1 -1
  149. package/dist/engines/managed-module-resolution.js +8 -4
  150. package/dist/engines/manager.js +1 -1
  151. package/dist/engines/node-vitest/adapter/adapter.js +1 -1
  152. package/dist/engines/node-vitest/adapter/driver.js +2 -0
  153. package/dist/engines/node-vitest/adapter/evidence.js +2 -2
  154. package/dist/engines/node-vitest/adapter/failure-details.js +4 -2
  155. package/dist/engines/node-vitest/adapter/reporter.js +1 -1
  156. package/dist/engines/node-vitest/adapter/workspace.js +17 -195
  157. package/dist/engines/node-vitest/inventory/index.js +2 -0
  158. package/dist/engines/node-vitest/inventory/list-files.js +3 -0
  159. package/dist/engines/node-vitest/runtime/data/index.js +1 -1
  160. package/dist/engines/node-vitest/runtime/data/report.js +5 -6
  161. package/dist/engines/node-vitest/runtime/data/scenario.js +2 -2
  162. package/dist/engines/node-vitest/runtime/runtime-input.js +1 -1
  163. package/dist/engines/node-vitest/selection.js +1 -0
  164. package/dist/engines/playwright/adapter/adapter.js +1 -1
  165. package/dist/engines/playwright/adapter/config.js +3 -3
  166. package/dist/engines/playwright/adapter/evidence-validation.js +1 -1
  167. package/dist/engines/playwright/adapter/evidence.js +1 -1
  168. package/dist/engines/playwright/adapter/reporter.js +1 -1
  169. package/dist/engines/playwright/runtime/config-file.js +1 -1
  170. package/dist/engines/playwright/runtime/config.js +1 -1
  171. package/dist/engines/playwright/runtime/managed-test.js +1 -0
  172. package/dist/engines/playwright/runtime/runtime-input.js +29 -10
  173. package/dist/engines/runtime-input-file.js +1 -1
  174. package/dist/environment/lifecycle-controller.js +1 -1
  175. package/dist/environment/lifecycle.js +1 -1
  176. package/dist/environment/ready-environment.js +1 -1
  177. package/dist/environment/run-environment.js +1 -1
  178. package/dist/environment/run-stopping.js +1 -1
  179. package/dist/environment/runtime-contexts.js +1 -1
  180. package/dist/environment/runtime-manager.js +1 -1
  181. package/dist/environment/runtime-planning.js +1 -1
  182. package/dist/environment/runtime-preparation.js +1 -1
  183. package/dist/environment/services.js +3 -3
  184. package/dist/environment/template.js +1 -1
  185. package/dist/evidence/artifact-config.js +1 -1
  186. package/dist/evidence/artifacts.js +2 -2
  187. package/dist/evidence/bundles.js +1 -1
  188. package/dist/evidence/environment-record.js +1 -1
  189. package/dist/evidence/index.js +1 -1
  190. package/dist/evidence/maintenance.js +1 -0
  191. package/dist/evidence/read-run.js +1 -1
  192. package/dist/evidence/reading.js +1 -1
  193. package/dist/evidence/redaction.js +4 -0
  194. package/dist/evidence/reporting.js +1 -1
  195. package/dist/evidence/run-model.js +1 -0
  196. package/dist/evidence/storage.js +2 -2
  197. package/dist/evidence/timing.js +1 -1
  198. package/dist/kernel/error-serialization.js +1 -1
  199. package/dist/kernel/known-keys.js +1 -0
  200. package/dist/kernel/redaction-targets.js +1 -0
  201. package/dist/kernel/redaction.js +4 -1
  202. package/dist/kernel/unknown-values.js +1 -1
  203. package/dist/process/environment.js +1 -1
  204. package/dist/process/execa-bundle.json +3 -3
  205. package/dist/process/files/json-file.js +1 -1
  206. package/dist/process/host/platform.js +1 -1
  207. package/dist/process/host-process.js +1 -1
  208. package/dist/process/index.js +1 -1
  209. package/dist/process/locks.js +4 -4
  210. package/dist/process/port-listener.js +2 -0
  211. package/dist/process/process-group.js +1 -1
  212. package/dist/process/process.js +32 -32
  213. package/dist/process/readiness.js +1 -1
  214. package/dist/process/ready-deadline.js +1 -0
  215. package/dist/process/runs/ownership.js +1 -1
  216. package/dist/process/runs/stop.js +1 -1
  217. package/dist/process/service-processes.js +1 -1
  218. package/dist/process/windows-cli-owner.js +3 -3
  219. package/dist/process/windows-native.js +1 -1
  220. package/dist/repo/fingerprint-policy.js +1 -1
  221. package/dist/repo/managed-git.js +1 -1
  222. package/dist/repo/physical-tree.js +1 -1
  223. package/dist/repo/state.js +4 -4
  224. package/dist/steps/build-config.js +1 -1
  225. package/dist/steps/configured-step-testkit-modules.js +1 -1
  226. package/dist/steps/configured-steps.js +1 -1
  227. package/dist/steps/environment.js +1 -1
  228. package/dist/steps/index.js +1 -1
  229. package/dist/toolchains/index.js +3 -3
  230. package/dist/toolchains/semver.js +1 -1
  231. package/dist/toolchains/vitest/index.js +1 -1
  232. package/dist/tracker/redaction.js +1 -2
  233. package/dist/{config/runtime/build-assets.d.ts → types/config-build-assets.d.ts} +5 -3
  234. package/dist/{database/steps.d.ts → types/config-database-steps.d.ts} +7 -7
  235. package/dist/{config/runtime/next-runtime-tsconfig.d.ts → types/config-next-runtime-tsconfig.d.ts} +5 -3
  236. package/dist/types/config.d.ts +422 -0
  237. package/dist/types/drizzle.d.ts +13 -0
  238. package/dist/{config/runtime/env/index.d.ts → types/env.d.ts} +22 -20
  239. package/dist/types/environment.d.ts +46 -0
  240. package/dist/types/index.d.ts +21 -0
  241. package/dist/types/node-vitest-data.d.ts +191 -0
  242. package/dist/types/playwright.d.ts +130 -0
  243. package/dist/types/tooling-vitest.d.ts +13 -0
  244. package/dist/types/workspace.d.ts +633 -0
  245. package/docs/bug-records.md +35 -40
  246. package/docs/engines.md +259 -0
  247. package/docs/release-notes.md +2116 -0
  248. package/docs/test-types.md +37 -85
  249. package/package.json +22 -32
  250. package/testkit-config-schema.md +391 -260
  251. package/dist/app/bugs/areas.d.ts +0 -38
  252. package/dist/app/bugs/assessment.d.ts +0 -9
  253. package/dist/app/bugs/categories.d.ts +0 -41
  254. package/dist/app/bugs/ci-report.d.ts +0 -21
  255. package/dist/app/bugs/ci-summary.d.ts +0 -13
  256. package/dist/app/bugs/draft.d.ts +0 -70
  257. package/dist/app/bugs/facts.d.ts +0 -49
  258. package/dist/app/bugs/file.d.ts +0 -45
  259. package/dist/app/bugs/gate.d.ts +0 -22
  260. package/dist/app/bugs/guide.d.ts +0 -20
  261. package/dist/app/bugs/issue.d.ts +0 -18
  262. package/dist/app/bugs/known-failures.d.ts +0 -49
  263. package/dist/app/bugs/record.d.ts +0 -14
  264. package/dist/app/bugs/run-reading.d.ts +0 -51
  265. package/dist/app/bugs/store.d.ts +0 -34
  266. package/dist/app/campaigns/brief.d.ts +0 -7
  267. package/dist/app/campaigns/campaign.d.ts +0 -14
  268. package/dist/app/campaigns/index.d.ts +0 -38
  269. package/dist/app/campaigns/store.d.ts +0 -5
  270. package/dist/app/campaigns/summary.d.ts +0 -13
  271. package/dist/app/cleanup/index.d.ts +0 -52
  272. package/dist/app/db-schema/prepare.d.ts +0 -11
  273. package/dist/app/db-schema/refresh.d.ts +0 -17
  274. package/dist/app/db-schema/verify.d.ts +0 -11
  275. package/dist/app/destroy/index.d.ts +0 -16
  276. package/dist/app/discover/index.d.ts +0 -8
  277. package/dist/app/doctor/index.d.ts +0 -17
  278. package/dist/app/environments/config-driven.d.ts +0 -5
  279. package/dist/app/environments/routing.d.ts +0 -6
  280. package/dist/app/environments/supplied.d.ts +0 -3
  281. package/dist/app/file-selection.d.ts +0 -1
  282. package/dist/app/inspect/artifacts.d.ts +0 -30
  283. package/dist/app/inspect/index.d.ts +0 -112
  284. package/dist/app/lint/index.d.ts +0 -28
  285. package/dist/app/lint/native.d.ts +0 -10
  286. package/dist/app/lint/options.d.ts +0 -66
  287. package/dist/app/lint/policy.d.ts +0 -21
  288. package/dist/app/lint/rules/data.d.ts +0 -3
  289. package/dist/app/lint/rules/data.js +0 -1
  290. package/dist/app/lint/rules/engine-imports.d.ts +0 -3
  291. package/dist/app/lint/rules/syntax.d.ts +0 -4
  292. package/dist/app/lint/rules/unit.d.ts +0 -3
  293. package/dist/app/lint/shared.d.ts +0 -34
  294. package/dist/app/package-inspection.d.ts +0 -20
  295. package/dist/app/reports/files.d.ts +0 -13
  296. package/dist/app/reports/prepare.d.ts +0 -20
  297. package/dist/app/reports/publish.d.ts +0 -21
  298. package/dist/app/run/endpoint-readiness.d.ts +0 -43
  299. package/dist/app/run/endpoint-readiness.js +0 -1
  300. package/dist/app/run/engine-evidence-persistence.d.ts +0 -39
  301. package/dist/app/run/engine-execution-cleanup.d.ts +0 -8
  302. package/dist/app/run/engine-execution-cleanup.js +0 -1
  303. package/dist/app/run/engine-execution-failures.d.ts +0 -41
  304. package/dist/app/run/engine-execution-observer.d.ts +0 -21
  305. package/dist/app/run/engine-execution-reporting.d.ts +0 -17
  306. package/dist/app/run/engine-execution.d.ts +0 -65
  307. package/dist/app/run/engine-failure-stack.d.ts +0 -1
  308. package/dist/app/run/engine-orchestration.d.ts +0 -30
  309. package/dist/app/run/environment.d.ts +0 -33
  310. package/dist/app/run/failure-details.d.ts +0 -37
  311. package/dist/app/run/live-run.d.ts +0 -29
  312. package/dist/app/run/operation-progress.d.ts +0 -13
  313. package/dist/app/run/orchestrator.d.ts +0 -75
  314. package/dist/app/run/planning-types.d.ts +0 -68
  315. package/dist/app/run/planning.d.ts +0 -14
  316. package/dist/app/run/request.d.ts +0 -30
  317. package/dist/app/run/results.d.ts +0 -161
  318. package/dist/app/run/run-events.d.ts +0 -144
  319. package/dist/app/run/run-finalization.d.ts +0 -56
  320. package/dist/app/run/run-guards.d.ts +0 -3
  321. package/dist/app/run/runtime-failures.d.ts +0 -18
  322. package/dist/app/run/runtime-fixtures.d.ts +0 -2
  323. package/dist/app/run/runtime-task-types.d.ts +0 -20
  324. package/dist/app/run/scheduler/estimates.d.ts +0 -32
  325. package/dist/app/run/scheduler/identity.d.ts +0 -9
  326. package/dist/app/run/scheduler/index.d.ts +0 -124
  327. package/dist/app/run/scheduler/locks.d.ts +0 -6
  328. package/dist/app/run/scheduler/observations.d.ts +0 -20
  329. package/dist/app/run/selection.d.ts +0 -9
  330. package/dist/app/run/setup/runtime-node-setup-errors.d.ts +0 -13
  331. package/dist/app/run/setup/runtime-node-setup-protocol.d.ts +0 -85
  332. package/dist/app/run/setup/runtime-node-setup-worker.d.ts +0 -1
  333. package/dist/app/run/setup/runtime-node-setup.d.ts +0 -48
  334. package/dist/app/run/task-batches.d.ts +0 -23
  335. package/dist/app/run/task-leases.d.ts +0 -15
  336. package/dist/app/run/worker-loop.d.ts +0 -66
  337. package/dist/app/setup/playwright.d.ts +0 -22
  338. package/dist/app/status/index.d.ts +0 -9
  339. package/dist/app/status/model.d.ts +0 -29
  340. package/dist/app/status/runs.d.ts +0 -99
  341. package/dist/app/stop/index.d.ts +0 -14
  342. package/dist/app/tracker/index.d.ts +0 -13
  343. package/dist/app/tracker/remote.d.ts +0 -13
  344. package/dist/app/tracker/token.d.ts +0 -7
  345. package/dist/app/typecheck/index.d.ts +0 -63
  346. package/dist/cli/command-catalog.d.ts +0 -156
  347. package/dist/cli/command-flags.d.ts +0 -19
  348. package/dist/cli/command-registry.d.ts +0 -3
  349. package/dist/cli/commands/artifacts.d.ts +0 -48
  350. package/dist/cli/commands/bug/file.d.ts +0 -16
  351. package/dist/cli/commands/bug/guide.d.ts +0 -5
  352. package/dist/cli/commands/bug/record.d.ts +0 -9
  353. package/dist/cli/commands/campaign/finish.d.ts +0 -10
  354. package/dist/cli/commands/campaign/start.d.ts +0 -7
  355. package/dist/cli/commands/campaign/status.d.ts +0 -13
  356. package/dist/cli/commands/ci/report.d.ts +0 -15
  357. package/dist/cli/commands/cleanup.d.ts +0 -13
  358. package/dist/cli/commands/db/schema/refresh.d.ts +0 -2
  359. package/dist/cli/commands/db/schema/verify.d.ts +0 -2
  360. package/dist/cli/commands/destroy.d.ts +0 -9
  361. package/dist/cli/commands/discover.d.ts +0 -2
  362. package/dist/cli/commands/doctor.d.ts +0 -2
  363. package/dist/cli/commands/guard/unsafe-entrypoint.d.ts +0 -2
  364. package/dist/cli/commands/lint.d.ts +0 -2
  365. package/dist/cli/commands/report/prepare.d.ts +0 -12
  366. package/dist/cli/commands/report/publish.d.ts +0 -13
  367. package/dist/cli/commands/run/status.d.ts +0 -5
  368. package/dist/cli/commands/run/stop.d.ts +0 -7
  369. package/dist/cli/commands/run.d.ts +0 -9
  370. package/dist/cli/commands/setup/playwright.d.ts +0 -2
  371. package/dist/cli/commands/status.d.ts +0 -5
  372. package/dist/cli/commands/stop.d.ts +0 -12
  373. package/dist/cli/commands/typecheck.d.ts +0 -2
  374. package/dist/cli/commands/workspace.d.ts +0 -2
  375. package/dist/cli/entrypoint.d.ts +0 -1
  376. package/dist/cli/framework/command.d.ts +0 -21
  377. package/dist/cli/framework/definitions.d.ts +0 -100
  378. package/dist/cli/framework/errors.d.ts +0 -6
  379. package/dist/cli/framework/execute.d.ts +0 -14
  380. package/dist/cli/framework/help.d.ts +0 -11
  381. package/dist/cli/framework/index.d.ts +0 -3
  382. package/dist/cli/framework/parser.d.ts +0 -6
  383. package/dist/cli/index.d.ts +0 -4
  384. package/dist/cli/json-errors.d.ts +0 -3
  385. package/dist/cli/operations/db/schema/refresh/operation.d.ts +0 -7
  386. package/dist/cli/operations/db/schema/verify/operation.d.ts +0 -7
  387. package/dist/cli/operations/run/operation.d.ts +0 -26
  388. package/dist/cli/process-signal.d.ts +0 -1
  389. package/dist/cli/renderers/bug/text.d.ts +0 -8
  390. package/dist/cli/renderers/campaign/text.d.ts +0 -2
  391. package/dist/cli/renderers/ci/text.d.ts +0 -2
  392. package/dist/cli/renderers/cleanup/format.d.ts +0 -14
  393. package/dist/cli/renderers/db-schema/text.d.ts +0 -4
  394. package/dist/cli/renderers/destroy/text.d.ts +0 -4
  395. package/dist/cli/renderers/discover/report.d.ts +0 -7
  396. package/dist/cli/renderers/discover/text.d.ts +0 -3
  397. package/dist/cli/renderers/doctor/text.d.ts +0 -2
  398. package/dist/cli/renderers/lint/text.d.ts +0 -2
  399. package/dist/cli/renderers/run/events.d.ts +0 -8
  400. package/dist/cli/renderers/run/failure.d.ts +0 -8
  401. package/dist/cli/renderers/run/formatting.d.ts +0 -79
  402. package/dist/cli/renderers/run/status.d.ts +0 -6
  403. package/dist/cli/renderers/run/text-reporter.d.ts +0 -19
  404. package/dist/cli/renderers/status/text.d.ts +0 -2
  405. package/dist/cli/renderers/stop/text.d.ts +0 -7
  406. package/dist/cli/renderers/typecheck/text.d.ts +0 -2
  407. package/dist/cli/terminal/colors.d.ts +0 -10
  408. package/dist/cli/terminal/layout.d.ts +0 -11
  409. package/dist/cli/version-drift.d.ts +0 -25
  410. package/dist/config/authoring/build-config-contract.d.ts +0 -27
  411. package/dist/config/authoring/configured-step-contract.d.ts +0 -18
  412. package/dist/config/authoring/http-execution-contract.d.ts +0 -70
  413. package/dist/config/authoring/http-methods.d.ts +0 -18
  414. package/dist/config/authoring/index.d.ts +0 -372
  415. package/dist/config/authoring/preset-env.d.ts +0 -19
  416. package/dist/config/authoring/runtime.d.ts +0 -64
  417. package/dist/config/authoring/runtime.js +0 -1
  418. package/dist/config/loader/bugs.d.ts +0 -15
  419. package/dist/config/loader/config-loader.d.ts +0 -9
  420. package/dist/config/loader/database-materialization.d.ts +0 -19
  421. package/dist/config/loader/database-roles.d.ts +0 -2
  422. package/dist/config/loader/database.d.ts +0 -55
  423. package/dist/config/loader/decode-discovery.d.ts +0 -5
  424. package/dist/config/loader/decode-execution.d.ts +0 -7
  425. package/dist/config/loader/dependencies.d.ts +0 -7
  426. package/dist/config/loader/discover-tests.d.ts +0 -111
  427. package/dist/config/loader/discovery-summary.d.ts +0 -29
  428. package/dist/config/loader/discovery.d.ts +0 -53
  429. package/dist/config/loader/env.d.ts +0 -4
  430. package/dist/config/loader/execution-model.d.ts +0 -15
  431. package/dist/config/loader/file-metadata.d.ts +0 -19
  432. package/dist/config/loader/groups.d.ts +0 -33
  433. package/dist/config/loader/index.d.ts +0 -10
  434. package/dist/config/loader/load.d.ts +0 -89
  435. package/dist/config/loader/managed-configs.d.ts +0 -23
  436. package/dist/config/loader/path-policy.d.ts +0 -9
  437. package/dist/config/loader/paths.d.ts +0 -5
  438. package/dist/config/loader/runtime-isolation.d.ts +0 -44
  439. package/dist/config/loader/runtime.d.ts +0 -16
  440. package/dist/config/loader/skip-config.d.ts +0 -44
  441. package/dist/config/loader/test-selection.d.ts +0 -15
  442. package/dist/config/loader/validation.d.ts +0 -15
  443. package/dist/config/loader/values.d.ts +0 -3
  444. package/dist/config/loader/values.js +0 -1
  445. package/dist/database/activity-gate.d.ts +0 -22
  446. package/dist/database/admin.d.ts +0 -31
  447. package/dist/database/cleanup.d.ts +0 -36
  448. package/dist/database/configured-steps.d.ts +0 -27
  449. package/dist/database/constants.d.ts +0 -11
  450. package/dist/database/docker-metadata.d.ts +0 -3
  451. package/dist/database/docker.d.ts +0 -65
  452. package/dist/database/drizzle/index.d.ts +0 -13
  453. package/dist/database/fingerprint.d.ts +0 -12
  454. package/dist/database/index.d.ts +0 -39
  455. package/dist/database/lifecycle-cleanup.d.ts +0 -8
  456. package/dist/database/local-postgres.d.ts +0 -71
  457. package/dist/database/naming.d.ts +0 -17
  458. package/dist/database/postgres/index.d.ts +0 -71
  459. package/dist/database/progress.d.ts +0 -6
  460. package/dist/database/roles.d.ts +0 -19
  461. package/dist/database/runtime-config.d.ts +0 -16
  462. package/dist/database/runtime-reservations.d.ts +0 -19
  463. package/dist/database/schema-operations.d.ts +0 -18
  464. package/dist/database/schema-source.d.ts +0 -96
  465. package/dist/database/source-refresh-lock.d.ts +0 -8
  466. package/dist/database/source-url.d.ts +0 -21
  467. package/dist/database/state-files.d.ts +0 -13
  468. package/dist/database/state.d.ts +0 -26
  469. package/dist/database/template-steps.d.ts +0 -39
  470. package/dist/domain/file-timeout.d.ts +0 -25
  471. package/dist/domain/identifiers.d.ts +0 -9
  472. package/dist/domain/operation-display.d.ts +0 -10
  473. package/dist/domain/operation-reason.d.ts +0 -5
  474. package/dist/domain/postgres-route.d.ts +0 -4
  475. package/dist/domain/runtime-identity.d.ts +0 -1
  476. package/dist/domain/runtime-isolation-contract.d.ts +0 -5
  477. package/dist/domain/service-name.d.ts +0 -2
  478. package/dist/domain/suite-selection.d.ts +0 -20
  479. package/dist/domain/test-outcomes.d.ts +0 -2
  480. package/dist/domain/test-types.d.ts +0 -16
  481. package/dist/engines/adapters/evidence-files.d.ts +0 -32
  482. package/dist/engines/adapters/evidence-identity.d.ts +0 -12
  483. package/dist/engines/adapters/execution.d.ts +0 -41
  484. package/dist/engines/adapters/native-report.d.ts +0 -25
  485. package/dist/engines/adapters/node-startup-cache.d.ts +0 -8
  486. package/dist/engines/adapters/workspace.d.ts +0 -4
  487. package/dist/engines/api/capabilities.d.ts +0 -21
  488. package/dist/engines/api/capabilities.js +0 -1
  489. package/dist/engines/api/evidence.d.ts +0 -38
  490. package/dist/engines/api/execution-observer.d.ts +0 -8
  491. package/dist/engines/api/execution-scope.d.ts +0 -17
  492. package/dist/engines/api/execution.d.ts +0 -101
  493. package/dist/engines/api/index.d.ts +0 -5
  494. package/dist/engines/api/k6-runtime-input.d.ts +0 -26
  495. package/dist/engines/api/k6-runtime-input.js +0 -1
  496. package/dist/engines/api/runtime-artifact.d.ts +0 -19
  497. package/dist/engines/bundle-cache.d.ts +0 -32
  498. package/dist/engines/catalog.d.ts +0 -27
  499. package/dist/engines/contracts/fixture-manifest.d.ts +0 -34
  500. package/dist/engines/contracts/json-bounds.d.ts +0 -36
  501. package/dist/engines/contracts/json-bounds.js +0 -2
  502. package/dist/engines/contracts/k6-repository-configuration.d.ts +0 -12
  503. package/dist/engines/contracts/k6-repository-configuration.js +0 -1
  504. package/dist/engines/contracts/test-context.d.ts +0 -15
  505. package/dist/engines/contracts/test-context.js +0 -1
  506. package/dist/engines/definitions.d.ts +0 -23
  507. package/dist/engines/factory.d.ts +0 -6
  508. package/dist/engines/generated-performance.d.ts +0 -1
  509. package/dist/engines/installation-catalog.d.ts +0 -27
  510. package/dist/engines/installation-catalog.js +0 -1
  511. package/dist/engines/installations/k6.d.ts +0 -98
  512. package/dist/engines/installations/k6.js +0 -1
  513. package/dist/engines/installations/node-vitest.d.ts +0 -33
  514. package/dist/engines/installations/package-requirements.d.ts +0 -28
  515. package/dist/engines/installations/package-resolution.d.ts +0 -51
  516. package/dist/engines/installations/playwright-resolution-child.d.ts +0 -1
  517. package/dist/engines/installations/playwright.d.ts +0 -75
  518. package/dist/engines/installations/types.d.ts +0 -10
  519. package/dist/engines/k6/adapter/bundle.d.ts +0 -25
  520. package/dist/engines/k6/adapter/bundle.js +0 -112
  521. package/dist/engines/k6/adapter/evidence.d.ts +0 -15
  522. package/dist/engines/k6/adapter/evidence.js +0 -4
  523. package/dist/engines/k6/adapter/executor.d.ts +0 -13
  524. package/dist/engines/k6/adapter/executor.js +0 -1
  525. package/dist/engines/k6/adapter/index.d.ts +0 -1
  526. package/dist/engines/k6/adapter/index.js +0 -1
  527. package/dist/engines/k6/adapter/input.d.ts +0 -21
  528. package/dist/engines/k6/adapter/input.js +0 -1
  529. package/dist/engines/k6/adapter/native-summary.d.ts +0 -11
  530. package/dist/engines/k6/adapter/native-summary.js +0 -1
  531. package/dist/engines/k6/adapter/repository-configuration.d.ts +0 -2
  532. package/dist/engines/k6/adapter/repository-configuration.js +0 -1
  533. package/dist/engines/k6/authoring-type-paths.d.ts +0 -3
  534. package/dist/engines/k6/authoring-type-paths.js +0 -1
  535. package/dist/engines/k6/runtime/ambient-types/bundle-manifest.json +0 -146
  536. package/dist/engines/k6/runtime/ambient-types/k6/LICENSE +0 -21
  537. package/dist/engines/k6/runtime/ambient-types/k6/browser/index.d.ts +0 -6332
  538. package/dist/engines/k6/runtime/ambient-types/k6/crypto/index.d.ts +0 -218
  539. package/dist/engines/k6/runtime/ambient-types/k6/data/index.d.ts +0 -16
  540. package/dist/engines/k6/runtime/ambient-types/k6/encoding/index.d.ts +0 -46
  541. package/dist/engines/k6/runtime/ambient-types/k6/execution/index.d.ts +0 -127
  542. package/dist/engines/k6/runtime/ambient-types/k6/experimental/csv/index.d.ts +0 -96
  543. package/dist/engines/k6/runtime/ambient-types/k6/experimental/fs/index.d.ts +0 -104
  544. package/dist/engines/k6/runtime/ambient-types/k6/experimental/redis/index.d.ts +0 -821
  545. package/dist/engines/k6/runtime/ambient-types/k6/experimental/streams/index.d.ts +0 -198
  546. package/dist/engines/k6/runtime/ambient-types/k6/global.d.ts +0 -83
  547. package/dist/engines/k6/runtime/ambient-types/k6/html/index.d.ts +0 -1325
  548. package/dist/engines/k6/runtime/ambient-types/k6/http/index.d.ts +0 -806
  549. package/dist/engines/k6/runtime/ambient-types/k6/index.d.ts +0 -126
  550. package/dist/engines/k6/runtime/ambient-types/k6/metrics/index.d.ts +0 -66
  551. package/dist/engines/k6/runtime/ambient-types/k6/net/grpc/index.d.ts +0 -247
  552. package/dist/engines/k6/runtime/ambient-types/k6/options/index.d.ts +0 -459
  553. package/dist/engines/k6/runtime/ambient-types/k6/package.json +0 -79
  554. package/dist/engines/k6/runtime/ambient-types/k6/secrets/index.d.ts +0 -36
  555. package/dist/engines/k6/runtime/ambient-types/k6/timers/index.d.ts +0 -47
  556. package/dist/engines/k6/runtime/ambient-types/k6/websockets/index.d.ts +0 -324
  557. package/dist/engines/k6/runtime/ambient-types/k6/ws/index.d.ts +0 -283
  558. package/dist/engines/k6/runtime/ambient-types/xk6-sql/LICENSE +0 -201
  559. package/dist/engines/k6/runtime/ambient-types/xk6-sql/index.d.ts +0 -397
  560. package/dist/engines/k6/runtime/ambient-types/xk6-sql/package.json +0 -15
  561. package/dist/engines/k6/runtime/artifacts.d.ts +0 -2
  562. package/dist/engines/k6/runtime/artifacts.js +0 -1
  563. package/dist/engines/k6/runtime/checks.d.ts +0 -17
  564. package/dist/engines/k6/runtime/checks.js +0 -1
  565. package/dist/engines/k6/runtime/dal-fixtures.d.ts +0 -24
  566. package/dist/engines/k6/runtime/dal-fixtures.js +0 -1
  567. package/dist/engines/k6/runtime/dal-suite.d.ts +0 -24
  568. package/dist/engines/k6/runtime/dal-suite.js +0 -1
  569. package/dist/engines/k6/runtime/dal.d.ts +0 -10
  570. package/dist/engines/k6/runtime/dal.js +0 -1
  571. package/dist/engines/k6/runtime/fixtures.d.ts +0 -3
  572. package/dist/engines/k6/runtime/fixtures.js +0 -1
  573. package/dist/engines/k6/runtime/http-assertions.d.ts +0 -19
  574. package/dist/engines/k6/runtime/http-assertions.js +0 -1
  575. package/dist/engines/k6/runtime/http-checks.d.ts +0 -19
  576. package/dist/engines/k6/runtime/http-checks.js +0 -1
  577. package/dist/engines/k6/runtime/http-suite-runtime.d.ts +0 -103
  578. package/dist/engines/k6/runtime/http-suite-runtime.js +0 -1
  579. package/dist/engines/k6/runtime/http.d.ts +0 -15
  580. package/dist/engines/k6/runtime/http.js +0 -1
  581. package/dist/engines/k6/runtime/index.d.ts +0 -11
  582. package/dist/engines/k6/runtime/index.js +0 -1
  583. package/dist/engines/k6/runtime/input.d.ts +0 -3
  584. package/dist/engines/k6/runtime/input.js +0 -1
  585. package/dist/engines/k6/runtime/k6-repository-configuration.d.ts +0 -9
  586. package/dist/engines/k6/runtime/k6-repository-configuration.js +0 -1
  587. package/dist/engines/k6/runtime/node-setup.d.ts +0 -13
  588. package/dist/engines/k6/runtime/node-setup.js +0 -1
  589. package/dist/engines/k6/runtime/runtime-globals.d.ts +0 -10
  590. package/dist/engines/k6/runtime/runtime.d.ts +0 -54
  591. package/dist/engines/k6/runtime/runtime.js +0 -1
  592. package/dist/engines/k6/runtime/shared/assertion-details.d.ts +0 -19
  593. package/dist/engines/k6/runtime/shared/assertion-details.js +0 -2
  594. package/dist/engines/k6/runtime/shared/db-normalization.d.ts +0 -19
  595. package/dist/engines/k6/runtime/shared/db-normalization.js +0 -1
  596. package/dist/engines/k6/runtime/shared/error-body.d.ts +0 -3
  597. package/dist/engines/k6/runtime/shared/error-body.js +0 -1
  598. package/dist/engines/k6/runtime/shared/file-data.d.ts +0 -1
  599. package/dist/engines/k6/runtime/shared/file-data.js +0 -1
  600. package/dist/engines/k6/runtime/shared/fixture-engine.d.ts +0 -8
  601. package/dist/engines/k6/runtime/shared/fixture-engine.js +0 -2
  602. package/dist/engines/k6/runtime/shared/http-check-plan.d.ts +0 -29
  603. package/dist/engines/k6/runtime/shared/http-check-plan.js +0 -1
  604. package/dist/engines/k6/runtime/shared/http-parsing.d.ts +0 -10
  605. package/dist/engines/k6/runtime/shared/http-parsing.js +0 -3
  606. package/dist/engines/k6/runtime/shared/ordering.d.ts +0 -2
  607. package/dist/engines/k6/runtime/shared/ordering.js +0 -1
  608. package/dist/engines/k6/runtime/shared/properties.d.ts +0 -1
  609. package/dist/engines/k6/runtime/shared/properties.js +0 -1
  610. package/dist/engines/k6/runtime/suite.d.ts +0 -4
  611. package/dist/engines/k6/runtime/suite.js +0 -1
  612. package/dist/engines/k6/runtime/types.d.ts +0 -244
  613. package/dist/engines/k6/runtime/types.js +0 -1
  614. package/dist/engines/k6/runtime/xk6-sql-driver-postgres.d.ts +0 -7
  615. package/dist/engines/k6/runtime/xk6-sql-driver-postgres.js +0 -1
  616. package/dist/engines/managed-module-resolution-policy-input.d.ts +0 -8
  617. package/dist/engines/managed-module-resolution-policy.d.ts +0 -25
  618. package/dist/engines/managed-module-resolution.d.ts +0 -13
  619. package/dist/engines/manager.d.ts +0 -25
  620. package/dist/engines/node-vitest/adapter/adapter.d.ts +0 -16
  621. package/dist/engines/node-vitest/adapter/consumer-typescript-paths.d.ts +0 -17
  622. package/dist/engines/node-vitest/adapter/consumer-typescript-paths.js +0 -3
  623. package/dist/engines/node-vitest/adapter/evidence.d.ts +0 -33
  624. package/dist/engines/node-vitest/adapter/failure-details.d.ts +0 -3
  625. package/dist/engines/node-vitest/adapter/index.d.ts +0 -1
  626. package/dist/engines/node-vitest/adapter/reporter.d.ts +0 -7
  627. package/dist/engines/node-vitest/adapter/resolution.d.ts +0 -12
  628. package/dist/engines/node-vitest/adapter/resolution.js +0 -1
  629. package/dist/engines/node-vitest/adapter/workspace.d.ts +0 -19
  630. package/dist/engines/node-vitest/runtime/contract/index.d.ts +0 -64
  631. package/dist/engines/node-vitest/runtime/contract/index.js +0 -1
  632. package/dist/engines/node-vitest/runtime/data/http.d.ts +0 -4
  633. package/dist/engines/node-vitest/runtime/data/http.js +0 -1
  634. package/dist/engines/node-vitest/runtime/data/index.d.ts +0 -8
  635. package/dist/engines/node-vitest/runtime/data/primitives.d.ts +0 -1
  636. package/dist/engines/node-vitest/runtime/data/report.d.ts +0 -3
  637. package/dist/engines/node-vitest/runtime/data/runner.d.ts +0 -4
  638. package/dist/engines/node-vitest/runtime/data/runner.js +0 -1
  639. package/dist/engines/node-vitest/runtime/data/scenario.d.ts +0 -11
  640. package/dist/engines/node-vitest/runtime/data/types.d.ts +0 -384
  641. package/dist/engines/node-vitest/runtime/runtime-input.d.ts +0 -64
  642. package/dist/engines/playwright/adapter/adapter.d.ts +0 -18
  643. package/dist/engines/playwright/adapter/attachments.d.ts +0 -26
  644. package/dist/engines/playwright/adapter/config.d.ts +0 -45
  645. package/dist/engines/playwright/adapter/evidence-validation.d.ts +0 -9
  646. package/dist/engines/playwright/adapter/evidence.d.ts +0 -32
  647. package/dist/engines/playwright/adapter/failure-details.d.ts +0 -2
  648. package/dist/engines/playwright/adapter/index.d.ts +0 -3
  649. package/dist/engines/playwright/adapter/reporter.d.ts +0 -12
  650. package/dist/engines/playwright/runtime/config-file.d.ts +0 -2
  651. package/dist/engines/playwright/runtime/config.d.ts +0 -24
  652. package/dist/engines/playwright/runtime/index.d.ts +0 -4
  653. package/dist/engines/playwright/runtime/runtime-input.d.ts +0 -36
  654. package/dist/engines/playwright/runtime/sandbox.d.ts +0 -84
  655. package/dist/engines/runtime-input-file.d.ts +0 -27
  656. package/dist/environment/lifecycle-artifacts.d.ts +0 -7
  657. package/dist/environment/lifecycle-controller.d.ts +0 -60
  658. package/dist/environment/lifecycle.d.ts +0 -32
  659. package/dist/environment/maintenance.d.ts +0 -68
  660. package/dist/environment/planning-types.d.ts +0 -33
  661. package/dist/environment/ports.d.ts +0 -10
  662. package/dist/environment/ready-environment.d.ts +0 -16
  663. package/dist/environment/run-environment.d.ts +0 -39
  664. package/dist/environment/run-stopping.d.ts +0 -13
  665. package/dist/environment/runtime-contexts.d.ts +0 -37
  666. package/dist/environment/runtime-manager.d.ts +0 -87
  667. package/dist/environment/runtime-planning.d.ts +0 -16
  668. package/dist/environment/runtime-preparation.d.ts +0 -30
  669. package/dist/environment/runtime-service.d.ts +0 -12
  670. package/dist/environment/services.d.ts +0 -56
  671. package/dist/environment/state.d.ts +0 -15
  672. package/dist/environment/status-runtime.d.ts +0 -53
  673. package/dist/environment/template.d.ts +0 -164
  674. package/dist/evidence/artifact-config.d.ts +0 -14
  675. package/dist/evidence/artifact-validation.d.ts +0 -4
  676. package/dist/evidence/artifacts.d.ts +0 -75
  677. package/dist/evidence/bundles.d.ts +0 -27
  678. package/dist/evidence/ci-provenance.d.ts +0 -9
  679. package/dist/evidence/contracts.d.ts +0 -154
  680. package/dist/evidence/environment-record.d.ts +0 -22
  681. package/dist/evidence/file-evidence.d.ts +0 -23
  682. package/dist/evidence/finalization.d.ts +0 -9
  683. package/dist/evidence/index.d.ts +0 -8
  684. package/dist/evidence/logs.d.ts +0 -31
  685. package/dist/evidence/operation-timings.d.ts +0 -60
  686. package/dist/evidence/read-bundle.d.ts +0 -4
  687. package/dist/evidence/read-fields.d.ts +0 -21
  688. package/dist/evidence/read-provenance.d.ts +0 -2
  689. package/dist/evidence/read-redaction.d.ts +0 -2
  690. package/dist/evidence/read-retention.d.ts +0 -2
  691. package/dist/evidence/read-run.d.ts +0 -2
  692. package/dist/evidence/reading.d.ts +0 -28
  693. package/dist/evidence/reporting-types.d.ts +0 -349
  694. package/dist/evidence/reporting.d.ts +0 -3
  695. package/dist/evidence/secure-file-copy.d.ts +0 -24
  696. package/dist/evidence/setup-progress.d.ts +0 -63
  697. package/dist/evidence/step-output.d.ts +0 -16
  698. package/dist/evidence/storage-inventory.d.ts +0 -27
  699. package/dist/evidence/storage.d.ts +0 -25
  700. package/dist/evidence/timing.d.ts +0 -23
  701. package/dist/file.d.ts +0 -11
  702. package/dist/index.d.ts +0 -4
  703. package/dist/kernel/error-serialization.d.ts +0 -40
  704. package/dist/kernel/redaction.d.ts +0 -2
  705. package/dist/kernel/unknown-values.d.ts +0 -11
  706. package/dist/kernel/work-metrics.d.ts +0 -6
  707. package/dist/process/capture-output.d.ts +0 -7
  708. package/dist/process/command-shell.d.ts +0 -1
  709. package/dist/process/environment-overlay.d.ts +0 -17
  710. package/dist/process/environment.d.ts +0 -33
  711. package/dist/process/files/contained-path.d.ts +0 -8
  712. package/dist/process/files/directory-status.d.ts +0 -14
  713. package/dist/process/files/dotenv.d.ts +0 -2
  714. package/dist/process/files/file-snapshot.d.ts +0 -34
  715. package/dist/process/files/json-file.d.ts +0 -11
  716. package/dist/process/files/paths.d.ts +0 -3
  717. package/dist/process/files/product-dir.d.ts +0 -1
  718. package/dist/process/files/temp-dir.d.ts +0 -11
  719. package/dist/process/host/metadata.d.ts +0 -6
  720. package/dist/process/host/platform.d.ts +0 -57
  721. package/dist/process/host-command.d.ts +0 -4
  722. package/dist/process/host-inspection-command.d.ts +0 -13
  723. package/dist/process/host-process.d.ts +0 -19
  724. package/dist/process/index.d.ts +0 -9
  725. package/dist/process/lifecycle-fence.d.ts +0 -10
  726. package/dist/process/locks.d.ts +0 -28
  727. package/dist/process/process-contracts.d.ts +0 -78
  728. package/dist/process/process-group.d.ts +0 -12
  729. package/dist/process/process-identity.d.ts +0 -27
  730. package/dist/process/process-limits.d.ts +0 -6
  731. package/dist/process/process.d.ts +0 -12
  732. package/dist/process/readiness.d.ts +0 -43
  733. package/dist/process/recovery.d.ts +0 -3
  734. package/dist/process/runs/inspection.d.ts +0 -5
  735. package/dist/process/runs/manifest.d.ts +0 -86
  736. package/dist/process/runs/ownership.d.ts +0 -11
  737. package/dist/process/runs/product-state.d.ts +0 -2
  738. package/dist/process/runs/schema.d.ts +0 -3
  739. package/dist/process/runs/stop.d.ts +0 -19
  740. package/dist/process/runtime-socket.d.ts +0 -4
  741. package/dist/process/service-processes.d.ts +0 -13
  742. package/dist/process/shutdown.d.ts +0 -10
  743. package/dist/process/stoppable-settlement.d.ts +0 -26
  744. package/dist/process/url-redaction.d.ts +0 -1
  745. package/dist/process/windows-cli-owner.d.ts +0 -2
  746. package/dist/process/windows-native.d.ts +0 -12
  747. package/dist/process/windows-process-identity.d.ts +0 -4
  748. package/dist/repo/ci-environment.d.ts +0 -7
  749. package/dist/repo/fingerprint-policy.d.ts +0 -13
  750. package/dist/repo/git-path.d.ts +0 -2
  751. package/dist/repo/history.d.ts +0 -17
  752. package/dist/repo/managed-git.d.ts +0 -10
  753. package/dist/repo/metadata.d.ts +0 -3
  754. package/dist/repo/physical-tree.d.ts +0 -37
  755. package/dist/repo/publish-directory.d.ts +0 -20
  756. package/dist/repo/remote.d.ts +0 -6
  757. package/dist/repo/state.d.ts +0 -26
  758. package/dist/repo/tree-listing.d.ts +0 -10
  759. package/dist/steps/build-config.d.ts +0 -34
  760. package/dist/steps/configured-step-testkit-modules.d.ts +0 -19
  761. package/dist/steps/configured-steps.d.ts +0 -51
  762. package/dist/steps/environment.d.ts +0 -82
  763. package/dist/steps/index.d.ts +0 -2
  764. package/dist/steps/module-runner.d.ts +0 -1
  765. package/dist/steps/run.d.ts +0 -36
  766. package/dist/toolchains/archive.d.ts +0 -53
  767. package/dist/toolchains/esbuild.d.ts +0 -9
  768. package/dist/toolchains/host-node-support.d.ts +0 -3
  769. package/dist/toolchains/index.d.ts +0 -114
  770. package/dist/toolchains/managed-node-releases.d.ts +0 -28
  771. package/dist/toolchains/node-cache.d.ts +0 -20
  772. package/dist/toolchains/node-integrity.d.ts +0 -18
  773. package/dist/toolchains/node-provisioning.d.ts +0 -29
  774. package/dist/toolchains/semver.d.ts +0 -13
  775. package/dist/toolchains/shared-operation.d.ts +0 -11
  776. package/dist/toolchains/timeouts.d.ts +0 -1
  777. package/dist/toolchains/vitest/index.d.ts +0 -13
  778. package/dist/tracker/gitea.d.ts +0 -14
  779. package/dist/tracker/github.d.ts +0 -14
  780. package/dist/tracker/http.d.ts +0 -33
  781. package/dist/tracker/index.d.ts +0 -4
  782. package/dist/tracker/redaction.d.ts +0 -4
  783. package/dist/tracker/requests.d.ts +0 -17
  784. package/dist/tracker/responses.d.ts +0 -24
  785. package/dist/tracker/types.d.ts +0 -51
  786. package/docs/engine-architecture.md +0 -682
  787. /package/dist/engines/{k6/runtime/runtime-globals.js → api/profiles.js} +0 -0
@@ -1 +1 @@
1
- import w from"net";import{setTimeout as x}from"node:timers/promises";import{redactUrlSecrets as E}from"./url-redaction.js";export const DEFAULT_READY_TIMEOUT_MS=12e4;export async function waitForReady({name:t,url:e,timeoutMs:o,process:i,signal:n}){const s=Date.now(),c=Promise.resolve(i.completion).then(l=>({kind:"completion",result:l})),r=h(n);let d=10,a;try{for(;Date.now()-s<o;){const l=Math.max(1,o-(Date.now()-s));a?.abort(),a=new AbortController;const f=x(Math.min(d,l),void 0,{signal:a.signal}).then(()=>({kind:"interval"}));d=Math.min(d*2,1e3);const u=new AbortController,p=fetch(e,{signal:u.signal}).then(b=>({kind:"endpoint",ready:b.ok}),()=>({kind:"endpoint",ready:!1}));let m=await Promise.race([c,...r?[r.promise]:[],p,f]).finally(()=>{u.abort()});if(m.kind==="endpoint"){if(m.ready)return;m=await Promise.race([c,...r?[r.promise]:[],f])}if(m.kind==="completion")throw serviceCompletionError(t,m.result);if(m.kind==="abort")throw m.reason}}finally{a?.abort(),r?.dispose()}throw new ServiceReadinessTimeoutError(`Timed out waiting for "${t}" to become ready at ${E(e)}`)}export class ServiceReadinessTimeoutError extends Error{constructor(e){super(e),this.name="ServiceReadinessTimeoutError"}}export class ServiceExitedBeforeReadyError extends Error{outcome;constructor(e,o,i){super(e,i),this.outcome=o,this.name="ServiceExitedBeforeReadyError"}}export function serviceCompletionError(t,e,o="before becoming ready"){const i=o==="unexpectedly"?"Local service":"Service",n=e.error||e.terminationError||null,s=`${e.exitCode!==null?`exit code ${e.exitCode.toString()}`:e.exitSignal?`signal ${e.exitSignal}`:"no exit status"}${n?`: ${n.message}`:""}`,c=`${i} "${t}" exited ${o} with ${s}`,r=n?{cause:n}:void 0;return o==="before becoming ready"?new ServiceExitedBeforeReadyError(c,s,r):new Error(c,r)}function h(t){if(!t)return null;let e=()=>{};const o=new Promise(i=>{e=()=>{i({kind:"abort",reason:t.reason||new Error("Service startup aborted")})},t.aborted?e():t.addEventListener("abort",e,{once:!0})});return{dispose(){t.removeEventListener("abort",e)},promise:o}}export function connectEndpoint(t,e,o){return new Promise(i=>{const n=w.createConnection({host:t.host,port:t.port});let s=!1;const c=Date.now(),r=a=>{s||(s=!0,o?.removeEventListener("abort",d),n.destroy(),i({host:t.host,port:t.port,durationMs:Math.max(0,Date.now()-c),...a}))};function d(){r({ok:!1,error:"connection cancelled"})}n.setTimeout(e),n.once("connect",()=>{r({ok:!0})}),n.once("timeout",()=>{r({ok:!1,error:`connect timed out after ${e.toString()}ms`})}),n.once("error",a=>{r({ok:!1,error:a.message})}),o?.addEventListener("abort",d,{once:!0}),o?.aborted&&d()})}
1
+ import b from"node:http";import y from"node:https";import{setTimeout as g}from"node:timers/promises";import{redactUrlSecrets as d}from"./url-redaction.js";export const DEFAULT_READY_TIMEOUT_MS=12e4;const x=new Set([301,302,303,307,308]),$=20,v=Object.freeze({accept:"*/*","accept-language":"*","sec-fetch-mode":"cors","user-agent":"node"}),A=Object.freeze({"http:":"gzip, deflate","https:":"br, gzip, deflate"});export async function waitForReady({name:t,url:e,timeoutMs:o,process:s,requirement:r="success",signal:i}){const n=parseHttpUrl(e),a=Date.now(),w=Promise.resolve(s.completion).then(u=>({kind:"completion",result:u})),p=L(i);let f=10,l;const m=R();try{for(;Date.now()-a<o;){const u=Math.max(1,o-(Date.now()-a));l?.abort(),l=new AbortController;const h=g(Math.min(f,u),void 0,{signal:l.signal}).then(()=>({kind:"interval"}));f=Math.min(f*2,1e3);const E=new AbortController,S=m.ready(n,r,E.signal).then(T=>({kind:"endpoint",ready:T}),()=>({kind:"endpoint",ready:!1}));let c=await Promise.race([w,...p?[p.promise]:[],S,h]).finally(()=>{E.abort()});if(c.kind==="endpoint"){if(c.ready)return;c=await Promise.race([w,...p?[p.promise]:[],h])}if(c.kind==="completion")throw serviceCompletionError(t,c.result);if(c.kind==="abort")throw c.reason}}finally{l?.abort(),p?.dispose(),m.close()}throw new ServiceReadinessTimeoutError(r==="success"?`Timed out waiting for "${t}" to become ready at ${d(e)}`:`Timed out waiting for "${t}" to answer HTTP at ${d(e)}`)}export async function requireHttpResponse(t,{signal:e,timeoutMs:o}){const s=parseHttpUrl(t);if(e?.aborted)throw e.reason;const r=AbortSignal.timeout(o),i=R();try{await i.ready(s,"response",e?AbortSignal.any([e,r]):r)}catch(n){throw e?.aborted?e.reason:new Error(r.aborted?`No HTTP response from ${d(t)} within ${o.toString()} ms`:`${d(t)} did not answer HTTP: ${n instanceof Error?n.message:String(n)}`,{cause:n})}finally{i.close()}}export function parseHttpUrl(t){let e;try{e=new URL(t)}catch{throw new Error(`${d(t)} is not a valid URL`)}if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Error(`${d(t)} is not an HTTP URL`);return e}function R(){const t={"http:":new b.Agent({keepAlive:!1}),"https:":new y.Agent({keepAlive:!1})};return{async ready(e,o,s){let r=e;for(let i=0;;i+=1){const{locations:n,status:a}=await C(r,t,s);if(o==="response")return!0;if(!x.has(a)||n.length===0)return a>=200&&a<300;if(n.length>1)throw new Error("Readiness redirect has more than one Location header");if(i===$)return!1;if(P(n[0],r))throw new Error("Readiness redirect location includes credentials");r=new URL(n[0],r)}},close(){t["http:"].destroy(),t["https:"].destroy()}}}function P(t,e){const o=new URL(e);o.username="",o.password="";const s=new URL(t,o);return s.username!==""||s.password!==""}function C(t,e,o){return new Promise((s,r)=>{if(t.protocol!=="http:"&&t.protocol!=="https:"){r(new Error(`Readiness cannot request a ${t.protocol} URL`));return}const i=(t.protocol==="https:"?y:b).request(t,{agent:e[t.protocol],headers:{...v,"accept-encoding":A[t.protocol]},signal:o},n=>{n.resume(),s({locations:n.headersDistinct.location??[],status:n.statusCode??0})});i.once("error",r),i.end()})}export class ServiceReadinessTimeoutError extends Error{constructor(e){super(e),this.name="ServiceReadinessTimeoutError"}}export class ServiceExitedBeforeReadyError extends Error{outcome;constructor(e,o,s){super(e,s),this.outcome=o,this.name="ServiceExitedBeforeReadyError"}}export function serviceCompletionError(t,e,o="before becoming ready"){const s=o==="unexpectedly"?"Local service":"Service",r=e.error||e.terminationError||null,i=`${e.exitCode!==null?`exit code ${e.exitCode.toString()}`:e.exitSignal?`signal ${e.exitSignal}`:"no exit status"}${r?`: ${r.message}`:""}`,n=`${s} "${t}" exited ${o} with ${i}`,a=r?{cause:r}:void 0;return o==="before becoming ready"?new ServiceExitedBeforeReadyError(n,i,a):new Error(n,a)}function L(t){if(!t)return null;let e=()=>{};const o=new Promise(s=>{e=()=>{s({kind:"abort",reason:t.reason||new Error("Service startup aborted")})},t.aborted?e():t.addEventListener("abort",e,{once:!0})});return{dispose(){t.removeEventListener("abort",e)},promise:o}}
@@ -0,0 +1 @@
1
+ import d from"node:fs";import{StringDecoder as l}from"node:string_decoder";const c=20;export function readyDeadline(e,n,t,r){const a=t+n;return r===null||r>=a?{at:a,phase:"startup"}:{at:r+e,phase:"run"}}export function createOutputMarkerDetector(e){const n=new l("utf8");let t="";return r=>{const a=t+(typeof r=="string"?r:n.write(Buffer.from(r)));return a.includes(e)?!0:(t=e.length>1?a.slice(1-e.length):"",!1)}}export function startReadyDeadline(e){const n=performance.now();let t=null,r=!1,a,o=()=>{};const i=()=>{r=!0,clearTimeout(a),o()},s=()=>{clearTimeout(a);const u=readyDeadline(e.timeoutMs,e.ready.startupTimeoutMs,n,t);a=setTimeout(()=>{r||(i(),e.onExpired(u.phase))},Math.max(0,u.at-performance.now()))},f=()=>{r||t!==null||(t=performance.now(),o(),s())};return o=m(e.ready,e.stdout,f),s(),i}function m(e,n,t){if("stdoutMarker"in e){if(!n)throw new Error("A stdout ready marker needs the command's captured stdout");const a=createOutputMarkerDetector(e.stdoutMarker),o=i=>{a(i)&&t()};return n.on("data",o),()=>{n.off("data",o)}}const r=setInterval(()=>{d.existsSync(e.readyFile)&&t()},c);return()=>{clearInterval(r)}}export function requireReadySignal(e){if(e===void 0)return;if(!Number.isSafeInteger(e.startupTimeoutMs)||e.startupTimeoutMs<=0)throw new Error("Managed process startup timeout must be a positive safe integer");const n="stdoutMarker"in e?e.stdoutMarker:void 0,t="readyFile"in e?e.readyFile:void 0;if(n===void 0==(t===void 0))throw new Error("Managed process ready signal must name exactly one stdout marker or ready file");if((n??t)?.length===0)throw new Error("Managed process ready signal must be non-empty")}
@@ -1 +1 @@
1
- import a from"node:fs";import l from"node:path";import{observeProcessCreationIdentity as p}from"../index.js";import{isTerminalRunStatus as m,RUN_MANIFEST_SCHEMA_VERSION as d}from"./schema.js";import{readDynamicProperty as t}from"../../kernel/unknown-values.js";export function hasActiveRunManifest(e,n=p){return hasActiveRunManifestWithTerminalAuthority(e,n)}export function hasActiveRunManifestWithTerminalAuthority(e,n,s){const u=l.join(e,".testkit","_runs"),c=h(u);let f=null;if(s!==void 0){const o=`${s.runId}.json`,r=c.filter(i=>i.fileName===o&&I(i.value,s));if(r.length!==1)return!0;f=r[0]}for(const o of c){if(o===f)continue;if(t(o.value,"schemaVersion")!==d)return!0;const r=t(o.value,"pid"),i=t(o.value,"processIdentity");if(!(r===0&&i===null)&&(typeof r!="number"||!Number.isSafeInteger(r)||r<=0||typeof i!="string"||i.length===0||n(r,i)!=="different"))return!0}return!1}function I(e,n){const s=t(e,"status"),u=t(e,"services");return t(e,"schemaVersion")===d&&t(e,"runId")===n.runId&&t(e,"incarnationId")===n.incarnationId&&t(e,"pid")===n.pid&&t(e,"processIdentity")===n.processIdentity&&t(e,"finishedAt")===n.finishedAt&&s===n.status&&m(s)&&Array.isArray(u)&&u.length===0}function h(e){return a.existsSync(e)?a.readdirSync(e,{withFileTypes:!0}).filter(n=>n.name.endsWith(".json")).map(n=>({fileName:n.name,value:n.isFile()?v(l.join(e,n.name)):null})):[]}function v(e){try{return JSON.parse(a.readFileSync(e,"utf8"))}catch{return null}}
1
+ import f from"node:fs";import l from"node:path";import{observeProcessCreationIdentity as p}from"../index.js";import{isTerminalRunStatus as m,RUN_MANIFEST_SCHEMA_VERSION as d}from"./schema.js";import{readDynamicProperty as t}from"../../kernel/unknown-values.js";import{readJsonFileOrNull as I}from"../files/json-file.js";export function hasActiveRunManifest(e,n=p){return hasActiveRunManifestWithTerminalAuthority(e,n)}export function hasActiveRunManifestWithTerminalAuthority(e,n,s){const u=l.join(e,".testkit","_runs"),a=v(u);let c=null;if(s!==void 0){const o=`${s.runId}.json`,r=a.filter(i=>i.fileName===o&&h(i.value,s));if(r.length!==1)return!0;c=r[0]}for(const o of a){if(o===c)continue;if(t(o.value,"schemaVersion")!==d)return!0;const r=t(o.value,"pid"),i=t(o.value,"processIdentity");if(!(r===0&&i===null)&&(typeof r!="number"||!Number.isSafeInteger(r)||r<=0||typeof i!="string"||i.length===0||n(r,i)!=="different"))return!0}return!1}function h(e,n){const s=t(e,"status"),u=t(e,"services");return t(e,"schemaVersion")===d&&t(e,"runId")===n.runId&&t(e,"incarnationId")===n.incarnationId&&t(e,"pid")===n.pid&&t(e,"processIdentity")===n.processIdentity&&t(e,"finishedAt")===n.finishedAt&&s===n.status&&m(s)&&Array.isArray(u)&&u.length===0}function v(e){return f.existsSync(e)?f.readdirSync(e,{withFileTypes:!0}).filter(n=>n.name.endsWith(".json")).map(n=>({fileName:n.name,value:n.isFile()?I(l.join(e,n.name)):null})):[]}
@@ -1 +1 @@
1
- import{isTerminalRunStatus as h}from"./schema.js";import{observeProcessCreationIdentity as c}from"../index.js";import{withProductLifecycleFence as a}from"../lifecycle-fence.js";import{terminateAttributedProcessLineage as f,terminateOwnedPosixProcessGroup as T}from"../service-processes.js";import{listRunManifests as d}from"./manifest.js";import{createShutdownDeadline as I,remainingShutdownMs as A,FORCE_TERMINATION_WAIT_MS as p}from"../shutdown.js";import{hasErrorCode as S}from"../../kernel/error-serialization.js";const w=5e3,E=5e3;export function isPidRunning(t){if(!Number.isInteger(Number(t))||Number(t)<=0)return!1;try{return process.kill(Number(t),0),!0}catch(n){return S(n,"EPERM")}}export async function waitForPreparedRunStop(t){if(t.controllerActive&&t.targetProcessIdentity!==null){const i=await D(t,t.targetProcessIdentity);let s=i,r=i;if(!s&&!r&&(await f(t.pid,"SIGKILL",t.targetProcessIdentity),s=await M(t.pid,w,t.targetProcessIdentity),r=!s&&await P(t)),!s&&!r)throw new Error(`Timed out stopping Testkit run process ${t.pid.toString()}`)}const n=new Set,e=await a(t.productDir,()=>d(t.productDir).find(i=>i.runId===t.runId)),o=new Map(t.manifest.services.map(i=>[runManifestServiceKey(i),i]));if(e&&sameRunManifestIncarnation(e,t.manifest))for(const i of e.services){const s=runManifestServiceKey(i),r=o.get(s);o.set(s,r?.shutdownDeadlineAt==null?i:{...i,shutdownTimeoutMs:r.shutdownTimeoutMs,shutdownDeadlineAt:Math.min(r.shutdownDeadlineAt,i.shutdownDeadlineAt??Number.MAX_VALUE)})}return await drainRunServices([...o.values()],n),n}async function D(t,n){const e=new Map,o=r=>{for(const u of r){const m=runManifestServiceKey(u),l=u.shutdownTimeoutMs??t.graceMs,g=e.get(m)??I(l+p);g.begin((u.shutdownDeadlineAt??Date.parse(t.requestedAt)+l)+p),e.set(m,g)}return Math.max(0,...r.map(u=>e.get(runManifestServiceKey(u))?.remainingMs()??0))};o(t.manifest.services);const i=I(t.graceMs);i.begin(Date.parse(t.requestedAt)+t.graceMs);let s=null;for(;;){if(c(t.pid,n)==="different")return!0;const r=await a(t.productDir,()=>d(t.productDir).find(u=>u.runId===t.runId));if(!r||!sameRunManifestIncarnation(r,t.manifest)||h(r.status))return!0;if(Math.max(i.remainingMs(),o(r.services))<=0){if(s===null){if(process.platform!=="win32")try{await f(t.pid,"SIGTERM",n)}catch{}s=performance.now()}if(performance.now()-s>=E)return!1}await y(100)}}async function P(t){return a(t.productDir,()=>{const n=d(t.productDir).find(e=>e.runId===t.runId);return n===void 0||!sameRunManifestIncarnation(n,t.manifest)||h(n.status)})}export async function drainRunServices(t,n){for(const e of[...t].reverse())await b(e),n.add(runManifestServiceKey(e))}async function b(t){const n=t.pid;if(!Number.isSafeInteger(n)||n<=0)return;const e=t.processIdentity;if(typeof e!="string"||e.length===0)throw new Error(`Application service process ${n.toString()} has no creation identity; refusing unsafe cleanup`);const o=Number(t.processGroupId);if(process.platform!=="win32"&&Number.isSafeInteger(o)&&o>0&&o===n){await T(o,e,t.shutdownTimeoutMs===void 0?w:t.shutdownDeadlineAt==null?t.shutdownTimeoutMs:A(t.shutdownTimeoutMs,t.shutdownDeadlineAt));return}if(process.platform!=="win32")throw new Error(`Application service process ${n.toString()} does not have an owned POSIX process group; refusing unsafe cleanup`);const i=c(n,e);if(i!=="matches"){if(i==="different"&&!isPidRunning(n))return;throw new Error(i==="different"?`Application service process creation identity no longer matches pid ${n.toString()}; refusing unsafe cleanup`:`Cannot establish the creation identity of application service process ${n.toString()}; refusing unsafe cleanup`)}if(await f(n,"SIGKILL",e),!await M(n,w,e))throw new Error(`Timed out stopping application service process ${n.toString()}`)}export function requestProcessStop(t,n,e){const o=c(t,n);if(o!=="matches"){if(o==="different"&&!isPidRunning(t))return;throw new Error(o==="different"?`Testkit run process creation identity no longer matches pid ${t.toString()}; refusing unsafe stop request`:`Cannot establish the creation identity of Testkit run process ${t.toString()}; refusing unsafe stop request`)}try{process.kill(t,e)}catch(i){if(!S(i,"ESRCH"))throw i}}async function M(t,n,e){const o=()=>e===void 0?isPidRunning(t):c(t,e)!=="different",i=Date.now();for(;Date.now()-i<n;){if(!o())return!0;await y(100)}return!o()}export function runManifestServiceKey(t){return`${t.pid.toString()}:${String(t.processGroupId)}:${t.processIdentity}`}export function sameRunManifestIncarnation(t,n){return t.runId===n.runId&&t.incarnationId===n.incarnationId&&t.pid===n.pid&&t.processIdentity===n.processIdentity}function y(t){return new Promise(n=>setTimeout(n,t))}
1
+ import{isTerminalRunStatus as h}from"./schema.js";import{observeProcessCreationIdentity as a}from"../index.js";import{withProductLifecycleFence as c}from"../lifecycle-fence.js";import{terminateAttributedProcessLineage as f,terminateOwnedPosixProcessGroup as T}from"../service-processes.js";import{listRunManifests as d}from"./manifest.js";import{createShutdownDeadline as I,remainingShutdownMs as A,FORCE_TERMINATION_WAIT_MS as p}from"../shutdown.js";import{hasErrorCode as S}from"../../kernel/error-serialization.js";import{delay as M}from"../process-group.js";const m=5e3,E=5e3;export function isPidRunning(t){if(!Number.isInteger(Number(t))||Number(t)<=0)return!1;try{return process.kill(Number(t),0),!0}catch(n){return S(n,"EPERM")}}export async function waitForPreparedRunStop(t){if(t.controllerActive&&t.targetProcessIdentity!==null){const i=await D(t,t.targetProcessIdentity);let s=i,r=i;if(!s&&!r&&(await f(t.pid,"SIGKILL",t.targetProcessIdentity),s=await y(t.pid,m,t.targetProcessIdentity),r=!s&&await b(t)),!s&&!r)throw new Error(`Timed out stopping Testkit run process ${t.pid.toString()}`)}const n=new Set,e=await c(t.productDir,()=>d(t.productDir).find(i=>i.runId===t.runId)),o=new Map(t.manifest.services.map(i=>[runManifestServiceKey(i),i]));if(e&&sameRunManifestIncarnation(e,t.manifest))for(const i of e.services){const s=runManifestServiceKey(i),r=o.get(s);o.set(s,r?.shutdownDeadlineAt==null?i:{...i,shutdownTimeoutMs:r.shutdownTimeoutMs,shutdownDeadlineAt:Math.min(r.shutdownDeadlineAt,i.shutdownDeadlineAt??Number.MAX_VALUE)})}return await drainRunServices([...o.values()],n),n}async function D(t,n){const e=new Map,o=r=>{for(const u of r){const w=runManifestServiceKey(u),l=u.shutdownTimeoutMs??t.graceMs,g=e.get(w)??I(l+p);g.begin((u.shutdownDeadlineAt??Date.parse(t.requestedAt)+l)+p),e.set(w,g)}return Math.max(0,...r.map(u=>e.get(runManifestServiceKey(u))?.remainingMs()??0))};o(t.manifest.services);const i=I(t.graceMs);i.begin(Date.parse(t.requestedAt)+t.graceMs);let s=null;for(;;){if(a(t.pid,n)==="different")return!0;const r=await c(t.productDir,()=>d(t.productDir).find(u=>u.runId===t.runId));if(!r||!sameRunManifestIncarnation(r,t.manifest)||h(r.status))return!0;if(Math.max(i.remainingMs(),o(r.services))<=0){if(s===null){if(process.platform!=="win32")try{await f(t.pid,"SIGTERM",n)}catch{}s=performance.now()}if(performance.now()-s>=E)return!1}await M(100)}}async function b(t){return c(t.productDir,()=>{const n=d(t.productDir).find(e=>e.runId===t.runId);return n===void 0||!sameRunManifestIncarnation(n,t.manifest)||h(n.status)})}export async function drainRunServices(t,n){for(const e of[...t].reverse())await P(e),n.add(runManifestServiceKey(e))}async function P(t){const n=t.pid;if(!Number.isSafeInteger(n)||n<=0)return;const e=t.processIdentity;if(typeof e!="string"||e.length===0)throw new Error(`Application service process ${n.toString()} has no creation identity; refusing unsafe cleanup`);const o=Number(t.processGroupId);if(process.platform!=="win32"&&Number.isSafeInteger(o)&&o>0&&o===n){await T(o,e,t.shutdownTimeoutMs===void 0?m:t.shutdownDeadlineAt==null?t.shutdownTimeoutMs:A(t.shutdownTimeoutMs,t.shutdownDeadlineAt));return}if(process.platform!=="win32")throw new Error(`Application service process ${n.toString()} does not have an owned POSIX process group; refusing unsafe cleanup`);const i=a(n,e);if(i!=="matches"){if(i==="different"&&!isPidRunning(n))return;throw new Error(i==="different"?`Application service process creation identity no longer matches pid ${n.toString()}; refusing unsafe cleanup`:`Cannot establish the creation identity of application service process ${n.toString()}; refusing unsafe cleanup`)}if(await f(n,"SIGKILL",e),!await y(n,m,e))throw new Error(`Timed out stopping application service process ${n.toString()}`)}export function requestProcessStop(t,n,e){const o=a(t,n);if(o!=="matches"){if(o==="different"&&!isPidRunning(t))return;throw new Error(o==="different"?`Testkit run process creation identity no longer matches pid ${t.toString()}; refusing unsafe stop request`:`Cannot establish the creation identity of Testkit run process ${t.toString()}; refusing unsafe stop request`)}try{process.kill(t,e)}catch(i){if(!S(i,"ESRCH"))throw i}}async function y(t,n,e){const o=()=>e===void 0?isPidRunning(t):a(t,e)!=="different",i=Date.now();for(;Date.now()-i<n;){if(!o())return!0;await M(100)}return!o()}export function runManifestServiceKey(t){return`${t.pid.toString()}:${String(t.processGroupId)}:${t.processIdentity}`}export function sameRunManifestIncarnation(t,n){return t.runId===n.runId&&t.incarnationId===n.incarnationId&&t.pid===n.pid&&t.processIdentity===n.processIdentity}
@@ -1 +1 @@
1
- import{captureProcessCreationIdentity as a,processCreationIdentityMatches as c,resolvePosixCommandShell as m,terminateAttributedProcessLineage as d,terminateOwnedPosixProcessGroup as u}from"./index.js";export{a as captureProcessCreationIdentity,c as processCreationIdentityMatches};export function normalizeServiceStartCommand(t){const r=t.trim();if(r.length===0)throw new Error("Service start command must not be empty");return r}export function prepareServiceStartInvocation(t,r,o=process.platform){const e=normalizeServiceStartCommand(t);if(o==="win32"){const i=e.replace(/^exec(?:\s+|$)/u,"").trim();if(i.length===0)throw new Error("Service start command must not contain only exec");return{executable:r.ComSpec||process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${i}"`],windowsVerbatimArguments:!0}}const n=m(r),s=/^exec(?:\s|$)/u.test(e)?e:`exec ${e}`;return{executable:n,args:["-lc",s]}}export async function terminateAttributedProcessLineage(t,r,o){const e=Number(t);!Number.isInteger(e)||e<=0||await d({displayLabel:"Testkit application service",...o===void 0?{}:{expectedCreationIdentity:o},pid:e,signal:r})}export async function terminateOwnedPosixProcessGroup(t,r,o){const e=Number(t);if(!Number.isSafeInteger(e)||e<=0)throw new Error("Owned POSIX process-group id must be a positive safe integer");await u({displayLabel:"Testkit application service",graceMs:o,leaderCreationIdentity:r,leaderPid:e,processGroupId:e})}export function sleep(t,r){return new Promise(o=>{const e=()=>{clearTimeout(n),r?.removeEventListener("abort",e),o()},n=setTimeout(e,t);r?.addEventListener("abort",e,{once:!0}),r?.aborted&&e()})}
1
+ import{captureProcessCreationIdentity as a,processCreationIdentityMatches as c,resolvePosixCommandShell as m,terminateAttributedProcessLineage as d,terminateOwnedPosixProcessGroup as p}from"./index.js";export{a as captureProcessCreationIdentity,c as processCreationIdentityMatches};export function normalizeServiceStartCommand(t){const r=t.trim();if(r.length===0)throw new Error("Service start command must not be empty");return r}export function prepareServiceStartInvocation(t,r,o=process.platform){const e=normalizeServiceStartCommand(t);if(o==="win32"){const n=e.replace(/^exec(?:\s+|$)/u,"").trim();if(n.length===0)throw new Error("Service start command must not contain only exec");return{executable:r.ComSpec||process.env.ComSpec||"cmd.exe",args:["/d","/s","/c",`"${n}"`],windowsVerbatimArguments:!0}}const s=m(r),i=/^exec(?:\s|$)/u.test(e)?e:`exec ${e}`;return{executable:s,args:["-lc",i]}}export async function terminateAttributedProcessLineage(t,r,o){const e=Number(t);!Number.isInteger(e)||e<=0||await d({displayLabel:"Testkit application service",...o===void 0?{}:{expectedCreationIdentity:o},pid:e,signal:r})}export async function terminateOwnedPosixProcessGroup(t,r,o){const e=Number(t);if(!Number.isSafeInteger(e)||e<=0)throw new Error("Owned POSIX process-group id must be a positive safe integer");await p({displayLabel:"Testkit application service",graceMs:o,leaderCreationIdentity:r,leaderPid:e,processGroupId:e})}
@@ -1,3 +1,3 @@
1
- import{spawn as p}from"node:child_process";import{windowsOwnerExecutable as c}from"./windows-native.js";let f;export function ensureWindowsCliOwnership(){return process.platform!=="win32"?Promise.resolve():f??=h()}async function h(){const e=p(c(),[String(process.pid)],{stdio:["pipe","pipe","inherit"],detached:!0,windowsHide:!0});await new Promise((l,a)=>{let n="",d=0,i=!1,o=!1;const u=setTimeout(()=>{r(new Error("Windows CLI process ownership handshake timed out"))},1e4);function r(t){o||(o=!0,clearTimeout(u),e.stdin.destroy(),e.stdout.destroy(),e.kill(),e.unref(),a(t))}e.once("error",r),e.stdin.on("error",r),e.stdout.on("error",r),e.once("exit",(t,s)=>{r(new Error(`Windows CLI process owner exited before readiness (${String(t)}, ${String(s)})`))}),e.stdout.once("end",()=>{r(new Error("Windows CLI process owner closed its handshake before readiness"))}),e.stdout.setEncoding("utf8"),e.stdout.on("data",t=>{if(o)return;if(d+=Buffer.byteLength(t),d>32){r(new Error("Windows CLI process ownership handshake exceeded its output limit"));return}n+=t;let s;for(;(s=n.indexOf(`
2
- `))>=0;){const w=n.slice(0,s);if(n=n.slice(s+1),w==="PREPARED"&&!i)i=!0,e.stdin.end(`ATTACH
3
- `);else if(w==="READY"&&i&&n.length===0){o=!0,clearTimeout(u),e.stdout.destroy(),e.unref(),l();return}else{r(new Error("Invalid Windows CLI process ownership handshake"));return}}})})}
1
+ import{spawn as c}from"node:child_process";import{windowsOwnerExecutable as f}from"./windows-native.js";let h,l=!1;export function ensureWindowsCliOwnership(){return process.platform!=="win32"?Promise.resolve():h??=m().then(()=>{l=!0})}export function windowsCliOwned(){return l}async function m(){const e=c(f(),[String(process.pid)],{stdio:["pipe","pipe","inherit"],detached:!0,windowsHide:!0});await new Promise((a,p)=>{let n="",d=0,i=!1,s=!1;const u=setTimeout(()=>{r(new Error("Windows CLI process ownership handshake timed out"))},1e4);function r(t){s||(s=!0,clearTimeout(u),e.stdin.destroy(),e.stdout.destroy(),e.kill(),e.unref(),p(t))}e.once("error",r),e.stdin.on("error",r),e.stdout.on("error",r),e.once("exit",(t,o)=>{r(new Error(`Windows CLI process owner exited before readiness (${String(t)}, ${String(o)})`))}),e.stdout.once("end",()=>{r(new Error("Windows CLI process owner closed its handshake before readiness"))}),e.stdout.setEncoding("utf8"),e.stdout.on("data",t=>{if(s)return;if(d+=Buffer.byteLength(t),d>32){r(new Error("Windows CLI process ownership handshake exceeded its output limit"));return}n+=t;let o;for(;(o=n.indexOf(`
2
+ `))>=0;){const w=n.slice(0,o);if(n=n.slice(o+1),w==="PREPARED"&&!i)i=!0,e.stdin.end(`ATTACH
3
+ `);else if(w==="READY"&&i&&n.length===0){s=!0,clearTimeout(u),e.stdout.destroy(),e.unref(),a();return}else{r(new Error("Invalid Windows CLI process ownership handshake"));return}}})})}
@@ -1 +1 @@
1
- import{execFile as u,execFileSync as d}from"node:child_process";import a from"node:fs";import o from"node:path";import{fileURLToPath as p}from"node:url";export function windowsOwnerExecutable(){if(!["x64","arm64"].includes(process.arch))throw new Error(`Unsupported Testkit Windows architecture: ${process.arch}`);return o.resolve(o.dirname(p(import.meta.url)),"../../bin",`testkit-windows-owner-${process.arch}.exe`)}export function publishWindowsFile(e,t){const r=a.lstatSync(e,{bigint:!0});try{d(windowsOwnerExecutable(),["publish-file",o.toNamespacedPath(o.resolve(e)),o.toNamespacedPath(o.resolve(t))],{encoding:"utf8",maxBuffer:16*1024,stdio:["ignore","pipe","pipe"],timeout:5e3,windowsHide:!0})}catch(i){if(typeof i=="object"&&i!==null&&Reflect.get(i,"status")===17)throw Object.assign(new Error("File already exists",{cause:i}),{code:"EEXIST"});try{const s={bigint:!0,throwIfNoEntry:!1},c=a.lstatSync(e,s),n=a.lstatSync(t,s);if(!c&&r.isFile()&&n?.isFile()&&sameFileAfterRename(r,n))return}catch{}throw i}}const f=11644473600000n;export function terminateWindowsProcessTree(e,t,r){const i=(BigInt(Math.floor(t))+f)*10000n;return new Promise((s,c)=>{u(windowsOwnerExecutable(),["terminate-tree",e.toString(),i.toString(),Math.ceil(r).toString()],{encoding:"utf8",maxBuffer:16*1024,timeout:r+5e3,windowsHide:!0},(n,w,l)=>{if(n===null)s("terminated");else if(n.code===3)s("absent");else{const m=l.trim()||`Could not terminate Windows process tree ${e.toString()}`;c(new Error(m,{cause:n}))}})})}export function sameFileAfterRename(e,t){return e.ino!==0n&&e.dev===t.dev&&e.ino===t.ino&&e.size===t.size&&e.mtimeNs===t.mtimeNs}
1
+ import{execFile as p,execFileSync as u}from"node:child_process";import l from"node:fs";import i from"node:path";import{fileURLToPath as w}from"node:url";export function windowsOwnerExecutable(){if(!["x64","arm64"].includes(process.arch))throw new Error(`Unsupported Testkit Windows architecture: ${process.arch}`);return i.resolve(i.dirname(w(import.meta.url)),"../../bin",`testkit-windows-owner-${process.arch}.exe`)}export function publishWindowsFile(e,t){const n=l.lstatSync(e,{bigint:!0});try{u(windowsOwnerExecutable(),["publish-file",i.toNamespacedPath(i.resolve(e)),i.toNamespacedPath(i.resolve(t))],{encoding:"utf8",maxBuffer:16*1024,stdio:["ignore","pipe","pipe"],timeout:5e3,windowsHide:!0})}catch(r){if(typeof r=="object"&&r!==null&&Reflect.get(r,"status")===17)throw Object.assign(new Error("File already exists",{cause:r}),{code:"EEXIST"});try{const o={bigint:!0,throwIfNoEntry:!1},c=l.lstatSync(e,o),s=l.lstatSync(t,o);if(!c&&n.isFile()&&s?.isFile()&&sameFileAfterRename(n,s))return}catch{}throw r}}const f=2,E=3,h=new Map([[5,"EACCES"],[17,"EXDEV"],[32,"EBUSY"],[80,"EEXIST"],[183,"EEXIST"],[303,"EPERM"]]);export function retireWindowsClaim(e,t,n){try{return u(windowsOwnerExecutable(),["retire-claim",i.toNamespacedPath(i.resolve(e)),i.toNamespacedPath(i.resolve(t))],{encoding:"utf8",maxBuffer:16*1024,stdio:["ignore","pipe","pipe"],timeout:5e3,windowsHide:!0}),"moved"}catch(r){const o=typeof r=="object"&&r!==null&&Reflect.get(r,"status")===2?parseWindowsClaimRetirementFailure(String(Reflect.get(r,"stdout"))):null;if(o!==null){if(isAbsentClaimFailure(o))return"absent";throw windowsClaimRetirementError(e,o,r)}try{const c={bigint:!0,throwIfNoEntry:!1},s=l.lstatSync(e,c),a=l.lstatSync(t,c);if(!s&&a!==void 0&&a.dev===n.dev&&a.ino===n.ino&&a.birthtimeNs===n.birthtimeNs)return"moved"}catch{}throw r}}export function parseWindowsClaimRetirementFailure(e){const t=/^(open|rename) ([1-9]\d*)$/u.exec(e.trim());return t===null?null:{stage:t[1]==="open"?"open":"rename",win32Error:Number(t[2])}}export function isAbsentClaimFailure({stage:e,win32Error:t}){return e==="open"&&(t===f||t===E)}export function windowsClaimRetirementError(e,t,n){const r=h.get(t.win32Error);return Object.assign(new Error(`Could not retire Windows lock claim ${e}: ${t.stage} failed with Win32 error ${t.win32Error.toString()}`,{cause:n}),{...r===void 0?{}:{code:r},syscall:t.stage,win32Error:t.win32Error})}const g=11644473600000n;export function terminateWindowsProcessTree(e,t,n){const r=(BigInt(Math.floor(t))+g)*10000n;return new Promise((o,c)=>{p(windowsOwnerExecutable(),["terminate-tree",e.toString(),r.toString(),Math.ceil(n).toString()],{encoding:"utf8",maxBuffer:16*1024,timeout:n+5e3,windowsHide:!0},(s,a,m)=>{if(s===null)o("terminated");else if(s.code===3)o("absent");else{const d=m.trim()||`Could not terminate Windows process tree ${e.toString()}`;c(new Error(d,{cause:s}))}})})}export function sameFileAfterRename(e,t){return e.ino!==0n&&e.dev===t.dev&&e.ino===t.ino&&e.size===t.size&&e.mtimeNs===t.mtimeNs}
@@ -1 +1 @@
1
- import y from"fs";import u from"path";import{physicalNodeMode as l,readPhysicalDirectoryEntries as b,readPhysicalNode as $}from"./physical-tree.js";import{isUnknownArray as w,isUnknownRecord as E}from"../kernel/unknown-values.js";const z=[".testkit",".next-testkit"],d={exclude:[],include:[]};export function normalizeFingerprintPolicy(t={}){if(t==null)return{exclude:[],include:[]};if(!E(t))throw new Error("testkit.config.ts fingerprints must be an object");return{exclude:h(t.exclude,"fingerprints.exclude"),include:h(t.include,"fingerprints.include")}}export function shouldIgnoreCanonicalFingerprintPath(t,n=d){return shouldIgnoreCanonicalFingerprintPathAtPrefix(t,"",n)}export function shouldIgnoreCanonicalFingerprintPathAtPrefix(t,n,e=d){const r=s(t),i=m(n,r);return!i||p(i,e.include)?!1:T(r)?!0:p(i,e.exclude)}export function hasIncludedFingerprintDescendantAtPrefix(t,n,e){const r=m(n,t);if(!r)return e.include.length>0;const i=`${r}/`;return e.include.some(c=>{const o=s(c);if(o.includes("*")){const f=S(o);return f.length===0||r.startsWith(f)||f.startsWith(i)}return P(o).startsWith(i)})}export function appendFingerprintPathToHash(t,n,e,r=d){const i=normalizeRelativePath(n,e),c=y.realpathSync.native(u.resolve(n));k(t,c,i,r)}export function normalizeRelativePath(t,n){const e=u.isAbsolute(n)?u.relative(t,n):n;return u.isAbsolute(n)?s(e.split(u.sep).join("/")):normalizePath(e)}export function normalizePath(t){return t.split(u.sep).join("/").replace(/\\/g,"/").replace(/^\.\/+/,"").replace(/\/+$/,"")}function h(t,n){if(t==null)return[];if(!w(t))throw new Error(`testkit.config.ts ${n} must be an array of paths`);return t.map((e,r)=>{if(typeof e!="string")throw new Error(`testkit.config.ts ${n}[${String(r)}] must be a string path`);const i=s(e.trim());if(!i)throw new Error(`testkit.config.ts ${n}[${String(r)}] must be a non-empty path`);if(L(i))throw new Error(`testkit.config.ts ${n}[${String(r)}] must use "/" as the path separator; a literal backslash is written doubled`);if(i.startsWith("/")||/^[a-z]:\//iu.test(i)||i.startsWith("../")||i==="..")throw new Error(`testkit.config.ts ${n}[${String(r)}] must be relative to the product directory`);return i})}function p(t,n){return n.some(e=>I(t,e))}function T(t){return p(t,z)}function I(t,n){const e=s(t),r=s(n);if(!r)return!1;const i=P(r);if(e===i||e.startsWith(`${i}/`))return!0;if(!r.includes("*"))return!1;const c=W(r);let o=e;for(;o;){if(c.test(o))return!0;const f=o.lastIndexOf("/");if(f<0)break;o=o.slice(0,f)}return!1}function s(t){return t.replace(/^\.\/+/,"").replace(/\/+$/,"")}function L(t){for(let n=0;n<t.length;n+=1)if(t[n]==="\\"){if(t[n+1]!=="\\")return!0;n+=1}return!1}function P(t){return t.replace(/\\\\/g,"\\")}function S(t){let n="";for(let e=0;e<t.length;e+=1){const r=t[e];if(r==="*")break;r==="\\"&&t[e+1]==="\\"?(n+="\\",e+=1):n+=r}return n}function k(t,n,e,r){const i=$(n,e),c=shouldIgnoreCanonicalFingerprintPath(e,r);if(!(c&&(i.kind!=="directory"||!hasIncludedFingerprintDescendantAtPrefix(e,"",r)))&&(c||R(t,e,i),i.kind==="directory"))for(const o of b(n,e))k(t,n,m(e,o),r)}function R(t,n,e){switch(t.update("node\0"),a(t,"path",n),a(t,"kind",e.kind),e.kind){case"file":a(t,"mode",l(e.mode)),g(t,"contents",e.contents);break;case"directory":a(t,"mode",l(e.mode));break;case"symlink":case"ancestor-symlink":"obstaclePath"in e&&a(t,"obstacle",e.obstaclePath),g(t,"target",e.target);break;case"ancestor-missing":a(t,"obstacle",e.obstaclePath);break;case"ancestor-non-directory":a(t,"obstacle",e.obstaclePath),a(t,"mode",l(e.mode));break;case"missing":break}}function a(t,n,e){g(t,n,Buffer.from(e))}function g(t,n,e){t.update(`${n}\0${e.byteLength.toString()}\0`),t.update(e),t.update("\0")}function m(t,n){const e=s(t),r=s(n);return e?r?`${e}/${r}`:e:r}function W(t){let n="^";for(let e=0;e<t.length;e+=1){const r=t[e],i=t[e+1];r==="\\"&&i==="\\"?(n+=x("\\"),e+=1):r==="*"&&i==="*"?(n+=".*",e+=1):r==="*"?n+="[^/]*":n+=x(r)}return n+="$",new RegExp(n)}function x(t){return t.replace(/[\\^$+?.()|[\]{}]/g,"\\$&")}export function appendFileToHash(t,n,e,r={}){appendFingerprintPathToHash(t,n,e,normalizeFingerprintPolicy(r))}
1
+ import x from"fs";import f from"path";import{physicalNodeMode as u,readPhysicalDirectoryEntries as y,readPhysicalNode as b}from"./physical-tree.js";import{rejectUnknownKeys as w}from"../kernel/known-keys.js";import{isUnknownArray as $,isUnknownRecord as E}from"../kernel/unknown-values.js";const z=[".testkit",".next-testkit"],l={exclude:[],include:[]};export function normalizeFingerprintPolicy(t={}){if(t==null)return{exclude:[],include:[]};if(!E(t))throw new Error("testkit.config.ts fingerprints must be an object");return w(t,["exclude","include"],"testkit.config.ts fingerprints"),{exclude:m(t.exclude,"fingerprints.exclude"),include:m(t.include,"fingerprints.include")}}export function shouldIgnoreCanonicalFingerprintPath(t,n=l){return shouldIgnoreCanonicalFingerprintPathAtPrefix(t,"",n)}export function shouldIgnoreCanonicalFingerprintPathAtPrefix(t,n,e=l){const r=normalizeCanonicalRelativePath(t),i=g(n,r);return!i||d(i,e.include)?!1:T(r)?!0:d(i,e.exclude)}export function hasIncludedFingerprintDescendantAtPrefix(t,n,e){const r=g(n,t);if(!r)return e.include.length>0;const i=`${r}/`;return e.include.some(c=>{const o=normalizeCanonicalRelativePath(c);if(o.includes("*")){const a=S(o);return a.length===0||r.startsWith(a)||a.startsWith(i)}return h(o).startsWith(i)})}export function appendFingerprintPathToHash(t,n,e,r=l){const i=normalizeRelativePath(n,e),c=x.realpathSync.native(f.resolve(n));P(t,c,i,r)}export function normalizeRelativePath(t,n){const e=f.isAbsolute(n)?f.relative(t,n):n;return f.isAbsolute(n)?normalizeCanonicalRelativePath(e.split(f.sep).join("/")):normalizePath(e)}export function normalizePath(t){return t.split(f.sep).join("/").replace(/\\/g,"/").replace(/^\.\/+/,"").replace(/\/+$/,"")}function m(t,n){if(t==null)return[];if(!$(t))throw new Error(`testkit.config.ts ${n} must be an array of paths`);return t.map((e,r)=>{if(typeof e!="string")throw new Error(`testkit.config.ts ${n}[${String(r)}] must be a string path`);const i=normalizeCanonicalRelativePath(e.trim());if(!i)throw new Error(`testkit.config.ts ${n}[${String(r)}] must be a non-empty path`);if(L(i))throw new Error(`testkit.config.ts ${n}[${String(r)}] must use "/" as the path separator; a literal backslash is written doubled`);if(i.startsWith("/")||/^[a-z]:\//iu.test(i)||i.startsWith("../")||i==="..")throw new Error(`testkit.config.ts ${n}[${String(r)}] must be relative to the product directory`);return i})}function d(t,n){return n.some(e=>I(t,e))}function T(t){return d(t,z)}function I(t,n){const e=normalizeCanonicalRelativePath(t),r=normalizeCanonicalRelativePath(n);if(!r)return!1;const i=h(r);if(e===i||e.startsWith(`${i}/`))return!0;if(!r.includes("*"))return!1;const c=W(r);let o=e;for(;o;){if(c.test(o))return!0;const a=o.lastIndexOf("/");if(a<0)break;o=o.slice(0,a)}return!1}export function normalizeCanonicalRelativePath(t){return t.replace(/^\.\/+/,"").replace(/\/+$/,"")}function L(t){for(let n=0;n<t.length;n+=1)if(t[n]==="\\"){if(t[n+1]!=="\\")return!0;n+=1}return!1}function h(t){return t.replace(/\\\\/g,"\\")}function S(t){let n="";for(let e=0;e<t.length;e+=1){const r=t[e];if(r==="*")break;r==="\\"&&t[e+1]==="\\"?(n+="\\",e+=1):n+=r}return n}function P(t,n,e,r){const i=b(n,e),c=shouldIgnoreCanonicalFingerprintPath(e,r);if(!(c&&(i.kind!=="directory"||!hasIncludedFingerprintDescendantAtPrefix(e,"",r)))&&(c||R(t,e,i),i.kind==="directory"))for(const o of y(n,e))P(t,n,g(e,o),r)}function R(t,n,e){switch(t.update("node\0"),s(t,"path",n),s(t,"kind",e.kind),e.kind){case"file":s(t,"mode",u(e.mode)),p(t,"contents",e.contents);break;case"directory":s(t,"mode",u(e.mode));break;case"symlink":case"ancestor-symlink":"obstaclePath"in e&&s(t,"obstacle",e.obstaclePath),p(t,"target",e.target);break;case"ancestor-missing":s(t,"obstacle",e.obstaclePath);break;case"ancestor-non-directory":s(t,"obstacle",e.obstaclePath),s(t,"mode",u(e.mode));break;case"missing":break}}function s(t,n,e){p(t,n,Buffer.from(e))}function p(t,n,e){t.update(`${n}\0${e.byteLength.toString()}\0`),t.update(e),t.update("\0")}function g(t,n){const e=normalizeCanonicalRelativePath(t),r=normalizeCanonicalRelativePath(n);return e?r?`${e}/${r}`:e:r}function W(t){let n="^";for(let e=0;e<t.length;e+=1){const r=t[e],i=t[e+1];r==="\\"&&i==="\\"?(n+=k("\\"),e+=1):r==="*"&&i==="*"?(n+=".*",e+=1):r==="*"?n+="[^/]*":n+=k(r)}return n+="$",new RegExp(n)}function k(t){return t.replace(/[\\^$+?.()|[\]{}]/g,"\\$&")}export function appendFileToHash(t,n,e,r={}){appendFingerprintPathToHash(t,n,e,normalizeFingerprintPolicy(r))}
@@ -1 +1 @@
1
- import{runManagedHostCommand as t}from"../process/index.js";export const DEFAULT_GIT_COMMAND_TIMEOUT_MS=3e4;const n=new Set(["GIT_ALTERNATE_OBJECT_DIRECTORIES","GIT_ATTR_SOURCE","GIT_COMMON_DIR","GIT_CONFIG","GIT_CONFIG_COUNT","GIT_CONFIG_GLOBAL","GIT_CONFIG_NOSYSTEM","GIT_CONFIG_PARAMETERS","GIT_CONFIG_SYSTEM","GIT_DIFF_OPTS","GIT_DIR","GIT_EXTERNAL_DIFF","GIT_GLOB_PATHSPECS","GIT_ICASE_PATHSPECS","GIT_IMPLICIT_WORK_TREE","GIT_INDEX_FILE","GIT_LITERAL_PATHSPECS","GIT_NAMESPACE","GIT_NOGLOB_PATHSPECS","GIT_NO_REPLACE_OBJECTS","GIT_OBJECT_DIRECTORY","GIT_PREFIX","GIT_QUARANTINE_PATH","GIT_REPLACE_REF_BASE","GIT_SHALLOW_FILE","GIT_WORK_TREE"]),C=new Set(["GIT_OPTIONAL_LOCKS"]);export function runManagedGitCommand(G,T,I={}){return t({args:T,cwd:G,displayLabel:L(T),env:createManagedGitEnvironment(I.env??process.env,process.platform,I.repositoryConfigOnly??!1),executable:"git",signal:I.signal,timeoutMs:I.timeoutMs??DEFAULT_GIT_COMMAND_TIMEOUT_MS})}export function createManagedGitEnvironment(G,T=process.platform,I=!1){const _={};for(const[E,O]of Object.entries(G)){const e=T==="win32"?E.toUpperCase():E;n.has(e)||/^GIT_CONFIG_(?:KEY|VALUE)_\d+$/u.test(e)||C.has(e)||e==="LANG"||e==="LC_ALL"||(_[E]=O)}if(_.LANG="C",_.LC_ALL="C",_.GIT_NO_REPLACE_OBJECTS="1",_.GIT_OPTIONAL_LOCKS="0",I){const E=T==="win32"?"NUL":"/dev/null";_.GIT_CONFIG_GLOBAL=E,_.GIT_CONFIG_NOSYSTEM="1",_.GIT_CONFIG_SYSTEM=E}return _}function L(G){const T=G.find(I=>!I.startsWith("-"));return T?`Git ${T}`:"Git command"}
1
+ import{runManagedHostCommand as O}from"../process/index.js";export const DEFAULT_GIT_COMMAND_TIMEOUT_MS=3e4;const n=new Set(["GIT_ALTERNATE_OBJECT_DIRECTORIES","GIT_ATTR_SOURCE","GIT_COMMON_DIR","GIT_CONFIG","GIT_CONFIG_COUNT","GIT_CONFIG_GLOBAL","GIT_CONFIG_NOSYSTEM","GIT_CONFIG_PARAMETERS","GIT_CONFIG_SYSTEM","GIT_DIFF_OPTS","GIT_DIR","GIT_EXTERNAL_DIFF","GIT_GLOB_PATHSPECS","GIT_ICASE_PATHSPECS","GIT_IMPLICIT_WORK_TREE","GIT_INDEX_FILE","GIT_LITERAL_PATHSPECS","GIT_NAMESPACE","GIT_NOGLOB_PATHSPECS","GIT_NO_REPLACE_OBJECTS","GIT_OBJECT_DIRECTORY","GIT_PREFIX","GIT_QUARANTINE_PATH","GIT_REPLACE_REF_BASE","GIT_SHALLOW_FILE","GIT_WORK_TREE"]),C=new Set(["GIT_OPTIONAL_LOCKS"]);export function runManagedGitCommand(G,T,I={}){return O({args:T,cwd:G,displayLabel:gitCommandLabel(T),env:createManagedGitEnvironment(I.env??process.env,process.platform,I.repositoryConfigOnly??!1),executable:"git",signal:I.signal,timeoutMs:I.timeoutMs??DEFAULT_GIT_COMMAND_TIMEOUT_MS})}export function createManagedGitEnvironment(G,T=process.platform,I=!1){const _={};for(const[E,t]of Object.entries(G)){const e=T==="win32"?E.toUpperCase():E;n.has(e)||/^GIT_CONFIG_(?:KEY|VALUE)_\d+$/u.test(e)||C.has(e)||e==="LANG"||e==="LC_ALL"||(_[E]=t)}if(_.LANG="C",_.LC_ALL="C",_.GIT_NO_REPLACE_OBJECTS="1",_.GIT_OPTIONAL_LOCKS="0",I){const E=T==="win32"?"NUL":"/dev/null";_.GIT_CONFIG_GLOBAL=E,_.GIT_CONFIG_NOSYSTEM="1",_.GIT_CONFIG_SYSTEM=E}return _}export function gitCommandLabel(G){const T=G.find(I=>!I.startsWith("-"));return T?`Git ${T}`:"Git command"}
@@ -1 +1 @@
1
- import i from"node:fs";import h from"node:path";import{hasErrorCode as w}from"../kernel/error-serialization.js";export function physicalPathAndHandleIdentitiesEqual(t,n,e){return(t.dev===n.dev||e==="win32"&&t.dev===0n&&n.dev!==0n)&&t.ino===n.ino&&t.type===n.type}const D=61440n;export function readPhysicalNode(t,n){const e=F(t,n);try{if(e.obstacle)return e.obstacle;const r=e.finalStat;if(!r)return{kind:"missing"};if(r.isSymbolicLink())return{kind:"symlink",target:R(e,r)};if(r.isFile())return $(e,r);if(r.isDirectory())return u(e,r),{identity:a(r),kind:"directory",mode:r.mode};throw u(e,r),P(n,r.mode)}finally{g(e.ancestors)}}export function readPhysicalDirectoryEntries(t,n){const e=F(t,n);try{if(e.obstacle||!e.finalStat?.isDirectory())throw new Error(`Fingerprint directory is not a stable physical directory: ${n||"."}`);u(e,e.finalStat);const r=i.readdirSync(e.finalPath,{encoding:"buffer"});return u(e,e.finalStat),r.map(o=>decodePhysicalPathSegment(o,n)).sort(T)}finally{g(e.ancestors)}}export function physicalNodeMode(t){return(t&4095n).toString(8).padStart(4,"0")}export function physicalNodeType(t){switch(t&D){case 4096n:return"fifo";case 8192n:return"character-device";case 16384n:return"directory";case 24576n:return"block-device";case 32768n:return"file";case 40960n:return"symlink";case 49152n:return"socket";default:return"unknown"}}export function decodePhysicalPathSegment(t,n=""){const e=Buffer.from(t),r=e.toString("utf8");if(!Buffer.from(r,"utf8").equals(e))throw new Error(`Fingerprint paths must be valid UTF-8: ${n||"."} contains filename bytes 0x${e.toString("hex")}`);return r}function F(t,n){const e=i.realpathSync.native(h.resolve(t)),r=_(n),o=[];let c=e;try{const l=i.lstatSync(e,{bigint:!0});if(!l.isDirectory()||l.isSymbolicLink())throw new Error(`Fingerprint root is not a physical directory: ${t}`);o.push(k(e,l));const f=r.length===0?[]:r.slice(0,-1);for(const[v,N]of f.entries()){c=h.join(c,N);const p=r.slice(0,v+1).join("/"),s=E(c);if(!s)return{ancestors:o,finalPath:c,finalStat:null,obstacle:{kind:"ancestor-missing",obstaclePath:p}};if(s.isSymbolicLink())return{ancestors:o,finalPath:c,finalStat:s,obstacle:{kind:"ancestor-symlink",obstaclePath:p,target:C(c,s,o)}};if(!s.isDirectory()){if(!s.isFile())throw P(p,s.mode);return{ancestors:o,finalPath:c,finalStat:s,obstacle:{kind:"ancestor-non-directory",mode:s.mode,obstaclePath:p}}}const L=k(c,s);o.push(L),y(o)}const b=r.length?h.join(e,...r):e,O=E(b);return y(o),{ancestors:o,finalPath:b,finalStat:O,obstacle:null}}catch(l){throw g(o),l}}function k(t,n){let e=null;if(process.platform!=="win32"){const r=Reflect.get(i.constants,"O_DIRECTORY"),o=Reflect.get(i.constants,"O_NOFOLLOW"),c=typeof r=="number"?r:0,l=typeof o=="number"?o:0;e=i.openSync(t,i.constants.O_RDONLY|c|l);const f=i.fstatSync(e,{bigint:!0});if(!f.isDirectory()||!m(f,n))throw i.closeSync(e),d(t)}return{fileDescriptor:e,identity:a(n),path:t}}function $(t,n){const e=Reflect.get(i.constants,"O_NOFOLLOW"),r=typeof e=="number"?e:0,o=i.openSync(t.finalPath,i.constants.O_RDONLY|r);try{const c=i.fstatSync(o,{bigint:!0});if(!c.isFile()||!physicalPathAndHandleIdentitiesEqual(a(n),a(c),process.platform))throw d(t.finalPath);u(t,c,"handle");const l=i.readFileSync(o),f=i.fstatSync(o,{bigint:!0});if(!x(c,f))throw d(t.finalPath);return u(t,f,"handle"),{contents:l,kind:"file",mode:f.mode}}finally{i.closeSync(o)}}function R(t,n){u(t,n);const e=i.readlinkSync(t.finalPath,{encoding:"buffer"});return u(t,n),e}function C(t,n,e){y(e);const r=i.readlinkSync(t,{encoding:"buffer"}),o=i.lstatSync(t,{bigint:!0});if(!o.isSymbolicLink()||!m(o,n))throw d(t);return y(e),r}function u(t,n,e="path"){y(t.ancestors);const r=i.lstatSync(t.finalPath,{bigint:!0});if(!(e==="handle"?physicalPathAndHandleIdentitiesEqual(a(r),a(n),process.platform):m(r,n)))throw d(t.finalPath)}function y(t){for(const n of t){const e=i.lstatSync(n.path,{bigint:!0});if(!e.isDirectory()||!S(a(e),n.identity))throw d(n.path);if(n.fileDescriptor!==null){const r=i.fstatSync(n.fileDescriptor,{bigint:!0});if(!r.isDirectory()||!S(a(r),n.identity))throw d(n.path)}}}function E(t){try{return i.lstatSync(t,{bigint:!0})}catch(n){if(w(n,"ENOENT")||w(n,"ENOTDIR"))return null;throw n}}function _(t){const n=t.replace(/^\.\/+/,"").replace(/\/+$/,"");if(!n)return[];const e=n.split("/");if(e.some(r=>r.length===0||r==="."||r===".."))throw new Error(`Invalid canonical fingerprint path: ${t}`);return e}function a(t){return{dev:t.dev,ino:t.ino,type:t.mode&D}}function m(t,n){return S(a(t),a(n))}function S(t,n){return t.dev===n.dev&&t.ino===n.ino&&t.type===n.type}function x(t,n){return m(t,n)&&t.mode===n.mode&&t.size===n.size&&t.mtimeNs===n.mtimeNs&&t.ctimeNs===n.ctimeNs}function g(t){for(const n of[...t].reverse())n.fileDescriptor!==null&&i.closeSync(n.fileDescriptor)}function d(t){return new Error(`Fingerprint path changed while reading: ${t}`)}function P(t,n){return new Error(`Fingerprinting does not support special filesystem nodes: ${t||"."} (${physicalNodeType(n)})`)}function T(t,n){return t<n?-1:t>n?1:0}
1
+ import i from"node:fs";import h from"node:path";import{hasErrorCode as b}from"../kernel/error-serialization.js";export function physicalPathAndHandleIdentitiesEqual(t,n,e){return(t.dev===n.dev||e==="win32"&&t.dev===0n&&n.dev!==0n)&&t.ino===n.ino&&t.type===n.type}const w=61440n;export function readPhysicalNode(t,n){const e=D(t,n);try{if(e.obstacle)return e.obstacle;const r=e.finalStat;if(!r)return{kind:"missing"};if(r.isSymbolicLink())return{kind:"symlink",target:$(e,r)};if(r.isFile())return L(e,r);if(r.isDirectory())return u(e,r),{identity:a(r),kind:"directory",mode:r.mode};throw u(e,r),E(n,r.mode)}finally{S(e.ancestors)}}export function readPhysicalDirectoryEntries(t,n){const e=D(t,n);try{if(e.obstacle||!e.finalStat?.isDirectory())throw new Error(`Fingerprint directory is not a stable physical directory: ${n||"."}`);u(e,e.finalStat);const r=i.readdirSync(e.finalPath,{encoding:"buffer"});return u(e,e.finalStat),r.map(o=>decodePhysicalPathSegment(o,n)).sort(compareStrings)}finally{S(e.ancestors)}}export function physicalNodeMode(t){return(t&4095n).toString(8).padStart(4,"0")}export function physicalNodeType(t){switch(t&w){case 4096n:return"fifo";case 8192n:return"character-device";case 16384n:return"directory";case 24576n:return"block-device";case 32768n:return"file";case 40960n:return"symlink";case 49152n:return"socket";default:return"unknown"}}export function decodePhysicalPathSegment(t,n=""){const e=Buffer.from(t),r=e.toString("utf8");if(!Buffer.from(r,"utf8").equals(e))throw new Error(`Fingerprint paths must be valid UTF-8: ${n||"."} contains filename bytes 0x${e.toString("hex")}`);return r}function D(t,n){const e=i.realpathSync.native(h.resolve(t)),r=R(n),o=[];let c=e;try{const l=i.lstatSync(e,{bigint:!0});if(!l.isDirectory()||l.isSymbolicLink())throw new Error(`Fingerprint root is not a physical directory: ${t}`);o.push(F(e,l));const f=r.length===0?[]:r.slice(0,-1);for(const[O,v]of f.entries()){c=h.join(c,v);const p=r.slice(0,O+1).join("/"),s=k(c);if(!s)return{ancestors:o,finalPath:c,finalStat:null,obstacle:{kind:"ancestor-missing",obstaclePath:p}};if(s.isSymbolicLink())return{ancestors:o,finalPath:c,finalStat:s,obstacle:{kind:"ancestor-symlink",obstaclePath:p,target:x(c,s,o)}};if(!s.isDirectory()){if(!s.isFile())throw E(p,s.mode);return{ancestors:o,finalPath:c,finalStat:s,obstacle:{kind:"ancestor-non-directory",mode:s.mode,obstaclePath:p}}}const N=F(c,s);o.push(N),y(o)}const g=r.length?h.join(e,...r):e,P=k(g);return y(o),{ancestors:o,finalPath:g,finalStat:P,obstacle:null}}catch(l){throw S(o),l}}function F(t,n){let e=null;if(process.platform!=="win32"){const r=Reflect.get(i.constants,"O_DIRECTORY"),o=Reflect.get(i.constants,"O_NOFOLLOW"),c=typeof r=="number"?r:0,l=typeof o=="number"?o:0;e=i.openSync(t,i.constants.O_RDONLY|c|l);const f=i.fstatSync(e,{bigint:!0});if(!f.isDirectory()||!m(f,n))throw i.closeSync(e),d(t)}return{fileDescriptor:e,identity:a(n),path:t}}function L(t,n){const e=Reflect.get(i.constants,"O_NOFOLLOW"),r=typeof e=="number"?e:0,o=i.openSync(t.finalPath,i.constants.O_RDONLY|r);try{const c=i.fstatSync(o,{bigint:!0});if(!c.isFile()||!physicalPathAndHandleIdentitiesEqual(a(n),a(c),process.platform))throw d(t.finalPath);u(t,c,"handle");const l=i.readFileSync(o),f=i.fstatSync(o,{bigint:!0});if(!C(c,f))throw d(t.finalPath);return u(t,f,"handle"),{contents:l,kind:"file",mode:f.mode}}finally{i.closeSync(o)}}function $(t,n){u(t,n);const e=i.readlinkSync(t.finalPath,{encoding:"buffer"});return u(t,n),e}function x(t,n,e){y(e);const r=i.readlinkSync(t,{encoding:"buffer"}),o=i.lstatSync(t,{bigint:!0});if(!o.isSymbolicLink()||!m(o,n))throw d(t);return y(e),r}function u(t,n,e="path"){y(t.ancestors);const r=i.lstatSync(t.finalPath,{bigint:!0});if(!(e==="handle"?physicalPathAndHandleIdentitiesEqual(a(r),a(n),process.platform):m(r,n)))throw d(t.finalPath)}function y(t){for(const n of t){const e=i.lstatSync(n.path,{bigint:!0});if(!e.isDirectory()||!sameIdentityRecord(a(e),n.identity))throw d(n.path);if(n.fileDescriptor!==null){const r=i.fstatSync(n.fileDescriptor,{bigint:!0});if(!r.isDirectory()||!sameIdentityRecord(a(r),n.identity))throw d(n.path)}}}function k(t){try{return i.lstatSync(t,{bigint:!0})}catch(n){if(b(n,"ENOENT")||b(n,"ENOTDIR"))return null;throw n}}function R(t){const n=t.replace(/^\.\/+/,"").replace(/\/+$/,"");if(!n)return[];const e=n.split("/");if(e.some(r=>r.length===0||r==="."||r===".."))throw new Error(`Invalid canonical fingerprint path: ${t}`);return e}function a(t){return{dev:t.dev,ino:t.ino,type:t.mode&w}}function m(t,n){return sameIdentityRecord(a(t),a(n))}export function sameIdentityRecord(t,n){return t.dev===n.dev&&t.ino===n.ino&&t.type===n.type}function C(t,n){return m(t,n)&&t.mode===n.mode&&t.size===n.size&&t.mtimeNs===n.mtimeNs&&t.ctimeNs===n.ctimeNs}function S(t){for(const n of[...t].reverse())n.fileDescriptor!==null&&i.closeSync(n.fileDescriptor)}function d(t){return new Error(`Fingerprint path changed while reading: ${t}`)}function E(t,n){return new Error(`Fingerprinting does not support special filesystem nodes: ${t||"."} (${physicalNodeType(n)})`)}export function compareStrings(t,n){return t<n?-1:t>n?1:0}
@@ -1,5 +1,5 @@
1
- import $ from"crypto";import p from"fs";import s from"path";import{appendFingerprintPathToHash as et,hasIncludedFingerprintDescendantAtPrefix as rt,normalizeFingerprintPolicy as N,shouldIgnoreCanonicalFingerprintPathAtPrefix as W}from"./fingerprint-policy.js";import{decodeGitPathRecord as C}from"./git-path.js";import{runManagedGitCommand as nt}from"./managed-git.js";import{physicalNodeMode as _,readPhysicalNode as D}from"./physical-tree.js";import{normalizeManagedHostEnvironment as ot,requireManagedHostCommandSuccess as F,resolveManagedHostExecutableIfAvailable as it}from"../process/index.js";import{readCiPullRequestHeadSha as at,resolveCiGitReference as z}from"./ci-environment.js";import{parseGitRepository as ct}from"./remote.js";import{hasErrorCode as v}from"../kernel/error-serialization.js";export async function collectRepoState(t,e={}){const r=N(e.fingerprints),o=e.env??process.env,n=z(o);return await B(t,r,o,n)??st(t,r,n)}export async function collectGitRepoState(t,e={}){const r=N(e.fingerprints),o=e.env??process.env;return B(t,r,o,z(o))}async function B(t,e,r,o){const n=at(r),i=it("git",s.resolve(t),ot(process.env));if(!i&&!jt(t)||i&&Ft(t))return null;const a=await K(t);if(a===null)return null;const c=Y(a,t),u=await R(c.repoRoot,["rev-parse","--verify","--quiet","HEAD"]),m=await lt(c.repoRoot,u,n),f=await R(c.repoRoot,["symbolic-ref","--quiet","--short","HEAD"]),b=await R(c.repoRoot,["config","--get","remote.origin.url"]),P=u!==null&&f===null,h=await ut(c,e,u,""),G=!!h,d=u||"unborn";return{kind:G?"dirty":"commit",repoRoot:c.repoRoot,worktreePath:c.repoRoot,branch:f??(P?o.branch:null),detached:P,commitSha:u,pullRequest:o.pullRequest,pullRequestHeadSha:m,remoteUrl:b,repository:ct(b),dirty:G,dirtyFingerprint:h,contentFingerprint:null,cacheKey:h?`dirty/${d}-${h}`:`commits/${d}`}}function st(t,e,r){const o=p.realpathSync.native(s.resolve(t)),n=Q(o,e);if(Q(o,e)!==n)throw new Error("Physical repository snapshot changed while collecting repository state");const a=n.slice(0,24);return{kind:"nogit",repoRoot:null,worktreePath:o,branch:null,detached:!1,commitSha:null,pullRequest:r.pullRequest,pullRequestHeadSha:null,remoteUrl:null,repository:null,dirty:!1,dirtyFingerprint:null,contentFingerprint:a,cacheKey:`nogit/${a}`}}async function K(t){const e=["rev-parse","--show-toplevel"],r=await O(t,e);if(r.exitCode===0){const o=r.stdout.trim();if(o.length>0)return o;throw new Error("Git rev-parse returned an empty repository root")}if(Dt(r))return null;throw F(T(e),r),new Error("Unreachable Git repository probe result")}function Y(t,e){const r=p.realpathSync.native(s.resolve(t)),o=p.realpathSync.native(s.resolve(e)),n=Ct(s.relative(r,o));if(n===".."||n.startsWith("../")||s.isAbsolute(n)||process.platform==="win32"&&s.win32.isAbsolute(n))throw new Error(`Product directory must be inside its Git worktree: ${o}`);return{productDir:o,productPathspec:n?$t(n):".",productRootRelativePath:n,repoRoot:r}}export function summarizeRepoStateForMetadata(t){return t?{kind:t.kind,cacheKey:t.cacheKey,branch:t.branch,detached:t.detached,commitSha:t.commitSha,dirty:t.dirty,dirtyFingerprint:t.dirtyFingerprint,contentFingerprint:t.contentFingerprint,pullRequest:t.pullRequest,pullRequestHeadSha:t.pullRequestHeadSha,repoRoot:t.repoRoot,repository:t.repository,worktreePath:t.worktreePath,remoteUrl:t.remoteUrl}:null}async function lt(t,e,r){if(e===null||r===null)return null;if(e===r)return r;const o=await w(t,["cat-file","commit","HEAD"]),n=[];for(const i of o.split(`
2
- `)){if(i.length===0)break;i.startsWith("parent ")&&n.push(i.slice(7))}return n.length>=2&&n.includes(r)?r:null}async function ut(t,e,r,o){const n=await j(t,e,r,o),i=await j(t,e,r,o);if(n!==i)throw new Error("Git HEAD, index, untracked inventory, submodule state, or physical snapshot changed while collecting repository state");return n?.slice(0,24)??null}async function j(t,e,r,o){await X(t.repoRoot,r);const n=$.createHash("sha256");let i=!1;const a=await vt(t.repoRoot),[c,u]=await Promise.all([V(t,a),pt(t,r,a)]),m=wt(c),f=Rt(u),b=[...new Set([...m.keys(),...f.keys()])].sort(y);for(const d of b){const g=m.get(d)??[],E=f.get(d)??[],M=g.some(x=>x.mode==="160000")||E.some(x=>x.mode==="160000");if(W(d,o,e)&&(!M||!rt(d,o,e)))continue;const tt=g.length>0?g[0]:E[0],H=D(t.productDir,d),U=M?await ft(t,tt,H,e,o):null;(!mt(g,E)||!ht(g,H,U,a))&&(i=!0,gt(n,d,E,g,H,U,a))}const P=await w(t.repoRoot,["ls-files","--others","--exclude-per-directory=.gitignore","--",t.productPathspec]),h=xt(t,A(P,"Git ls-files").map(d=>C(d))).filter(d=>!W(d.productRelativePath,o,e));if(h.length>0){i=!0,n.update("untracked-state-v2\0");for(const d of h)l(n,"path",d.productRelativePath),q(n,D(t.productDir,d.productRelativePath),a)}const G=await V(t,a);if(!Gt(c,G))throw new Error("Git index changed while collecting repository state");return await X(t.repoRoot,r),i?n.digest("hex"):null}async function V(t,e){const r=await w(t.repoRoot,["ls-files","--stage","--abbrev=64","--",t.productPathspec]);return dt(t,r,e)}function dt(t,e,r){const o=[];for(const n of A(e,"Git ls-files")){const i=n.indexOf(" ");if(i<0)throw new Error("Git ls-files returned malformed stage metadata");const a=n.slice(0,i).split(" "),c=I(C(n.slice(i+1)));if(a.length!==3||!/^[0-7]{6}$/u.test(a[0])||!J(a[1],r)||!/^[0-3]$/u.test(a[2]))throw new Error("Git ls-files returned invalid stage metadata");const u=L(t,c);if(!u)throw new Error(`Git ls-files returned a path outside the product: ${c}`);o.push({mode:a[0],objectId:a[1],productRelativePath:u,rootRelativePath:c,stage:Number(a[2])})}return o.sort(Ht)}async function pt(t,e,r){if(e===null)return[];const o=await w(t.repoRoot,["ls-tree","-r","--full-tree",e,"--",t.productPathspec]);return yt(t,o,r)}async function ft(t,e,r,o,n){if(r.kind==="missing"||r.kind==="ancestor-missing")return{kind:"missing",node:r};if(r.kind!=="directory")return{kind:"non-directory",node:r};const i=St(t,e),a=await K(i);if(a===null||!It(a,i))throw new Error(`Gitlink is not initialized as a repository: ${e.productRelativePath}`);const c=Y(a,i),u=await R(c.repoRoot,["rev-parse","--verify","--quiet","HEAD"]),m=await j(c,o,u,kt(n,e.productRelativePath)),f=D(t.productDir,e.productRelativePath);if(f.kind!=="directory"||!Et(f.identity,r.identity))throw new Error(`Gitlink path changed while collecting repository state: ${e.productRelativePath}`);return{kind:"initialized",dirtyFingerprint:m,head:u,identity:f.identity}}function ht(t,e,r,o){if(t.length!==1||t[0]?.stage!==0)return!1;const n=t[0];return n.mode==="160000"?r?.kind==="initialized"&&r.head===n.objectId&&r.dirtyFingerprint===null:n.mode==="120000"?e.kind==="symlink"&&k(o,e.target)===n.objectId:n.mode==="100644"||n.mode==="100755"?e.kind==="file"&&Pt(e.mode,n.mode)===n.mode&&k(o,e.contents)===n.objectId:!1}function mt(t,e){return e.length===0&&t.length===0?!0:e.length!==1||t.length!==1||t[0]?.stage!==0?!1:e[0]?.mode===t[0]?.mode&&e[0]?.objectId===t[0]?.objectId}function gt(t,e,r,o,n,i,a){t.update("tracked-path-state-v2\0"),l(t,"path",e),r.length===0&&t.update("head-missing\0");for(const c of r)t.update("head-entry\0"),l(t,"mode",c.mode),l(t,"object",c.objectId);o.length===0&&t.update("index-missing\0");for(const c of o)t.update("index-entry\0"),l(t,"mode",c.mode),l(t,"object",c.objectId),l(t,"stage",c.stage.toString());i?bt(t,i,a):q(t,n,a)}function yt(t,e,r){const o=[];for(const n of A(e,"Git ls-tree")){const i=n.indexOf(" "),a=n.slice(0,i).split(" ");if(i<0||a.length!==3||!/^[0-7]{6}$/u.test(a[0])||!/^(?:blob|commit)$/u.test(a[1])||!J(a[2],r))throw new Error("Git ls-tree returned invalid tree metadata");const c=I(C(n.slice(i+1))),u=L(t,c);if(!u)throw new Error(`Git ls-tree returned a path outside the product: ${c}`);o.push({mode:a[0],objectId:a[2],productRelativePath:u,rootRelativePath:c})}return o.sort((n,i)=>y(n.productRelativePath,i.productRelativePath))}async function vt(t){const e=(await w(t,["rev-parse","--show-object-format"])).trim();if(e==="sha1"||e==="sha256")return e;throw new Error(`Unsupported Git object format: ${e||"empty"}`)}function wt(t){const e=new Map;for(const r of t){const o=e.get(r.productRelativePath);o?o.push(r):e.set(r.productRelativePath,[r])}return e}function Rt(t){const e=new Map;for(const r of t){const o=e.get(r.productRelativePath);o?o.push(r):e.set(r.productRelativePath,[r])}return e}function bt(t,e,r){if(t.update("gitlink-worktree-state-v2\0"),l(t,"kind",e.kind),e.kind==="initialized"){e.head===null?t.update("head-missing\0"):l(t,"head",e.head),e.dirtyFingerprint===null?t.update("nested-clean\0"):l(t,"nested-dirty",e.dirtyFingerprint);return}q(t,e.node,r)}function q(t,e,r){switch(t.update("physical-node-v2\0"),l(t,"kind",e.kind),e.kind){case"file":l(t,"mode",process.platform==="win32"?"platform-mode-ignored":e.mode&73n?"100755":"100644"),l(t,"blob",k(r,e.contents)),S(t,e.contents);break;case"symlink":l(t,"blob",k(r,e.target)),S(t,e.target);break;case"directory":l(t,"mode",_(e.mode));break;case"ancestor-symlink":l(t,"obstacle",e.obstaclePath),S(t,e.target);break;case"ancestor-non-directory":l(t,"obstacle",e.obstaclePath),l(t,"mode",_(e.mode));break;case"ancestor-missing":l(t,"obstacle",e.obstaclePath);break;case"missing":break}}function Pt(t,e){return process.platform==="win32"?e:t&73n?"100755":"100644"}function k(t,e){return $.createHash(t).update(`blob ${e.byteLength.toString()}\0`).update(e).digest("hex")}function Gt(t,e){return t.length===e.length&&t.every((r,o)=>{const n=e[o];return r.mode===n.mode&&r.objectId===n.objectId&&r.productRelativePath===n.productRelativePath&&r.rootRelativePath===n.rootRelativePath&&r.stage===n.stage})}function Et(t,e){return t.dev===e.dev&&t.ino===e.ino&&t.type===e.type}function J(t,e){const r=e==="sha1"?40:64;return t.length===r&&/^[0-9a-f]+$/u.test(t)}function kt(t,e){return t?e?`${t}/${e}`:t:e}function St(t,e){const r=e.productRelativePath.split("/");if(r.some(i=>i.length===0||i==="."||i===".."))throw new Error(`Git returned an invalid product path: ${e.productRelativePath}`);const o=s.resolve(t.productDir,...r),n=s.relative(t.productDir,o);if(n===".."||n.startsWith(`..${s.sep}`)||s.isAbsolute(n))throw new Error(`Git returned a path outside the product: ${e.rootRelativePath}`);return o}function It(t,e){const r=p.realpathSync.native(s.resolve(t)),o=p.realpathSync.native(s.resolve(e));return process.platform==="win32"?r.toLocaleLowerCase("en-US")===o.toLocaleLowerCase("en-US"):r===o}function l(t,e,r){t.update(`${e}\0`),S(t,Buffer.from(r))}function S(t,e){t.update(`${e.byteLength.toString()}\0`),t.update(e),t.update("\0")}function Ht(t,e){return y(t.productRelativePath,e.productRelativePath)||t.stage-e.stage||y(t.mode,e.mode)||y(t.objectId,e.objectId)}function xt(t,e){const r=new Map;for(const o of e){const n=I(o);if(n===".."||n.startsWith("../")||s.isAbsolute(n)||process.platform==="win32"&&s.win32.isAbsolute(n))throw new Error(`Git returned a path outside its worktree: ${n}`);const i=L(t,n);i&&r.set(n,{productRelativePath:i,rootRelativePath:n})}return[...r.values()].sort((o,n)=>y(o.productRelativePath,n.productRelativePath))}function L(t,e){if(!e)return null;if(!t.productRootRelativePath)return e;const r=`${t.productRootRelativePath}/`;return(process.platform==="win32"?e.toLocaleLowerCase("en-US").startsWith(r.toLocaleLowerCase("en-US")):e.startsWith(r))?e.slice(r.length):null}function $t(t){return`:(top,literal)${t}`}function I(t){return t.replace(/^\.\/+/,"").replace(/\/+$/,"")}function Ct(t){return I(t.split(s.sep).join("/"))}function y(t,e){return t<e?-1:t>e?1:0}function Q(t,e){const r=$.createHash("sha256");return et(r,t,t,e),r.digest("hex")}async function w(t,e){const r=await O(t,e);return F(T(e),r).stdout}async function R(t,e){const r=await O(t,e);if(r.exitCode===0)return r.stdout.trim()||null;if(r.exitCode===1&&r.stdout.trim().length===0&&r.stderr.trim().length===0)return null;throw F(T(e),r),new Error("Unreachable Git command result")}function O(t,e){return nt(t,["--no-replace-objects","--no-pager","--no-optional-locks","-c","core.fsmonitor=false","-c","core.quotePath=true",...e],{repositoryConfigOnly:!0})}async function X(t,e){if(await R(t,["rev-parse","--verify","--quiet","HEAD"])!==e)throw new Error("Git HEAD changed while collecting repository state")}function A(t,e){if(t.length===0)return[];if(!t.endsWith(`
1
+ import C from"crypto";import p from"fs";import c from"path";import{appendFingerprintPathToHash as et,hasIncludedFingerprintDescendantAtPrefix as rt,normalizeFingerprintPolicy as N,shouldIgnoreCanonicalFingerprintPathAtPrefix as W,normalizeCanonicalRelativePath as k}from"./fingerprint-policy.js";import{decodeGitPathRecord as $}from"./git-path.js";import{runManagedGitCommand as nt,gitCommandLabel as D}from"./managed-git.js";import{physicalNodeMode as _,readPhysicalNode as F,sameIdentityRecord as ot,compareStrings as y}from"./physical-tree.js";import{normalizeManagedHostEnvironment as it,requireManagedHostCommandSuccess as j,resolveManagedHostExecutableIfAvailable as at}from"../process/index.js";import{readCiPullRequestHeadSha as st,resolveCiGitReference as z}from"./ci-environment.js";import{parseGitRepository as ct}from"./remote.js";import{hasErrorCode as v}from"../kernel/error-serialization.js";export async function collectRepoState(t,e={}){const r=N(e.fingerprints),o=e.env??process.env,n=z(o);return await B(t,r,o,n)??lt(t,r,n)}export async function collectGitRepoState(t,e={}){const r=N(e.fingerprints),o=e.env??process.env;return B(t,r,o,z(o))}async function B(t,e,r,o){const n=st(r),i=at("git",c.resolve(t),it(process.env));if(!i&&!jt(t)||i&&Ft(t))return null;const a=await K(t);if(a===null)return null;const s=Y(a,t),u=await R(s.repoRoot,["rev-parse","--verify","--quiet","HEAD"]),m=await ut(s.repoRoot,u,n),f=await R(s.repoRoot,["symbolic-ref","--quiet","--short","HEAD"]),b=await R(s.repoRoot,["config","--get","remote.origin.url"]),P=u!==null&&f===null,h=await dt(s,e,u,""),G=!!h,d=u||"unborn";return{kind:G?"dirty":"commit",repoRoot:s.repoRoot,worktreePath:s.repoRoot,branch:f??(P?o.branch:null),detached:P,commitSha:u,pullRequest:o.pullRequest,pullRequestHeadSha:m,remoteUrl:b,repository:ct(b),dirty:G,dirtyFingerprint:h,contentFingerprint:null,cacheKey:h?`dirty/${d}-${h}`:`commits/${d}`}}function lt(t,e,r){const o=p.realpathSync.native(c.resolve(t)),n=Q(o,e);if(Q(o,e)!==n)throw new Error("Physical repository snapshot changed while collecting repository state");const a=n.slice(0,24);return{kind:"nogit",repoRoot:null,worktreePath:o,branch:null,detached:!1,commitSha:null,pullRequest:r.pullRequest,pullRequestHeadSha:null,remoteUrl:null,repository:null,dirty:!1,dirtyFingerprint:null,contentFingerprint:a,cacheKey:`nogit/${a}`}}async function K(t){const e=["rev-parse","--show-toplevel"],r=await A(t,e);if(r.exitCode===0){const o=r.stdout.trim();if(o.length>0)return o;throw new Error("Git rev-parse returned an empty repository root")}if(Dt(r))return null;throw j(D(e),r),new Error("Unreachable Git repository probe result")}function Y(t,e){const r=p.realpathSync.native(c.resolve(t)),o=p.realpathSync.native(c.resolve(e)),n=$t(c.relative(r,o));if(n===".."||n.startsWith("../")||c.isAbsolute(n)||process.platform==="win32"&&c.win32.isAbsolute(n))throw new Error(`Product directory must be inside its Git worktree: ${o}`);return{productDir:o,productPathspec:n?Ct(n):".",productRootRelativePath:n,repoRoot:r}}export function summarizeRepoStateForMetadata(t){return t?{kind:t.kind,cacheKey:t.cacheKey,branch:t.branch,detached:t.detached,commitSha:t.commitSha,dirty:t.dirty,dirtyFingerprint:t.dirtyFingerprint,contentFingerprint:t.contentFingerprint,pullRequest:t.pullRequest,pullRequestHeadSha:t.pullRequestHeadSha,repoRoot:t.repoRoot,repository:t.repository,worktreePath:t.worktreePath,remoteUrl:t.remoteUrl}:null}async function ut(t,e,r){if(e===null||r===null)return null;if(e===r)return r;const o=await w(t,["cat-file","commit","HEAD"]),n=[];for(const i of o.split(`
2
+ `)){if(i.length===0)break;i.startsWith("parent ")&&n.push(i.slice(7))}return n.length>=2&&n.includes(r)?r:null}async function dt(t,e,r,o){const n=await q(t,e,r,o),i=await q(t,e,r,o);if(n!==i)throw new Error("Git HEAD, index, untracked inventory, submodule state, or physical snapshot changed while collecting repository state");return n?.slice(0,24)??null}async function q(t,e,r,o){await X(t.repoRoot,r);const n=C.createHash("sha256");let i=!1;const a=await wt(t.repoRoot),[s,u]=await Promise.all([V(t,a),ft(t,r,a)]),m=Rt(s),f=bt(u),b=[...new Set([...m.keys(),...f.keys()])].sort(y);for(const d of b){const g=m.get(d)??[],E=f.get(d)??[],M=g.some(x=>x.mode==="160000")||E.some(x=>x.mode==="160000");if(W(d,o,e)&&(!M||!rt(d,o,e)))continue;const tt=g.length>0?g[0]:E[0],H=F(t.productDir,d),U=M?await ht(t,tt,H,e,o):null;(!gt(g,E)||!mt(g,H,U,a))&&(i=!0,yt(n,d,E,g,H,U,a))}const P=await w(t.repoRoot,["ls-files","--others","--exclude-per-directory=.gitignore","--",t.productPathspec]),h=xt(t,T(P,"Git ls-files").map(d=>$(d))).filter(d=>!W(d.productRelativePath,o,e));if(h.length>0){i=!0,n.update("untracked-state-v2\0");for(const d of h)l(n,"path",d.productRelativePath),L(n,F(t.productDir,d.productRelativePath),a)}const G=await V(t,a);if(!Et(s,G))throw new Error("Git index changed while collecting repository state");return await X(t.repoRoot,r),i?n.digest("hex"):null}async function V(t,e){const r=await w(t.repoRoot,["ls-files","--stage","--abbrev=64","--",t.productPathspec]);return pt(t,r,e)}function pt(t,e,r){const o=[];for(const n of T(e,"Git ls-files")){const i=n.indexOf(" ");if(i<0)throw new Error("Git ls-files returned malformed stage metadata");const a=n.slice(0,i).split(" "),s=k($(n.slice(i+1)));if(a.length!==3||!/^[0-7]{6}$/u.test(a[0])||!J(a[1],r)||!/^[0-3]$/u.test(a[2]))throw new Error("Git ls-files returned invalid stage metadata");const u=O(t,s);if(!u)throw new Error(`Git ls-files returned a path outside the product: ${s}`);o.push({mode:a[0],objectId:a[1],productRelativePath:u,rootRelativePath:s,stage:Number(a[2])})}return o.sort(Ht)}async function ft(t,e,r){if(e===null)return[];const o=await w(t.repoRoot,["ls-tree","-r","--full-tree",e,"--",t.productPathspec]);return vt(t,o,r)}async function ht(t,e,r,o,n){if(r.kind==="missing"||r.kind==="ancestor-missing")return{kind:"missing",node:r};if(r.kind!=="directory")return{kind:"non-directory",node:r};const i=St(t,e),a=await K(i);if(a===null||!It(a,i))throw new Error(`Gitlink is not initialized as a repository: ${e.productRelativePath}`);const s=Y(a,i),u=await R(s.repoRoot,["rev-parse","--verify","--quiet","HEAD"]),m=await q(s,o,u,kt(n,e.productRelativePath)),f=F(t.productDir,e.productRelativePath);if(f.kind!=="directory"||!ot(f.identity,r.identity))throw new Error(`Gitlink path changed while collecting repository state: ${e.productRelativePath}`);return{kind:"initialized",dirtyFingerprint:m,head:u,identity:f.identity}}function mt(t,e,r,o){if(t.length!==1||t[0]?.stage!==0)return!1;const n=t[0];return n.mode==="160000"?r?.kind==="initialized"&&r.head===n.objectId&&r.dirtyFingerprint===null:n.mode==="120000"?e.kind==="symlink"&&S(o,e.target)===n.objectId:n.mode==="100644"||n.mode==="100755"?e.kind==="file"&&Gt(e.mode,n.mode)===n.mode&&S(o,e.contents)===n.objectId:!1}function gt(t,e){return e.length===0&&t.length===0?!0:e.length!==1||t.length!==1||t[0]?.stage!==0?!1:e[0]?.mode===t[0]?.mode&&e[0]?.objectId===t[0]?.objectId}function yt(t,e,r,o,n,i,a){t.update("tracked-path-state-v2\0"),l(t,"path",e),r.length===0&&t.update("head-missing\0");for(const s of r)t.update("head-entry\0"),l(t,"mode",s.mode),l(t,"object",s.objectId);o.length===0&&t.update("index-missing\0");for(const s of o)t.update("index-entry\0"),l(t,"mode",s.mode),l(t,"object",s.objectId),l(t,"stage",s.stage.toString());i?Pt(t,i,a):L(t,n,a)}function vt(t,e,r){const o=[];for(const n of T(e,"Git ls-tree")){const i=n.indexOf(" "),a=n.slice(0,i).split(" ");if(i<0||a.length!==3||!/^[0-7]{6}$/u.test(a[0])||!/^(?:blob|commit)$/u.test(a[1])||!J(a[2],r))throw new Error("Git ls-tree returned invalid tree metadata");const s=k($(n.slice(i+1))),u=O(t,s);if(!u)throw new Error(`Git ls-tree returned a path outside the product: ${s}`);o.push({mode:a[0],objectId:a[2],productRelativePath:u,rootRelativePath:s})}return o.sort((n,i)=>y(n.productRelativePath,i.productRelativePath))}async function wt(t){const e=(await w(t,["rev-parse","--show-object-format"])).trim();if(e==="sha1"||e==="sha256")return e;throw new Error(`Unsupported Git object format: ${e||"empty"}`)}function Rt(t){const e=new Map;for(const r of t){const o=e.get(r.productRelativePath);o?o.push(r):e.set(r.productRelativePath,[r])}return e}function bt(t){const e=new Map;for(const r of t){const o=e.get(r.productRelativePath);o?o.push(r):e.set(r.productRelativePath,[r])}return e}function Pt(t,e,r){if(t.update("gitlink-worktree-state-v2\0"),l(t,"kind",e.kind),e.kind==="initialized"){e.head===null?t.update("head-missing\0"):l(t,"head",e.head),e.dirtyFingerprint===null?t.update("nested-clean\0"):l(t,"nested-dirty",e.dirtyFingerprint);return}L(t,e.node,r)}function L(t,e,r){switch(t.update("physical-node-v2\0"),l(t,"kind",e.kind),e.kind){case"file":l(t,"mode",process.platform==="win32"?"platform-mode-ignored":e.mode&73n?"100755":"100644"),l(t,"blob",S(r,e.contents)),I(t,e.contents);break;case"symlink":l(t,"blob",S(r,e.target)),I(t,e.target);break;case"directory":l(t,"mode",_(e.mode));break;case"ancestor-symlink":l(t,"obstacle",e.obstaclePath),I(t,e.target);break;case"ancestor-non-directory":l(t,"obstacle",e.obstaclePath),l(t,"mode",_(e.mode));break;case"ancestor-missing":l(t,"obstacle",e.obstaclePath);break;case"missing":break}}function Gt(t,e){return process.platform==="win32"?e:t&73n?"100755":"100644"}function S(t,e){return C.createHash(t).update(`blob ${e.byteLength.toString()}\0`).update(e).digest("hex")}function Et(t,e){return t.length===e.length&&t.every((r,o)=>{const n=e[o];return r.mode===n.mode&&r.objectId===n.objectId&&r.productRelativePath===n.productRelativePath&&r.rootRelativePath===n.rootRelativePath&&r.stage===n.stage})}function J(t,e){const r=e==="sha1"?40:64;return t.length===r&&/^[0-9a-f]+$/u.test(t)}function kt(t,e){return t?e?`${t}/${e}`:t:e}function St(t,e){const r=e.productRelativePath.split("/");if(r.some(i=>i.length===0||i==="."||i===".."))throw new Error(`Git returned an invalid product path: ${e.productRelativePath}`);const o=c.resolve(t.productDir,...r),n=c.relative(t.productDir,o);if(n===".."||n.startsWith(`..${c.sep}`)||c.isAbsolute(n))throw new Error(`Git returned a path outside the product: ${e.rootRelativePath}`);return o}function It(t,e){const r=p.realpathSync.native(c.resolve(t)),o=p.realpathSync.native(c.resolve(e));return process.platform==="win32"?r.toLocaleLowerCase("en-US")===o.toLocaleLowerCase("en-US"):r===o}function l(t,e,r){t.update(`${e}\0`),I(t,Buffer.from(r))}function I(t,e){t.update(`${e.byteLength.toString()}\0`),t.update(e),t.update("\0")}function Ht(t,e){return y(t.productRelativePath,e.productRelativePath)||t.stage-e.stage||y(t.mode,e.mode)||y(t.objectId,e.objectId)}function xt(t,e){const r=new Map;for(const o of e){const n=k(o);if(n===".."||n.startsWith("../")||c.isAbsolute(n)||process.platform==="win32"&&c.win32.isAbsolute(n))throw new Error(`Git returned a path outside its worktree: ${n}`);const i=O(t,n);i&&r.set(n,{productRelativePath:i,rootRelativePath:n})}return[...r.values()].sort((o,n)=>y(o.productRelativePath,n.productRelativePath))}function O(t,e){if(!e)return null;if(!t.productRootRelativePath)return e;const r=`${t.productRootRelativePath}/`;return(process.platform==="win32"?e.toLocaleLowerCase("en-US").startsWith(r.toLocaleLowerCase("en-US")):e.startsWith(r))?e.slice(r.length):null}function Ct(t){return`:(top,literal)${t}`}function $t(t){return k(t.split(c.sep).join("/"))}function Q(t,e){const r=C.createHash("sha256");return et(r,t,t,e),r.digest("hex")}async function w(t,e){const r=await A(t,e);return j(D(e),r).stdout}async function R(t,e){const r=await A(t,e);if(r.exitCode===0)return r.stdout.trim()||null;if(r.exitCode===1&&r.stdout.trim().length===0&&r.stderr.trim().length===0)return null;throw j(D(e),r),new Error("Unreachable Git command result")}function A(t,e){return nt(t,["--no-replace-objects","--no-pager","--no-optional-locks","-c","core.fsmonitor=false","-c","core.quotePath=true",...e],{repositoryConfigOnly:!0})}async function X(t,e){if(await R(t,["rev-parse","--verify","--quiet","HEAD"])!==e)throw new Error("Git HEAD changed while collecting repository state")}function T(t,e){if(t.length===0)return[];if(!t.endsWith(`
3
3
  `))throw new Error(`${e} returned an unterminated path record`);return t.slice(0,-1).split(`
4
- `)}function T(t){const e=t.find(r=>!r.startsWith("-"));return e?`Git ${e}`:"Git command"}function Dt(t){return`${t.stderr}
5
- ${t.stdout}`.toLowerCase().includes("not a git repository")}function Ft(t){const e=new Set(["GIT_CEILING_DIRECTORIES","GIT_DISCOVERY_ACROSS_FILESYSTEM"]);if(Object.keys(process.env).some(r=>e.has(process.platform==="win32"?r.toUpperCase():r)))return!1;try{let r=p.realpathSync.native(s.resolve(t));for(;;){if(!p.statSync(r).isDirectory())return!1;for(const n of[".git","HEAD"])try{return p.lstatSync(s.join(r,n)),!1}catch(i){if(!v(i,"ENOENT"))return!1}const o=s.dirname(r);if(o===r)return!0;r=o}}catch{return!1}}function jt(t){let e=p.realpathSync.native(s.resolve(t)),r=p.statSync(e).dev;const o=qt(),n=Ot(process.env.GIT_DISCOVERY_ACROSS_FILESYSTEM);let i=s.dirname(e);for(;i!==e;){if(o.has(e))return!1;if(Z(s.join(e,".git")))return!0;const a=p.statSync(i).dev;if(!n&&a!==r)return!1;e=i,r=a,i=s.dirname(e)}return o.has(e)?!1:Z(s.join(e,".git"))}function qt(){const t=process.env.GIT_CEILING_DIRECTORIES;return t?new Set(t.split(s.delimiter).filter(Boolean).map(e=>Lt(e))):new Set}function Lt(t){const e=s.resolve(t);try{return p.realpathSync.native(e)}catch(r){if(v(r,"ENOENT")||v(r,"ENOTDIR"))return e;throw r}}function Ot(t){return/^(?:1|on|true|yes)$/iu.test(t||"")}function Z(t){try{return p.lstatSync(t),!0}catch(e){if(v(e,"ENOENT")||v(e,"ENOTDIR"))return!1;throw e}}
4
+ `)}function Dt(t){return`${t.stderr}
5
+ ${t.stdout}`.toLowerCase().includes("not a git repository")}function Ft(t){const e=new Set(["GIT_CEILING_DIRECTORIES","GIT_DISCOVERY_ACROSS_FILESYSTEM"]);if(Object.keys(process.env).some(r=>e.has(process.platform==="win32"?r.toUpperCase():r)))return!1;try{let r=p.realpathSync.native(c.resolve(t));for(;;){if(!p.statSync(r).isDirectory())return!1;for(const n of[".git","HEAD"])try{return p.lstatSync(c.join(r,n)),!1}catch(i){if(!v(i,"ENOENT"))return!1}const o=c.dirname(r);if(o===r)return!0;r=o}}catch{return!1}}function jt(t){let e=p.realpathSync.native(c.resolve(t)),r=p.statSync(e).dev;const o=qt(),n=Ot(process.env.GIT_DISCOVERY_ACROSS_FILESYSTEM);let i=c.dirname(e);for(;i!==e;){if(o.has(e))return!1;if(Z(c.join(e,".git")))return!0;const a=p.statSync(i).dev;if(!n&&a!==r)return!1;e=i,r=a,i=c.dirname(e)}return o.has(e)?!1:Z(c.join(e,".git"))}function qt(){const t=process.env.GIT_CEILING_DIRECTORIES;return t?new Set(t.split(c.delimiter).filter(Boolean).map(e=>Lt(e))):new Set}function Lt(t){const e=c.resolve(t);try{return p.realpathSync.native(e)}catch(r){if(v(r,"ENOENT")||v(r,"ENOTDIR"))return e;throw r}}function Ot(t){return/^(?:1|on|true|yes)$/iu.test(t||"")}function Z(t){try{return p.lstatSync(t),!0}catch(e){if(v(e,"ENOENT")||v(e,"ENOTDIR"))return!1;throw e}}
@@ -1 +1 @@
1
- import c from"path";import{normalizeConfiguredInputs as o,normalizeConfiguredSteps as p,normalizeOptionalString as e}from"./configured-steps.js";export function normalizeBuildConfig(t,s){if(t==null)return null;if(!w(t))throw new Error(`${s} must be an object`);const n=e(t.kind);if(n==="tsc")return{kind:n,cwd:e(t.cwd),entry:e(t.entry)||"src/index.ts",tsconfig:e(t.tsconfig)||"tsconfig.json",outDir:e(t.outDir)||"dist",inputs:o(t.inputs,s)};if(n==="script"){const r=e(t.script);if(!r)throw new Error(`${s}.script must be a non-empty string`);return{kind:n,cwd:e(t.cwd),script:r,inputs:o(t.inputs,s)}}if(n==="next")return{kind:n,cwd:e(t.cwd),distDir:e(t.distDir)||"dist",tsconfig:e(t.tsconfig)||"tsconfig.json",inputs:o(t.inputs,s)};if(n==="steps")return{kind:n,inputs:o(t.inputs,s),steps:p(t.steps,`${s}.steps`)};throw new Error(`${s}.kind must be one of: tsc, script, next, steps`)}export function buildConfigToPrepare(t){if(!t)return{inputs:[],steps:[]};if(t.kind==="steps")return{inputs:[...t.inputs],steps:[...t.steps]};if(t.kind==="script")return{inputs:[...t.inputs],steps:[{kind:"command",cmd:t.script,cwd:t.cwd||void 0,inputs:[]}]};if(t.kind==="next")return{inputs:t.inputs.length>0?[...t.inputs]:u(t),steps:[{kind:"module",specifier:"@gfdelarue/testkit/config/next-runtime-tsconfig#writeNextRuntimeTsconfig",cwd:t.cwd||void 0,inputs:[]},{kind:"command",cmd:"{bin:next} build",cwd:t.cwd||void 0,inputs:[]}]};const s=t.inputs.length>0?[...t.inputs]:d(t),n=`{bin:tsc} -p ${t.tsconfig} --outDir "{prepareDir}/${t.outDir}"`,r=f(t.entry);return{inputs:s,steps:[{kind:"command",cmd:n,cwd:t.cwd||void 0,inputs:[]},{kind:"module",specifier:"@gfdelarue/testkit/config/build-assets#copyTscRuntimeAssets",cwd:t.cwd||void 0,inputs:[],args:{sourceDir:r,outDir:t.outDir}}]}}function f(t){const s=t.split(c.sep).join("/");if(s.startsWith("src/"))return"src";const n=s.split("/").filter(Boolean);return n.length>1?n[0]??".":"."}function d(t){const s=new Set([i(t.cwd,t.tsconfig),i(t.cwd,"package.json")]),n=i(t.cwd,t.entry.split(c.sep).join("/")),r=n.includes("/")?n.slice(0,n.indexOf("/")):n;return r&&s.add(r),[...s]}function u(t){return[...new Set([i(t.cwd,t.tsconfig),i(t.cwd,"package.json"),i(t.cwd,"src"),i(t.cwd,"app"),i(t.cwd,"public"),i(t.cwd,"next.config.js"),i(t.cwd,"next.config.mjs"),i(t.cwd,"next.config.ts")])]}function i(t,s){const n=(t||"").split(c.sep).join("/").replace(/^\.\/+/,"").replace(/\/+$/g,""),r=s.split(c.sep).join("/").replace(/^\.\/+/,"");return!n||n==="."?r:`${n}/${r}`.replace(/\/+/g,"/")}function w(t){return t!==null&&typeof t=="object"}
1
+ import c from"path";import{normalizeConfiguredInputs as o,normalizeConfiguredSteps as p}from"./configured-steps.js";import{isNonNullObject as f,normalizeOptionalString as e}from"../kernel/unknown-values.js";export function normalizeBuildConfig(t,s){if(t==null)return null;if(!f(t))throw new Error(`${s} must be an object`);const n=e(t.kind);if(n==="tsc")return{kind:n,cwd:e(t.cwd),entry:e(t.entry)||"src/index.ts",tsconfig:e(t.tsconfig)||"tsconfig.json",outDir:e(t.outDir)||"dist",inputs:o(t.inputs,s)};if(n==="script"){const r=e(t.script);if(!r)throw new Error(`${s}.script must be a non-empty string`);return{kind:n,cwd:e(t.cwd),script:r,inputs:o(t.inputs,s)}}if(n==="next")return{kind:n,cwd:e(t.cwd),distDir:e(t.distDir)||"dist",tsconfig:e(t.tsconfig)||"tsconfig.json",inputs:o(t.inputs,s)};if(n==="steps")return{kind:n,inputs:o(t.inputs,s),steps:p(t.steps,`${s}.steps`)};throw new Error(`${s}.kind must be one of: tsc, script, next, steps`)}export function buildConfigToPrepare(t){if(!t)return{inputs:[],steps:[]};if(t.kind==="steps")return{inputs:[...t.inputs],steps:[...t.steps]};if(t.kind==="script")return{inputs:[...t.inputs],steps:[{kind:"command",cmd:t.script,cwd:t.cwd||void 0,inputs:[]}]};if(t.kind==="next")return{inputs:t.inputs.length>0?[...t.inputs]:w(t),steps:[{kind:"module",specifier:"@gfdelarue/testkit/config/next-runtime-tsconfig#writeNextRuntimeTsconfig",cwd:t.cwd||void 0,inputs:[]},{kind:"command",cmd:"{bin:next} build",cwd:t.cwd||void 0,inputs:[]}]};const s=t.inputs.length>0?[...t.inputs]:u(t),n=`{bin:tsc} -p ${t.tsconfig} --outDir "{prepareDir}/${t.outDir}"`,r=d(t.entry);return{inputs:s,steps:[{kind:"command",cmd:n,cwd:t.cwd||void 0,inputs:[]},{kind:"module",specifier:"@gfdelarue/testkit/config/build-assets#copyTscRuntimeAssets",cwd:t.cwd||void 0,inputs:[],args:{sourceDir:r,outDir:t.outDir}}]}}function d(t){const s=t.split(c.sep).join("/");if(s.startsWith("src/"))return"src";const n=s.split("/").filter(Boolean);return n.length>1?n[0]??".":"."}function u(t){const s=new Set([i(t.cwd,t.tsconfig),i(t.cwd,"package.json")]),n=i(t.cwd,t.entry.split(c.sep).join("/")),r=n.includes("/")?n.slice(0,n.indexOf("/")):n;return r&&s.add(r),[...s]}function w(t){return[...new Set([i(t.cwd,t.tsconfig),i(t.cwd,"package.json"),i(t.cwd,"src"),i(t.cwd,"app"),i(t.cwd,"public"),i(t.cwd,"next.config.js"),i(t.cwd,"next.config.mjs"),i(t.cwd,"next.config.ts")])]}function i(t,s){const n=(t||"").split(c.sep).join("/").replace(/^\.\/+/,"").replace(/\/+$/g,""),r=s.split(c.sep).join("/").replace(/^\.\/+/,"");return!n||n==="."?r:`${n}/${r}`.replace(/\/+/g,"/")}
@@ -1 +1 @@
1
- export const CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS=["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"];const n=new Set(["@gfdelarue/testkit/k6","@gfdelarue/testkit/node-vitest/contract","@gfdelarue/testkit/node-vitest/data","@gfdelarue/testkit/playwright"]);export const CONFIGURED_STEP_TESTKIT_MODULE_DIST_PATHS={"@gfdelarue/testkit":["index"],"@gfdelarue/testkit/config":["config","authoring","index"],"@gfdelarue/testkit/config/build-assets":["config","runtime","build-assets"],"@gfdelarue/testkit/config/database-steps":["database","steps"],"@gfdelarue/testkit/config/next-runtime-tsconfig":["config","runtime","next-runtime-tsconfig"],"@gfdelarue/testkit/drizzle":["database","drizzle","index"],"@gfdelarue/testkit/env":["config","runtime","env","index"],"@gfdelarue/testkit/tooling/vitest":["toolchains","vitest","index"]};export function isTestkitPackageSpecifier(t){return t==="@gfdelarue/testkit"||t.startsWith("@gfdelarue/testkit/")}export function requireConfiguredStepTestkitModuleSpecifier(t){if(n.has(t))throw new Error(`Configured lifecycle modules run in Node and may not import engine authoring module ${JSON.stringify(t)}`);const e=CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS.find(i=>i===t);if(!e)throw new Error(`Unsupported configured Testkit module specifier ${JSON.stringify(t)}`);return e}
1
+ export const CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS=["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"];const n=new Set(["@gfdelarue/testkit/environment","@gfdelarue/testkit/node-vitest/data","@gfdelarue/testkit/playwright"]);export const CONFIGURED_STEP_TESTKIT_MODULE_DIST_PATHS={"@gfdelarue/testkit":["index"],"@gfdelarue/testkit/config":["config","authoring","index"],"@gfdelarue/testkit/config/build-assets":["config","runtime","build-assets"],"@gfdelarue/testkit/config/database-steps":["database","steps"],"@gfdelarue/testkit/config/next-runtime-tsconfig":["config","runtime","next-runtime-tsconfig"],"@gfdelarue/testkit/drizzle":["database","drizzle","index"],"@gfdelarue/testkit/env":["config","runtime","env","index"],"@gfdelarue/testkit/tooling/vitest":["toolchains","vitest","index"]};export function isTestkitPackageSpecifier(t){return t==="@gfdelarue/testkit"||t.startsWith("@gfdelarue/testkit/")}export function requireConfiguredStepTestkitModuleSpecifier(t){if(n.has(t))throw new Error(`Configured lifecycle modules run in Node and may not import engine authoring module ${JSON.stringify(t)}`);const e=CONFIGURED_STEP_TESTKIT_MODULE_SPECIFIERS.find(i=>i===t);if(!e)throw new Error(`Unsupported configured Testkit module specifier ${JSON.stringify(t)}`);return e}
@@ -1 +1 @@
1
- import c from"fs";import s from"path";import{isTestkitPackageSpecifier as m,requireConfiguredStepTestkitModuleSpecifier as w}from"./configured-step-testkit-modules.js";import{isUnknownArray as a}from"../kernel/unknown-values.js";export function normalizeOptionalString(n){if(typeof n!="string")return null;const r=n.trim();return r.length>0?r:null}export function normalizeConfiguredInputs(n,r){if(n==null)return[];if(!a(n))throw new Error(`${r}.inputs must be an array`);return n.map((t,e)=>{const i=normalizeOptionalString(t);if(!i)throw new Error(`${r}.inputs[${String(e)}] must be a non-empty string`);return i})}export function normalizeConfiguredSteps(n,r){if(n==null)return[];if(!a(n))throw new Error(`${r} must be an array`);return n.map((t,e)=>normalizeConfiguredStep(t,`${r}[${String(e)}]`))}export function normalizeConfiguredStep(n,r){if(!p(n))throw new Error(`${r} must be an object`);const t=normalizeOptionalString(n.kind);if(t==="command"){const e=normalizeOptionalString(n.run);if(!e)throw new Error(`${r}.run must be a non-empty string`);const i=normalizeStepArgs(n.args,r);return{kind:t,cmd:e,cwd:normalizeOptionalString(n.cwd),inputs:normalizeConfiguredInputs(n.inputs,r),...i!==void 0?{args:i}:{}}}if(t==="sql-file"){const e=normalizeOptionalString(n.path);if(!e)throw new Error(`${r}.path must be a non-empty string`);const i=normalizeStepArgs(n.args,r);return{kind:t,path:e,cwd:normalizeOptionalString(n.cwd),inputs:normalizeConfiguredInputs(n.inputs,r),...i!==void 0?{args:i}:{}}}if(t==="module"){const e=normalizeOptionalString(n.target);if(!e)throw new Error(`${r}.target must be a non-empty string`);const i=normalizeStepArgs(n.args,r);return{kind:t,specifier:e,cwd:normalizeOptionalString(n.cwd),inputs:normalizeConfiguredInputs(n.inputs,r),...i!==void 0?{args:i}:{}}}throw new Error(`${r}.kind must be one of: command, sql-file, module`)}export function parseModuleSpecifier(n){const[r="",t]=String(n).split("#",2);return{modulePath:r,exportName:t||"default"}}export function normalizeStepArgs(n,r){if(n!=null)try{const t=JSON.stringify(n);if(typeof t!="string")throw new Error("JSON serialization returned undefined");return JSON.parse(t)}catch{throw new Error(`${r}.args must be JSON-serializable`)}}export function isBareModuleSpecifier(n){return typeof n!="string"||n.length===0||n.startsWith("./")||n.startsWith("../")?!1:!s.isAbsolute(n)}export function resolveConfiguredCwd(n,r){return s.resolve(n,r||".")}export function resolveConfiguredPath(n,r,t){return s.resolve(resolveConfiguredCwd(n,r),t)}export function collectConfiguredInputs(n,{inputs:r=[],steps:t=[]}={}){const e=new Set;for(const i of r)e.add(resolveConfiguredPath(n,null,i));for(const i of t){if(i.kind==="sql-file"&&e.add(resolveConfiguredPath(n,i.cwd,i.path)),i.kind==="module"){const f=g(i),{modulePath:o}=parseModuleSpecifier(f),u=resolveConfiguredPath(n,i.cwd,o);o.startsWith("@gfdelarue/testkit")||c.existsSync(u)?o.startsWith("@gfdelarue/testkit")||e.add(u):isBareModuleSpecifier(o)||e.add(u)}for(const f of i.inputs||[])e.add(resolveConfiguredPath(n,i.cwd,f))}return[...e].sort()}export function summarizeConfiguredStep(n){return n.kind==="command"?`command: ${n.cmd.trim()}`:n.kind==="sql-file"?`sql: ${n.path}`:`module: ${n.specifier}`}export function finalizeConfiguredInputs(n=[],r){return n.map(t=>r(t))}export function finalizeConfiguredStep(n,r){return n.kind==="command"?{...n,cmd:r(n.cmd),...typeof n.cwd=="string"?{cwd:r(n.cwd)}:{},inputs:finalizeConfiguredInputs(n.inputs,r),...n.args!==void 0?{args:n.args}:{}}:n.kind==="sql-file"?{...n,path:r(n.path),...typeof n.cwd=="string"?{cwd:r(n.cwd)}:{},inputs:finalizeConfiguredInputs(n.inputs,r),...n.args!==void 0?{args:n.args}:{}}:{...n,specifier:r(n.specifier),...typeof n.cwd=="string"?{cwd:r(n.cwd)}:{},inputs:finalizeConfiguredInputs(n.inputs,r),...n.args!==void 0?{args:n.args}:{}}}export function finalizeConfiguredSteps(n=[],r){return n.map(t=>finalizeConfiguredStep(t,r))}export function validateConfiguredCollection({productDir:n,label:r,inputs:t=[],steps:e=[]}){for(const i of t)d(resolveConfiguredPath(n,null,i),`${r} input`);for(const i of e){if(i.cwd&&d(resolveConfiguredCwd(n,i.cwd),`${r} step cwd`),i.kind==="sql-file"&&d(resolveConfiguredPath(n,i.cwd,i.path),`${r} sql file`),i.kind==="module"){const f=g(i),{modulePath:o}=parseModuleSpecifier(f),u=resolveConfiguredPath(n,i.cwd,o);m(o)?w(o):c.existsSync(u)?d(u,`${r} module`):isBareModuleSpecifier(o)||d(u,`${r} module`)}for(const f of i.inputs||[])d(resolveConfiguredPath(n,i.cwd,f),`${r} step input`)}}function d(n,r){if(!c.existsSync(n))throw new Error(`${r} does not exist: ${n}`)}function g(n){const r="specifier"in n?n.specifier:void 0,t="target"in n?n.target:void 0;return r||t}function p(n){return n!==null&&typeof n=="object"}
1
+ import c from"fs";import a from"path";import{isTestkitPackageSpecifier as w,requireConfiguredStepTestkitModuleSpecifier as p}from"./configured-step-testkit-modules.js";import{isUnknownArray as g,isNonNullObject as l,normalizeOptionalString as f}from"../kernel/unknown-values.js";export function normalizeConfiguredInputs(n,r){if(n==null)return[];if(!g(n))throw new Error(`${r}.inputs must be an array`);return n.map((t,e)=>{const i=f(t);if(!i)throw new Error(`${r}.inputs[${String(e)}] must be a non-empty string`);return i})}export function normalizeConfiguredSteps(n,r){if(n==null)return[];if(!g(n))throw new Error(`${r} must be an array`);return n.map((t,e)=>normalizeConfiguredStep(t,`${r}[${String(e)}]`))}export function normalizeConfiguredStep(n,r){if(!l(n))throw new Error(`${r} must be an object`);const t=f(n.kind);if(t==="command"){const e=f(n.run);if(!e)throw new Error(`${r}.run must be a non-empty string`);const i=normalizeStepArgs(n.args,r);return{kind:t,cmd:e,cwd:f(n.cwd),inputs:normalizeConfiguredInputs(n.inputs,r),...i!==void 0?{args:i}:{}}}if(t==="sql-file"){const e=f(n.path);if(!e)throw new Error(`${r}.path must be a non-empty string`);const i=normalizeStepArgs(n.args,r);return{kind:t,path:e,cwd:f(n.cwd),inputs:normalizeConfiguredInputs(n.inputs,r),...i!==void 0?{args:i}:{}}}if(t==="module"){const e=f(n.target);if(!e)throw new Error(`${r}.target must be a non-empty string`);const i=normalizeStepArgs(n.args,r);return{kind:t,specifier:e,cwd:f(n.cwd),inputs:normalizeConfiguredInputs(n.inputs,r),...i!==void 0?{args:i}:{}}}throw new Error(`${r}.kind must be one of: command, sql-file, module`)}export function parseModuleSpecifier(n){const[r="",t]=String(n).split("#",2);return{modulePath:r,exportName:t||"default"}}export function normalizeStepArgs(n,r){if(n!=null)try{const t=JSON.stringify(n);if(typeof t!="string")throw new Error("JSON serialization returned undefined");return JSON.parse(t)}catch{throw new Error(`${r}.args must be JSON-serializable`)}}export function isBareModuleSpecifier(n){return typeof n!="string"||n.length===0||n.startsWith("./")||n.startsWith("../")?!1:!a.isAbsolute(n)}export function resolveConfiguredCwd(n,r){return a.resolve(n,r||".")}export function resolveConfiguredPath(n,r,t){return a.resolve(resolveConfiguredCwd(n,r),t)}export function collectConfiguredInputs(n,{inputs:r=[],steps:t=[]}={}){const e=new Set;for(const i of r)e.add(resolveConfiguredPath(n,null,i));for(const i of t){if(i.kind==="sql-file"&&e.add(resolveConfiguredPath(n,i.cwd,i.path)),i.kind==="module"){const u=m(i),{modulePath:o}=parseModuleSpecifier(u),d=resolveConfiguredPath(n,i.cwd,o);o.startsWith("@gfdelarue/testkit")||c.existsSync(d)?o.startsWith("@gfdelarue/testkit")||e.add(d):isBareModuleSpecifier(o)||e.add(d)}for(const u of i.inputs||[])e.add(resolveConfiguredPath(n,i.cwd,u))}return[...e].sort()}export function summarizeConfiguredStep(n){return n.kind==="command"?`command: ${n.cmd.trim()}`:n.kind==="sql-file"?`sql: ${n.path}`:`module: ${n.specifier}`}export function finalizeConfiguredInputs(n=[],r){return n.map(t=>r(t))}export function finalizeConfiguredStep(n,r){return n.kind==="command"?{...n,cmd:r(n.cmd),...typeof n.cwd=="string"?{cwd:r(n.cwd)}:{},inputs:finalizeConfiguredInputs(n.inputs,r),...n.args!==void 0?{args:n.args}:{}}:n.kind==="sql-file"?{...n,path:r(n.path),...typeof n.cwd=="string"?{cwd:r(n.cwd)}:{},inputs:finalizeConfiguredInputs(n.inputs,r),...n.args!==void 0?{args:n.args}:{}}:{...n,specifier:r(n.specifier),...typeof n.cwd=="string"?{cwd:r(n.cwd)}:{},inputs:finalizeConfiguredInputs(n.inputs,r),...n.args!==void 0?{args:n.args}:{}}}export function finalizeConfiguredSteps(n=[],r){return n.map(t=>finalizeConfiguredStep(t,r))}export function validateConfiguredCollection({productDir:n,label:r,inputs:t=[],steps:e=[]}){for(const i of t)s(resolveConfiguredPath(n,null,i),`${r} input`);for(const i of e){if(i.cwd&&s(resolveConfiguredCwd(n,i.cwd),`${r} step cwd`),i.kind==="sql-file"&&s(resolveConfiguredPath(n,i.cwd,i.path),`${r} sql file`),i.kind==="module"){const u=m(i),{modulePath:o}=parseModuleSpecifier(u),d=resolveConfiguredPath(n,i.cwd,o);w(o)?p(o):c.existsSync(d)?s(d,`${r} module`):isBareModuleSpecifier(o)||s(d,`${r} module`)}for(const u of i.inputs||[])s(resolveConfiguredPath(n,i.cwd,u),`${r} step input`)}}function s(n,r){if(!c.existsSync(n))throw new Error(`${r} does not exist: ${n}`)}function m(n){const r="specifier"in n?n.specifier:void 0,t="target"in n?n.target:void 0;return r||t}
@@ -1 +1 @@
1
- import v from"path";import{joinPathList as m,packageBinPath as E,shellQuote as w}from"../process/host/platform.js";export function buildExecutionEnv(r,e={},s=process.env,n={}){return o(r,null,e,s,n)}export function buildTemplateExecutionEnv(r,e={},s=process.env,n={}){return o(r,null,e,s,{...n,omitRuntimeDatabaseBindings:!0})}export function buildTaskExecutionEnv(r,e,s={},n=process.env,i={}){return o(r,e,s,n,i)}export function resolveExecutionEnvValues(r,e,s=process.env){return o(r,null,{},s,{includeTestkitControls:!1},new Set(e))}function o(r,e,s,n,i={},t=null){const a=c(i.inheritProcessEnv===!1?{}:n,t,!1);delete a.DATABASE_URL;const u=buildTemplateContext(r,e),p=i.omitRuntimeDatabaseBindings===!0,b=c(r.testkit.serviceEnv,t,p),f=c(r.testkit.local?.env,t,p);return{...a,...d(b,u),...d(f,u),...d(c(s,t,!1),u),...i.includeTestkitControls===!1?{}:{TESTKIT_ACTIVE:"1",TESTKIT_MODE:i.mode||r.testkit.mode||"test",...r.runtimeId?{TESTKIT_RUNTIME_ID:String(r.runtimeId)}:{},...e?.leaseId?{TESTKIT_LEASE_ID:String(e.leaseId)}:{},...e?.leaseDir?{TESTKIT_LEASE_DIR:e.leaseDir}:{}}}}export function buildTemplateContext(r,e){const s=r.testkit.templateContext||{};return{...s,runtimeId:r.runtimeId||s.runtimeId||null,runtimeLabel:r.runtimeLabel||s.runtimeLabel||null,productDir:r.productDir||s.productDir||null,serviceName:r.name,serviceStateDir:r.stateDir||s.serviceStateDir||null,prepareDir:r.testkit.prepareDir||s.prepareDir||null,leaseId:e?.leaseId||null,leaseDir:e?.leaseDir||null}}export function finalizeString(r,e){return resolveTemplateString(r,e)}export function finalizeSerializable(r,e){return typeof r=="string"?finalizeString(r,e):Array.isArray(r)?r.map(s=>finalizeSerializable(s,e)):r===null||typeof r!="object"?r:Object.fromEntries(Object.entries(r).map(([s,n])=>[s,finalizeSerializable(n,e)]))}export function resolveTemplateString(r,e){return typeof r!="string"?r:r.replace(/\{([a-zA-Z]+)(?::([^}]+))?\}/g,(s,n,i)=>{switch(n){case"runtime":case"runtimeId":return String(e.runtimeId);case"service":return e.serviceName;case"stateDir":return String(e.serviceStateDir);case"productDir":return e.productDir||"";case"bin":{const t=v.resolve(e.productDir||process.cwd(),e.serviceCwd||".");return w(E(t,i))}case"pathList":{const t=l(i||"").split(",").map(a=>a.trim()).filter(Boolean).map(a=>v.resolve(e.productDir||process.cwd(),a));return m(t)}case"prepareDir":return e.prepareDir||"";case"lease":return e.leaseId?String(e.leaseId):"";case"leaseDir":return e.leaseDir||"";case"port":{const t=i||e.serviceName,a=e.portMap?.get(t);if(!a)throw new Error(`Unknown port placeholder for service "${t}"`);return String(a)}case"baseUrl":{const t=i||e.serviceName,a=e.baseUrlByService?.get(t);if(!a)throw new Error(`Unknown baseUrl placeholder for service "${t}"`);return a}case"readyUrl":{const t=i||e.serviceName,a=e.readyUrlByService?.get(t);if(!a)throw new Error(`Unknown readyUrl placeholder for service "${t}"`);return a}case"publicHost":return e.publicHost||"127.0.0.1";case"publicBaseUrl":{const t=i||e.serviceName,a=e.publicBaseUrlByService?.get(t)||e.baseUrlByService?.get(t);if(!a)throw new Error(`Unknown publicBaseUrl placeholder for service "${t}"`);return a}case"privateBaseUrl":{const t=i||e.serviceName,a=e.privateBaseUrlByService?.get(t)||e.baseUrlByService?.get(t);if(!a)throw new Error(`Unknown privateBaseUrl placeholder for service "${t}"`);return a}case"serviceContextUrl":{const t=i||e.serviceName,a=e.serviceContextUrlByService?.get(t)||e.baseUrlByService?.get(t);if(!a)throw new Error(`Unknown serviceContextUrl placeholder for service "${t}"`);return a}case"dbUrl":case"dbHost":case"dbPort":case"dbName":case"dbUser":case"dbPassword":case"dbSsl":{const t=i||e.serviceName;return U(n,s,t,e)}default:throw new Error(`Unsupported template token "{${n}${i?`:${i}`:""}}"`)}})}function d(r,e){return Object.fromEntries(Object.entries(r||{}).map(([s,n])=>[s,typeof n=="string"?S(s,n,e):n]))}function S(r,e,s){try{return finalizeString(e,s)}catch(n){const i=n instanceof Error?n.message:l(n);throw new Error(`Service "${s.serviceName}" env ${r}: ${i}`,{cause:n})}}function c(r,e,s){return Object.fromEntries(Object.entries(r||{}).filter(([n,i])=>e&&!e.has(n)?!1:!(s&&typeof i=="string"&&findDatabasePlaceholders(i).length>0)))}export function findDatabasePlaceholders(r){return[...r.matchAll(/\{db(?:Url|Host|Port|Name|User|Password|Ssl)(?::([^}]+))?\}/g)].map(e=>({placeholder:e[0],serviceName:e.at(1)??null}))}function U(r,e,s,n){const i=n.stateDirByService?.get(s),t=n.databaseBindingsByService?n.databaseBindingsByService.get(s):i?n.databaseBindingsReader?.(i):null;if(!t)throw new Error(`Cannot resolve ${e}: service "${s}" has no database binding in this context`);switch(r){case"dbUrl":return t.url;case"dbHost":return t.host;case"dbPort":return String(t.port);case"dbName":return t.database;case"dbUser":return t.user;case"dbPassword":return t.password;case"dbSsl":return D(t)}}function D(r){const e=r.sslMode,s=l(e||"").trim();return s&&!B(s)?s:h(r.sslMode)?"1":"0"}function h(r){const e=l(r||"").trim().toLowerCase();return!!(e&&!["0","false","no","off","disable","disabled"].includes(e))}function B(r){return["0","1","true","false","yes","no","on","off","disable","disabled","require","verify-ca","verify-full"].includes(l(r||"").trim().toLowerCase())}function l(r){const e=Reflect.apply(String,void 0,[r]);if(typeof e!="string")throw new Error("String conversion returned an invalid result");return e}
1
+ import v from"path";import{joinPathList as f,packageBinPath as E,shellQuote as w,stringifyUnknown as l}from"../process/host/platform.js";export function buildExecutionEnv(r,e={},t=process.env,i={}){return o(r,null,e,t,i)}export function buildTemplateExecutionEnv(r,e={},t=process.env,i={}){return o(r,null,e,t,{...i,omitRuntimeDatabaseBindings:!0})}export function buildTaskExecutionEnv(r,e,t={},i=process.env,s={}){return o(r,e,t,i,s)}export function resolveExecutionEnvValues(r,e,t=process.env){return o(r,null,{},t,{includeTestkitControls:!1},new Set(e))}function o(r,e,t,i,s={},n=null){const a=c(s.inheritProcessEnv===!1?{}:i,n,!1);delete a.DATABASE_URL;const u=buildTemplateContext(r,e),p=s.omitRuntimeDatabaseBindings===!0,m=c(r.testkit.serviceEnv,n,p),b=c(r.testkit.local?.env,n,p);return{...a,...d(m,u),...d(b,u),...d(c(t,n,!1),u),...s.includeTestkitControls===!1?{}:{TESTKIT_ACTIVE:"1",TESTKIT_MODE:s.mode||r.testkit.mode||"test",...r.runtimeId?{TESTKIT_RUNTIME_ID:String(r.runtimeId)}:{},...e?.leaseId?{TESTKIT_LEASE_ID:String(e.leaseId)}:{},...e?.leaseDir?{TESTKIT_LEASE_DIR:e.leaseDir}:{}}}}export function buildTemplateContext(r,e){const t=r.testkit.templateContext||{};return{...t,runtimeId:r.runtimeId||t.runtimeId||null,runtimeLabel:r.runtimeLabel||t.runtimeLabel||null,productDir:r.productDir||t.productDir||null,serviceName:r.name,serviceStateDir:r.stateDir||t.serviceStateDir||null,prepareDir:r.testkit.prepareDir||t.prepareDir||null,leaseId:e?.leaseId||null,leaseDir:e?.leaseDir||null}}export function serviceDatabaseBinding(r,e=r.name){return r.testkit.templateContext?.databaseBindingsByService?.get(e)??null}export function withDatabaseBindings(r,e){return{...r,testkit:{...r.testkit,templateContext:{...r.testkit.templateContext,databaseBindingsByService:e}}}}export function finalizeString(r,e){return resolveTemplateString(r,e)}export function finalizeSerializable(r,e){return typeof r=="string"?finalizeString(r,e):Array.isArray(r)?r.map(t=>finalizeSerializable(t,e)):r===null||typeof r!="object"?r:Object.fromEntries(Object.entries(r).map(([t,i])=>[t,finalizeSerializable(i,e)]))}export function resolveTemplateString(r,e){return typeof r!="string"?r:r.replace(/\{([a-zA-Z]+)(?::([^}]+))?\}/g,(t,i,s)=>{switch(i){case"runtime":case"runtimeId":return String(e.runtimeId);case"service":return e.serviceName;case"stateDir":return String(e.serviceStateDir);case"productDir":return e.productDir||"";case"bin":{const n=v.resolve(e.productDir||process.cwd(),e.serviceCwd||".");return w(E(n,s))}case"pathList":{const n=l(s||"").split(",").map(a=>a.trim()).filter(Boolean).map(a=>v.resolve(e.productDir||process.cwd(),a));return f(n)}case"prepareDir":return e.prepareDir||"";case"lease":return e.leaseId?String(e.leaseId):"";case"leaseDir":return e.leaseDir||"";case"port":{const n=s||e.serviceName,a=e.portMap?.get(n);if(!a)throw new Error(`Unknown port placeholder for service "${n}"`);return String(a)}case"baseUrl":{const n=s||e.serviceName,a=e.baseUrlByService?.get(n);if(!a)throw new Error(`Unknown baseUrl placeholder for service "${n}"`);return a}case"readyUrl":{const n=s||e.serviceName,a=e.readyUrlByService?.get(n);if(!a)throw new Error(`Unknown readyUrl placeholder for service "${n}"`);return a}case"publicHost":return e.publicHost||"127.0.0.1";case"publicBaseUrl":{const n=s||e.serviceName,a=e.publicBaseUrlByService?.get(n)||e.baseUrlByService?.get(n);if(!a)throw new Error(`Unknown publicBaseUrl placeholder for service "${n}"`);return a}case"privateBaseUrl":{const n=s||e.serviceName,a=e.privateBaseUrlByService?.get(n)||e.baseUrlByService?.get(n);if(!a)throw new Error(`Unknown privateBaseUrl placeholder for service "${n}"`);return a}case"serviceContextUrl":{const n=s||e.serviceName,a=e.serviceContextUrlByService?.get(n)||e.baseUrlByService?.get(n);if(!a)throw new Error(`Unknown serviceContextUrl placeholder for service "${n}"`);return a}case"dbUrl":case"dbHost":case"dbPort":case"dbName":case"dbUser":case"dbPassword":case"dbSsl":{const n=s||e.serviceName;return U(i,t,n,e)}default:throw new Error(`Unsupported template token "{${i}${s?`:${s}`:""}}"`)}})}function d(r,e){return Object.fromEntries(Object.entries(r||{}).map(([t,i])=>[t,typeof i=="string"?S(t,i,e):i]))}function S(r,e,t){try{return finalizeString(e,t)}catch(i){const s=i instanceof Error?i.message:l(i);throw new Error(`Service "${t.serviceName}" env ${r}: ${s}`,{cause:i})}}function c(r,e,t){return Object.fromEntries(Object.entries(r||{}).filter(([i,s])=>e&&!e.has(i)?!1:!(t&&typeof s=="string"&&findDatabasePlaceholders(s).length>0)))}export function findDatabasePlaceholders(r){return[...r.matchAll(/\{db(?:Url|Host|Port|Name|User|Password|Ssl)(?::([^}]+))?\}/g)].map(e=>({placeholder:e[0],serviceName:e.at(1)??null}))}function U(r,e,t,i){const s=i.databaseBindingsByService?.get(t);if(!s)throw new Error(`Cannot resolve ${e}: service "${t}" has no database binding in this context`);switch(r){case"dbUrl":return s.url;case"dbHost":return s.host;case"dbPort":return String(s.port);case"dbName":return s.database;case"dbUser":return s.user;case"dbPassword":return s.password;case"dbSsl":return D(s)}}function D(r){const e=r.sslMode,t=l(e||"").trim();return t&&!B(t)?t:h(r.sslMode)?"1":"0"}function h(r){const e=l(r||"").trim().toLowerCase();return!!(e&&!["0","false","no","off","disable","disabled"].includes(e))}function B(r){return["0","1","true","false","yes","no","on","off","disable","disabled","require","verify-ca","verify-full"].includes(l(r||"").trim().toLowerCase())}
@@ -1 +1 @@
1
- export{buildExecutionEnv,buildTaskExecutionEnv,buildTemplateContext,buildTemplateExecutionEnv,finalizeSerializable,finalizeString,findDatabasePlaceholders,resolveExecutionEnvValues,resolveTemplateString}from"./environment.js";export{collectConfiguredInputs,configuredCommandInvocation,parseModuleSpecifier,resolveConfiguredCwd,resolveConfiguredPath}from"./run.js";
1
+ export{buildExecutionEnv,buildTaskExecutionEnv,buildTemplateContext,buildTemplateExecutionEnv,finalizeSerializable,finalizeString,findDatabasePlaceholders,resolveExecutionEnvValues,resolveTemplateString,serviceDatabaseBinding,withDatabaseBindings}from"./environment.js";export{collectConfiguredInputs,configuredCommandInvocation,parseModuleSpecifier,resolveConfiguredCwd,resolveConfiguredPath}from"./run.js";
@@ -1,4 +1,4 @@
1
- import b from"crypto";import f from"fs";import u from"path";import{prepareCommandForSpawn as I,resolveCommandForSpawn as A}from"../process/host/platform.js";import{normalizeContainedRelativePath as V,resolveContainedPath as k}from"../process/files/contained-path.js";import{deriveSemverMinimum as D,isExactSemver as L,normalizeSemver as p,satisfiesSemver as g}from"./semver.js";import{managedHostProcessInfrastructureError as M,runManagedHostProcess as H}from"../process/index.js";import{managedNodeRelease as j}from"./managed-node-releases.js";import{createSharedToolchainOperation as R,waitForSharedToolchainOperation as F}from"./shared-operation.js";import{TOOLCHAIN_METADATA_TIMEOUT_MS as y}from"./timeouts.js";import{isUnknownRecord as N}from"../kernel/unknown-values.js";const P=".",z="auto",W="require-host",q=600*1e3,U=['"use strict";','const { spawn } = require("node:child_process");',"const [command, ...args] = process.argv.slice(1);",'if (typeof command !== "string" || command.length === 0) {',' process.stderr.write("Missing Windows toolchain command\\n");'," process.exitCode = 126;","} else {"," let spawnFailed = false;"," const child = spawn(command, args, {"," shell: false,",' stdio: "inherit",'," windowsHide: true,"," windowsVerbatimArguments: true,"," });",' child.once("error", (error) => {'," spawnFailed = true;"," process.stderr.write(`${error.stack ?? String(error)}\\n`);"," process.exitCode = 126;"," });",' child.once("close", (code, signal) => {'," if (spawnFailed) return;"," if (signal !== null) {"," process.stderr.write(`Windows toolchain command exited on signal ${signal}\\n`);"," process.exitCode = 1;"," return;"," }"," process.exitCode = code ?? 1;"," });","}"].join(`
2
- `),T=new WeakMap,O=new WeakSet;export function nodeToolchain(n={}){return{...n}}export function normalizeToolchainRegistry(n){if(n==null)return{};if(!N(n))throw new Error("testkit.config.ts toolchains must be an object");const e={};for(const[o,r]of Object.entries(n))e[o]=x(r,`testkit.config.ts toolchains.${o}`);return e}export function normalizeRuntimeToolchain(n,e,o={}){if(n==null)return null;if(typeof n=="string"){const t=n.trim();if(!t)throw new Error(`${e} must reference a non-empty toolchain name`);const i=o[t];if(!i)throw new Error(`${e} references unknown toolchain "${t}"`);return{...i,refName:t,sourceLabel:`${e} -> ${t}`}}return{...x(n,e),refName:null,sourceLabel:e}}export async function resolveConfiguredToolchain(n,e={}){const o=n?.testkit?.runtime?.toolchain;if(!n||!o)return null;let r=T.get(n);if(r===void 0){r=R(i=>B(n,o,{...e,signal:i})),T.set(n,r);const t=r;r.promise.catch(()=>{T.get(n)===t&&T.delete(n)})}return F(r,e.signal)}export function announceResolvedToolchain(n,e,o=null){return!e||O.has(n)||(O.add(n),o?.toolchainResolved&&o.toolchainResolved(n,e)),Promise.resolve()}export function applyToolchainEnv(n,e,o=process.env){if(!e)return{...n};const r={...n,PATH:ee(e.binDir,n.PATH||o.PATH||""),TESTKIT_TOOLCHAIN_KIND:"node",TESTKIT_TOOLCHAIN_NODE_VERSION:e.nodeVersion,TESTKIT_TOOLCHAIN_NODE_SOURCE:e.nodeSource,TESTKIT_TOOLCHAIN_INSTALL_MODE:e.install};return e.npmVersion&&(r.TESTKIT_TOOLCHAIN_NPM_VERSION=e.npmVersion,r.TESTKIT_TOOLCHAIN_NPM_SOURCE=e.npmSource),r}function x(n,e){if(!N(n))throw new Error(`${e} must be an object`);const o=V(d(n.cwd)||P,`${e}.cwd`),r=d(n.detect)||z,t=d(n.install)||W;if(r!=="auto"&&r!=="off")throw new Error(`${e}.detect must be "auto" or "off"`);if(t!=="require-host"&&t!=="download")throw new Error(`${e}.install must be "require-host" or "download"`);return{cwd:o,detect:r,install:t,node:d(n.node),npm:d(n.npm)}}async function B(n,e,o){const r=n.productDir,t=k(r,e.cwd,`${e.sourceLabel}.cwd`),i=J(t),s=e.node||(e.detect==="auto"?i.nodeSpec:null),a=e.node?"toolchain.node":e.detect==="auto"?i.nodeSource??"none":"none",l=e.npm||(e.detect==="auto"?i.npmSpec:null),c=e.npm?"toolchain.npm":e.detect==="auto"?i.npmSource??"none":"none";if(!s&&!l)throw new Error(`Service "${n.name}" enables runtime.toolchain but no Node/npm version could be resolved in ${e.cwd}`);return e.install==="require-host"?K({config:n,cwd:t,nodeSpec:s,nodeSource:a,npmSpec:l,npmSource:c,toolchain:e,options:o}):G({config:n,cwd:t,nodeSpec:s,nodeSource:a,npmSpec:l,npmSource:c,toolchain:e,options:o})}function J(n){const e=u.join(n,"package.json"),o=Y(e),r=Z(u.join(n,".tool-versions")),t=C(u.join(n,".nvmrc")),i=C(u.join(n,".node-version")),s=d(w(o,"volta","node")),a=d(w(o,"engines","node")),l=d(r.nodejs),c=s||t||i||l||a;let m=null;s?m="package.json#volta.node":t?m=".nvmrc":i?m=".node-version":l?m=".tool-versions#nodejs":a&&(m="package.json#engines.node");const E=d(w(o,"volta","npm")),$=d(w(o,"engines","npm")),v=X(w(o,"packageManager")),_=E||(v?.name==="npm"?v.version:null)||$;let h=null;return E?h="package.json#volta.npm":v?.name==="npm"?h="package.json#packageManager":$&&(h="package.json#engines.npm"),{nodeSpec:c,nodeSource:m,npmSpec:_,npmSource:h}}async function K({config:n,cwd:e,nodeSpec:o,nodeSource:r,npmSpec:t,npmSource:i,toolchain:s,options:a}){const l=p(a.hostNodeVersion||process.versions.node);if(o&&!g(l,o))throw new Error(`Service "${n.name}" requires Node ${o} (${r}), but host Node is ${l}`);let c=null;if(t&&(c=p(a.hostNpmVersion||await Q({command:"npm",args:["--version"],cwd:e,env:process.env,commandExecutor:a.commandExecutor,signal:a.signal})),!g(c,t)))throw new Error(`Service "${n.name}" requires npm ${t} (${i}), but host npm is ${c}`);return{install:s.install,cwd:s.cwd,nodeVersion:l,nodeSource:r,nodeSpec:o,npmVersion:c,npmSource:i,npmSpec:t,nodeExecutable:process.execPath,binDir:u.dirname(process.execPath),toolchainDir:u.dirname(process.execPath),fingerprint:S({install:s.install,nodeVersion:l,npmVersion:c,nodeSource:r,npmSource:i}),summary:`${s.install} node=${l}${c?` npm=${c}`:""} (${r})`}}async function G({config:n,nodeSpec:e,nodeSource:o,npmSpec:r,npmSource:t,toolchain:i,options:s}){if(!e)throw new Error(`Service "${n.name}" download toolchain mode requires a resolvable Node version`);const a=L(e)?p(e):D(e);if(!a)throw new Error(`Service "${n.name}" cannot deterministically provision Node from "${e}". Provide an exact version in runtime.toolchain.node, .nvmrc, .node-version, .tool-versions, or package.json#volta.node.`);const l=await provisionNodeToolchain({productDir:n.productDir,version:a,fetchImpl:s.fetchImpl||fetchToolchain,commandExecutor:s.commandExecutor||executeToolchainCommand,signal:s.signal});if(!g(a,e))throw new Error(`Service "${n.name}" resolved Node ${a}, which does not satisfy ${e}`);const c=l.npmVersion?p(l.npmVersion):null;if(r&&(!c||!g(c,r)))throw new Error(`Service "${n.name}" requires npm ${r} (${t}), but Node ${a} bundles npm ${c||"unknown"}`);return{install:i.install,cwd:i.cwd,nodeVersion:a,nodeSource:o,nodeSpec:e,npmVersion:c,npmSource:t,npmSpec:r,nodeExecutable:l.nodeExecutable,binDir:l.binDir,toolchainDir:l.toolchainDir,fingerprint:S({install:i.install,nodeVersion:a,npmVersion:c,nodeSource:o,npmSource:t}),summary:`download node=${a}${c?` npm=${c}`:""} (${o})`}}export async function provisionNodeToolchain({productDir:n,version:e,fetchImpl:o=fetchToolchain,commandExecutor:r=executeToolchainCommand,signal:t}){const i=p(e);if(e!==i)throw new Error(`Downloaded Node toolchain version must use canonical x.y.z form; received ${JSON.stringify(e)}`);const s=j(i),{provisionNodeToolchainWithRelease:a}=await import("./node-provisioning.js");return a({commandExecutor:r,fetchImpl:o,productDir:n,release:s,signal:t})}function S(n){return b.createHash("sha256").update(JSON.stringify({kind:"node",...n})).digest("hex")}async function Q({command:n,args:e,cwd:o,env:r,commandExecutor:t=executeToolchainCommand,signal:i}){const s=await t(n,e,{cwd:o,env:r,signal:i,stdio:"pipe",timeoutMs:y,windowsHide:!0});return s.stdout==null?"":typeof s.stdout=="string"?s.stdout.trim():Buffer.from(s.stdout).toString().trim()}function X(n){const e=d(n);if(!e)return null;const o=e.lastIndexOf("@");return o<=0||o===e.length-1?null:{name:e.slice(0,o),version:e.slice(o+1)}}function Y(n){if(!f.existsSync(n))return null;try{return JSON.parse(f.readFileSync(n,"utf8"))}catch{return null}}function C(n){if(!f.existsSync(n))return null;const o=f.readFileSync(n,"utf8").split(/\r?\n/).find(r=>r.trim().length>0);return o?o.trim():null}function Z(n){if(!f.existsSync(n))return{};const e={};for(const o of f.readFileSync(n,"utf8").split(/\r?\n/)){const r=o.trim();if(!r||r.startsWith("#"))continue;const[t,i]=r.split(/\s+/,2);t&&i&&(e[t]=i.trim())}return e}function ee(n,e){const o=d(n);if(!o)return e;const r=(e||"").split(u.delimiter).filter(Boolean).filter(t=>t!==o);return[o,...r].join(u.delimiter)}function d(n){if(typeof n!="string")return null;const e=n.trim();return e.length>0?e:null}export async function fetchToolchain(n,e={}){const o=AbortSignal.timeout(q),r=await fetch(n,{signal:e.signal===void 0?o:AbortSignal.any([e.signal,o])});return{arrayBuffer:()=>r.arrayBuffer(),body:r.body===null?null:ne(r.body),ok:r.ok,status:r.status}}async function*ne(n){const e=n.getReader();let o=!1;try{for(;;){const r=await e.read();if(r.done){o=!0;return}yield r.value}}finally{o||await e.cancel(),e.releaseLock()}}export function prepareToolchainCommandForManagedHost(n,e,o={}){const r={env:o.env||process.env,platform:o.platform},t=A(n,r),i=I(t,e,r);return i.windowsVerbatimArguments?(oe(t,e),{executable:o.hostNodeExecutable||process.execPath,args:["--input-type=commonjs","--eval",U,"--",i.command,...i.args]}):{executable:i.command,args:i.args}}function oe(n,e){if(/[%!"\0\r\n]/u.test(n))throw new Error(`Windows batch toolchain commands cannot safely preserve command path ${JSON.stringify(n)}`);const o=e.find(r=>/[%!"\0\r\n]/u.test(r)||r.endsWith("\\"));if(o!==void 0)throw new Error(`Windows batch toolchain commands cannot safely preserve argument ${JSON.stringify(o)}`)}export async function executeToolchainCommand(n,e,o={}){const r=re(o.timeoutMs),t=u.resolve(o.cwd||process.cwd()),i=prepareToolchainCommandForManagedHost(n,e,{env:o.env||process.env}),s=await H({args:i.args,cwd:t,displayLabel:`Toolchain command ${n}`,env:o.env||process.env,executable:i.executable,signal:o.signal,timeoutMs:r}),a=M(`Toolchain command ${n}`,s);if(a)throw a;if(s.exitCode!==0)throw new Error(`Toolchain command ${n} exited with code ${String(s.exitCode)}${te(s.stdout,s.stderr)}`);return{stdout:s.stdout}}function re(n){const e=n??y;if(!Number.isSafeInteger(e)||e<=0)throw new Error("Toolchain command timeout must be a positive safe integer in milliseconds");return e}function te(n,e){const o=[n,e].map(r=>r.trim()).filter(Boolean).join(`
1
+ import _ from"crypto";import h from"fs";import m from"path";import{prepareCommandForSpawn as I,resolveCommandForSpawn as A}from"../process/host/platform.js";import{normalizeContainedRelativePath as k,resolveContainedPath as V}from"../process/files/contained-path.js";import{deriveSemverMinimum as D,isExactSemver as L,normalizeSemver as f,satisfiesSemver as g}from"./semver.js";import{managedHostProcessInfrastructureError as M,runManagedHostProcess as j}from"../process/index.js";import{managedNodeRelease as H}from"./managed-node-releases.js";import{createSharedToolchainOperation as P,waitForSharedToolchainOperation as R}from"./shared-operation.js";import{TOOLCHAIN_METADATA_TIMEOUT_MS as O}from"./timeouts.js";import{rejectUnknownKeys as F}from"../kernel/known-keys.js";import{isUnknownRecord as N,normalizeOptionalString as l}from"../kernel/unknown-values.js";import{readJsonFileOrNull as W}from"../process/files/json-file.js";const z=".",q="auto",U="require-host",B=600*1e3,K=['"use strict";','const { spawn } = require("node:child_process");',"const [command, ...args] = process.argv.slice(1);",'if (typeof command !== "string" || command.length === 0) {',' process.stderr.write("Missing Windows toolchain command\\n");'," process.exitCode = 126;","} else {"," let spawnFailed = false;"," const child = spawn(command, args, {"," shell: false,",' stdio: "inherit",'," windowsHide: true,"," windowsVerbatimArguments: true,"," });",' child.once("error", (error) => {'," spawnFailed = true;"," process.stderr.write(`${error.stack ?? String(error)}\\n`);"," process.exitCode = 126;"," });",' child.once("close", (code, signal) => {'," if (spawnFailed) return;"," if (signal !== null) {"," process.stderr.write(`Windows toolchain command exited on signal ${signal}\\n`);"," process.exitCode = 1;"," return;"," }"," process.exitCode = code ?? 1;"," });","}"].join(`
2
+ `),v=new WeakMap,y=new WeakSet;export function normalizeToolchainRegistry(n){if(n==null)return{};if(!N(n))throw new Error("testkit.config.ts toolchains must be an object");const e={};for(const[o,r]of Object.entries(n))e[o]=x(r,`testkit.config.ts toolchains.${o}`);return e}export function normalizeRuntimeToolchain(n,e,o={}){if(n==null)return null;if(typeof n=="string"){const t=n.trim();if(!t)throw new Error(`${e} must reference a non-empty toolchain name`);const i=o[t];if(!i)throw new Error(`${e} references unknown toolchain "${t}"`);return{...i,refName:t,sourceLabel:`${e} -> ${t}`}}return{...x(n,e),refName:null,sourceLabel:e}}export async function resolveConfiguredToolchain(n,e={}){const o=n?.testkit?.runtime?.toolchain;if(!n||!o)return null;let r=v.get(n);if(r===void 0){r=P(i=>J(n,o,{...e,signal:i})),v.set(n,r);const t=r;r.promise.catch(()=>{v.get(n)===t&&v.delete(n)})}return R(r,e.signal)}export function announceResolvedToolchain(n,e,o=null){return!e||y.has(n)||(y.add(n),o?.toolchainResolved&&o.toolchainResolved({serviceName:n.name,runtimeLabel:n.runtimeLabel||n.name},e.summary)),Promise.resolve()}export function applyToolchainEnv(n,e,o=process.env){if(!e)return{...n};const r={...n,PATH:ne(e.binDir,n.PATH||o.PATH||""),TESTKIT_TOOLCHAIN_KIND:"node",TESTKIT_TOOLCHAIN_NODE_VERSION:e.nodeVersion,TESTKIT_TOOLCHAIN_NODE_SOURCE:e.nodeSource,TESTKIT_TOOLCHAIN_INSTALL_MODE:e.install};return e.npmVersion&&(r.TESTKIT_TOOLCHAIN_NPM_VERSION=e.npmVersion,r.TESTKIT_TOOLCHAIN_NPM_SOURCE=e.npmSource),r}function x(n,e){if(!N(n))throw new Error(`${e} must be an object`);F(n,["cwd","detect","install","node","npm"],e);const o=k(l(n.cwd)||z,`${e}.cwd`),r=l(n.detect)||q,t=l(n.install)||U;if(r!=="auto"&&r!=="off")throw new Error(`${e}.detect must be "auto" or "off"`);if(t!=="require-host"&&t!=="download")throw new Error(`${e}.install must be "require-host" or "download"`);return{cwd:o,detect:r,install:t,node:l(n.node),npm:l(n.npm)}}async function J(n,e,o){const r=n.productDir,t=V(r,e.cwd,`${e.sourceLabel}.cwd`),i=G(t),s=e.node||(e.detect==="auto"?i.nodeSpec:null),a=e.node?"toolchain.node":e.detect==="auto"?i.nodeSource??"none":"none",d=e.npm||(e.detect==="auto"?i.npmSpec:null),c=e.npm?"toolchain.npm":e.detect==="auto"?i.npmSource??"none":"none";if(!s&&!d)throw new Error(`Service "${n.name}" enables runtime.toolchain but no Node/npm version could be resolved in ${e.cwd}`);return e.install==="require-host"?Q({config:n,cwd:t,nodeSpec:s,nodeSource:a,npmSpec:d,npmSource:c,toolchain:e,options:o}):X({config:n,cwd:t,nodeSpec:s,nodeSource:a,npmSpec:d,npmSource:c,toolchain:e,options:o})}function G(n){const e=m.join(n,"package.json"),o=W(e),r=ee(m.join(n,".tool-versions")),t=b(m.join(n,".nvmrc")),i=b(m.join(n,".node-version")),s=l(p(o,"volta","node")),a=l(p(o,"engines","node")),d=l(r.nodejs),c=s||t||i||d||a;let u=null;s?u="package.json#volta.node":t?u=".nvmrc":i?u=".node-version":d?u=".tool-versions#nodejs":a&&(u="package.json#engines.node");const E=l(p(o,"volta","npm")),$=l(p(o,"engines","npm")),T=Z(p(o,"packageManager")),C=E||(T?.name==="npm"?T.version:null)||$;let w=null;return E?w="package.json#volta.npm":T?.name==="npm"?w="package.json#packageManager":$&&(w="package.json#engines.npm"),{nodeSpec:c,nodeSource:u,npmSpec:C,npmSource:w}}async function Q({config:n,cwd:e,nodeSpec:o,nodeSource:r,npmSpec:t,npmSource:i,toolchain:s,options:a}){const d=f(a.hostNodeVersion||process.versions.node);if(o&&!g(d,o))throw new Error(`Service "${n.name}" requires Node ${o} (${r}), but host Node is ${d}`);let c=null;if(t&&(c=f(a.hostNpmVersion||await Y({command:"npm",args:["--version"],cwd:e,env:process.env,commandExecutor:a.commandExecutor,signal:a.signal})),!g(c,t)))throw new Error(`Service "${n.name}" requires npm ${t} (${i}), but host npm is ${c}`);return{install:s.install,cwd:s.cwd,nodeVersion:d,nodeSource:r,nodeSpec:o,npmVersion:c,npmSource:i,npmSpec:t,nodeExecutable:process.execPath,binDir:m.dirname(process.execPath),toolchainDir:m.dirname(process.execPath),fingerprint:S({install:s.install,nodeVersion:d,npmVersion:c,nodeSource:r,npmSource:i}),summary:`${s.install} node=${d}${c?` npm=${c}`:""} (${r})`}}async function X({config:n,nodeSpec:e,nodeSource:o,npmSpec:r,npmSource:t,toolchain:i,options:s}){if(!e)throw new Error(`Service "${n.name}" download toolchain mode requires a resolvable Node version`);const a=L(e)?f(e):D(e);if(!a)throw new Error(`Service "${n.name}" cannot deterministically provision Node from "${e}". Provide an exact version in runtime.toolchain.node, .nvmrc, .node-version, .tool-versions, or package.json#volta.node.`);const d=await provisionNodeToolchain({productDir:n.productDir,version:a,fetchImpl:s.fetchImpl||fetchToolchain,commandExecutor:s.commandExecutor||executeToolchainCommand,signal:s.signal});if(!g(a,e))throw new Error(`Service "${n.name}" resolved Node ${a}, which does not satisfy ${e}`);const c=d.npmVersion?f(d.npmVersion):null;if(r&&(!c||!g(c,r)))throw new Error(`Service "${n.name}" requires npm ${r} (${t}), but Node ${a} bundles npm ${c||"unknown"}`);return{install:i.install,cwd:i.cwd,nodeVersion:a,nodeSource:o,nodeSpec:e,npmVersion:c,npmSource:t,npmSpec:r,nodeExecutable:d.nodeExecutable,binDir:d.binDir,toolchainDir:d.toolchainDir,fingerprint:S({install:i.install,nodeVersion:a,npmVersion:c,nodeSource:o,npmSource:t}),summary:`download node=${a}${c?` npm=${c}`:""} (${o})`}}export async function provisionNodeToolchain({productDir:n,version:e,fetchImpl:o=fetchToolchain,commandExecutor:r=executeToolchainCommand,signal:t}){const i=f(e);if(e!==i)throw new Error(`Downloaded Node toolchain version must use canonical x.y.z form; received ${JSON.stringify(e)}`);const s=H(i),{provisionNodeToolchainWithRelease:a}=await import("./node-provisioning.js");return a({commandExecutor:r,fetchImpl:o,productDir:n,release:s,signal:t})}function S(n){return _.createHash("sha256").update(JSON.stringify({kind:"node",...n})).digest("hex")}async function Y({command:n,args:e,cwd:o,env:r,commandExecutor:t=executeToolchainCommand,signal:i}){const s=await t(n,e,{cwd:o,env:r,signal:i,stdio:"pipe",timeoutMs:O,windowsHide:!0});return s.stdout==null?"":typeof s.stdout=="string"?s.stdout.trim():Buffer.from(s.stdout).toString().trim()}function Z(n){const e=l(n);if(!e)return null;const o=e.lastIndexOf("@");return o<=0||o===e.length-1?null:{name:e.slice(0,o),version:e.slice(o+1)}}function b(n){if(!h.existsSync(n))return null;const o=h.readFileSync(n,"utf8").split(/\r?\n/).find(r=>r.trim().length>0);return o?o.trim():null}function ee(n){if(!h.existsSync(n))return{};const e={};for(const o of h.readFileSync(n,"utf8").split(/\r?\n/)){const r=o.trim();if(!r||r.startsWith("#"))continue;const[t,i]=r.split(/\s+/,2);t&&i&&(e[t]=i.trim())}return e}function ne(n,e){const o=l(n);if(!o)return e;const r=(e||"").split(m.delimiter).filter(Boolean).filter(t=>t!==o);return[o,...r].join(m.delimiter)}export async function fetchToolchain(n,e={}){const o=AbortSignal.timeout(B),r=await fetch(n,{signal:e.signal===void 0?o:AbortSignal.any([e.signal,o])});return{arrayBuffer:()=>r.arrayBuffer(),body:r.body===null?null:oe(r.body),ok:r.ok,status:r.status}}async function*oe(n){const e=n.getReader();let o=!1;try{for(;;){const r=await e.read();if(r.done){o=!0;return}yield r.value}}finally{o||await e.cancel(),e.releaseLock()}}export function prepareToolchainCommandForManagedHost(n,e,o={}){const r={env:o.env||process.env,platform:o.platform},t=A(n,r),i=I(t,e,r);return i.windowsVerbatimArguments?(re(t,e),{executable:o.hostNodeExecutable||process.execPath,args:["--input-type=commonjs","--eval",K,"--",i.command,...i.args]}):{executable:i.command,args:i.args}}function re(n,e){if(/[%!"\0\r\n]/u.test(n))throw new Error(`Windows batch toolchain commands cannot safely preserve command path ${JSON.stringify(n)}`);const o=e.find(r=>/[%!"\0\r\n]/u.test(r)||r.endsWith("\\"));if(o!==void 0)throw new Error(`Windows batch toolchain commands cannot safely preserve argument ${JSON.stringify(o)}`)}export async function executeToolchainCommand(n,e,o={}){const r=te(o.timeoutMs),t=m.resolve(o.cwd||process.cwd()),i=prepareToolchainCommandForManagedHost(n,e,{env:o.env||process.env}),s=await j({args:i.args,cwd:t,displayLabel:`Toolchain command ${n}`,env:o.env||process.env,executable:i.executable,signal:o.signal,timeoutMs:r}),a=M(`Toolchain command ${n}`,s);if(a)throw a;if(s.exitCode!==0)throw new Error(`Toolchain command ${n} exited with code ${String(s.exitCode)}${ie(s.stdout,s.stderr)}`);return{stdout:s.stdout}}function te(n){const e=n??O;if(!Number.isSafeInteger(e)||e<=0)throw new Error("Toolchain command timeout must be a positive safe integer in milliseconds");return e}function ie(n,e){const o=[n,e].map(r=>r.trim()).filter(Boolean).join(`
3
3
  `);return o?`
4
- ${o.slice(-4e3)}`:""}function w(n,...e){let o=n;for(const r of e){if(!N(o))return;o=o[r]}return o}
4
+ ${o.slice(-4e3)}`:""}function p(n,...e){let o=n;for(const r of e){if(!N(o))return;o=o[r]}return o}
@@ -1 +1 @@
1
- const c=String;export function normalizeSemver(r){return formatSemver(parseSemver(r))}export function isExactSemver(r){try{return parseSemver(r),!0}catch{return!1}}export function parseSemver(r){const e=c(r||"").trim().replace(/^v/iu,"").match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?$/u);if(!e)throw u(r);const o=Number.parseInt(e[1],10),n=Number.parseInt(e[2]||"0",10),i=Number.parseInt(e[3]||"0",10);if(!s(o)||!s(n)||!s(i))throw u(r);return{major:o,minor:n,patch:i}}export function compareSemver(r,t){const e=m(r),o=m(t);return e.major!==o.major?e.major-o.major:e.minor!==o.minor?e.minor-o.minor:e.patch-o.patch}export function formatSemver(r){const t=m(r);return`${c(t.major)}.${c(t.minor)}.${c(t.patch)}`}export function satisfiesSemver(r,t){const e=d(t);if(!e)return!0;const o=m(r);for(const n of j(e))if(S(o,n))return!0;return!1}export function deriveSemverMinimum(r){const t=d(r);if(!t)return null;const e=[];for(const o of j(t)){const n=x(o);n!==null&&e.push(n)}return e.length===0?null:(e.sort(compareSemver),formatSemver(e[0]))}function S(r,t){return l(t).every(o=>v(r,o))}function x(r){const t=l(r);if(t.length===0)return null;let e=null;for(const n of t){if(n.operator==="="||n.operator===">="){e=h(e,n.version);continue}n.operator===">"&&(e=h(e,b(n.version)))}const o=e||{major:0,minor:0,patch:0};return t.every(n=>v(o,n))?o:null}function l(r){const t=[];for(const e of w(r))t.push(...$(e));return t}function w(r){return r.trim().replace(/([<>=])\s+(?=v?\d)/giu,"$1").split(/\s+/u).filter(Boolean)}function $(r){const t=r.trim();if(!t)return[];const e=t.match(/^(<=|>=|<|>|=)?\s*(.*)$/u);if(!e)throw new Error(`Unsupported semver comparator "${t}"`);const o=I(e[1]),n=e[2];if(o!==null){if(!n)throw new Error(`Unsupported semver comparator "${t}"`);return[{operator:o,version:parseSemver(n)}]}if(n.startsWith("^")){const i=n.slice(1),a=parseSemver(i);return[{operator:">=",version:a},{operator:"<",version:y(a,g(i))}]}if(n.startsWith("~")){const i=parseSemver(n.slice(1));return[{operator:">=",version:i},{operator:"<",version:{major:i.major,minor:i.minor+1,patch:0}}]}if(/^\d+(?:\.(?:x|\*))?$/iu.test(n)){const[i]=n.split("."),a=parseSemver(i);return[{operator:">=",version:a},{operator:"<",version:{major:a.major+1,minor:0,patch:0}}]}if(/^\d+\.\d+(?:\.(?:x|\*))?$/iu.test(n)){const[i,a]=n.split("."),p=parseSemver(`${i}.${a}`);return[{operator:">=",version:p},{operator:"<",version:{major:p.major,minor:p.minor+1,patch:0}}]}return[{operator:"=",version:parseSemver(n)}]}function v(r,t){const e=compareSemver(r,t.version);switch(t.operator){case"=":return e===0;case">":return e>0;case">=":return e>=0;case"<":return e<0;case"<=":return e<=0}}function y(r,t){return r.major>0||t<=1?{major:r.major+1,minor:0,patch:0}:r.minor>0||t===2?{major:0,minor:r.minor+1,patch:0}:{major:0,minor:0,patch:r.patch+1}}function g(r){return r.trim().replace(/^v/iu,"").split(".").length}function b(r){return{major:r.major,minor:r.minor,patch:r.patch+1}}function h(r,t){return r&&compareSemver(r,t)>=0?r:t}function m(r){return typeof r=="string"?parseSemver(r):A(r)}function A(r){if(!N(r))throw u(r);const t=f(r,"major"),e=f(r,"minor"),o=f(r,"patch");if(!s(t)||!s(e)||!s(o))throw u(r);return{major:t,minor:e,patch:o}}function I(r){switch(r){case"=":case">":case">=":case"<":case"<=":return r;case void 0:return null;default:throw new Error(`Unsupported semver operator "${r}"`)}}function d(r){return c(r||"").trim()}function j(r){return r.split("||").map(t=>t.trim()).filter(Boolean)}function u(r){return new Error(`Invalid semver "${c(r)}"`)}function f(r,t){return Reflect.get(r,t)}function N(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)}function s(r){return typeof r=="number"&&Number.isInteger(r)&&r>=0}
1
+ import{readDynamicProperty as f,isUnknownRecord as S}from"../kernel/unknown-values.js";const c=String;export function normalizeSemver(r){return formatSemver(parseSemver(r))}export function isExactSemver(r){try{return parseSemver(r),!0}catch{return!1}}export function parseSemver(r){const e=c(r||"").trim().replace(/^v/iu,"").match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?$/u);if(!e)throw u(r);const o=Number.parseInt(e[1],10),n=Number.parseInt(e[2]||"0",10),i=Number.parseInt(e[3]||"0",10);if(!s(o)||!s(n)||!s(i))throw u(r);return{major:o,minor:n,patch:i}}export function compareSemver(r,t){const e=m(r),o=m(t);return e.major!==o.major?e.major-o.major:e.minor!==o.minor?e.minor-o.minor:e.patch-o.patch}export function formatSemver(r){const t=m(r);return`${c(t.major)}.${c(t.minor)}.${c(t.patch)}`}export function satisfiesSemver(r,t){const e=d(t);if(!e)return!0;const o=m(r);for(const n of j(e))if(x(o,n))return!0;return!1}export function deriveSemverMinimum(r){const t=d(r);if(!t)return null;const e=[];for(const o of j(t)){const n=w(o);n!==null&&e.push(n)}return e.length===0?null:(e.sort(compareSemver),formatSemver(e[0]))}function x(r,t){return l(t).every(o=>v(r,o))}function w(r){const t=l(r);if(t.length===0)return null;let e=null;for(const n of t){if(n.operator==="="||n.operator===">="){e=h(e,n.version);continue}n.operator===">"&&(e=h(e,b(n.version)))}const o=e||{major:0,minor:0,patch:0};return t.every(n=>v(o,n))?o:null}function l(r){const t=[];for(const e of $(r))t.push(...g(e));return t}function $(r){return r.trim().replace(/([<>=])\s+(?=v?\d)/giu,"$1").split(/\s+/u).filter(Boolean)}function g(r){const t=r.trim();if(!t)return[];const e=t.match(/^(<=|>=|<|>|=)?\s*(.*)$/u);if(!e)throw new Error(`Unsupported semver comparator "${t}"`);const o=N(e[1]),n=e[2];if(o!==null){if(!n)throw new Error(`Unsupported semver comparator "${t}"`);return[{operator:o,version:parseSemver(n)}]}if(n.startsWith("^")){const i=n.slice(1),a=parseSemver(i);return[{operator:">=",version:a},{operator:"<",version:y(a,I(i))}]}if(n.startsWith("~")){const i=parseSemver(n.slice(1));return[{operator:">=",version:i},{operator:"<",version:{major:i.major,minor:i.minor+1,patch:0}}]}if(/^\d+(?:\.(?:x|\*))?$/iu.test(n)){const[i]=n.split("."),a=parseSemver(i);return[{operator:">=",version:a},{operator:"<",version:{major:a.major+1,minor:0,patch:0}}]}if(/^\d+\.\d+(?:\.(?:x|\*))?$/iu.test(n)){const[i,a]=n.split("."),p=parseSemver(`${i}.${a}`);return[{operator:">=",version:p},{operator:"<",version:{major:p.major,minor:p.minor+1,patch:0}}]}return[{operator:"=",version:parseSemver(n)}]}function v(r,t){const e=compareSemver(r,t.version);switch(t.operator){case"=":return e===0;case">":return e>0;case">=":return e>=0;case"<":return e<0;case"<=":return e<=0}}function y(r,t){return r.major>0||t<=1?{major:r.major+1,minor:0,patch:0}:r.minor>0||t===2?{major:0,minor:r.minor+1,patch:0}:{major:0,minor:0,patch:r.patch+1}}function I(r){return r.trim().replace(/^v/iu,"").split(".").length}function b(r){return{major:r.major,minor:r.minor,patch:r.patch+1}}function h(r,t){return r&&compareSemver(r,t)>=0?r:t}function m(r){return typeof r=="string"?parseSemver(r):E(r)}function E(r){if(!S(r))throw u(r);const t=f(r,"major"),e=f(r,"minor"),o=f(r,"patch");if(!s(t)||!s(e)||!s(o))throw u(r);return{major:t,minor:e,patch:o}}function N(r){switch(r){case"=":case">":case">=":case"<":case"<=":return r;case void 0:return null;default:throw new Error(`Unsupported semver operator "${r}"`)}}function d(r){return c(r||"").trim()}function j(r){return r.split("||").map(t=>t.trim()).filter(Boolean)}function u(r){return new Error(`Invalid semver "${c(r)}"`)}function s(r){return typeof r=="number"&&Number.isInteger(r)&&r>=0}
@@ -1 +1 @@
1
- import{isUnknownRecord as o}from"../../kernel/unknown-values.js";const n=["**/*.int.testkit.ts","**/*.e2e.testkit.ts","**/*.contract.testkit.ts","**/*.data.testkit.ts","**/*.dal.testkit.ts","**/*.load.testkit.ts","**/*.ui.testkit.ts"];export function defineConfig(t={},r={}){const e=Reflect.get(t,"test"),s={...o(e)?e:{}},i=new Set([...c(s.exclude,"config.test.exclude"),...r.exclude??[],...n]);return{...t,test:{...s,exclude:[...i]}}}export function testkitExcludes(){return[...n]}function c(t,r){if(t===void 0)return[];if(!Array.isArray(t)||!t.every(e=>typeof e=="string"))throw new TypeError(`${r} must be an array of strings`);return t}
1
+ import{isUnknownRecord as i}from"../../kernel/unknown-values.js";const o=["**/*.ui.testkit.ts"];export function defineConfig(e={},r={}){const t=Reflect.get(e,"test"),n={...i(t)?t:{}},s=new Set([...c(n.exclude,"config.test.exclude"),...r.exclude??[],...o]);return{...e,test:{...n,exclude:[...s]}}}export function testkitExcludes(){return[...o]}function c(e,r){if(e===void 0)return[];if(!Array.isArray(e)||!e.every(t=>typeof t=="string"))throw new TypeError(`${r} must be an array of strings`);return e}
@@ -1,2 +1 @@
1
- import{redactSensitiveText as d,SENSITIVE_KEY_PATTERN as T}from"../kernel/redaction.js";const c="<redacted>",E=/<redacted>(?!@)/u,A=/\b([A-Z0-9_]+)=(?=\S)/giu,R=/(?:^|_)URL$/iu,f=/["']?[a-z][a-z0-9+.-]*:\/\//iuy,_=/(?:basic|bearer|digest|negotiate|token)[ \t]/iuy,l=/(:\/\/[^:\s/@]*:)[^\s/]+(?=@)/gu,a=/\s/u,g=/(["'`]?)\b(?:(?:proxy-)?authorization|(?:set-)?cookie)[ \t]*:[ \t]*(?=\S)/giu,S=/"([^"\\\r\n]+)"(\s*:\s*)"(?:[^"\\\r\n]|\\.?)*("|$)/gmu,h=8;export function redactBugText(t){return redactUntilUnchanged(t,r=>P(I(p(d(x(r))))))}export function redactRunResultText(t){const r=t.replace(/\s+/gu," ").trim(),e=E.exec(r);return redactBugText(e===null?r:r.slice(0,e.index+c.length))}export function holdsRedaction(t){return t.includes(c)}export function redactUntilUnchanged(t,r){let e=t;for(let n=0;n<h;n+=1){const s=r(e);if(s===e)return e;e=s}return c}function x(t){const r=[];let e=0;for(const n of t.matchAll(A)){if(n.index<e)continue;const s=n[1];if(!T.test(s))continue;const o=n.index+n[0].length;R.test(s)&&u(f,t,o)||(r.push(t.slice(e,o),c),e=N(t,o))}return r.push(t.slice(e)),r.join("")}function N(t,r){const e=t[r];if(e==='"'||e==="'"){const n=i(t,r+1,e);return t[n]===e?n+1:n}if(u(_,t,r))return i(t,r,"");for(let n=r;n<t.length;n+=1)if(a.test(t[n]))return n;return t.length}function u(t,r,e){return t.lastIndex=e,t.test(r)}function p(t){return t.replace(l,`$1${c}`)}function I(t){const r=[];let e=0;for(const n of t.matchAll(g)){if(n.index<e)continue;const s=n.index+n[0].length;r.push(t.slice(e,s),c),e=i(t,s,n[1])}return r.push(t.slice(e)),r.join("")}function i(t,r,e){for(let n=r;n<t.length;n+=1){const s=t[n];if(s==="\r"||s===`
2
- `||s===e&&t[n-1]!=="\\")return n}return t.length}function P(t){return t.replace(S,(r,e,n,s)=>T.test(e)?`"${e}"${n}"${c}${s}`:r)}
1
+ import{REDACTED as n,redactSensitiveText as c}from"../kernel/redaction.js";export{redactSensitiveText as redactBugText}from"../kernel/redaction.js";const i=/<redacted>(?!@)["']?/u;export function redactRunResultText(e){const t=e.replace(/\s+/gu," ").trim(),r=i.exec(t);return c(r===null?t:t.slice(0,r.index+r[0].length))}export function holdsRedaction(e){return e.includes(n)}
@@ -1,6 +1,8 @@
1
1
  export interface CopyTscRuntimeAssetsContext {
2
- args?: unknown;
3
- cwd: string;
4
- prepareDir?: string | null;
2
+ args?: unknown;
3
+ cwd: string;
4
+ prepareDir?: string | null;
5
5
  }
6
6
  export declare function copyTscRuntimeAssets(context: Readonly<CopyTscRuntimeAssetsContext>): Promise<void>;
7
+
8
+ export {};
@@ -1,11 +1,9 @@
1
- import type { OwnedPostgresContainerRoute } from "../domain/postgres-route.js";
2
1
  export interface DatabaseStepContext {
3
- args?: unknown;
4
- cwd?: string;
5
- databaseUrl?: string;
6
- env?: Record<string, string | undefined>;
7
- ownedContainer?: OwnedPostgresContainerRoute | null;
8
- productDir?: string;
2
+ args?: unknown;
3
+ cwd?: string;
4
+ databaseUrl?: string;
5
+ env?: Record<string, string | undefined>;
6
+ productDir?: string;
9
7
  }
10
8
  export declare function verifySeed(context?: DatabaseStepContext): Promise<void>;
11
9
  export declare function verifyRows(context?: DatabaseStepContext): Promise<void>;
@@ -14,3 +12,5 @@ export declare function runSql(context?: DatabaseStepContext): Promise<void>;
14
12
  export declare function seedRows(context?: DatabaseStepContext): Promise<void>;
15
13
  export declare function materializePostgresBinding(context?: DatabaseStepContext): Promise<void>;
16
14
  export declare function updateRows(context?: DatabaseStepContext): Promise<void>;
15
+
16
+ export {};
@@ -1,6 +1,8 @@
1
1
  export interface NextRuntimeTsconfigContext {
2
- cwd?: string;
3
- productDir?: string;
4
- runtimeId?: string | null;
2
+ cwd?: string;
3
+ productDir?: string;
4
+ runtimeId?: string | null;
5
5
  }
6
6
  export declare function writeNextRuntimeTsconfig(context?: NextRuntimeTsconfigContext): Promise<void>;
7
+
8
+ export {};