@hominis/fireforge 0.45.0 → 0.46.1

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 (662) hide show
  1. package/CHANGELOG.md +409 -446
  2. package/dist/bin/fireforge.d.ts +1 -1
  3. package/dist/bin/fireforge.js +21 -15
  4. package/dist/build-info.json +4 -4
  5. package/dist/src/cli-usage-error.d.ts +46 -0
  6. package/dist/src/cli-usage-error.js +81 -0
  7. package/dist/src/cli.d.ts +7 -2
  8. package/dist/src/cli.js +47 -47
  9. package/dist/src/commands/bootstrap-checks.js +2 -1
  10. package/dist/src/commands/bootstrap.js +3 -4
  11. package/dist/src/commands/build.js +27 -17
  12. package/dist/src/commands/config.js +9 -9
  13. package/dist/src/commands/destructive-decision.d.ts +19 -0
  14. package/dist/src/commands/destructive-decision.js +31 -0
  15. package/dist/src/commands/discard.js +5 -5
  16. package/dist/src/commands/doctor-check-core.d.ts +4 -10
  17. package/dist/src/commands/doctor-check-core.js +0 -8
  18. package/dist/src/commands/doctor-external-toolchains.js +2 -2
  19. package/dist/src/commands/doctor-furnace-config-sync.d.ts +2 -2
  20. package/dist/src/commands/doctor-furnace-config-sync.js +20 -20
  21. package/dist/src/commands/doctor-furnace-jar.d.ts +1 -1
  22. package/dist/src/commands/doctor-furnace-jar.js +1 -1
  23. package/dist/src/commands/doctor-furnace.js +22 -22
  24. package/dist/src/commands/doctor-orphaned-harness.d.ts +10 -17
  25. package/dist/src/commands/doctor-orphaned-harness.js +14 -23
  26. package/dist/src/commands/doctor-patch-manifest.d.ts +2 -1
  27. package/dist/src/commands/doctor-patch-manifest.js +7 -6
  28. package/dist/src/commands/doctor-post-rebase-audit.js +3 -3
  29. package/dist/src/commands/doctor-source-pin.d.ts +12 -12
  30. package/dist/src/commands/doctor-source-pin.js +14 -14
  31. package/dist/src/commands/doctor-working-tree.d.ts +3 -3
  32. package/dist/src/commands/doctor-working-tree.js +3 -3
  33. package/dist/src/commands/doctor.d.ts +3 -1
  34. package/dist/src/commands/doctor.js +15 -16
  35. package/dist/src/commands/download.js +50 -37
  36. package/dist/src/commands/export-all.js +29 -12
  37. package/dist/src/commands/export-flow.d.ts +5 -5
  38. package/dist/src/commands/export-flow.js +29 -59
  39. package/dist/src/commands/export-placement-conflicts.d.ts +3 -3
  40. package/dist/src/commands/export-placement-conflicts.js +12 -12
  41. package/dist/src/commands/export-placement-gate.d.ts +2 -2
  42. package/dist/src/commands/export-placement-gate.js +7 -13
  43. package/dist/src/commands/export-placement-policy.d.ts +1 -1
  44. package/dist/src/commands/export-placement-policy.js +4 -6
  45. package/dist/src/commands/export-shared.d.ts +51 -32
  46. package/dist/src/commands/export-shared.js +17 -32
  47. package/dist/src/commands/export.js +14 -5
  48. package/dist/src/commands/furnace/apply.js +16 -16
  49. package/dist/src/commands/furnace/authoring-config.d.ts +13 -0
  50. package/dist/src/commands/furnace/authoring-config.js +19 -0
  51. package/dist/src/commands/furnace/chrome-doc-remove.d.ts +1 -1
  52. package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
  53. package/dist/src/commands/furnace/chrome-doc-templates.d.ts +14 -14
  54. package/dist/src/commands/furnace/chrome-doc-templates.js +17 -17
  55. package/dist/src/commands/furnace/chrome-doc-tests.d.ts +2 -2
  56. package/dist/src/commands/furnace/chrome-doc-tests.js +4 -4
  57. package/dist/src/commands/furnace/chrome-doc.d.ts +8 -8
  58. package/dist/src/commands/furnace/chrome-doc.js +18 -18
  59. package/dist/src/commands/furnace/create-browser-test.d.ts +1 -1
  60. package/dist/src/commands/furnace/create-browser-test.js +7 -12
  61. package/dist/src/commands/furnace/create-dry-run.d.ts +4 -4
  62. package/dist/src/commands/furnace/create-dry-run.js +6 -9
  63. package/dist/src/commands/furnace/create-features.d.ts +2 -2
  64. package/dist/src/commands/furnace/create-features.js +2 -2
  65. package/dist/src/commands/furnace/create-mochikit.d.ts +4 -4
  66. package/dist/src/commands/furnace/create-mochikit.js +7 -7
  67. package/dist/src/commands/furnace/create-templates.d.ts +31 -15
  68. package/dist/src/commands/furnace/create-templates.js +20 -19
  69. package/dist/src/commands/furnace/create-xpcshell.d.ts +5 -5
  70. package/dist/src/commands/furnace/create-xpcshell.js +8 -8
  71. package/dist/src/commands/furnace/create.d.ts +1 -1
  72. package/dist/src/commands/furnace/create.js +35 -29
  73. package/dist/src/commands/furnace/deploy.js +15 -6
  74. package/dist/src/commands/furnace/diff.js +7 -7
  75. package/dist/src/commands/furnace/index.js +1 -1
  76. package/dist/src/commands/furnace/init.js +17 -16
  77. package/dist/src/commands/furnace/list.js +2 -2
  78. package/dist/src/commands/furnace/override.d.ts +1 -1
  79. package/dist/src/commands/furnace/override.js +43 -34
  80. package/dist/src/commands/furnace/preview.js +17 -17
  81. package/dist/src/commands/furnace/refresh.js +15 -7
  82. package/dist/src/commands/furnace/remove-mutations.d.ts +9 -10
  83. package/dist/src/commands/furnace/remove-mutations.js +19 -19
  84. package/dist/src/commands/furnace/remove-state.d.ts +1 -1
  85. package/dist/src/commands/furnace/remove-state.js +1 -1
  86. package/dist/src/commands/furnace/remove.js +4 -8
  87. package/dist/src/commands/furnace/rename-browser-test.js +10 -15
  88. package/dist/src/commands/furnace/rename-xpcshell.d.ts +2 -2
  89. package/dist/src/commands/furnace/rename-xpcshell.js +3 -3
  90. package/dist/src/commands/furnace/rename.js +36 -36
  91. package/dist/src/commands/furnace/scan.js +3 -3
  92. package/dist/src/commands/furnace/status.js +19 -16
  93. package/dist/src/commands/furnace/sync.js +6 -6
  94. package/dist/src/commands/furnace/test-file-name.d.ts +28 -0
  95. package/dist/src/commands/furnace/test-file-name.js +39 -0
  96. package/dist/src/commands/furnace/validate.js +11 -12
  97. package/dist/src/commands/furnace/validation-output.d.ts +21 -9
  98. package/dist/src/commands/furnace/validation-output.js +3 -8
  99. package/dist/src/commands/import.js +22 -29
  100. package/dist/src/commands/lint-per-patch.d.ts +2 -2
  101. package/dist/src/commands/lint-per-patch.js +27 -12
  102. package/dist/src/commands/lint-per-run-checkjs.d.ts +14 -15
  103. package/dist/src/commands/lint-per-run-checkjs.js +14 -15
  104. package/dist/src/commands/lint-report.d.ts +3 -3
  105. package/dist/src/commands/lint-report.js +4 -4
  106. package/dist/src/commands/lint.d.ts +5 -4
  107. package/dist/src/commands/lint.js +36 -36
  108. package/dist/src/commands/manifest.d.ts +4 -4
  109. package/dist/src/commands/manifest.js +1 -1
  110. package/dist/src/commands/package.js +4 -6
  111. package/dist/src/commands/patch/compact.d.ts +2 -2
  112. package/dist/src/commands/patch/compact.js +19 -20
  113. package/dist/src/commands/patch/delete.d.ts +1 -1
  114. package/dist/src/commands/patch/delete.js +23 -33
  115. package/dist/src/commands/patch/entry-projection.d.ts +13 -0
  116. package/dist/src/commands/patch/entry-projection.js +24 -0
  117. package/dist/src/commands/patch/lint-ignore.d.ts +3 -12
  118. package/dist/src/commands/patch/lint-ignore.js +33 -44
  119. package/dist/src/commands/patch/move-files-create.d.ts +2 -2
  120. package/dist/src/commands/patch/move-files-create.js +29 -15
  121. package/dist/src/commands/patch/move-files-into.d.ts +2 -2
  122. package/dist/src/commands/patch/move-files-into.js +41 -37
  123. package/dist/src/commands/patch/move-files.js +5 -14
  124. package/dist/src/commands/patch/patch-context.d.ts +1 -1
  125. package/dist/src/commands/patch/rename.d.ts +4 -4
  126. package/dist/src/commands/patch/rename.js +35 -49
  127. package/dist/src/commands/patch/reorder.js +35 -48
  128. package/dist/src/commands/patch/split-plan.d.ts +7 -8
  129. package/dist/src/commands/patch/split-plan.js +10 -13
  130. package/dist/src/commands/patch/split.d.ts +2 -2
  131. package/dist/src/commands/patch/split.js +50 -48
  132. package/dist/src/commands/patch/staged-dependency-validate.d.ts +1 -1
  133. package/dist/src/commands/patch/staged-dependency-validate.js +3 -3
  134. package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
  135. package/dist/src/commands/patch/staged-dependency.js +22 -28
  136. package/dist/src/commands/patch/tier.d.ts +2 -2
  137. package/dist/src/commands/patch/tier.js +20 -30
  138. package/dist/src/commands/patch-rename-map.d.ts +19 -0
  139. package/dist/src/commands/patch-rename-map.js +36 -0
  140. package/dist/src/commands/pending-resolution.d.ts +15 -0
  141. package/dist/src/commands/pending-resolution.js +25 -0
  142. package/dist/src/commands/re-export-adjacent.d.ts +25 -3
  143. package/dist/src/commands/re-export-adjacent.js +40 -24
  144. package/dist/src/commands/re-export-bulk-scan.d.ts +3 -3
  145. package/dist/src/commands/re-export-bulk-scan.js +23 -27
  146. package/dist/src/commands/re-export-drift.d.ts +10 -10
  147. package/dist/src/commands/re-export-drift.js +33 -33
  148. package/dist/src/commands/re-export-files.d.ts +2 -3
  149. package/dist/src/commands/re-export-files.js +52 -44
  150. package/dist/src/commands/re-export-lint.d.ts +29 -30
  151. package/dist/src/commands/re-export-lint.js +36 -29
  152. package/dist/src/commands/re-export-options.d.ts +1 -1
  153. package/dist/src/commands/re-export-options.js +1 -1
  154. package/dist/src/commands/re-export-register.d.ts +1 -1
  155. package/dist/src/commands/re-export-register.js +1 -1
  156. package/dist/src/commands/re-export-scan.d.ts +1 -1
  157. package/dist/src/commands/re-export-scan.js +12 -9
  158. package/dist/src/commands/re-export-single.d.ts +23 -4
  159. package/dist/src/commands/re-export-single.js +39 -31
  160. package/dist/src/commands/re-export.js +35 -17
  161. package/dist/src/commands/rebase/abort.js +9 -14
  162. package/dist/src/commands/rebase/continue.js +20 -19
  163. package/dist/src/commands/rebase/index.d.ts +1 -1
  164. package/dist/src/commands/rebase/index.js +5 -5
  165. package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
  166. package/dist/src/commands/rebase/patch-loop.js +20 -24
  167. package/dist/src/commands/register.js +5 -5
  168. package/dist/src/commands/reset.js +1 -1
  169. package/dist/src/commands/resolve.d.ts +2 -2
  170. package/dist/src/commands/resolve.js +21 -13
  171. package/dist/src/commands/run.d.ts +0 -13
  172. package/dist/src/commands/run.js +38 -51
  173. package/dist/src/commands/setup-support.d.ts +16 -4
  174. package/dist/src/commands/setup-support.js +20 -20
  175. package/dist/src/commands/setup.js +4 -10
  176. package/dist/src/commands/source.js +9 -2
  177. package/dist/src/commands/status-check.d.ts +3 -3
  178. package/dist/src/commands/status-check.js +6 -6
  179. package/dist/src/commands/status-json.d.ts +14 -13
  180. package/dist/src/commands/status-json.js +9 -8
  181. package/dist/src/commands/status-output.d.ts +3 -3
  182. package/dist/src/commands/status-output.js +5 -5
  183. package/dist/src/commands/status-ownership.d.ts +3 -3
  184. package/dist/src/commands/status-ownership.js +3 -3
  185. package/dist/src/commands/status.js +25 -26
  186. package/dist/src/commands/test-build-phase.d.ts +3 -3
  187. package/dist/src/commands/test-build-phase.js +48 -24
  188. package/dist/src/commands/test-diagnose.d.ts +1 -1
  189. package/dist/src/commands/test-diagnose.js +20 -20
  190. package/dist/src/commands/test-modes.d.ts +4 -4
  191. package/dist/src/commands/test-modes.js +4 -5
  192. package/dist/src/commands/test-register.js +5 -3
  193. package/dist/src/commands/test-run.d.ts +11 -11
  194. package/dist/src/commands/test-run.js +40 -33
  195. package/dist/src/commands/test-stale-gate.d.ts +12 -12
  196. package/dist/src/commands/test-stale-gate.js +17 -17
  197. package/dist/src/commands/test-verdict.d.ts +19 -5
  198. package/dist/src/commands/test-verdict.js +26 -11
  199. package/dist/src/commands/test.d.ts +3 -3
  200. package/dist/src/commands/test.js +73 -36
  201. package/dist/src/commands/token-coverage.js +3 -3
  202. package/dist/src/commands/token-list.d.ts +26 -0
  203. package/dist/src/commands/token-list.js +153 -0
  204. package/dist/src/commands/token.js +26 -10
  205. package/dist/src/commands/tree.js +26 -21
  206. package/dist/src/commands/typecheck.d.ts +6 -6
  207. package/dist/src/commands/typecheck.js +16 -16
  208. package/dist/src/commands/verify.d.ts +3 -3
  209. package/dist/src/commands/verify.js +10 -10
  210. package/dist/src/commands/watch.js +11 -11
  211. package/dist/src/commands/wire.js +17 -16
  212. package/dist/src/core/ast-utils.d.ts +7 -7
  213. package/dist/src/core/ast-utils.js +8 -8
  214. package/dist/src/core/branding.d.ts +5 -12
  215. package/dist/src/core/branding.js +6 -5
  216. package/dist/src/core/browser-wire.d.ts +1 -1
  217. package/dist/src/core/browser-wire.js +10 -7
  218. package/dist/src/core/build-audit-platform.d.ts +32 -3
  219. package/dist/src/core/build-audit-platform.js +153 -13
  220. package/dist/src/core/build-audit-registration.d.ts +5 -5
  221. package/dist/src/core/build-audit-registration.js +10 -9
  222. package/dist/src/core/build-audit-resolve.d.ts +5 -5
  223. package/dist/src/core/build-audit-resolve.js +6 -6
  224. package/dist/src/core/build-audit-skip.d.ts +57 -0
  225. package/dist/src/core/build-audit-skip.js +112 -0
  226. package/dist/src/core/build-audit-transforms.d.ts +2 -2
  227. package/dist/src/core/build-audit-transforms.js +3 -3
  228. package/dist/src/core/build-audit.d.ts +21 -8
  229. package/dist/src/core/build-audit.js +142 -40
  230. package/dist/src/core/build-baseline-types.d.ts +19 -18
  231. package/dist/src/core/build-baseline-types.js +1 -1
  232. package/dist/src/core/build-baseline.d.ts +48 -31
  233. package/dist/src/core/build-baseline.js +20 -43
  234. package/dist/src/core/build-jar-escalation.d.ts +8 -8
  235. package/dist/src/core/build-jar-escalation.js +18 -17
  236. package/dist/src/core/build-overwrite-guard.d.ts +4 -4
  237. package/dist/src/core/build-overwrite-guard.js +14 -14
  238. package/dist/src/core/build-prepare.d.ts +4 -12
  239. package/dist/src/core/build-prepare.js +22 -26
  240. package/dist/src/core/config-mutate.js +4 -4
  241. package/dist/src/core/config-paths.d.ts +2 -6
  242. package/dist/src/core/config-paths.js +4 -2
  243. package/dist/src/core/config-state.d.ts +0 -6
  244. package/dist/src/core/config-state.js +3 -21
  245. package/dist/src/core/config-validate-build-audit.d.ts +8 -0
  246. package/dist/src/core/config-validate-build-audit.js +80 -0
  247. package/dist/src/core/config-validate-file-size.d.ts +1 -1
  248. package/dist/src/core/config-validate-file-size.js +3 -3
  249. package/dist/src/core/config-validate-patch-policy.d.ts +2 -2
  250. package/dist/src/core/config-validate-patch-policy.js +3 -3
  251. package/dist/src/core/config-validate-test-toolchains.d.ts +2 -2
  252. package/dist/src/core/config-validate-test-toolchains.js +4 -5
  253. package/dist/src/core/config-validate.js +22 -12
  254. package/dist/src/core/config.d.ts +12 -12
  255. package/dist/src/core/config.js +21 -25
  256. package/dist/src/core/coverage-extend.d.ts +16 -16
  257. package/dist/src/core/coverage-extend.js +20 -20
  258. package/dist/src/core/destructive.d.ts +14 -14
  259. package/dist/src/core/destructive.js +9 -9
  260. package/dist/src/core/diff-hunks.d.ts +2 -2
  261. package/dist/src/core/diff-hunks.js +7 -7
  262. package/dist/src/core/discard-baseline.d.ts +10 -10
  263. package/dist/src/core/discard-baseline.js +22 -23
  264. package/dist/src/core/display-state.d.ts +11 -11
  265. package/dist/src/core/display-state.js +12 -12
  266. package/dist/src/core/engine-changes.d.ts +2 -2
  267. package/dist/src/core/engine-changes.js +2 -2
  268. package/dist/src/core/engine-precondition.d.ts +5 -13
  269. package/dist/src/core/engine-precondition.js +5 -10
  270. package/dist/src/core/engine-session-lock.d.ts +18 -18
  271. package/dist/src/core/engine-session-lock.js +50 -54
  272. package/dist/src/core/export-moved-code-shape.d.ts +7 -7
  273. package/dist/src/core/export-moved-code-shape.js +10 -10
  274. package/dist/src/core/file-lock-owner.d.ts +103 -0
  275. package/dist/src/core/file-lock-owner.js +259 -0
  276. package/dist/src/core/file-lock.d.ts +14 -19
  277. package/dist/src/core/file-lock.js +90 -128
  278. package/dist/src/core/firefox-cache.d.ts +13 -1
  279. package/dist/src/core/firefox-cache.js +61 -36
  280. package/dist/src/core/firefox-download.d.ts +15 -0
  281. package/dist/src/core/firefox-download.js +38 -22
  282. package/dist/src/core/firefox-extract.d.ts +8 -7
  283. package/dist/src/core/firefox-extract.js +45 -27
  284. package/dist/src/core/firefox.d.ts +34 -36
  285. package/dist/src/core/firefox.js +13 -44
  286. package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
  287. package/dist/src/core/furnace-apply-dry-run.js +2 -8
  288. package/dist/src/core/furnace-apply-ftl.d.ts +5 -5
  289. package/dist/src/core/furnace-apply-ftl.js +8 -8
  290. package/dist/src/core/furnace-apply-helpers.d.ts +9 -20
  291. package/dist/src/core/furnace-apply-helpers.js +28 -39
  292. package/dist/src/core/furnace-apply-output.js +1 -1
  293. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +9 -9
  294. package/dist/src/core/furnace-apply-overwrite-warn.js +13 -11
  295. package/dist/src/core/furnace-apply-undeploy-actions.d.ts +1 -1
  296. package/dist/src/core/furnace-apply-undeploy-actions.js +1 -1
  297. package/dist/src/core/furnace-apply.d.ts +4 -4
  298. package/dist/src/core/furnace-apply.js +50 -29
  299. package/dist/src/core/furnace-checksum-utils.d.ts +5 -5
  300. package/dist/src/core/furnace-checksum-utils.js +5 -5
  301. package/dist/src/core/furnace-config-custom.d.ts +1 -1
  302. package/dist/src/core/furnace-config-custom.js +2 -2
  303. package/dist/src/core/furnace-config-order.js +1 -1
  304. package/dist/src/core/furnace-config-tokens.d.ts +3 -3
  305. package/dist/src/core/furnace-config-tokens.js +3 -3
  306. package/dist/src/core/furnace-config-validate.js +2 -2
  307. package/dist/src/core/furnace-config.d.ts +5 -5
  308. package/dist/src/core/furnace-config.js +40 -53
  309. package/dist/src/core/furnace-constants.d.ts +6 -6
  310. package/dist/src/core/furnace-constants.js +9 -8
  311. package/dist/src/core/furnace-css-fragments.d.ts +6 -6
  312. package/dist/src/core/furnace-css-fragments.js +11 -11
  313. package/dist/src/core/furnace-dir-entry.d.ts +20 -0
  314. package/dist/src/core/furnace-dir-entry.js +21 -0
  315. package/dist/src/core/furnace-jsconfig.d.ts +7 -7
  316. package/dist/src/core/furnace-jsconfig.js +22 -20
  317. package/dist/src/core/furnace-operation.d.ts +22 -19
  318. package/dist/src/core/furnace-operation.js +38 -34
  319. package/dist/src/core/furnace-precondition.d.ts +10 -10
  320. package/dist/src/core/furnace-precondition.js +8 -8
  321. package/dist/src/core/furnace-refresh.d.ts +18 -6
  322. package/dist/src/core/furnace-refresh.js +5 -8
  323. package/dist/src/core/furnace-registration-ast.d.ts +2 -3
  324. package/dist/src/core/furnace-registration-ast.js +9 -12
  325. package/dist/src/core/furnace-registration-remove.d.ts +4 -4
  326. package/dist/src/core/furnace-registration-remove.js +6 -6
  327. package/dist/src/core/furnace-registration-validate.d.ts +2 -2
  328. package/dist/src/core/furnace-registration-validate.js +2 -2
  329. package/dist/src/core/furnace-registration.d.ts +7 -6
  330. package/dist/src/core/furnace-registration.js +29 -36
  331. package/dist/src/core/furnace-rollback.d.ts +1 -1
  332. package/dist/src/core/furnace-rollback.js +5 -5
  333. package/dist/src/core/furnace-scanner.js +3 -6
  334. package/dist/src/core/furnace-stale-export.d.ts +17 -16
  335. package/dist/src/core/furnace-stale-export.js +16 -15
  336. package/dist/src/core/furnace-staleness.d.ts +2 -2
  337. package/dist/src/core/furnace-staleness.js +2 -2
  338. package/dist/src/core/furnace-state-persist.d.ts +12 -12
  339. package/dist/src/core/furnace-state-persist.js +10 -10
  340. package/dist/src/core/furnace-step-errors.d.ts +6 -6
  341. package/dist/src/core/furnace-step-errors.js +6 -6
  342. package/dist/src/core/furnace-validate-accessibility.js +14 -14
  343. package/dist/src/core/furnace-validate-compatibility.js +9 -9
  344. package/dist/src/core/furnace-validate-registration.d.ts +2 -2
  345. package/dist/src/core/furnace-validate-registration.js +18 -20
  346. package/dist/src/core/furnace-validate-structure.d.ts +1 -1
  347. package/dist/src/core/furnace-validate-structure.js +4 -4
  348. package/dist/src/core/furnace-validate.js +9 -9
  349. package/dist/src/core/furnace-version-drift.d.ts +5 -5
  350. package/dist/src/core/furnace-version-drift.js +5 -5
  351. package/dist/src/core/git-base.d.ts +6 -4
  352. package/dist/src/core/git-base.js +29 -7
  353. package/dist/src/core/git-diff-new-file.d.ts +40 -0
  354. package/dist/src/core/git-diff-new-file.js +119 -0
  355. package/dist/src/core/git-diff.d.ts +13 -13
  356. package/dist/src/core/git-diff.js +121 -189
  357. package/dist/src/core/git-file-ops.d.ts +6 -13
  358. package/dist/src/core/git-file-ops.js +11 -35
  359. package/dist/src/core/git-readonly-index.d.ts +12 -14
  360. package/dist/src/core/git-readonly-index.js +12 -16
  361. package/dist/src/core/git-status.d.ts +9 -2
  362. package/dist/src/core/git-status.js +23 -11
  363. package/dist/src/core/git.d.ts +3 -9
  364. package/dist/src/core/git.js +28 -57
  365. package/dist/src/core/harness-orphans.d.ts +17 -17
  366. package/dist/src/core/harness-orphans.js +28 -27
  367. package/dist/src/core/history-log.d.ts +19 -0
  368. package/dist/src/core/history-log.js +29 -0
  369. package/dist/src/core/license-headers.d.ts +19 -18
  370. package/dist/src/core/license-headers.js +29 -28
  371. package/dist/src/core/mach-build-artifacts.d.ts +21 -21
  372. package/dist/src/core/mach-build-artifacts.js +23 -23
  373. package/dist/src/core/mach-error-hints.d.ts +5 -10
  374. package/dist/src/core/mach-error-hints.js +14 -14
  375. package/dist/src/core/mach-known-noise-filter.d.ts +42 -38
  376. package/dist/src/core/mach-known-noise-filter.js +57 -56
  377. package/dist/src/core/mach-mozconfig.d.ts +6 -6
  378. package/dist/src/core/mach-mozconfig.js +17 -16
  379. package/dist/src/core/mach-python.d.ts +3 -0
  380. package/dist/src/core/mach-python.js +13 -7
  381. package/dist/src/core/mach-resource-shim.d.ts +24 -12
  382. package/dist/src/core/mach-resource-shim.js +124 -21
  383. package/dist/src/core/mach.d.ts +59 -73
  384. package/dist/src/core/mach.js +47 -115
  385. package/dist/src/core/marionette-port.d.ts +15 -30
  386. package/dist/src/core/marionette-port.js +46 -89
  387. package/dist/src/core/marionette-preflight.d.ts +6 -6
  388. package/dist/src/core/marionette-preflight.js +32 -50
  389. package/dist/src/core/markdown-table.d.ts +9 -9
  390. package/dist/src/core/markdown-table.js +14 -14
  391. package/dist/src/core/mochitest-server-port.d.ts +8 -8
  392. package/dist/src/core/mochitest-server-port.js +17 -17
  393. package/dist/src/core/module-resolution-preflight.d.ts +8 -8
  394. package/dist/src/core/module-resolution-preflight.js +11 -11
  395. package/dist/src/core/moz-manifest-helpers.d.ts +7 -7
  396. package/dist/src/core/moz-manifest-helpers.js +7 -7
  397. package/dist/src/core/moz-manifest-register.d.ts +1 -1
  398. package/dist/src/core/moz-manifest-register.js +2 -2
  399. package/dist/src/core/moz-manifest-rules.js +46 -42
  400. package/dist/src/core/moz-manifest-tokenizers.js +1 -1
  401. package/dist/src/core/ownership-table.d.ts +5 -5
  402. package/dist/src/core/ownership-table.js +7 -7
  403. package/dist/src/core/parser-fallback.d.ts +3 -3
  404. package/dist/src/core/parser-fallback.js +3 -3
  405. package/dist/src/core/patch-apply-fuzz.d.ts +5 -5
  406. package/dist/src/core/patch-apply-fuzz.js +13 -13
  407. package/dist/src/core/patch-apply.d.ts +13 -14
  408. package/dist/src/core/patch-apply.js +36 -42
  409. package/dist/src/core/patch-export-coverage.d.ts +0 -9
  410. package/dist/src/core/patch-export-coverage.js +1 -30
  411. package/dist/src/core/patch-export-update.d.ts +21 -4
  412. package/dist/src/core/patch-export-update.js +7 -6
  413. package/dist/src/core/patch-export.d.ts +20 -30
  414. package/dist/src/core/patch-export.js +55 -77
  415. package/dist/src/core/patch-files.d.ts +0 -4
  416. package/dist/src/core/patch-files.js +0 -11
  417. package/dist/src/core/patch-identifier-suggest.d.ts +1 -1
  418. package/dist/src/core/patch-identifier-suggest.js +4 -4
  419. package/dist/src/core/patch-lint-binary.d.ts +12 -18
  420. package/dist/src/core/patch-lint-cache.d.ts +18 -2
  421. package/dist/src/core/patch-lint-cache.js +16 -19
  422. package/dist/src/core/patch-lint-checkjs.d.ts +55 -38
  423. package/dist/src/core/patch-lint-checkjs.js +78 -64
  424. package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +8 -9
  425. package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -11
  426. package/dist/src/core/patch-lint-creators.d.ts +5 -9
  427. package/dist/src/core/patch-lint-creators.js +3 -3
  428. package/dist/src/core/patch-lint-cross.d.ts +27 -19
  429. package/dist/src/core/patch-lint-cross.js +67 -110
  430. package/dist/src/core/patch-lint-css.d.ts +1 -1
  431. package/dist/src/core/patch-lint-css.js +15 -11
  432. package/dist/src/core/patch-lint-diff-tag.d.ts +5 -5
  433. package/dist/src/core/patch-lint-diff-tag.js +5 -5
  434. package/dist/src/core/patch-lint-diff.d.ts +4 -4
  435. package/dist/src/core/patch-lint-diff.js +4 -4
  436. package/dist/src/core/patch-lint-file-size.d.ts +3 -3
  437. package/dist/src/core/patch-lint-file-size.js +6 -6
  438. package/dist/src/core/patch-lint-forward-registration.d.ts +58 -0
  439. package/dist/src/core/patch-lint-forward-registration.js +210 -0
  440. package/dist/src/core/patch-lint-jsdoc.d.ts +2 -2
  441. package/dist/src/core/patch-lint-jsdoc.js +46 -46
  442. package/dist/src/core/patch-lint-module-registration.d.ts +3 -9
  443. package/dist/src/core/patch-lint-module-registration.js +1 -1
  444. package/dist/src/core/patch-lint-mozbuild.d.ts +1 -1
  445. package/dist/src/core/patch-lint-mozbuild.js +10 -10
  446. package/dist/src/core/patch-lint-observer.d.ts +3 -3
  447. package/dist/src/core/patch-lint-observer.js +7 -7
  448. package/dist/src/core/patch-lint-ownership.d.ts +6 -6
  449. package/dist/src/core/patch-lint-ownership.js +6 -6
  450. package/dist/src/core/patch-lint-prettier.d.ts +6 -6
  451. package/dist/src/core/patch-lint-prettier.js +7 -7
  452. package/dist/src/core/patch-lint-queue-types.d.ts +60 -0
  453. package/dist/src/core/patch-lint-queue-types.js +12 -0
  454. package/dist/src/core/patch-lint-staged-registration.d.ts +61 -0
  455. package/dist/src/core/patch-lint-staged-registration.js +90 -0
  456. package/dist/src/core/patch-lint-unmanaged-companion.d.ts +23 -23
  457. package/dist/src/core/patch-lint-unmanaged-companion.js +26 -26
  458. package/dist/src/core/patch-lint.d.ts +41 -35
  459. package/dist/src/core/patch-lint.js +52 -49
  460. package/dist/src/core/patch-lock.d.ts +1 -1
  461. package/dist/src/core/patch-lock.js +11 -11
  462. package/dist/src/core/patch-manifest-consistency.d.ts +7 -7
  463. package/dist/src/core/patch-manifest-consistency.js +16 -17
  464. package/dist/src/core/patch-manifest-files-affected.d.ts +1 -1
  465. package/dist/src/core/patch-manifest-files-affected.js +3 -3
  466. package/dist/src/core/patch-manifest-io.d.ts +14 -14
  467. package/dist/src/core/patch-manifest-io.js +35 -34
  468. package/dist/src/core/patch-manifest-query.d.ts +1 -1
  469. package/dist/src/core/patch-manifest-query.js +4 -4
  470. package/dist/src/core/patch-manifest-resolve.d.ts +5 -5
  471. package/dist/src/core/patch-manifest-resolve.js +7 -7
  472. package/dist/src/core/patch-manifest-validate.js +3 -3
  473. package/dist/src/core/patch-manifest.d.ts +2 -2
  474. package/dist/src/core/patch-manifest.js +2 -2
  475. package/dist/src/core/patch-parse.d.ts +32 -21
  476. package/dist/src/core/patch-parse.js +40 -15
  477. package/dist/src/core/patch-policy.js +15 -27
  478. package/dist/src/core/patch-registration-refs.d.ts +4 -4
  479. package/dist/src/core/patch-registration-refs.js +7 -7
  480. package/dist/src/core/patch-source-metadata.d.ts +1 -3
  481. package/dist/src/core/patch-source-metadata.js +0 -4
  482. package/dist/src/core/patch-transform.d.ts +8 -16
  483. package/dist/src/core/patch-transform.js +13 -23
  484. package/dist/src/core/process-cpu-time.d.ts +1 -1
  485. package/dist/src/core/process-cpu-time.js +6 -6
  486. package/dist/src/core/rebase-session.d.ts +9 -15
  487. package/dist/src/core/rebase-session.js +13 -25
  488. package/dist/src/core/register-browser-content.js +3 -2
  489. package/dist/src/core/register-browser-test.js +2 -1
  490. package/dist/src/core/register-module.js +2 -1
  491. package/dist/src/core/register-result.d.ts +1 -1
  492. package/dist/src/core/register-result.js +1 -1
  493. package/dist/src/core/register-scaffold.d.ts +2 -2
  494. package/dist/src/core/register-scaffold.js +8 -7
  495. package/dist/src/core/register-shared-css.d.ts +3 -3
  496. package/dist/src/core/register-shared-css.js +6 -5
  497. package/dist/src/core/register-xpcshell-test.d.ts +2 -2
  498. package/dist/src/core/register-xpcshell-test.js +2 -2
  499. package/dist/src/core/run-log-redact.d.ts +38 -0
  500. package/dist/src/core/run-log-redact.js +69 -0
  501. package/dist/src/core/run-log.d.ts +21 -10
  502. package/dist/src/core/run-log.js +76 -27
  503. package/dist/src/core/shared-ftl.d.ts +2 -2
  504. package/dist/src/core/shared-ftl.js +6 -6
  505. package/dist/src/core/signal-critical.d.ts +2 -2
  506. package/dist/src/core/signal-critical.js +4 -6
  507. package/dist/src/core/smoke-patterns.d.ts +5 -6
  508. package/dist/src/core/smoke-patterns.js +15 -20
  509. package/dist/src/core/state-file.d.ts +15 -4
  510. package/dist/src/core/state-file.js +14 -1
  511. package/dist/src/core/status-binary.d.ts +8 -8
  512. package/dist/src/core/status-binary.js +12 -12
  513. package/dist/src/core/status-classify.d.ts +17 -17
  514. package/dist/src/core/status-classify.js +13 -12
  515. package/dist/src/core/test-changed-prefs.d.ts +12 -12
  516. package/dist/src/core/test-changed-prefs.js +40 -25
  517. package/dist/src/core/test-harness-crash.d.ts +39 -39
  518. package/dist/src/core/test-harness-crash.js +69 -69
  519. package/dist/src/core/test-harness-output.d.ts +7 -7
  520. package/dist/src/core/test-harness-output.js +7 -7
  521. package/dist/src/core/test-harness-verdict-notes.d.ts +13 -14
  522. package/dist/src/core/test-harness-verdict-notes.js +4 -4
  523. package/dist/src/core/test-path-scope.d.ts +8 -8
  524. package/dist/src/core/test-path-scope.js +11 -11
  525. package/dist/src/core/test-stale-check.d.ts +22 -23
  526. package/dist/src/core/test-stale-check.js +31 -30
  527. package/dist/src/core/test-stale-symlink.d.ts +1 -1
  528. package/dist/src/core/test-stale-symlink.js +1 -1
  529. package/dist/src/core/test-stall-triage.d.ts +9 -9
  530. package/dist/src/core/test-stall-triage.js +22 -22
  531. package/dist/src/core/test-xpcshell-retry.d.ts +26 -7
  532. package/dist/src/core/test-xpcshell-retry.js +14 -11
  533. package/dist/src/core/token-category.d.ts +35 -2
  534. package/dist/src/core/token-category.js +67 -58
  535. package/dist/src/core/token-coverage.js +4 -5
  536. package/dist/src/core/token-dark-mode.d.ts +9 -9
  537. package/dist/src/core/token-dark-mode.js +13 -25
  538. package/dist/src/core/token-docs.d.ts +1 -1
  539. package/dist/src/core/token-inventory.d.ts +56 -0
  540. package/dist/src/core/token-inventory.js +109 -0
  541. package/dist/src/core/token-manager.d.ts +4 -4
  542. package/dist/src/core/token-manager.js +22 -22
  543. package/dist/src/core/token-scaffold.d.ts +4 -4
  544. package/dist/src/core/token-scaffold.js +4 -4
  545. package/dist/src/core/token-variant.d.ts +14 -14
  546. package/dist/src/core/token-variant.js +52 -53
  547. package/dist/src/core/toolchain-preflight.d.ts +15 -15
  548. package/dist/src/core/toolchain-preflight.js +23 -23
  549. package/dist/src/core/tree-cow.d.ts +3 -5
  550. package/dist/src/core/tree-cow.js +8 -8
  551. package/dist/src/core/tree-guard.d.ts +3 -3
  552. package/dist/src/core/tree-guard.js +23 -23
  553. package/dist/src/core/tree-store.d.ts +15 -15
  554. package/dist/src/core/tree-store.js +39 -38
  555. package/dist/src/core/typecheck-shim.d.ts +16 -15
  556. package/dist/src/core/typecheck-shim.js +26 -25
  557. package/dist/src/core/typecheck.d.ts +12 -12
  558. package/dist/src/core/typecheck.js +33 -33
  559. package/dist/src/core/wire-destroy.d.ts +2 -2
  560. package/dist/src/core/wire-destroy.js +5 -5
  561. package/dist/src/core/wire-dom-fragment.d.ts +3 -3
  562. package/dist/src/core/wire-dom-fragment.js +12 -23
  563. package/dist/src/core/wire-init.d.ts +2 -2
  564. package/dist/src/core/wire-init.js +7 -7
  565. package/dist/src/core/wire-subscript.d.ts +1 -1
  566. package/dist/src/core/wire-subscript.js +3 -3
  567. package/dist/src/core/wire-utils.d.ts +9 -9
  568. package/dist/src/core/wire-utils.js +16 -28
  569. package/dist/src/core/xpcshell-appdir.d.ts +20 -20
  570. package/dist/src/core/xpcshell-appdir.js +28 -30
  571. package/dist/src/core/xpcshell-profile-dir.d.ts +3 -3
  572. package/dist/src/core/xpcshell-profile-dir.js +7 -7
  573. package/dist/src/errors/base.d.ts +69 -16
  574. package/dist/src/errors/base.js +95 -26
  575. package/dist/src/errors/build.d.ts +6 -6
  576. package/dist/src/errors/build.js +26 -34
  577. package/dist/src/errors/codes.d.ts +10 -10
  578. package/dist/src/errors/codes.js +10 -10
  579. package/dist/src/errors/config.d.ts +0 -14
  580. package/dist/src/errors/config.js +13 -34
  581. package/dist/src/errors/download.d.ts +13 -0
  582. package/dist/src/errors/download.js +53 -24
  583. package/dist/src/errors/furnace.d.ts +2 -2
  584. package/dist/src/errors/furnace.js +8 -9
  585. package/dist/src/errors/git.d.ts +9 -9
  586. package/dist/src/errors/git.js +21 -31
  587. package/dist/src/errors/patch.d.ts +3 -3
  588. package/dist/src/errors/patch.js +11 -13
  589. package/dist/src/errors/rebase.d.ts +1 -1
  590. package/dist/src/errors/rebase.js +8 -8
  591. package/dist/src/errors/run.d.ts +1 -1
  592. package/dist/src/errors/run.js +1 -1
  593. package/dist/src/index.d.ts +4 -4
  594. package/dist/src/index.js +4 -4
  595. package/dist/src/types/commands/options.d.ts +155 -200
  596. package/dist/src/types/commands/patches.d.ts +19 -19
  597. package/dist/src/types/commands/project.d.ts +3 -3
  598. package/dist/src/types/config.d.ts +52 -19
  599. package/dist/src/types/furnace.d.ts +17 -17
  600. package/dist/src/types/index.d.ts +0 -1
  601. package/dist/src/types/json.d.ts +3 -3
  602. package/dist/src/types/json.js +2 -2
  603. package/dist/src/types/typecheck.d.ts +3 -3
  604. package/dist/src/utils/assert.d.ts +4 -16
  605. package/dist/src/utils/assert.js +7 -24
  606. package/dist/src/utils/build-info.d.ts +6 -6
  607. package/dist/src/utils/build-info.js +6 -6
  608. package/dist/src/utils/child-env.d.ts +7 -6
  609. package/dist/src/utils/child-env.js +5 -5
  610. package/dist/src/utils/concurrency.d.ts +2 -2
  611. package/dist/src/utils/concurrency.js +2 -2
  612. package/dist/src/utils/elapsed.js +10 -1
  613. package/dist/src/utils/errors.d.ts +8 -8
  614. package/dist/src/utils/errors.js +8 -8
  615. package/dist/src/utils/fs.d.ts +1 -1
  616. package/dist/src/utils/fs.js +15 -20
  617. package/dist/src/utils/hash.d.ts +12 -0
  618. package/dist/src/utils/hash.js +16 -0
  619. package/dist/src/utils/line-dispatch.d.ts +15 -0
  620. package/dist/src/utils/line-dispatch.js +48 -0
  621. package/dist/src/utils/logger.d.ts +4 -4
  622. package/dist/src/utils/logger.js +11 -11
  623. package/dist/src/utils/machine-output.js +2 -2
  624. package/dist/src/utils/options.d.ts +14 -20
  625. package/dist/src/utils/options.js +26 -27
  626. package/dist/src/utils/package-root.js +5 -14
  627. package/dist/src/utils/paths.d.ts +4 -4
  628. package/dist/src/utils/paths.js +4 -4
  629. package/dist/src/utils/platform.d.ts +0 -4
  630. package/dist/src/utils/process-group.d.ts +10 -9
  631. package/dist/src/utils/process-group.js +37 -36
  632. package/dist/src/utils/process.d.ts +70 -55
  633. package/dist/src/utils/process.js +129 -179
  634. package/dist/src/utils/ps-duration.d.ts +4 -4
  635. package/dist/src/utils/ps-duration.js +9 -9
  636. package/dist/src/utils/regex.d.ts +4 -4
  637. package/dist/src/utils/regex.js +7 -7
  638. package/dist/src/utils/sleep.d.ts +26 -0
  639. package/dist/src/utils/sleep.js +31 -0
  640. package/dist/src/utils/stdio-drain.d.ts +7 -7
  641. package/dist/src/utils/stdio-drain.js +8 -8
  642. package/dist/src/utils/validation.d.ts +12 -49
  643. package/dist/src/utils/validation.js +26 -36
  644. package/docs/README.md +2 -2
  645. package/docs/configuration.md +163 -69
  646. package/docs/exit-codes.md +66 -49
  647. package/docs/furnace.md +20 -19
  648. package/docs/lifecycle-invariants.md +414 -247
  649. package/docs/machine-output.md +58 -34
  650. package/docs/patch-workflow.md +48 -44
  651. package/docs/run-logs.md +72 -28
  652. package/docs/testing.md +105 -98
  653. package/docs/verification-trees.md +23 -22
  654. package/package.json +7 -6
  655. package/dist/src/commands/rebase.d.ts +0 -4
  656. package/dist/src/commands/rebase.js +0 -5
  657. package/dist/src/core/patch-artifact-normalize.d.ts +0 -21
  658. package/dist/src/core/patch-artifact-normalize.js +0 -24
  659. package/dist/src/core/patch-lint-reexports.d.ts +0 -7
  660. package/dist/src/core/patch-lint-reexports.js +0 -8
  661. package/dist/src/core/wire-targets.d.ts +0 -7
  662. package/dist/src/core/wire-targets.js +0 -8
