@hominis/fireforge 0.49.2 → 0.51.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 (400) hide show
  1. package/CHANGELOG.md +87 -1
  2. package/README.md +1 -1
  3. package/dist/bin/fireforge.js +6 -0
  4. package/dist/build-info.json +4 -4
  5. package/dist/src/commands/build-prelock.d.ts +20 -0
  6. package/dist/src/commands/build-prelock.js +50 -0
  7. package/dist/src/commands/build.d.ts +3 -1
  8. package/dist/src/commands/build.js +13 -6
  9. package/dist/src/commands/check-report.d.ts +41 -0
  10. package/dist/src/commands/check-report.js +91 -0
  11. package/dist/src/commands/check-run.d.ts +33 -0
  12. package/dist/src/commands/check-run.js +112 -0
  13. package/dist/src/commands/check-steps.d.ts +75 -0
  14. package/dist/src/commands/check-steps.js +200 -0
  15. package/dist/src/commands/check.d.ts +32 -0
  16. package/dist/src/commands/check.js +160 -0
  17. package/dist/src/commands/config.js +5 -6
  18. package/dist/src/commands/declarations-report.d.ts +43 -0
  19. package/dist/src/commands/declarations-report.js +76 -0
  20. package/dist/src/commands/doctor-engine-eslint.js +6 -1
  21. package/dist/src/commands/doctor-source-pin.js +4 -1
  22. package/dist/src/commands/export-adopt-check.d.ts +38 -0
  23. package/dist/src/commands/export-adopt-check.js +98 -0
  24. package/dist/src/commands/export-flow.js +29 -14
  25. package/dist/src/commands/export-placement-gate.d.ts +6 -2
  26. package/dist/src/commands/export-placement-gate.js +8 -0
  27. package/dist/src/commands/export-shared.d.ts +2 -1
  28. package/dist/src/commands/export-staged-registration.d.ts +46 -0
  29. package/dist/src/commands/export-staged-registration.js +91 -0
  30. package/dist/src/commands/forward-import-remedy.d.ts +32 -0
  31. package/dist/src/commands/forward-import-remedy.js +63 -0
  32. package/dist/src/commands/furnace/apply.js +3 -3
  33. package/dist/src/commands/furnace/chrome-doc-remove.d.ts +2 -1
  34. package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
  35. package/dist/src/commands/furnace/chrome-doc.d.ts +2 -1
  36. package/dist/src/commands/furnace/chrome-doc.js +2 -2
  37. package/dist/src/commands/furnace/create.js +2 -2
  38. package/dist/src/commands/furnace/deploy-named.d.ts +48 -0
  39. package/dist/src/commands/furnace/deploy-named.js +107 -0
  40. package/dist/src/commands/furnace/deploy.d.ts +3 -2
  41. package/dist/src/commands/furnace/deploy.js +50 -86
  42. package/dist/src/commands/furnace/diff.js +26 -3
  43. package/dist/src/commands/furnace/index.js +66 -41
  44. package/dist/src/commands/furnace/init.js +13 -6
  45. package/dist/src/commands/furnace/override.js +4 -2
  46. package/dist/src/commands/furnace/preview.js +4 -3
  47. package/dist/src/commands/furnace/refresh.js +2 -2
  48. package/dist/src/commands/furnace/remove.js +4 -3
  49. package/dist/src/commands/furnace/rename-dry-run.d.ts +29 -0
  50. package/dist/src/commands/furnace/rename-dry-run.js +127 -0
  51. package/dist/src/commands/furnace/rename-helpers.d.ts +7 -0
  52. package/dist/src/commands/furnace/rename-helpers.js +15 -1
  53. package/dist/src/commands/furnace/rename-registrations.d.ts +41 -0
  54. package/dist/src/commands/furnace/rename-registrations.js +98 -0
  55. package/dist/src/commands/furnace/rename.d.ts +2 -1
  56. package/dist/src/commands/furnace/rename.js +28 -66
  57. package/dist/src/commands/furnace/scan.d.ts +9 -4
  58. package/dist/src/commands/furnace/scan.js +11 -9
  59. package/dist/src/commands/furnace/sync.js +3 -2
  60. package/dist/src/commands/furnace/validate-report.d.ts +45 -0
  61. package/dist/src/commands/furnace/validate-report.js +91 -0
  62. package/dist/src/commands/furnace/validate.d.ts +1 -1
  63. package/dist/src/commands/furnace/validate.js +151 -113
  64. package/dist/src/commands/furnace/validation-output.js +14 -3
  65. package/dist/src/commands/lint-per-patch.js +36 -61
  66. package/dist/src/commands/lint-per-run-checkjs.js +2 -2
  67. package/dist/src/commands/lint-report.d.ts +8 -4
  68. package/dist/src/commands/lint-report.js +20 -5
  69. package/dist/src/commands/lint.js +15 -34
  70. package/dist/src/commands/manifest.js +4 -0
  71. package/dist/src/commands/park.d.ts +22 -0
  72. package/dist/src/commands/park.js +232 -0
  73. package/dist/src/commands/patch/delete-gap-notice.js +3 -1
  74. package/dist/src/commands/patch/delete.d.ts +1 -1
  75. package/dist/src/commands/patch/delete.js +24 -104
  76. package/dist/src/commands/patch/index.d.ts +3 -3
  77. package/dist/src/commands/patch/index.js +10 -4
  78. package/dist/src/commands/patch/lint-ignore-from.d.ts +44 -0
  79. package/dist/src/commands/patch/lint-ignore-from.js +142 -0
  80. package/dist/src/commands/patch/lint-ignore.d.ts +5 -1
  81. package/dist/src/commands/patch/lint-ignore.js +78 -31
  82. package/dist/src/commands/patch/move-files-create.js +34 -18
  83. package/dist/src/commands/patch/move-files-into.js +15 -7
  84. package/dist/src/commands/patch/move-files.js +6 -2
  85. package/dist/src/commands/patch/removal-created-files.d.ts +48 -0
  86. package/dist/src/commands/patch/removal-created-files.js +83 -0
  87. package/dist/src/commands/patch/removal-dependents.d.ts +63 -0
  88. package/dist/src/commands/patch/removal-dependents.js +133 -0
  89. package/dist/src/commands/patch/rename.js +20 -1
  90. package/dist/src/commands/patch/reserve.d.ts +33 -0
  91. package/dist/src/commands/patch/reserve.js +152 -0
  92. package/dist/src/commands/patch/retire.d.ts +34 -0
  93. package/dist/src/commands/patch/retire.js +133 -0
  94. package/dist/src/commands/patch/split-plan.d.ts +17 -8
  95. package/dist/src/commands/patch/split-plan.js +60 -28
  96. package/dist/src/commands/patch/split-staged.d.ts +108 -0
  97. package/dist/src/commands/patch/split-staged.js +202 -0
  98. package/dist/src/commands/patch/split.d.ts +5 -0
  99. package/dist/src/commands/patch/split.js +62 -17
  100. package/dist/src/commands/patch/stage.d.ts +34 -0
  101. package/dist/src/commands/patch/stage.js +153 -0
  102. package/dist/src/commands/patch/staged-dependency-batch.d.ts +48 -0
  103. package/dist/src/commands/patch/staged-dependency-batch.js +176 -0
  104. package/dist/src/commands/patch/staged-dependency-entries.d.ts +36 -0
  105. package/dist/src/commands/patch/staged-dependency-entries.js +52 -0
  106. package/dist/src/commands/patch/staged-dependency-from.d.ts +14 -0
  107. package/dist/src/commands/patch/staged-dependency-from.js +108 -0
  108. package/dist/src/commands/patch/staged-dependency-remove.d.ts +31 -0
  109. package/dist/src/commands/patch/staged-dependency-remove.js +80 -0
  110. package/dist/src/commands/patch/staged-dependency.js +54 -139
  111. package/dist/src/commands/re-export-adjacent-registrations.d.ts +20 -0
  112. package/dist/src/commands/re-export-adjacent-registrations.js +75 -0
  113. package/dist/src/commands/re-export-adjacent.d.ts +50 -2
  114. package/dist/src/commands/re-export-adjacent.js +160 -40
  115. package/dist/src/commands/re-export-bulk-scan.d.ts +2 -1
  116. package/dist/src/commands/re-export-bulk-scan.js +22 -7
  117. package/dist/src/commands/re-export-drift.d.ts +36 -8
  118. package/dist/src/commands/re-export-drift.js +73 -49
  119. package/dist/src/commands/re-export-files.js +11 -8
  120. package/dist/src/commands/re-export-hunks.d.ts +35 -0
  121. package/dist/src/commands/re-export-hunks.js +220 -0
  122. package/dist/src/commands/re-export-lint.d.ts +2 -1
  123. package/dist/src/commands/re-export-lint.js +23 -10
  124. package/dist/src/commands/re-export-options.js +74 -6
  125. package/dist/src/commands/re-export-preflight.d.ts +23 -0
  126. package/dist/src/commands/re-export-preflight.js +160 -0
  127. package/dist/src/commands/re-export-purity-scope.d.ts +18 -0
  128. package/dist/src/commands/re-export-purity-scope.js +131 -0
  129. package/dist/src/commands/re-export-register.js +56 -17
  130. package/dist/src/commands/re-export-removed.d.ts +13 -2
  131. package/dist/src/commands/re-export-removed.js +57 -12
  132. package/dist/src/commands/re-export-scan-owner.d.ts +44 -0
  133. package/dist/src/commands/re-export-scan-owner.js +116 -0
  134. package/dist/src/commands/re-export-scan.d.ts +19 -9
  135. package/dist/src/commands/re-export-scan.js +60 -24
  136. package/dist/src/commands/re-export-single.js +122 -46
  137. package/dist/src/commands/re-export-stale-registrations.d.ts +18 -0
  138. package/dist/src/commands/re-export-stale-registrations.js +62 -0
  139. package/dist/src/commands/re-export-summary.d.ts +28 -0
  140. package/dist/src/commands/re-export-summary.js +36 -0
  141. package/dist/src/commands/re-export.js +71 -57
  142. package/dist/src/commands/rebase/index.js +17 -17
  143. package/dist/src/commands/run.js +16 -2
  144. package/dist/src/commands/status-check.d.ts +55 -16
  145. package/dist/src/commands/status-check.js +92 -37
  146. package/dist/src/commands/status-json.d.ts +22 -9
  147. package/dist/src/commands/status-json.js +47 -32
  148. package/dist/src/commands/status-output.js +3 -1
  149. package/dist/src/commands/status-scope.d.ts +37 -0
  150. package/dist/src/commands/status-scope.js +54 -0
  151. package/dist/src/commands/status.js +66 -23
  152. package/dist/src/commands/test-browser-preflight.js +19 -3
  153. package/dist/src/commands/test-build-furnace.d.ts +22 -0
  154. package/dist/src/commands/test-build-furnace.js +54 -0
  155. package/dist/src/commands/test-build-phase.js +64 -41
  156. package/dist/src/commands/test-checkjs.js +10 -2
  157. package/dist/src/commands/test-diagnose.js +7 -0
  158. package/dist/src/commands/test-dispatch.d.ts +39 -0
  159. package/dist/src/commands/test-dispatch.js +211 -0
  160. package/dist/src/commands/test-furnace-reach.d.ts +37 -0
  161. package/dist/src/commands/test-furnace-reach.js +132 -0
  162. package/dist/src/commands/test-modes.d.ts +16 -1
  163. package/dist/src/commands/test-modes.js +24 -1
  164. package/dist/src/commands/test-multi-verdict.d.ts +61 -0
  165. package/dist/src/commands/test-multi-verdict.js +111 -0
  166. package/dist/src/commands/test-orchestrate.d.ts +52 -0
  167. package/dist/src/commands/test-orchestrate.js +240 -0
  168. package/dist/src/commands/test-perf-scope.d.ts +50 -0
  169. package/dist/src/commands/test-perf-scope.js +138 -0
  170. package/dist/src/commands/test-prelock.d.ts +51 -0
  171. package/dist/src/commands/test-prelock.js +273 -0
  172. package/dist/src/commands/test-register.js +69 -10
  173. package/dist/src/commands/test-results.d.ts +62 -0
  174. package/dist/src/commands/test-results.js +62 -0
  175. package/dist/src/commands/test-run.d.ts +13 -55
  176. package/dist/src/commands/test-run.js +74 -99
  177. package/dist/src/commands/test-shards.d.ts +110 -0
  178. package/dist/src/commands/test-shards.js +255 -0
  179. package/dist/src/commands/test-stale-gate.d.ts +5 -1
  180. package/dist/src/commands/test-stale-gate.js +60 -28
  181. package/dist/src/commands/test-verdict.d.ts +11 -1
  182. package/dist/src/commands/test-verdict.js +28 -1
  183. package/dist/src/commands/test.d.ts +6 -1
  184. package/dist/src/commands/test.js +120 -124
  185. package/dist/src/commands/token-lint.d.ts +14 -0
  186. package/dist/src/commands/token-lint.js +151 -0
  187. package/dist/src/commands/token.js +10 -0
  188. package/dist/src/commands/verify-scope.d.ts +28 -0
  189. package/dist/src/commands/verify-scope.js +67 -0
  190. package/dist/src/commands/verify.d.ts +10 -2
  191. package/dist/src/commands/verify.js +67 -36
  192. package/dist/src/core/build-baseline-types.d.ts +46 -0
  193. package/dist/src/core/build-baseline-validate.js +19 -0
  194. package/dist/src/core/build-baseline.d.ts +5 -1
  195. package/dist/src/core/build-baseline.js +3 -1
  196. package/dist/src/core/build-overwrite-guard.d.ts +50 -0
  197. package/dist/src/core/build-overwrite-guard.js +84 -4
  198. package/dist/src/core/build-prepare.d.ts +13 -0
  199. package/dist/src/core/build-prepare.js +42 -10
  200. package/dist/src/core/build-run-record.d.ts +74 -0
  201. package/dist/src/core/build-run-record.js +136 -0
  202. package/dist/src/core/checkjs-support-heads.d.ts +41 -0
  203. package/dist/src/core/checkjs-support-heads.js +104 -0
  204. package/dist/src/core/config-paths.d.ts +2 -2
  205. package/dist/src/core/config-paths.js +10 -0
  206. package/dist/src/core/config-validate-check.d.ts +8 -0
  207. package/dist/src/core/config-validate-check.js +219 -0
  208. package/dist/src/core/config-validate-file-size.d.ts +9 -6
  209. package/dist/src/core/config-validate-file-size.js +91 -2
  210. package/dist/src/core/config-validate-history.d.ts +11 -0
  211. package/dist/src/core/config-validate-history.js +38 -0
  212. package/dist/src/core/config-validate-patch-policy.js +100 -0
  213. package/dist/src/core/config-validate-test-toolchains.js +21 -0
  214. package/dist/src/core/config-validate-token-scales.d.ts +9 -0
  215. package/dist/src/core/config-validate-token-scales.js +92 -0
  216. package/dist/src/core/config-validate.js +20 -5
  217. package/dist/src/core/config.d.ts +5 -0
  218. package/dist/src/core/config.js +16 -0
  219. package/dist/src/core/coverage-dispatch.d.ts +24 -0
  220. package/dist/src/core/coverage-dispatch.js +44 -0
  221. package/dist/src/core/coverage-extend.d.ts +70 -45
  222. package/dist/src/core/coverage-extend.js +199 -144
  223. package/dist/src/core/coverage-records.d.ts +108 -0
  224. package/dist/src/core/coverage-records.js +384 -0
  225. package/dist/src/core/destructive.d.ts +7 -4
  226. package/dist/src/core/destructive.js +10 -10
  227. package/dist/src/core/engine-session-lock.d.ts +16 -1
  228. package/dist/src/core/engine-session-lock.js +38 -10
  229. package/dist/src/core/export-moved-code-shape.d.ts +49 -11
  230. package/dist/src/core/export-moved-code-shape.js +135 -44
  231. package/dist/src/core/file-lock-queue.d.ts +67 -0
  232. package/dist/src/core/file-lock-queue.js +221 -0
  233. package/dist/src/core/file-lock-shared.d.ts +57 -0
  234. package/dist/src/core/file-lock-shared.js +117 -0
  235. package/dist/src/core/file-lock.d.ts +13 -25
  236. package/dist/src/core/file-lock.js +163 -140
  237. package/dist/src/core/furnace-apply-output.d.ts +10 -0
  238. package/dist/src/core/furnace-apply-output.js +31 -1
  239. package/dist/src/core/furnace-apply.js +22 -12
  240. package/dist/src/core/furnace-composed-source.d.ts +76 -0
  241. package/dist/src/core/furnace-composed-source.js +167 -0
  242. package/dist/src/core/furnace-config-validate-exceptions.d.ts +16 -0
  243. package/dist/src/core/furnace-config-validate-exceptions.js +102 -0
  244. package/dist/src/core/furnace-config-validate.js +14 -0
  245. package/dist/src/core/furnace-css-fragments.d.ts +10 -0
  246. package/dist/src/core/furnace-css-fragments.js +26 -0
  247. package/dist/src/core/furnace-operation.d.ts +3 -3
  248. package/dist/src/core/furnace-registration-jar-inplace.d.ts +12 -0
  249. package/dist/src/core/furnace-registration-jar-inplace.js +80 -0
  250. package/dist/src/core/furnace-registration-remove.d.ts +22 -1
  251. package/dist/src/core/furnace-registration-remove.js +53 -17
  252. package/dist/src/core/furnace-registration-rename.d.ts +26 -0
  253. package/dist/src/core/furnace-registration-rename.js +77 -0
  254. package/dist/src/core/furnace-registration.d.ts +14 -4
  255. package/dist/src/core/furnace-registration.js +44 -10
  256. package/dist/src/core/furnace-staleness.d.ts +7 -0
  257. package/dist/src/core/furnace-staleness.js +34 -24
  258. package/dist/src/core/furnace-validate-accessibility.d.ts +8 -4
  259. package/dist/src/core/furnace-validate-accessibility.js +71 -28
  260. package/dist/src/core/furnace-validate-exceptions.d.ts +48 -0
  261. package/dist/src/core/furnace-validate-exceptions.js +80 -0
  262. package/dist/src/core/furnace-validate-icon-button.d.ts +7 -0
  263. package/dist/src/core/furnace-validate-icon-button.js +78 -0
  264. package/dist/src/core/furnace-validate.js +1 -1
  265. package/dist/src/core/harness-port-fallback.d.ts +60 -0
  266. package/dist/src/core/harness-port-fallback.js +96 -0
  267. package/dist/src/core/history-log-file.d.ts +61 -0
  268. package/dist/src/core/history-log-file.js +164 -0
  269. package/dist/src/core/history-log.d.ts +2 -1
  270. package/dist/src/core/history-log.js +2 -1
  271. package/dist/src/core/json-preserving-edit.d.ts +22 -0
  272. package/dist/src/core/json-preserving-edit.js +199 -0
  273. package/dist/src/core/line-prefixer.d.ts +18 -0
  274. package/dist/src/core/line-prefixer.js +34 -0
  275. package/dist/src/core/mach.d.ts +7 -0
  276. package/dist/src/core/mach.js +32 -10
  277. package/dist/src/core/module-resolution-preflight.d.ts +19 -3
  278. package/dist/src/core/module-resolution-preflight.js +24 -6
  279. package/dist/src/core/negative-control-compiled.d.ts +27 -0
  280. package/dist/src/core/negative-control-compiled.js +73 -0
  281. package/dist/src/core/negative-control-diff.d.ts +51 -0
  282. package/dist/src/core/negative-control-diff.js +179 -0
  283. package/dist/src/core/negative-control.d.ts +150 -0
  284. package/dist/src/core/negative-control.js +399 -0
  285. package/dist/src/core/objdir-install-manifests.d.ts +73 -0
  286. package/dist/src/core/objdir-install-manifests.js +226 -0
  287. package/dist/src/core/park-store.d.ts +63 -0
  288. package/dist/src/core/park-store.js +216 -0
  289. package/dist/src/core/patch-export-update.d.ts +6 -0
  290. package/dist/src/core/patch-export-update.js +13 -3
  291. package/dist/src/core/patch-export.d.ts +3 -2
  292. package/dist/src/core/patch-export.js +22 -16
  293. package/dist/src/core/patch-files.js +26 -8
  294. package/dist/src/core/patch-lint-checkjs-any-import.d.ts +39 -0
  295. package/dist/src/core/patch-lint-checkjs-any-import.js +63 -0
  296. package/dist/src/core/patch-lint-checkjs-diagnostics.d.ts +17 -0
  297. package/dist/src/core/patch-lint-checkjs-diagnostics.js +32 -0
  298. package/dist/src/core/patch-lint-checkjs.d.ts +10 -1
  299. package/dist/src/core/patch-lint-checkjs.js +20 -13
  300. package/dist/src/core/patch-lint-code-lines.d.ts +59 -0
  301. package/dist/src/core/patch-lint-code-lines.js +105 -0
  302. package/dist/src/core/patch-lint-cross.d.ts +3 -1
  303. package/dist/src/core/patch-lint-cross.js +17 -4
  304. package/dist/src/core/patch-lint-css.d.ts +8 -2
  305. package/dist/src/core/patch-lint-css.js +24 -14
  306. package/dist/src/core/patch-lint-file-size.d.ts +12 -5
  307. package/dist/src/core/patch-lint-file-size.js +22 -11
  308. package/dist/src/core/patch-lint-forward-registration-extended.d.ts +23 -0
  309. package/dist/src/core/patch-lint-forward-registration-extended.js +36 -11
  310. package/dist/src/core/patch-lint-forward-registration.js +10 -0
  311. package/dist/src/core/patch-lint-ignore.d.ts +196 -0
  312. package/dist/src/core/patch-lint-ignore.js +429 -0
  313. package/dist/src/core/patch-lint-ownership.d.ts +10 -0
  314. package/dist/src/core/patch-lint-ownership.js +26 -0
  315. package/dist/src/core/patch-lint-size-thresholds.d.ts +52 -0
  316. package/dist/src/core/patch-lint-size-thresholds.js +110 -0
  317. package/dist/src/core/patch-lint-size.d.ts +117 -0
  318. package/dist/src/core/patch-lint-size.js +331 -0
  319. package/dist/src/core/patch-lint-staged-registration.d.ts +18 -1
  320. package/dist/src/core/patch-lint-staged-registration.js +20 -0
  321. package/dist/src/core/patch-lint-token-scale.d.ts +57 -0
  322. package/dist/src/core/patch-lint-token-scale.js +286 -0
  323. package/dist/src/core/patch-lint.d.ts +11 -83
  324. package/dist/src/core/patch-lint.js +66 -288
  325. package/dist/src/core/patch-lock.js +7 -6
  326. package/dist/src/core/patch-manifest-consistency.js +7 -6
  327. package/dist/src/core/patch-manifest-io.d.ts +6 -3
  328. package/dist/src/core/patch-manifest-io.js +27 -9
  329. package/dist/src/core/patch-manifest-key-order.d.ts +24 -0
  330. package/dist/src/core/patch-manifest-key-order.js +61 -0
  331. package/dist/src/core/patch-manifest-stage.d.ts +46 -0
  332. package/dist/src/core/patch-manifest-stage.js +96 -0
  333. package/dist/src/core/patch-manifest-validate.js +61 -3
  334. package/dist/src/core/patch-order-legal.d.ts +26 -0
  335. package/dist/src/core/patch-order-legal.js +88 -0
  336. package/dist/src/core/patch-policy-content.d.ts +40 -0
  337. package/dist/src/core/patch-policy-content.js +216 -0
  338. package/dist/src/core/patch-policy.d.ts +22 -5
  339. package/dist/src/core/patch-policy.js +26 -12
  340. package/dist/src/core/patch-retired.d.ts +57 -0
  341. package/dist/src/core/patch-retired.js +92 -0
  342. package/dist/src/core/patch-subset.d.ts +16 -0
  343. package/dist/src/core/patch-subset.js +66 -0
  344. package/dist/src/core/preflight-wait.d.ts +20 -0
  345. package/dist/src/core/preflight-wait.js +38 -0
  346. package/dist/src/core/rebase-from-version.d.ts +46 -0
  347. package/dist/src/core/rebase-from-version.js +71 -0
  348. package/dist/src/core/run-log.d.ts +26 -0
  349. package/dist/src/core/run-log.js +106 -4
  350. package/dist/src/core/run-profile.d.ts +7 -0
  351. package/dist/src/core/run-profile.js +7 -1
  352. package/dist/src/core/smoke-patterns.d.ts +5 -0
  353. package/dist/src/core/smoke-patterns.js +13 -0
  354. package/dist/src/core/test-harness-crash.d.ts +19 -1
  355. package/dist/src/core/test-harness-crash.js +8 -9
  356. package/dist/src/core/test-harness-signature.d.ts +33 -0
  357. package/dist/src/core/test-harness-signature.js +23 -1
  358. package/dist/src/core/test-raw-log.d.ts +66 -0
  359. package/dist/src/core/test-raw-log.js +122 -0
  360. package/dist/src/core/test-run-completeness.d.ts +90 -0
  361. package/dist/src/core/test-run-completeness.js +184 -0
  362. package/dist/src/core/test-stale-check.d.ts +27 -1
  363. package/dist/src/core/test-stale-check.js +39 -49
  364. package/dist/src/core/test-stale-exempt.d.ts +40 -0
  365. package/dist/src/core/test-stale-exempt.js +70 -0
  366. package/dist/src/core/test-xpcshell-retry.d.ts +2 -0
  367. package/dist/src/core/test-xpcshell-retry.js +2 -1
  368. package/dist/src/core/token-lint.d.ts +53 -0
  369. package/dist/src/core/token-lint.js +131 -0
  370. package/dist/src/core/token-sibling-sheets.d.ts +46 -0
  371. package/dist/src/core/token-sibling-sheets.js +119 -0
  372. package/dist/src/core/tree-guard.js +5 -0
  373. package/dist/src/core/typecheck-shim.d.ts +6 -2
  374. package/dist/src/core/typecheck-shim.js +205 -4
  375. package/dist/src/core/typecheck.js +3 -1
  376. package/dist/src/index.d.ts +14 -3
  377. package/dist/src/index.js +6 -1
  378. package/dist/src/types/commands/index.d.ts +2 -2
  379. package/dist/src/types/commands/options.d.ts +212 -24
  380. package/dist/src/types/commands/patches.d.ts +118 -1
  381. package/dist/src/types/config.d.ts +264 -0
  382. package/dist/src/types/config.js +9 -0
  383. package/dist/src/types/furnace.d.ts +63 -1
  384. package/dist/src/types/furnace.js +7 -0
  385. package/dist/src/types/index.d.ts +1 -1
  386. package/dist/src/utils/options.d.ts +36 -7
  387. package/dist/src/utils/options.js +94 -8
  388. package/dist/src/utils/path-glob.d.ts +15 -0
  389. package/dist/src/utils/path-glob.js +47 -0
  390. package/dist/src/utils/regex.d.ts +15 -3
  391. package/dist/src/utils/regex.js +37 -16
  392. package/docs/configuration.md +369 -11
  393. package/docs/exit-codes.md +18 -1
  394. package/docs/furnace.md +139 -3
  395. package/docs/lifecycle-invariants.md +65 -30
  396. package/docs/machine-output.md +120 -12
  397. package/docs/patch-workflow.md +458 -22
  398. package/docs/run-logs.md +20 -1
  399. package/docs/testing.md +346 -21
  400. package/package.json +3 -3