@@ -16,6 +16,7 @@ import { pathExists, readText, removeDir, writeText } from '../../utils/fs.js';
16
16
  import { cancel, info, intro, isCancel, outro, warn } from '../../utils/logger.js';
17
17
  import { performCustomRemovalMutations, performOverrideRemovalMutations, } from './remove-mutations.js';
18
18
  import { dropChecksumsByPrefix } from './remove-state.js';
19
+ import { browserTestFileName } from './test-file-name.js';
19
20
  /**
20
21
  * Removes an entire TOML section (header + body lines) for a given test file.
21
22
  * Matches from `["filename"]` up to the next section header `[` or end-of-file,
@@ -94,12 +95,7 @@ async function cleanupCustomTestFiles(name, projectRoot, journal) {
94
95
  }
95
96
  const paths = getProjectPaths(projectRoot);
96
97
  const binaryName = forgeConfig.binaryName;
97
- const strippedName = name.startsWith('moz-') ? name.slice(4) : name;
98
- const withoutBinaryPrefix = strippedName.startsWith(binaryName + '-')
99
- ? strippedName.slice(binaryName.length + 1)
100
- : strippedName;
101
- const underscored = withoutBinaryPrefix.replace(/-/g, '_');
102
- const testFileName = `browser_${binaryName}_${underscored}.js`;
98
+ const testFileName = browserTestFileName(name, binaryName);
103
99
  const testDir = join(paths.engine, 'browser/base/content/test', binaryName);
104
100
  if (!(await pathExists(testDir)))
105
101
  return { partialFailures };
@@ -222,7 +218,7 @@ async function cleanupCustomMochikitTestFiles(name, projectRoot, journal) {
222
218
  * leaves an operator who ran `furnace create --with-tests --xpcshell`
223
219
  * followed by `furnace remove` with orphan `xpcshell.toml` +
224
220
  * `test_<name>_packaged.js` files still referencing the removed component.
225
- * This pass mirrors the mochitest one — snapshot before removal,
221
+ * This pass mirrors the mochitest one: snapshot before removal,
226
222
  * warn-and-continue semantics, explicit summary on partial failures.
227
223
  */
228
224
  async function cleanupCustomXpcshellTestFiles(name, projectRoot, journal) {
@@ -311,7 +307,7 @@ async function confirmFurnaceRemove(name, type, options, isInteractive) {
311
307
  }
312
308
  /**
313
309
  * Enforces the engine-as-git precondition for both override and custom
314
- * removals. Runs BEFORE the lock is acquired or a journal is registered so
310
+ * removals. Runs before the lock is acquired or a journal is registered so
315
311
  * the failure path does not involve any rollback infrastructure.
316
312
  */
317
313
  async function requireGitEngineForRemove(type, name, engineDir) {
@@ -1,13 +1,7 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  import { tagNameToClassName } from '../../core/furnace-constants.js';
3
3
  import { escapeRegex } from '../../utils/regex.js';
4
- function deriveTestStem(componentName, binaryName) {
5
- const strippedName = componentName.startsWith('moz-') ? componentName.slice(4) : componentName;
6
- const withoutBinaryPrefix = strippedName.startsWith(binaryName + '-')
7
- ? strippedName.slice(binaryName.length + 1)
8
- : strippedName;
9
- return withoutBinaryPrefix.replace(/-/g, '_');
10
- }
4
+ import { deriveTestStem } from './test-file-name.js';
11
5
  /** Rewrites scaffolded browser-chrome test literals after a component rename. */
12
6
  export function updateBrowserChromeTestContent(content, oldName, newName, binaryName) {
13
7
  const oldClassName = tagNameToClassName(oldName);
@@ -16,7 +10,7 @@ export function updateBrowserChromeTestContent(content, oldName, newName, binary
16
10
  const newUnderscored = newName.replace(/-/g, '_');
17
11
  const oldTestStem = deriveTestStem(oldName, binaryName);
18
12
  const newTestStem = deriveTestStem(newName, binaryName);
19
- // ONE pass over the content, not four chained `.replace()` calls.
13
+ // One pass over the content, instead of four chained `.replace()` calls.
20
14
  //
21
15
  // Chaining let each rule see the previous rule's output. Renaming
22
16
  // `acme-widget` to `acme-widget-v2` rewrote `test_acme_widget_defined` to
@@ -29,12 +23,12 @@ export function updateBrowserChromeTestContent(content, oldName, newName, binary
29
23
  // alternative that matches at a given position.
30
24
  const alternatives = [
31
25
  // The stem is a short bare fragment (`moz-` and binary prefixes stripped,
32
- // hyphens underscored) — `panel` for `moz-panel`. Matching it loose, even
26
+ // hyphens underscored), so `panel` for `moz-panel`. Matching it loose, even
33
27
  // with hyphen guards, rewrote unrelated underscore-delimited identifiers
34
28
  // such as `test_panel_group_integration`, because `_` must stay a legal
35
29
  // neighbour for the generated name to match at all. The scaffold emits the
36
30
  // stem in exactly one shape, so anchor to that shape instead of guessing
37
- // from boundaries — with its own guards, so the anchored shape cannot
31
+ // from boundaries. The anchored shape carries its own guards so it cannot
38
32
  // match inside a longer identifier (`mytest_panel_defined_extra`).
39
33
  {
40
34
  pattern: `(?<![\\w-])test_${escapeRegex(oldTestStem)}_defined(?![\\w-])`,
@@ -43,10 +37,10 @@ export function updateBrowserChromeTestContent(content, oldName, newName, binary
43
37
  // Word-boundary-aware, matching `furnace/rename.ts` and
44
38
  // `rename-xpcshell.ts`: without the guards a rename of `moz-panel` rewrote
45
39
  // `moz-panel-group`. `_` stays a legal neighbour for the underscored form
46
- // because it is deliberately embedded in generated identifiers; `-` does
40
+ // because it is embedded in generated identifiers on purpose. `-` is
47
41
  // not.
48
42
  //
49
- // Skipped when the underscored form IS the tag name (a hyphen-less
43
+ // Skipped when the underscored form is the tag name (a hyphen-less
50
44
  // component): both rules then match the same text and this one would win
51
45
  // on order, substituting `newUnderscored` where the tag `newName` was
52
46
  // meant. The stem rule still covers the one generated identifier shape.
@@ -61,9 +55,10 @@ export function updateBrowserChromeTestContent(content, oldName, newName, binary
61
55
  { pattern: `(?<![\\w-])${escapeRegex(oldName)}(?![\\w-])`, to: newName },
62
56
  { pattern: `\\b${escapeRegex(oldClassName)}\\b`, to: newClassName },
63
57
  ];
64
- // Each alternative is its own capture group and the replacement is picked by
65
- // the group that matched — not by matched TEXT, which is ambiguous whenever
66
- // two rules can produce the same match with different substitutions.
58
+ // Each alternative is its own capture group and the replacement is picked
59
+ // by the group that matched, rather than by the matched text, which is
60
+ // ambiguous whenever two rules can produce the same match with different
61
+ // substitutions.
67
62
  const combined = new RegExp(alternatives.map(({ pattern }) => `(${pattern})`).join('|'), 'g');
68
63
  return content.replace(combined, (matched, ...args) => {
69
64
  const groups = args.slice(0, alternatives.length);
@@ -8,7 +8,7 @@
8
8
  * so word-boundary occurrences of the old tag / underscored name map to the
9
9
  * new ones.
10
10
  *
11
- * Extracted to keep `rename.ts` under the per-file LOC budget — it already
11
+ * Extracted to keep `rename.ts` under the per-file LOC budget. It already
12
12
  * carries mochikit + browser-mochitest + FTL handling.
13
13
  */
14
14
  import { type RollbackJournal } from '../../core/furnace-rollback.js';
@@ -19,7 +19,7 @@ import { type RollbackJournal } from '../../core/furnace-rollback.js';
19
19
  * old tag / old underscored name inside the test body.
20
20
  *
21
21
  * Best-effort: any failure logs a warning through the shared logger
22
- * but never throws — the component rename itself has already succeeded
22
+ * but never throws. The component rename itself has already succeeded
23
23
  * at this point, and blocking on a test rewrite would leave the
24
24
  * operator with a half-renamed component.
25
25
  *
@@ -9,7 +9,7 @@
9
9
  * so word-boundary occurrences of the old tag / underscored name map to the
10
10
  * new ones.
11
11
  *
12
- * Extracted to keep `rename.ts` under the per-file LOC budget — it already
12
+ * Extracted to keep `rename.ts` under the per-file LOC budget. It already
13
13
  * carries mochikit + browser-mochitest + FTL handling.
14
14
  */
15
15
  import { readdir } from 'node:fs/promises';
@@ -28,7 +28,7 @@ import { escapeRegex } from '../../utils/regex.js';
28
28
  * old tag / old underscored name inside the test body.
29
29
  *
30
30
  * Best-effort: any failure logs a warning through the shared logger
31
- * but never throws — the component rename itself has already succeeded
31
+ * but never throws. The component rename itself has already succeeded
32
32
  * at this point, and blocking on a test rewrite would leave the
33
33
  * operator with a half-renamed component.
34
34
  *
@@ -59,7 +59,7 @@ export async function renameXpcshellTestFiles(engineDir, projectRoot, oldName, n
59
59
  const newTestFileName = `test_${newUnderscored}_packaged.js`;
60
60
  try {
61
61
  // Journal the new scaffold dir + files so rollback (including the
62
- // SIGINT path) removes them; only the old-name files were journaled
62
+ // SIGINT path) removes them. Only the old-name files were journaled
63
63
  // before, so a failed rename stranded the new-name scaffold.
64
64
  recordCreatedDir(journal, newScaffoldDir);
65
65
  await ensureDir(newScaffoldDir);
@@ -18,18 +18,7 @@ import { escapeRegex } from '../../utils/regex.js';
18
18
  import { updateBrowserChromeTestContent } from './rename-browser-test.js';
19
19
  import { rekeyStateChecksums, renameComponentFileName, updateConfigForCustomRename, updateConfigForOverrideRename, } from './rename-helpers.js';
20
20
  import { renameXpcshellTestFiles } from './rename-xpcshell.js';
21
- /**
22
- * Derives the test file name for a component, matching the convention used by
23
- * `furnace create --with-tests`.
24
- */
25
- function deriveTestFileName(componentName, binaryName) {
26
- const strippedName = componentName.startsWith('moz-') ? componentName.slice(4) : componentName;
27
- const withoutBinaryPrefix = strippedName.startsWith(binaryName + '-')
28
- ? strippedName.slice(binaryName.length + 1)
29
- : strippedName;
30
- const underscored = withoutBinaryPrefix.replace(/-/g, '_');
31
- return `browser_${binaryName}_${underscored}.js`;
32
- }
21
+ import { browserTestFileName } from './test-file-name.js';
33
22
  /**
34
23
  * Renames test files created by `furnace create --with-tests` in the engine
35
24
  * test directory. Best-effort: failures are logged as warnings but do not
@@ -44,8 +33,8 @@ async function renameTestFiles(engineDir, projectRoot, oldName, newName, journal
44
33
  return; // Cannot determine test paths without config.
45
34
  }
46
35
  const binaryName = forgeConfig.binaryName;
47
- const oldTestFileName = deriveTestFileName(oldName, binaryName);
48
- const newTestFileName = deriveTestFileName(newName, binaryName);
36
+ const oldTestFileName = browserTestFileName(oldName, binaryName);
37
+ const newTestFileName = browserTestFileName(newName, binaryName);
49
38
  const testDir = join(engineDir, 'browser/base/content/test', binaryName);
50
39
  if (!(await pathExists(testDir)))
51
40
  return;
@@ -88,7 +77,7 @@ async function renameTestFiles(engineDir, projectRoot, oldName, newName, journal
88
77
  * deployment. Best-effort: logs a warning but never blocks the rename.
89
78
  *
90
79
  * Without it, a rename registers and deploys the new name correctly but
91
- * leaves `engine/toolkit/content/widgets/<old>/` in place — subsequent
80
+ * leaves `engine/toolkit/content/widgets/<old>/` in place: subsequent
92
81
  * `furnace sync` runs cannot clear the stale widget, and packaging pulls in
93
82
  * both copies. The snapshot is taken before the remove so the rollback
94
83
  * journal restores the old directory if any later step in
@@ -114,7 +103,7 @@ async function removeStaleDeployedComponentDir(engineDir, oldTargetPath, journal
114
103
  * accompanying `chrome.toml` entry names the same file. Leaving both
115
104
  * unhandled produces a `test_<old>.html` that still imports
116
105
  * `chrome://global/content/elements/<old>.mjs` and references
117
- * `customElements.whenDefined("<old>")` — running against a component that
106
+ * `customElements.whenDefined("<old>")`, running against a component that
118
107
  * no longer exists under that name, and either failing or (if the old
119
108
  * component is still deployed) passing for the wrong reason.
120
109
  *
@@ -150,7 +139,7 @@ async function renameMochikitTestFiles(engineDir, oldName, newName, journal) {
150
139
  }
151
140
  }
152
141
  // Update `chrome.toml` entry if present. The file may live in the
153
- // same widgets/tests directory as the test file itself; upstream
142
+ // same widgets/tests directory as the test file itself. Upstream
154
143
  // convention places exactly one `chrome.toml` there for all widget
155
144
  // scaffolds.
156
145
  const chromeTomlPath = join(testDir, 'chrome.toml');
@@ -206,9 +195,9 @@ async function performRenameMutations(args) {
206
195
  }
207
196
  await snapshotDir(journal, oldDir);
208
197
  await snapshotFile(journal, args.furnaceConfigPath);
209
- // Journal the state file BEFORE step 4 re-keys its checksums, plus
198
+ // Journal the state file before step 4 re-keys its checksums, plus
210
199
  // the new dir and every new-name destination below (a snapshot of a
211
- // missing path records {existed: false} → rollback DELETES it).
200
+ // missing path records {existed: false}, so rollback deletes it).
212
201
  // Without these, a failed or SIGINT'd rename stranded the new-name
213
202
  // scaffold and kept re-keyed state for a nonexistent component.
214
203
  await snapshotFile(journal, getFurnacePaths(projectRoot).furnaceState);
@@ -220,7 +209,7 @@ async function performRenameMutations(args) {
220
209
  if (!entry.isFile())
221
210
  continue;
222
211
  const oldFileName = entry.name;
223
- // Rename only when the filename starts with the component name — the
212
+ // Rename only when the filename starts with the component name. The
224
213
  // scaffolding convention for both create and override is
225
214
  // `${name}.ext`. A plain `replace(oldName, newName)` produces wrong
226
215
  // results when the old name occurs more than once (`foo-foo.mjs`
@@ -259,7 +248,15 @@ async function performRenameMutations(args) {
259
248
  if (isCustom && config.custom[newName]?.register && (await pathExists(args.engineDir))) {
260
249
  const ftlDir = resolveFtlDir(config.ftlBasePath);
261
250
  const isLocalized = config.custom[newName].localized;
262
- await updateEngineRegistrations(args.engineDir, oldName, newName, newDir, ftlDir, isLocalized, journal);
251
+ await updateEngineRegistrations({
252
+ engineDir: args.engineDir,
253
+ oldName,
254
+ newName,
255
+ newDir,
256
+ ftlDir,
257
+ isLocalized,
258
+ journal,
259
+ });
263
260
  }
264
261
  // 4. Re-key furnace-state.json checksums from old name to new name
265
262
  await rekeyStateChecksums(args.projectRoot, componentType, oldName, newName);
@@ -279,7 +276,7 @@ async function performRenameMutations(args) {
279
276
  await renameTestFiles(args.engineDir, projectRoot, oldName, newName, journal);
280
277
  // The mochikit scaffold and widgets/chrome.toml live in a different
281
278
  // tree than browser.toml-registered browser-chrome tests, so
282
- // renameTestFiles does not reach them — leaving
279
+ // renameTestFiles does not reach them, leaving
283
280
  // `engine/toolkit/content/tests/widgets/test_<old>.html` and its
284
281
  // `chrome.toml` entry pointing at the old name, which either fails
285
282
  // the test run outright or passes for the wrong component.
@@ -323,7 +320,14 @@ async function performRenameMutations(args) {
323
320
  }
324
321
  });
325
322
  }
326
- async function updateEngineRegistrations(engineDir, oldName, newName, newDir, ftlDir, isLocalized, journal) {
323
+ /**
324
+ * Re-points the engine-side registrations (customElements.js, jar.mn, and
325
+ * the localized `.ftl` entries) from the old tag name to the new one.
326
+ *
327
+ * @param options - See {@link UpdateEngineRegistrationsOptions}
328
+ */
329
+ async function updateEngineRegistrations(options) {
330
+ const { engineDir, oldName, newName, newDir, ftlDir, isLocalized, journal } = options;
327
331
  const customElementsPath = join(engineDir, 'toolkit/content/customElements.js');
328
332
  const jarMnPath = join(engineDir, 'toolkit/content/jar.mn');
329
333
  if (await pathExists(customElementsPath)) {
@@ -396,15 +400,15 @@ export async function furnaceRenameCommand(projectRoot, oldName, newName) {
396
400
  if (newName in config.custom || newName in config.overrides || config.stock.includes(newName)) {
397
401
  throw new FurnaceError(`A component named "${newName}" already exists in furnace.json.`, newName);
398
402
  }
399
- const componentType = isCustom ? 'custom' : 'override';
400
- // `componentType` is the furnace-state key (singular: `custom` /
401
- // `override`); the on-disk directory label differs — custom components
402
- // live under `components/custom/` (singular) while overrides live under
403
- // `components/overrides/` (plural). Appending an `s` to `componentType`
404
- // produces the wrong label `components/customs/` for custom components
405
- // and is correct for overrides only by coincidence. `componentDirLabel`
406
- // centralises the pick so every operator-facing string names the
407
- // directory that actually exists on disk.
403
+ // The furnace-state key is singular (`custom` / `override`, derived
404
+ // inside performRenameMutations). The on-disk directory label differs.
405
+ // Custom components live under `components/custom/` (singular) while
406
+ // overrides live under `components/overrides/` (plural). Appending an
407
+ // `s` to the state key produces the wrong label `components/customs/`
408
+ // for custom components and is correct for overrides only by
409
+ // coincidence. `componentDirLabel` centralises the pick so every
410
+ // operator-facing string names the directory that actually exists on
411
+ // disk.
408
412
  const componentDirLabel = isCustom ? 'custom' : 'overrides';
409
413
  const baseDir = isCustom ? furnacePaths.customDir : furnacePaths.overridesDir;
410
414
  const oldDir = join(baseDir, oldName);
@@ -419,11 +423,7 @@ export async function furnaceRenameCommand(projectRoot, oldName, newName) {
419
423
  projectRoot,
420
424
  oldName,
421
425
  newName,
422
- oldDir,
423
426
  newDir,
424
- isCustom,
425
- componentType,
426
- config,
427
427
  furnaceConfigPath: furnacePaths.furnaceConfig,
428
428
  furnacePaths,
429
429
  engineDir: paths.engine,
@@ -59,7 +59,7 @@ async function promptAddComponents(components, tracked, projectRoot) {
59
59
  /**
60
60
  * Persists discovered component tag names into the `stock` section of
61
61
  * furnace.json. Shared by the interactive confirm flow and the
62
- * non-interactive `--track` flag — without it, scan prints a full inventory
62
+ * non-interactive `--track` flag. Without it, scan prints a full inventory
63
63
  * but persists nothing and says nothing about where the inventory goes.
64
64
  *
65
65
  * Wraps the furnace.json mutation in the standard furnace lifecycle so the
@@ -81,7 +81,7 @@ async function persistStockComponents(projectRoot, names) {
81
81
  // re-filter catches the edge case where the config on disk changed
82
82
  // between the scan's read and the write (concurrent scan / manual
83
83
  // edit). Without it a duplicate scan would introduce duplicate
84
- // entries into stock; writeFurnaceConfig's validator would then
84
+ // entries into stock. writeFurnaceConfig's validator would then
85
85
  // reject the write, but the error would be less actionable than
86
86
  // silently de-duplicating here.
87
87
  const toAdd = names.filter((s) => !config.stock.includes(s));
@@ -163,7 +163,7 @@ export async function furnaceScanCommand(projectRoot, options = {}) {
163
163
  note(`Total: ${components.length} Tracked: ${trackedCount} Untracked: ${untrackedCount}`, 'Summary');
164
164
  // --track: persist the discovered untracked inventory into the `stock`
165
165
  // section without prompting (works non-interactively). Without it, scan
166
- // stays report-only; the interactive confirm flow below is the other
166
+ // stays report-only. The interactive confirm flow below is the other
167
167
  // persistence path.
168
168
  if (options.track) {
169
169
  if (untrackedCount === 0) {
@@ -11,15 +11,10 @@ import { pathExists } from '../../utils/fs.js';
11
11
  import { info, intro, note, outro, warn } from '../../utils/logger.js';
12
12
  /**
13
13
  * Displays detailed status for a single Furnace component, including registration drift.
14
- * @param name - Component tag name to inspect
15
- * @param config - Loaded Furnace configuration
16
- * @param state - Loaded furnace state, for applied/engine checksums
17
- * @param projectRoot - Root directory of the project
18
- * @param paths - Resolved project paths
19
- * @param furnacePaths - Resolved Furnace-specific paths
20
- * @param ftlDir - Engine-relative directory localized components deploy their `.ftl` into
14
+ * @param options - See {@link DetailedComponentStatusOptions}
21
15
  */
22
- async function showDetailedComponentStatus(name, config, state, projectRoot, paths, furnacePaths, ftlDir) {
16
+ async function showDetailedComponentStatus(options) {
17
+ const { name, config, state, projectRoot, paths, furnacePaths, ftlDir } = options;
23
18
  const customConfig = config.custom[name];
24
19
  const overrideConfig = config.overrides[name];
25
20
  if (!customConfig && !overrideConfig && !config.stock.includes(name)) {
@@ -72,7 +67,7 @@ async function showDetailedComponentStatus(name, config, state, projectRoot, pat
72
67
  outro('Status complete');
73
68
  return;
74
69
  }
75
- // Custom component — run registration consistency check
70
+ // Custom component: run registration consistency check
76
71
  const status = await checkRegistrationConsistency(projectRoot, name, customConfig, ftlDir);
77
72
  const lines = [];
78
73
  const check = (ok, label) => {
@@ -113,13 +108,21 @@ export async function furnaceStatusCommand(projectRoot, name) {
113
108
  const furnacePaths = getFurnacePaths(projectRoot);
114
109
  const ftlDir = resolveFtlDir(config.ftlBasePath);
115
110
  if (name) {
116
- await showDetailedComponentStatus(name, config, state, projectRoot, paths, furnacePaths, ftlDir);
111
+ await showDetailedComponentStatus({
112
+ name,
113
+ config,
114
+ state,
115
+ projectRoot,
116
+ paths,
117
+ furnacePaths,
118
+ ftlDir,
119
+ });
117
120
  return;
118
121
  }
119
122
  // Surface a pendingRepair marker before the normal summary so it cannot
120
123
  // be missed. The marker means the last mutation could not roll back
121
124
  // cleanly, so the engine and workspace may have drifted in ways apply
122
- // cannot detect from checksums alone — doctor is the right next step.
125
+ // cannot detect from checksums alone, so doctor is the right next step.
123
126
  if (state.pendingRepair) {
124
127
  warn(`Furnace is in pending-repair state from ${state.pendingRepair.operation} (${state.pendingRepair.timestamp}): ${state.pendingRepair.reason}. Run \`fireforge doctor --repair-furnace\` to reconcile.`);
125
128
  }
@@ -151,7 +154,7 @@ export async function furnaceStatusCommand(projectRoot, name) {
151
154
  // Surface override baseVersion drift from the project config. This check
152
155
  // is cheap (no I/O besides the already-loaded fireforge.json) and catches
153
156
  // the single most common silent-drift case: Firefox bumped, overrides
154
- // still point at the old version. Advisory only — status never fails.
157
+ // still point at the old version. Advisory only. Status never fails.
155
158
  const forgeConfig = await loadConfig(projectRoot);
156
159
  for (const entry of findOverrideBaseVersionDrift(config, forgeConfig.firefox.version)) {
157
160
  warn(formatOverrideBaseVersionDriftWarning(entry));
@@ -163,17 +166,17 @@ export async function furnaceStatusCommand(projectRoot, name) {
163
166
  if (await pathExists(paths.engine)) {
164
167
  // Held in an object rather than two `let`s: the scanner below mutates
165
168
  // them from inside a closure, and TS's control-flow analysis does not
166
- // propagate that through the call — it would narrow both to the literal
169
+ // propagate that through the call. It would narrow both to the literal
167
170
  // `false` and flag every later read as always-falsy.
168
171
  const drift = { workspaceChanged: false, engineDrifted: false };
169
172
  /**
170
173
  * Scans one component family for workspace or engine drift.
171
174
  *
172
- * The engine probe sits behind `else if` deliberately: a component whose
175
+ * The engine probe sits behind `else if` on purpose: a component whose
173
176
  * workspace already changed does not need an engine comparison to decide
174
177
  * what `status` reports, and the probe is the expensive half (it
175
- * re-hashes deployed files). The consequence is that engine drift can go
176
- * UNREPORTED for a component that also has workspace changes — the
178
+ * re-hashes deployed files). The consequence is that engine drift goes
179
+ * unreported for a component that also has workspace changes. The
177
180
  * summary says "workspace changed", not both.
178
181
  */
179
182
  const scanFamily = async (entries, baseDir, kind, probeEngineDrift) => {
@@ -91,12 +91,12 @@ export async function furnaceSyncCommand(projectRoot, options = {}) {
91
91
  else {
92
92
  info('All overrides are up-to-date with the current Firefox version.');
93
93
  }
94
- // Phase 2.5: post-refresh gates. Refresh deliberately leaves conflict
95
- // markers in workspace files and does NOT bump baseVersion on conflict —
96
- // so without this gate sync warns about conflicts and then copies the
97
- // marker-laden files straight into the engine via Phase 3, producing a
98
- // broken build from the one command whose whole purpose is a safe upgrade.
99
- // Apply and deploy both enforce a drift gate; sync must not be the back
94
+ // Phase 2.5: post-refresh gates. Refresh leaves conflict markers in
95
+ // workspace files and does not bump baseVersion on conflict, so without
96
+ // this gate sync warns about conflicts and then copies the marker-laden
97
+ // files straight into the engine via Phase 3, producing a broken build
98
+ // from the one command meant to make an upgrade safe.
99
+ // Apply and deploy both enforce a drift gate. Sync must not be the back
100
100
  // door around it.
101
101
  if (!options.dryRun) {
102
102
  const refreshedConfig = await loadFurnaceConfig(projectRoot);
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Derives the underscored stem a component's generated test files are named
3
+ * after.
4
+ *
5
+ * Five modules (`create-browser-test`, `create-dry-run`, `remove`, `rename`,
6
+ * `rename-browser-test`) had each inlined this three-step transform. The steps
7
+ * are not arbitrary and must agree exactly, or `furnace rename` and
8
+ * `furnace remove` compute a different filename than `furnace create` wrote
9
+ * and silently leave the old test behind:
10
+ *
11
+ * 1. drop the upstream `moz-` custom-element prefix, which never appears in a
12
+ * test filename.
13
+ * 2. drop a leading `<binaryName>-`, because the test directory is already
14
+ * named after the binary and the prefix would be doubled.
15
+ * 3. underscore the remaining dashes, matching mozilla-central's
16
+ * `browser_*.js` convention.
17
+ * @param componentName - Custom-element name, e.g. `moz-mybrowser-sidebar`.
18
+ * @param binaryName - Configured binary name, e.g. `mybrowser`.
19
+ * @returns The stem, e.g. `sidebar`.
20
+ */
21
+ export declare function deriveTestStem(componentName: string, binaryName: string): string;
22
+ /**
23
+ * Builds the browser-chrome test filename for a component.
24
+ * @param componentName - Custom-element name.
25
+ * @param binaryName - Configured binary name.
26
+ * @returns The filename, e.g. `browser_mybrowser_sidebar.js`.
27
+ */
28
+ export declare function browserTestFileName(componentName: string, binaryName: string): string;
@@ -0,0 +1,39 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * Derives the underscored stem a component's generated test files are named
4
+ * after.
5
+ *
6
+ * Five modules (`create-browser-test`, `create-dry-run`, `remove`, `rename`,
7
+ * `rename-browser-test`) had each inlined this three-step transform. The steps
8
+ * are not arbitrary and must agree exactly, or `furnace rename` and
9
+ * `furnace remove` compute a different filename than `furnace create` wrote
10
+ * and silently leave the old test behind:
11
+ *
12
+ * 1. drop the upstream `moz-` custom-element prefix, which never appears in a
13
+ * test filename.
14
+ * 2. drop a leading `<binaryName>-`, because the test directory is already
15
+ * named after the binary and the prefix would be doubled.
16
+ * 3. underscore the remaining dashes, matching mozilla-central's
17
+ * `browser_*.js` convention.
18
+ * @param componentName - Custom-element name, e.g. `moz-mybrowser-sidebar`.
19
+ * @param binaryName - Configured binary name, e.g. `mybrowser`.
20
+ * @returns The stem, e.g. `sidebar`.
21
+ */
22
+ export function deriveTestStem(componentName, binaryName) {
23
+ const withoutMozPrefix = componentName.startsWith('moz-')
24
+ ? componentName.slice(4)
25
+ : componentName;
26
+ const withoutBinaryPrefix = withoutMozPrefix.startsWith(`${binaryName}-`)
27
+ ? withoutMozPrefix.slice(binaryName.length + 1)
28
+ : withoutMozPrefix;
29
+ return withoutBinaryPrefix.replace(/-/g, '_');
30
+ }
31
+ /**
32
+ * Builds the browser-chrome test filename for a component.
33
+ * @param componentName - Custom-element name.
34
+ * @param binaryName - Configured binary name.
35
+ * @returns The filename, e.g. `browser_mybrowser_sidebar.js`.
36
+ */
37
+ export function browserTestFileName(componentName, binaryName) {
38
+ return `browser_${binaryName}_${deriveTestStem(componentName, binaryName)}.js`;
39
+ }
@@ -78,16 +78,15 @@ async function autoFixIssues(projectRoot, issues) {
78
78
  warn(`Could not fix jar.mn for ${componentName}: ${toError(err).message}`);
79
79
  }
80
80
  }
81
- // `wrong-registration-pattern` is deliberately NOT auto-fixed: it means the
82
- // component IS registered but in the wrong block, and moving code between
83
- // blocks is too risky to do unattended. Only truly missing registrations are
84
- // repaired, below.
81
+ // `wrong-registration-pattern` is not auto-fixed: the component is
82
+ // registered but in the wrong block, and moving code between blocks is too
83
+ // risky to do unattended. Only missing registrations are repaired, below.
85
84
  // Repair components missing from customElements.js entirely (reported by
86
85
  // validate as `missing-custom-element-registration`).
87
86
  //
88
87
  // Scoped to the components named in `issues`: iterating every entry in
89
88
  // `config.custom` makes `furnace validate <one-component> --fix` write
90
- // customElements.js registrations for EVERY custom component, outside the
89
+ // customElements.js registrations for every custom component, outside the
91
90
  // issue list it was handed and invisibly, since `fixed` is never
92
91
  // incremented here.
93
92
  const componentsWithIssues = new Set(issues.map((issue) => issue.component));
@@ -109,7 +108,7 @@ async function autoFixIssues(projectRoot, issues) {
109
108
  await addCustomElementRegistration(engineDir, componentName, modulePath);
110
109
  }
111
110
  catch {
112
- // Best-effort repair — the re-validation pass at the call site reports
111
+ // Best-effort repair. The re-validation pass at the call site reports
113
112
  // whatever is still outstanding.
114
113
  }
115
114
  }
@@ -194,11 +193,11 @@ export async function furnaceValidateCommand(projectRoot, name, options = {}) {
194
193
  }
195
194
  }
196
195
  // Auto-fix fixable issues when --fix is passed. The counter returned by
197
- // `autoFixIssues` only counts function calls that did not throw — a write
198
- // that succeeded but did not actually resolve the issue (addJarMnEntries
199
- // appending to a file mach later ignores) would still bump it. Re-validate
200
- // the affected components and compute the *actual* drop in fixable issues
201
- // so the reported number is honest.
196
+ // `autoFixIssues` only counts function calls that did not throw, so a
197
+ // write that succeeded but did not actually resolve the issue
198
+ // (addJarMnEntries appending to a file mach later ignores) would still
199
+ // bump it. Re-validate the affected components and compute the real drop
200
+ // in fixable issues so the reported number is honest.
202
201
  if (options.fix && allIssues.length > 0) {
203
202
  const fixableIssues = allIssues.filter((issue) => FIXABLE_CHECKS.has(issue.check));
204
203
  if (fixableIssues.length > 0) {
@@ -254,7 +253,7 @@ async function reValidateComponents(projectRoot, config, furnacePaths, component
254
253
  componentDir = join(furnacePaths.customDir, componentName);
255
254
  }
256
255
  else {
257
- // Stock or removed components are not local-validated; skip silently.
256
+ // Stock or removed components are not local-validated, so skip silently.
258
257
  continue;
259
258
  }
260
259
  if (!(await pathExists(componentDir)))
@@ -1,4 +1,4 @@
1
- import type { getFurnacePaths } from '../../core/furnace-config.js';
1
+ import type { FurnacePaths } from '../../core/furnace-config.js';
2
2
  import type { DryRunAction, FurnaceConfig, ValidationIssue } from '../../types/furnace.js';
3
3
  import { type SpinnerHandle } from '../../utils/logger.js';
4
4
  /**
@@ -16,15 +16,27 @@ export type ValidationResult = {
16
16
  componentCount: number;
17
17
  skippedValidationCount: number;
18
18
  };
19
+ export interface RunDeployValidationOptions {
20
+ /** Active spinner handle for progress display. */
21
+ validateSpinner: SpinnerHandle;
22
+ /** Optional component name (validates all if omitted). */
23
+ name: string | undefined;
24
+ /** Loaded Furnace configuration. */
25
+ config: FurnaceConfig;
26
+ /** Resolved Furnace workspace paths. */
27
+ furnacePaths: FurnacePaths;
28
+ /** Names of components whose apply step failed. */
29
+ failedComponents: Set<string>;
30
+ /** Whether deploy is running in dry-run mode. */
31
+ isDryRun: boolean;
32
+ /** Root directory of the project. */
33
+ projectRoot: string;
34
+ /** Projected actions of a dry run, used to filter projected issues. */
35
+ dryRunActions?: DryRunAction[] | undefined;
36
+ }
19
37
  /**
20
38
  * Runs the validation phase of a furnace deploy, checking all or a single component.
21
- * @param validateSpinner - Active spinner handle for progress display
22
- * @param name - Optional component name (validates all if omitted)
23
- * @param config - Loaded Furnace configuration
24
- * @param furnacePaths - Resolved Furnace workspace paths
25
- * @param failedComponents - Names of components whose apply step failed
26
- * @param isDryRun - Whether deploy is running in dry-run mode
27
- * @param projectRoot - Root directory of the project
39
+ * @param options - See {@link RunDeployValidationOptions}
28
40
  * @returns Validation counts, or `done: true` if the caller should early-return
29
41
  */
30
- export declare function runDeployValidation(validateSpinner: SpinnerHandle, name: string | undefined, config: FurnaceConfig, furnacePaths: ReturnType<typeof getFurnacePaths>, failedComponents: Set<string>, isDryRun: boolean, projectRoot: string, dryRunActions?: DryRunAction[]): Promise<ValidationResult>;
42
+ export declare function runDeployValidation(options: RunDeployValidationOptions): Promise<ValidationResult>;
@@ -56,16 +56,11 @@ function resolveNamedValidationTarget(name, config, furnacePaths) {
56
56
  }
57
57
  /**
58
58
  * Runs the validation phase of a furnace deploy, checking all or a single component.
59
- * @param validateSpinner - Active spinner handle for progress display
60
- * @param name - Optional component name (validates all if omitted)
61
- * @param config - Loaded Furnace configuration
62
- * @param furnacePaths - Resolved Furnace workspace paths
63
- * @param failedComponents - Names of components whose apply step failed
64
- * @param isDryRun - Whether deploy is running in dry-run mode
65
- * @param projectRoot - Root directory of the project
59
+ * @param options - See {@link RunDeployValidationOptions}
66
60
  * @returns Validation counts, or `done: true` if the caller should early-return
67
61
  */
68
- export async function runDeployValidation(validateSpinner, name, config, furnacePaths, failedComponents, isDryRun, projectRoot, dryRunActions) {
62
+ export async function runDeployValidation(options) {
63
+ const { validateSpinner, name, config, furnacePaths, failedComponents, isDryRun, projectRoot, dryRunActions, } = options;
69
64
  let totalErrors = 0;
70
65
  let totalWarnings = 0;
71
66
  let componentCount = 0;