@@ -0,0 +1,240 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * Multi-run orchestration for `fireforge test`, all under the one
4
+ * engine-session lock hold the command already has:
5
+ *
6
+ * - mixed harness paths run as two consecutive mach invocations, xpcshell
7
+ * first, with one pre-test build (when `--build`) packaging both halves;
8
+ * - `--repeat <n>` runs the same selection n times, building once;
9
+ * - `--negative-control <diff>` applies a reviewed mutation after the
10
+ * build and right before each dispatch, and restores it after the run.
11
+ *
12
+ * Each sub-run is the ordinary single-run body. Its verdict line is
13
+ * captured rather than printed (see `setVerdictCapture`) and echoed as a
14
+ * `FIREFORGE-RUN:` line, and the invocation ends with one aggregate
15
+ * `FIREFORGE-VERDICT:` line. A request that needs none of this runs the
16
+ * body exactly as before.
17
+ */
18
+ import { getProjectPaths } from '../core/config.js';
19
+ import { applyNegativeControl, planNegativeControl, recoverPendingNegativeControl, restoreNegativeControl, } from '../core/negative-control.js';
20
+ import { formatCompiledControlRefusal } from '../core/negative-control-compiled.js';
21
+ import { getActiveRunLogPath, writeToActiveRunLog } from '../core/run-log.js';
22
+ import { GeneralError, InvalidArgumentError, PreflightRefusalError } from '../errors/base.js';
23
+ import { TestFailureError } from '../errors/build.js';
24
+ import { toError } from '../utils/errors.js';
25
+ import { info, notice, success } from '../utils/logger.js';
26
+ import { stripEnginePrefix } from '../utils/paths.js';
27
+ import { classifyTestHarnesses } from './test-modes.js';
28
+ import { deriveControlOutcome, describeControlOutcome, formatAggregateBody, formatRunLine, parseCapturedVerdict, worstRun, } from './test-multi-verdict.js';
29
+ import { emitAggregateVerdict, emitFailVerdict, setVerdictCapture, setVerdictRunAttribute, verdictEmitted, } from './test-verdict.js';
30
+ function assertMultiRunUsage(testPaths, options) {
31
+ const flag = options.negativeControl !== undefined ? '--negative-control' : '--repeat';
32
+ if (testPaths.length === 0) {
33
+ throw new InvalidArgumentError(`${flag} needs explicit test paths.`, flag);
34
+ }
35
+ if (options.buildOnly === true || options.canary !== undefined || options.auto === true) {
36
+ throw new InvalidArgumentError(`${flag} runs tests, so it cannot be combined with --build-only, --canary or --auto.`, flag);
37
+ }
38
+ }
39
+ async function splitHarnesses(engineDir, testPaths, options) {
40
+ // `--build-only` packages a mixed union itself and dispatches nothing.
41
+ if (testPaths.length === 0 || options.buildOnly === true || options.canary !== undefined) {
42
+ return undefined;
43
+ }
44
+ const normalized = testPaths.map((path) => stripEnginePrefix(path).trim());
45
+ const classification = await classifyTestHarnesses(engineDir, normalized);
46
+ if (classification.xpcshell.length === 0 || classification.nonXpcshell.length === 0) {
47
+ return undefined;
48
+ }
49
+ notice(`Mixed harnesses: running ${classification.xpcshell.length} xpcshell path(s), then ` +
50
+ `${classification.nonXpcshell.length} browser/mochitest path(s), as two mach invocations ` +
51
+ 'under this lock hold' +
52
+ (options.build === true ? ', after one pre-test build that packages both.' : '.'));
53
+ return [
54
+ { harness: 'xpcshell', paths: classification.xpcshell },
55
+ { harness: 'mochitest', paths: classification.nonXpcshell },
56
+ ];
57
+ }
58
+ /** Options for every run after the first: the build and doctor run once. */
59
+ function laterRunOptions(options) {
60
+ const later = { ...options };
61
+ delete later.build;
62
+ delete later.extendCoverage;
63
+ delete later.refuseUnexportedDrift;
64
+ delete later.doctor;
65
+ return later;
66
+ }
67
+ async function planRuns(engineDir, testPaths, options) {
68
+ const repeat = options.repeat ?? 1;
69
+ const control = options.negativeControl !== undefined;
70
+ if (repeat > 1 || control)
71
+ assertMultiRunUsage(testPaths, options);
72
+ const halves = await splitHarnesses(engineDir, testPaths, options);
73
+ if (halves === undefined && repeat === 1 && !control)
74
+ return undefined;
75
+ const groups = halves ?? [
76
+ { paths: testPaths },
77
+ ];
78
+ const union = halves?.flatMap((half) => half.paths);
79
+ const runs = [];
80
+ for (let repetition = 1; repetition <= repeat; repetition += 1) {
81
+ for (const group of groups) {
82
+ const first = runs.length === 0;
83
+ runs.push({
84
+ repetition,
85
+ ...(group.harness === undefined ? {} : { harness: group.harness }),
86
+ paths: group.paths,
87
+ options: first ? options : laterRunOptions(options),
88
+ hooks: {
89
+ repetition,
90
+ ...(first && union !== undefined ? { coveragePaths: union } : {}),
91
+ },
92
+ });
93
+ }
94
+ }
95
+ return runs;
96
+ }
97
+ function writeRunLine(line) {
98
+ process.stdout.write(`${line}\n`);
99
+ writeToActiveRunLog(`${line}\n`);
100
+ }
101
+ function controlHook(paths, plan, slot) {
102
+ return async () => {
103
+ slot.applied = await applyNegativeControl(paths, plan);
104
+ notice(`Negative control applied to ${plan.targets.map((target) => `engine/${target.enginePath}`).join(', ')}; ` +
105
+ 'it stays in place until this run has finished.');
106
+ };
107
+ }
108
+ /**
109
+ * Throws the invocation's error after the aggregate verdict, or returns
110
+ * when the invocation succeeded (all runs green, or a control caught).
111
+ */
112
+ function finishInvocation(results, plannedTotal, control) {
113
+ if (control !== undefined)
114
+ info(describeControlOutcome(control));
115
+ if (control === 'caught') {
116
+ success('Negative control caught.');
117
+ return;
118
+ }
119
+ if (control === 'missed') {
120
+ throw new TestFailureError('Negative control stayed green: no run went red with the mutation applied, so the selected tests do not detect it.', 'mach test', undefined, getActiveRunLogPath());
121
+ }
122
+ const worst = worstRun(results);
123
+ if (worst === undefined)
124
+ return;
125
+ if (worst.reason === 'preflight' || worst.reason === 'inconclusive') {
126
+ throw worst.error instanceof Error
127
+ ? worst.error
128
+ : new GeneralError(`Run ${results.indexOf(worst) + 1} was refused.`);
129
+ }
130
+ const failing = results
131
+ .map((result, index) => ({ result, index }))
132
+ .filter(({ result }) => !result.passed)
133
+ .map(({ result, index }) => `run ${index + 1} (${result.reason ?? 'failed'})`);
134
+ throw new TestFailureError(`${failing.length} of ${plannedTotal} run(s) did not pass: ${failing.join(', ')}. See each FIREFORGE-RUN line above.`, 'mach test', undefined, getActiveRunLogPath());
135
+ }
136
+ /**
137
+ * Runs `fireforge test` as one or several sub-runs. Always recovers a
138
+ * negative control a killed earlier run left applied, first.
139
+ *
140
+ * @param projectRoot - Project root
141
+ * @param testPaths - The positional test paths
142
+ * @param options - Parsed test options
143
+ * @param body - The single-run body
144
+ * @param onRefusal - Renders a sub-run's preflight refusal and emits its
145
+ * `FAIL reason=preflight` verdict (captured), as `testCommand` does for a
146
+ * single run
147
+ */
148
+ export async function orchestrateTestRuns(projectRoot, testPaths, options, body, onRefusal) {
149
+ const projectPaths = getProjectPaths(projectRoot);
150
+ const controlPaths = {
151
+ engineDir: projectPaths.engine,
152
+ fireforgeDir: projectPaths.fireforgeDir,
153
+ };
154
+ await recoverPendingNegativeControl(controlPaths);
155
+ const runs = await planRuns(projectPaths.engine, testPaths, options);
156
+ if (runs === undefined) {
157
+ await body(testPaths, options, {});
158
+ return;
159
+ }
160
+ const plan = options.negativeControl === undefined
161
+ ? undefined
162
+ : await planNegativeControl(projectRoot, projectPaths.engine, options.negativeControl, {
163
+ deferApplyCheck: options.build === true,
164
+ });
165
+ // A compiled target only reaches the binary through a build, so its
166
+ // control goes in before the first run's pre-test build.
167
+ const compiled = plan?.compiled;
168
+ const compiledControl = compiled !== undefined;
169
+ if (compiledControl) {
170
+ if (options.build !== true) {
171
+ throw new PreflightRefusalError(formatCompiledControlRefusal(compiled), 'negative-control');
172
+ }
173
+ setVerdictRunAttribute('control-build', 'compiled');
174
+ }
175
+ const results = [];
176
+ let restoreError;
177
+ for (const [index, run] of runs.entries()) {
178
+ notice(`Run ${index + 1}/${runs.length}${run.harness === undefined ? '' : ` (${run.harness})`}` +
179
+ `${plan === undefined ? '' : ', negative control'}: ${run.paths.join(' ')}`);
180
+ const capture = {};
181
+ const slot = {};
182
+ let error;
183
+ setVerdictCapture(capture);
184
+ try {
185
+ await body(run.paths, run.options, {
186
+ ...run.hooks,
187
+ ...(plan === undefined
188
+ ? {}
189
+ : compiledControl && index === 0
190
+ ? { beforeBuild: controlHook(controlPaths, plan, slot) }
191
+ : { beforeDispatch: controlHook(controlPaths, plan, slot) }),
192
+ });
193
+ }
194
+ catch (caught) {
195
+ error = caught;
196
+ if (capture.line === undefined)
197
+ onRefusal(caught);
198
+ }
199
+ finally {
200
+ setVerdictCapture(undefined);
201
+ }
202
+ // Only a kill writes a real verdict while a capture is installed (see
203
+ // emitKilledVerdict). The invocation is over: restore, start nothing
204
+ // more, print nothing after that line.
205
+ const killed = verdictEmitted();
206
+ if (slot.applied !== undefined) {
207
+ try {
208
+ const restored = await restoreNegativeControl(slot.applied);
209
+ info(`Negative control restored byte-exact: ${restored.restored.length} file(s).`);
210
+ }
211
+ catch (caught) {
212
+ restoreError = caught;
213
+ }
214
+ }
215
+ if (killed)
216
+ throw toError(restoreError ?? error ?? new GeneralError('The run was killed.'));
217
+ const result = {
218
+ repetition: run.repetition,
219
+ ...(run.harness === undefined ? {} : { harness: run.harness }),
220
+ ...parseCapturedVerdict(capture.line),
221
+ ...(error === undefined ? {} : { error }),
222
+ };
223
+ results.push(result);
224
+ writeRunLine(formatRunLine(result, index, runs.length));
225
+ if (restoreError !== undefined)
226
+ break;
227
+ if (result.reason === 'preflight' || result.reason === 'inconclusive')
228
+ break;
229
+ }
230
+ if (restoreError !== undefined) {
231
+ emitFailVerdict('inconclusive', 'negative-control-restore');
232
+ throw toError(restoreError);
233
+ }
234
+ const repetitions = options.repeat ?? 1;
235
+ const control = plan === undefined
236
+ ? undefined
237
+ : deriveControlOutcome(results, repetitions, results.length === runs.length);
238
+ emitAggregateVerdict(formatAggregateBody(results, runs.length, control));
239
+ finishInvocation(results, runs.length, control);
240
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Scope of the evidence a `--perf-samples` run reports and invalidates on.
3
+ *
4
+ * - A stale-build refusal on a perf run says which stale packaged files are
5
+ * staging inputs of the sampled test and which lie elsewhere, so a sample
6
+ * whose fixture is unaffected can proceed knowingly under
7
+ * `--allow-stale-build`.
8
+ * - An engine edit that lands while a sample runs makes the verdict
9
+ * `inconclusive` only when the edited path is something the running build
10
+ * packages (an install-manifest source, or a test file). An edit to a
11
+ * compiled source, a build file or anything else no manifest installs
12
+ * cannot reach the running binary, so the sample stands with a warning.
13
+ */
14
+ /**
15
+ * The perf-impact line of a stale-build refusal.
16
+ *
17
+ * @param engineDir - Absolute engine directory
18
+ * @param stalePaths - Stale packaged paths the refusal names
19
+ * @param requested - Normalized request paths of the run
20
+ */
21
+ export declare function describePerfStaleImpact(engineDir: string, stalePaths: readonly string[], requested: readonly string[]): Promise<string>;
22
+ /**
23
+ * Tolerance for `assertEngineGenerationUnchanged` on a `--perf-samples` run:
24
+ * true (with a warning naming the edits) when HEAD did not move and no
25
+ * changed path is packaged by the running build.
26
+ *
27
+ * @param engineDir - Absolute engine directory
28
+ */
29
+ export declare function perfGenerationTolerance(engineDir: string): (before: string, after: string) => Promise<boolean>;
30
+ /**
31
+ * Tolerance for `assertEngineGenerationUnchanged` on an ordinary run: true
32
+ * (with a warning, and `drift-tolerated=<n>` on the verdict) when HEAD did
33
+ * not move and every changed path is one the running browser cannot see.
34
+ *
35
+ * A peer deleting an unrelated chrome script used to make a whole run
36
+ * inconclusive. What a running browser can see mid-run is narrower than
37
+ * "anything under engine/": a file the objdir links to its source (`live`),
38
+ * one the harness stages at dispatch (`at-dispatch`), and the run's own
39
+ * test files and the staging inputs their manifests name. A compiled
40
+ * source, or a file the build copied into the package, is already fixed in
41
+ * the running binary or package; the next run's stale-build gate judges it.
42
+ *
43
+ * Perf runs keep {@link perfGenerationTolerance}: a sample is also void
44
+ * when a packaged path changes.
45
+ *
46
+ * @param engineDir - Absolute engine directory
47
+ * @param requested - Normalized request paths of the run
48
+ * @param onTolerated - Receives the tolerated path count
49
+ */
50
+ export declare function runGenerationTolerance(engineDir: string, requested: readonly string[], onTolerated: (count: number) => void): (before: string, after: string) => Promise<boolean>;
@@ -0,0 +1,138 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * Scope of the evidence a `--perf-samples` run reports and invalidates on.
4
+ *
5
+ * - A stale-build refusal on a perf run says which stale packaged files are
6
+ * staging inputs of the sampled test and which lie elsewhere, so a sample
7
+ * whose fixture is unaffected can proceed knowingly under
8
+ * `--allow-stale-build`.
9
+ * - An engine edit that lands while a sample runs makes the verdict
10
+ * `inconclusive` only when the edited path is something the running build
11
+ * packages (an install-manifest source, or a test file). An edit to a
12
+ * compiled source, a build file or anything else no manifest installs
13
+ * cannot reach the running binary, so the sample stands with a warning.
14
+ */
15
+ import { isTestPath } from '../core/build-audit-resolve.js';
16
+ import { collectStagingInputs, isUnderPath } from '../core/coverage-records.js';
17
+ import { generationDeltaPaths } from '../core/engine-session-lock.js';
18
+ import { classifyRuntimeDelivery, installsFromDirectory, } from '../core/objdir-install-manifests.js';
19
+ import { loadEngineInstallIndex } from '../core/test-stale-exempt.js';
20
+ import { warn } from '../utils/logger.js';
21
+ /** How many paths an impact line names per group. */
22
+ const IMPACT_LIST_LIMIT = 5;
23
+ function capList(paths) {
24
+ const head = paths.slice(0, IMPACT_LIST_LIMIT).join(', ');
25
+ const extra = paths.length - Math.min(paths.length, IMPACT_LIST_LIMIT);
26
+ return extra > 0 ? `${head}, … (+${extra} more)` : head;
27
+ }
28
+ /**
29
+ * The perf-impact line of a stale-build refusal.
30
+ *
31
+ * @param engineDir - Absolute engine directory
32
+ * @param stalePaths - Stale packaged paths the refusal names
33
+ * @param requested - Normalized request paths of the run
34
+ */
35
+ export async function describePerfStaleImpact(engineDir, stalePaths, requested) {
36
+ const inputs = [];
37
+ for (const path of requested)
38
+ inputs.push(...(await collectStagingInputs(engineDir, path)));
39
+ const fixture = stalePaths.filter((path) => inputs.some((input) => isUnderPath(path, input)));
40
+ const elsewhere = stalePaths.filter((path) => !fixture.includes(path));
41
+ const fixturePart = fixture.length > 0
42
+ ? `${fixture.length} stale file(s) are staging inputs of the sampled test (${capList(fixture)}), so the sample would measure the old content`
43
+ : requested.length > 0
44
+ ? "the sampled test's own staging inputs are unaffected"
45
+ : 'no test paths were named, so every stale file may be measured';
46
+ const elsewherePart = elsewhere.length > 0 && requested.length > 0
47
+ ? `; ${elsewhere.length} stale packaged file(s) lie outside them (${capList(elsewhere)}) and affect the sample only if the measured path loads them`
48
+ : '';
49
+ return (`Perf sample impact: ${fixturePart}${elsewherePart}. Repackage first, or pass ` +
50
+ '--allow-stale-build to take the sample knowingly.');
51
+ }
52
+ /**
53
+ * Tolerance for `assertEngineGenerationUnchanged` on a `--perf-samples` run:
54
+ * true (with a warning naming the edits) when HEAD did not move and no
55
+ * changed path is packaged by the running build.
56
+ *
57
+ * @param engineDir - Absolute engine directory
58
+ */
59
+ export function perfGenerationTolerance(engineDir) {
60
+ return async (before, after) => {
61
+ const delta = generationDeltaPaths(before, after);
62
+ if (delta.headMoved || delta.paths.length === 0)
63
+ return false;
64
+ const index = await loadEngineInstallIndex(engineDir);
65
+ if (index === undefined)
66
+ return false;
67
+ for (const path of delta.paths) {
68
+ if (isTestPath(path))
69
+ return false;
70
+ if (path.endsWith('/')) {
71
+ if (installsFromDirectory(index, path))
72
+ return false;
73
+ }
74
+ else if ((await classifyRuntimeDelivery(index, engineDir, path)) !== 'unlisted') {
75
+ return false;
76
+ }
77
+ }
78
+ warn(`engine/ changed while this perf sample ran, but only in files the running build does not ` +
79
+ `package (${capList(delta.paths)}); the sample stands. Rebuild before the next sample if ` +
80
+ 'they belong in it.');
81
+ return true;
82
+ };
83
+ }
84
+ /**
85
+ * Tolerance for `assertEngineGenerationUnchanged` on an ordinary run: true
86
+ * (with a warning, and `drift-tolerated=<n>` on the verdict) when HEAD did
87
+ * not move and every changed path is one the running browser cannot see.
88
+ *
89
+ * A peer deleting an unrelated chrome script used to make a whole run
90
+ * inconclusive. What a running browser can see mid-run is narrower than
91
+ * "anything under engine/": a file the objdir links to its source (`live`),
92
+ * one the harness stages at dispatch (`at-dispatch`), and the run's own
93
+ * test files and the staging inputs their manifests name. A compiled
94
+ * source, or a file the build copied into the package, is already fixed in
95
+ * the running binary or package; the next run's stale-build gate judges it.
96
+ *
97
+ * Perf runs keep {@link perfGenerationTolerance}: a sample is also void
98
+ * when a packaged path changes.
99
+ *
100
+ * @param engineDir - Absolute engine directory
101
+ * @param requested - Normalized request paths of the run
102
+ * @param onTolerated - Receives the tolerated path count
103
+ */
104
+ export function runGenerationTolerance(engineDir, requested, onTolerated) {
105
+ return async (before, after) => {
106
+ const delta = generationDeltaPaths(before, after);
107
+ if (delta.headMoved || delta.paths.length === 0)
108
+ return false;
109
+ const index = await loadEngineInstallIndex(engineDir);
110
+ if (index === undefined)
111
+ return false;
112
+ const inputs = [...requested];
113
+ for (const path of requested)
114
+ inputs.push(...(await collectStagingInputs(engineDir, path)));
115
+ for (const path of delta.paths) {
116
+ const bare = path.endsWith('/') ? path.slice(0, -1) : path;
117
+ if (inputs.some((input) => isUnderPath(bare, input) || isUnderPath(input, bare))) {
118
+ return false;
119
+ }
120
+ // A path-less run requests every test, so any test file is its own.
121
+ if (requested.length === 0 && isTestPath(path))
122
+ return false;
123
+ if (path.endsWith('/')) {
124
+ if (installsFromDirectory(index, path))
125
+ return false;
126
+ continue;
127
+ }
128
+ const delivery = await classifyRuntimeDelivery(index, engineDir, path);
129
+ if (delivery === 'live' || delivery === 'at-dispatch')
130
+ return false;
131
+ }
132
+ warn(`engine/ changed while this run was in flight, but only in files the running browser ` +
133
+ `cannot see (${capList(delta.paths)}); the verdict stands. The next run's stale-build ` +
134
+ 'gate judges whether they need a rebuild.');
135
+ onTolerated(delta.paths.length);
136
+ return true;
137
+ };
138
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The `fireforge test` checks that run BEFORE the engine session lock.
3
+ *
4
+ * Everything here reads, never writes, so none of it needs the lock, and
5
+ * each check used to cost a full place in the lock queue before it could
6
+ * refuse:
7
+ *
8
+ * - a missing launchable binary (a peer's interrupted build) refused only
9
+ * after the wait, in every session, with nothing naming the cause;
10
+ * - the named-file checkJs pass refused an `Element | null` after an
11
+ * eighteen-minute queue;
12
+ * - `--wait-browser` and `--wait-port` spent their budget holding the
13
+ * lock, so every peer queued behind a run that was doing nothing.
14
+ *
15
+ * The in-lock ladder in `test.ts` still runs in full afterwards. That is
16
+ * the "re-check once under the lock": the waits this pass spent are
17
+ * stripped from the options it returns, so the in-lock browser and port
18
+ * checks probe once instead of waiting again.
19
+ */
20
+ import type { TestOptions } from '../types/commands/index.js';
21
+ /**
22
+ * Resolves the launchable binary a test run needs, or refuses naming why
23
+ * it is missing. The cause comes from the build run record, which any
24
+ * session's build writes, so a session that never ran the build can still
25
+ * say "a peer's build was interrupted" rather than only "the binary is
26
+ * missing".
27
+ *
28
+ * @param projectRoot - Project root
29
+ * @param engineDir - Absolute engine directory
30
+ * @param binaryName - Configured binary name
31
+ * @param objDir - Active objdir, when one exists
32
+ * @returns The engine-relative launchable path, or undefined without an objdir
33
+ */
34
+ export declare function resolveLaunchablePathForTests(projectRoot: string, engineDir: string, binaryName: string, objDir: string | undefined): Promise<string | undefined>;
35
+ /** Build-artifact preflight wording for `fireforge test`. */
36
+ export declare const TEST_BUILD_PREFLIGHT: {
37
+ readonly label: "Tests";
38
+ readonly requirement: "Tests require a completed build.";
39
+ readonly remediation: "Run 'fireforge build' first, then run 'fireforge test'.";
40
+ readonly requireExisting: true;
41
+ };
42
+ /**
43
+ * Runs the lock-free checks and waits, and returns the options the in-lock
44
+ * run should use: with `waitBrowser`/`waitPort` removed when their budget
45
+ * was already spent here.
46
+ *
47
+ * @param projectRoot - Project root
48
+ * @param testPaths - Requested test paths
49
+ * @param options - Parsed test options
50
+ */
51
+ export declare function runTestPreLockPreflight(projectRoot: string, testPaths: string[], options: TestOptions): Promise<TestOptions>;