@hominis/fireforge 0.43.1 → 0.44.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 (478) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/README.md +3 -3
  3. package/dist/bin/fireforge.d.ts +4 -9
  4. package/dist/bin/fireforge.js +42 -40
  5. package/dist/build-info.json +4 -4
  6. package/dist/src/cli.js +74 -8
  7. package/dist/src/commands/bootstrap.js +17 -20
  8. package/dist/src/commands/build.js +25 -32
  9. package/dist/src/commands/config.js +34 -41
  10. package/dist/src/commands/discard.js +8 -9
  11. package/dist/src/commands/doctor-check-core.d.ts +13 -18
  12. package/dist/src/commands/doctor-check-core.js +8 -35
  13. package/dist/src/commands/doctor-external-toolchains.js +2 -2
  14. package/dist/src/commands/doctor-furnace-config-sync.d.ts +18 -0
  15. package/dist/src/commands/{doctor-furnace-manifest-sync.js → doctor-furnace-config-sync.js} +27 -26
  16. package/dist/src/commands/doctor-furnace-jar.d.ts +7 -9
  17. package/dist/src/commands/doctor-furnace-jar.js +7 -9
  18. package/dist/src/commands/doctor-furnace.js +21 -24
  19. package/dist/src/commands/doctor-orphaned-harness.d.ts +16 -20
  20. package/dist/src/commands/doctor-orphaned-harness.js +18 -44
  21. package/dist/src/commands/doctor-patch-manifest.d.ts +8 -0
  22. package/dist/src/commands/doctor-patch-manifest.js +155 -0
  23. package/dist/src/commands/doctor-post-rebase-audit.d.ts +2 -0
  24. package/dist/src/commands/{doctor/post-rebase-audit.js → doctor-post-rebase-audit.js} +3 -3
  25. package/dist/src/commands/doctor-working-tree.d.ts +10 -12
  26. package/dist/src/commands/doctor-working-tree.js +11 -18
  27. package/dist/src/commands/doctor.d.ts +1 -1
  28. package/dist/src/commands/doctor.js +64 -96
  29. package/dist/src/commands/download.js +32 -48
  30. package/dist/src/commands/export-all.js +29 -33
  31. package/dist/src/commands/export-flow.js +6 -6
  32. package/dist/src/commands/export-placement-conflicts.js +10 -9
  33. package/dist/src/commands/export-placement-gate.js +5 -5
  34. package/dist/src/commands/export-shared.d.ts +30 -33
  35. package/dist/src/commands/export-shared.js +45 -43
  36. package/dist/src/commands/export.js +21 -27
  37. package/dist/src/commands/furnace/apply.js +14 -23
  38. package/dist/src/commands/furnace/chrome-doc-remove.js +14 -21
  39. package/dist/src/commands/furnace/chrome-doc-templates.d.ts +23 -23
  40. package/dist/src/commands/furnace/chrome-doc-templates.js +23 -23
  41. package/dist/src/commands/furnace/chrome-doc-tests.js +26 -29
  42. package/dist/src/commands/furnace/chrome-doc.d.ts +16 -17
  43. package/dist/src/commands/furnace/chrome-doc.js +31 -41
  44. package/dist/src/commands/furnace/create-browser-test.d.ts +4 -4
  45. package/dist/src/commands/furnace/create-browser-test.js +8 -8
  46. package/dist/src/commands/furnace/create-mochikit.d.ts +6 -7
  47. package/dist/src/commands/furnace/create-mochikit.js +8 -9
  48. package/dist/src/commands/furnace/create-readback.d.ts +12 -13
  49. package/dist/src/commands/furnace/create-readback.js +12 -13
  50. package/dist/src/commands/furnace/create-templates.d.ts +22 -28
  51. package/dist/src/commands/furnace/create-templates.js +35 -30
  52. package/dist/src/commands/furnace/create-xpcshell.js +2 -2
  53. package/dist/src/commands/furnace/create.js +33 -23
  54. package/dist/src/commands/furnace/deploy.js +16 -24
  55. package/dist/src/commands/furnace/diff.js +15 -10
  56. package/dist/src/commands/furnace/init.js +33 -36
  57. package/dist/src/commands/furnace/override.js +23 -25
  58. package/dist/src/commands/furnace/preview.js +47 -67
  59. package/dist/src/commands/furnace/refresh.js +12 -16
  60. package/dist/src/commands/furnace/remove-mutations.d.ts +3 -6
  61. package/dist/src/commands/furnace/remove-mutations.js +14 -17
  62. package/dist/src/commands/furnace/remove-state.js +1 -1
  63. package/dist/src/commands/furnace/remove.js +33 -38
  64. package/dist/src/commands/furnace/rename-xpcshell.d.ts +8 -11
  65. package/dist/src/commands/furnace/rename-xpcshell.js +8 -11
  66. package/dist/src/commands/furnace/rename.js +59 -69
  67. package/dist/src/commands/furnace/scan.js +19 -33
  68. package/dist/src/commands/furnace/status.js +12 -9
  69. package/dist/src/commands/furnace/sync.js +9 -16
  70. package/dist/src/commands/furnace/validate.js +20 -20
  71. package/dist/src/commands/import.js +48 -37
  72. package/dist/src/commands/lint-per-patch.js +15 -10
  73. package/dist/src/commands/lint-per-run-checkjs.d.ts +13 -13
  74. package/dist/src/commands/lint-per-run-checkjs.js +13 -13
  75. package/dist/src/commands/lint-report.js +6 -7
  76. package/dist/src/commands/lint.d.ts +15 -16
  77. package/dist/src/commands/lint.js +86 -102
  78. package/dist/src/commands/package.js +6 -11
  79. package/dist/src/commands/patch/compact.js +1 -1
  80. package/dist/src/commands/patch/delete.js +24 -33
  81. package/dist/src/commands/patch/index.d.ts +5 -6
  82. package/dist/src/commands/patch/index.js +10 -12
  83. package/dist/src/commands/patch/lint-ignore.js +14 -13
  84. package/dist/src/commands/patch/move-files-create.d.ts +6 -6
  85. package/dist/src/commands/patch/move-files-create.js +8 -8
  86. package/dist/src/commands/patch/move-files-into.d.ts +6 -6
  87. package/dist/src/commands/patch/move-files-into.js +8 -8
  88. package/dist/src/commands/patch/patch-context.d.ts +2 -3
  89. package/dist/src/commands/patch/patch-context.js +2 -3
  90. package/dist/src/commands/patch/rename.d.ts +10 -11
  91. package/dist/src/commands/patch/rename.js +11 -12
  92. package/dist/src/commands/patch/reorder.js +8 -9
  93. package/dist/src/commands/patch/split-plan.js +1 -1
  94. package/dist/src/commands/patch/split.d.ts +8 -10
  95. package/dist/src/commands/patch/split.js +9 -11
  96. package/dist/src/commands/patch/staged-dependency-validate.js +8 -8
  97. package/dist/src/commands/patch/staged-dependency.js +7 -3
  98. package/dist/src/commands/patch/tier.d.ts +9 -9
  99. package/dist/src/commands/patch/tier.js +18 -15
  100. package/dist/src/commands/re-export-adjacent.js +9 -8
  101. package/dist/src/commands/re-export-bulk-scan.d.ts +9 -9
  102. package/dist/src/commands/re-export-bulk-scan.js +22 -21
  103. package/dist/src/commands/re-export-drift.js +10 -10
  104. package/dist/src/commands/re-export-files.d.ts +6 -7
  105. package/dist/src/commands/re-export-files.js +34 -44
  106. package/dist/src/commands/re-export-lint.d.ts +10 -13
  107. package/dist/src/commands/re-export-lint.js +16 -14
  108. package/dist/src/commands/re-export-options.d.ts +6 -6
  109. package/dist/src/commands/re-export-options.js +6 -6
  110. package/dist/src/commands/re-export-register.d.ts +4 -10
  111. package/dist/src/commands/re-export-register.js +5 -11
  112. package/dist/src/commands/re-export-scan.js +1 -1
  113. package/dist/src/commands/re-export-single.d.ts +3 -3
  114. package/dist/src/commands/re-export-single.js +33 -25
  115. package/dist/src/commands/re-export.js +13 -21
  116. package/dist/src/commands/rebase/abort.js +3 -3
  117. package/dist/src/commands/rebase/confirm.js +2 -1
  118. package/dist/src/commands/rebase/continue.d.ts +1 -1
  119. package/dist/src/commands/rebase/continue.js +14 -9
  120. package/dist/src/commands/rebase/index.js +11 -11
  121. package/dist/src/commands/rebase/patch-loop.d.ts +7 -1
  122. package/dist/src/commands/rebase/patch-loop.js +60 -39
  123. package/dist/src/commands/rebase/summary.js +1 -1
  124. package/dist/src/commands/register.js +5 -7
  125. package/dist/src/commands/reset.js +2 -1
  126. package/dist/src/commands/resolve.d.ts +16 -13
  127. package/dist/src/commands/resolve.js +30 -33
  128. package/dist/src/commands/run.js +33 -35
  129. package/dist/src/commands/setup-support.js +15 -19
  130. package/dist/src/commands/setup.js +13 -9
  131. package/dist/src/commands/status-check.d.ts +6 -6
  132. package/dist/src/commands/status-json.d.ts +6 -6
  133. package/dist/src/commands/status-json.js +5 -0
  134. package/dist/src/commands/status-output.d.ts +5 -5
  135. package/dist/src/commands/status-output.js +6 -6
  136. package/dist/src/commands/status-ownership.d.ts +16 -14
  137. package/dist/src/commands/status-ownership.js +16 -14
  138. package/dist/src/commands/status.js +42 -34
  139. package/dist/src/commands/test-build-phase.js +26 -13
  140. package/dist/src/commands/test-diagnose.js +44 -44
  141. package/dist/src/commands/test-register.js +1 -0
  142. package/dist/src/commands/test-run.d.ts +14 -16
  143. package/dist/src/commands/test-run.js +21 -13
  144. package/dist/src/commands/test-stale-gate.d.ts +15 -16
  145. package/dist/src/commands/test-stale-gate.js +15 -16
  146. package/dist/src/commands/test-verdict.d.ts +20 -3
  147. package/dist/src/commands/test-verdict.js +30 -0
  148. package/dist/src/commands/test.js +83 -76
  149. package/dist/src/commands/token-coverage.js +3 -4
  150. package/dist/src/commands/token.js +16 -18
  151. package/dist/src/commands/tree.js +47 -31
  152. package/dist/src/commands/typecheck.d.ts +10 -12
  153. package/dist/src/commands/typecheck.js +24 -27
  154. package/dist/src/commands/verify.js +13 -15
  155. package/dist/src/commands/watch.js +21 -23
  156. package/dist/src/commands/wire.js +52 -62
  157. package/dist/src/core/ast-utils.d.ts +8 -7
  158. package/dist/src/core/ast-utils.js +8 -7
  159. package/dist/src/core/branding.d.ts +9 -14
  160. package/dist/src/core/branding.js +7 -11
  161. package/dist/src/core/browser-wire.d.ts +1 -1
  162. package/dist/src/core/browser-wire.js +14 -19
  163. package/dist/src/core/build-audit-platform.js +25 -33
  164. package/dist/src/core/build-audit-registration.js +17 -25
  165. package/dist/src/core/build-audit-resolve.d.ts +15 -17
  166. package/dist/src/core/build-audit-resolve.js +39 -36
  167. package/dist/src/core/build-audit-transforms.js +18 -19
  168. package/dist/src/core/build-audit.js +28 -42
  169. package/dist/src/core/build-baseline-types.d.ts +29 -35
  170. package/dist/src/core/build-baseline.d.ts +5 -4
  171. package/dist/src/core/build-baseline.js +14 -14
  172. package/dist/src/core/build-overwrite-guard.d.ts +7 -14
  173. package/dist/src/core/build-overwrite-guard.js +17 -27
  174. package/dist/src/core/build-prepare.d.ts +2 -2
  175. package/dist/src/core/build-prepare.js +8 -9
  176. package/dist/src/core/config-mutate.js +20 -19
  177. package/dist/src/core/config-state.js +12 -4
  178. package/dist/src/core/config-validate.js +8 -5
  179. package/dist/src/core/config.d.ts +5 -8
  180. package/dist/src/core/config.js +7 -16
  181. package/dist/src/core/coverage-extend.d.ts +15 -13
  182. package/dist/src/core/coverage-extend.js +15 -13
  183. package/dist/src/core/destructive.d.ts +31 -9
  184. package/dist/src/core/destructive.js +29 -26
  185. package/dist/src/core/diff-hunks.js +10 -12
  186. package/dist/src/core/discard-baseline.d.ts +8 -8
  187. package/dist/src/core/discard-baseline.js +16 -15
  188. package/dist/src/core/display-state.d.ts +12 -14
  189. package/dist/src/core/display-state.js +12 -14
  190. package/dist/src/core/engine-changes.d.ts +2 -4
  191. package/dist/src/core/engine-changes.js +2 -4
  192. package/dist/src/core/engine-precondition.d.ts +28 -13
  193. package/dist/src/core/engine-precondition.js +25 -10
  194. package/dist/src/core/engine-session-lock.d.ts +47 -21
  195. package/dist/src/core/engine-session-lock.js +168 -33
  196. package/dist/src/core/export-moved-code-shape.d.ts +10 -10
  197. package/dist/src/core/export-moved-code-shape.js +10 -10
  198. package/dist/src/core/file-lock.d.ts +62 -5
  199. package/dist/src/core/file-lock.js +196 -59
  200. package/dist/src/core/firefox-cache.js +1 -3
  201. package/dist/src/core/firefox-extract.js +10 -14
  202. package/dist/src/core/firefox.d.ts +7 -5
  203. package/dist/src/core/firefox.js +4 -5
  204. package/dist/src/core/furnace-apply-dry-run.d.ts +2 -2
  205. package/dist/src/core/furnace-apply-dry-run.js +3 -2
  206. package/dist/src/core/furnace-apply-ftl.d.ts +7 -9
  207. package/dist/src/core/furnace-apply-ftl.js +16 -13
  208. package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
  209. package/dist/src/core/furnace-apply-helpers.js +30 -21
  210. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +8 -9
  211. package/dist/src/core/furnace-apply-overwrite-warn.js +8 -9
  212. package/dist/src/core/furnace-apply-undeploy-actions.d.ts +3 -4
  213. package/dist/src/core/furnace-apply-undeploy-actions.js +3 -4
  214. package/dist/src/core/furnace-apply.d.ts +5 -8
  215. package/dist/src/core/furnace-apply.js +19 -24
  216. package/dist/src/core/furnace-checksum-utils.d.ts +14 -0
  217. package/dist/src/core/furnace-checksum-utils.js +16 -0
  218. package/dist/src/core/furnace-config.d.ts +21 -30
  219. package/dist/src/core/furnace-config.js +32 -54
  220. package/dist/src/core/furnace-constants.d.ts +8 -0
  221. package/dist/src/core/furnace-constants.js +10 -2
  222. package/dist/src/core/furnace-css-fragments.d.ts +5 -5
  223. package/dist/src/core/furnace-css-fragments.js +5 -5
  224. package/dist/src/core/furnace-jsconfig.d.ts +11 -12
  225. package/dist/src/core/furnace-jsconfig.js +11 -12
  226. package/dist/src/core/furnace-marker.d.ts +7 -8
  227. package/dist/src/core/furnace-marker.js +7 -8
  228. package/dist/src/core/furnace-operation.d.ts +31 -0
  229. package/dist/src/core/furnace-operation.js +54 -17
  230. package/dist/src/core/furnace-precondition.d.ts +61 -0
  231. package/dist/src/core/furnace-precondition.js +67 -0
  232. package/dist/src/core/furnace-registration-remove.d.ts +5 -6
  233. package/dist/src/core/furnace-registration-remove.js +6 -7
  234. package/dist/src/core/furnace-registration-validate.d.ts +13 -0
  235. package/dist/src/core/furnace-registration-validate.js +20 -1
  236. package/dist/src/core/furnace-registration.d.ts +5 -6
  237. package/dist/src/core/furnace-registration.js +10 -12
  238. package/dist/src/core/furnace-rollback.js +7 -7
  239. package/dist/src/core/furnace-scanner.d.ts +1 -0
  240. package/dist/src/core/furnace-scanner.js +1 -2
  241. package/dist/src/core/furnace-stale-export.d.ts +10 -10
  242. package/dist/src/core/furnace-stale-export.js +10 -10
  243. package/dist/src/core/furnace-state-persist.d.ts +6 -8
  244. package/dist/src/core/furnace-state-persist.js +6 -8
  245. package/dist/src/core/furnace-validate-accessibility.d.ts +22 -0
  246. package/dist/src/core/furnace-validate-accessibility.js +310 -1
  247. package/dist/src/core/furnace-validate-compatibility.js +141 -1
  248. package/dist/src/core/furnace-validate-helpers.d.ts +5 -116
  249. package/dist/src/core/furnace-validate-helpers.js +0 -491
  250. package/dist/src/core/furnace-validate-registration.d.ts +7 -0
  251. package/dist/src/core/furnace-validate-registration.js +115 -41
  252. package/dist/src/core/furnace-validate.d.ts +16 -0
  253. package/dist/src/core/furnace-validate.js +188 -145
  254. package/dist/src/core/furnace-version-drift.d.ts +10 -11
  255. package/dist/src/core/furnace-version-drift.js +10 -11
  256. package/dist/src/core/git-base.d.ts +21 -9
  257. package/dist/src/core/git-base.js +24 -9
  258. package/dist/src/core/git-diff.d.ts +20 -9
  259. package/dist/src/core/git-diff.js +148 -63
  260. package/dist/src/core/git-file-ops.d.ts +19 -19
  261. package/dist/src/core/git-file-ops.js +19 -19
  262. package/dist/src/core/git-readonly-index.d.ts +53 -19
  263. package/dist/src/core/git-readonly-index.js +75 -31
  264. package/dist/src/core/git-status.d.ts +5 -6
  265. package/dist/src/core/git-status.js +5 -6
  266. package/dist/src/core/git.d.ts +9 -10
  267. package/dist/src/core/git.js +57 -71
  268. package/dist/src/core/license-headers.d.ts +17 -23
  269. package/dist/src/core/license-headers.js +17 -23
  270. package/dist/src/core/mach-build-artifacts.d.ts +9 -9
  271. package/dist/src/core/mach-build-artifacts.js +57 -19
  272. package/dist/src/core/mach-error-hints.js +42 -29
  273. package/dist/src/core/mach-known-noise-filter.d.ts +15 -16
  274. package/dist/src/core/mach-known-noise-filter.js +18 -20
  275. package/dist/src/core/mach-mozconfig.d.ts +14 -0
  276. package/dist/src/core/mach-mozconfig.js +30 -0
  277. package/dist/src/core/mach-resource-shim.d.ts +43 -58
  278. package/dist/src/core/mach-resource-shim.js +50 -67
  279. package/dist/src/core/mach.d.ts +37 -41
  280. package/dist/src/core/mach.js +50 -51
  281. package/dist/src/core/marionette-port.d.ts +36 -1
  282. package/dist/src/core/marionette-port.js +96 -31
  283. package/dist/src/core/marionette-preflight.d.ts +8 -12
  284. package/dist/src/core/marionette-preflight.js +86 -52
  285. package/dist/src/core/mochitest-server-port.d.ts +42 -0
  286. package/dist/src/core/mochitest-server-port.js +119 -0
  287. package/dist/src/core/module-resolution-preflight.d.ts +9 -11
  288. package/dist/src/core/module-resolution-preflight.js +9 -11
  289. package/dist/src/core/moz-manifest-helpers.d.ts +79 -0
  290. package/dist/src/core/moz-manifest-helpers.js +163 -0
  291. package/dist/src/core/{manifest-register.d.ts → moz-manifest-register.d.ts} +1 -1
  292. package/dist/src/core/{manifest-register.js → moz-manifest-register.js} +13 -28
  293. package/dist/src/core/{manifest-rules.d.ts → moz-manifest-rules.d.ts} +10 -1
  294. package/dist/src/core/{manifest-rules.js → moz-manifest-rules.js} +31 -24
  295. package/dist/src/core/{manifest-tokenizers.d.ts → moz-manifest-tokenizers.d.ts} +3 -5
  296. package/dist/src/core/{manifest-tokenizers.js → moz-manifest-tokenizers.js} +9 -12
  297. package/dist/src/core/ownership-table.d.ts +14 -16
  298. package/dist/src/core/ownership-table.js +14 -16
  299. package/dist/src/core/parser-fallback.d.ts +15 -1
  300. package/dist/src/core/parser-fallback.js +22 -3
  301. package/dist/src/core/patch-apply-fuzz.d.ts +10 -12
  302. package/dist/src/core/patch-apply-fuzz.js +15 -18
  303. package/dist/src/core/patch-apply.d.ts +13 -34
  304. package/dist/src/core/patch-apply.js +16 -76
  305. package/dist/src/core/patch-artifact-normalize.d.ts +13 -15
  306. package/dist/src/core/patch-artifact-normalize.js +13 -15
  307. package/dist/src/core/patch-export-metadata.d.ts +12 -2
  308. package/dist/src/core/patch-export-metadata.js +13 -4
  309. package/dist/src/core/patch-export-update.d.ts +13 -1
  310. package/dist/src/core/patch-export-update.js +25 -8
  311. package/dist/src/core/patch-export.d.ts +15 -8
  312. package/dist/src/core/patch-export.js +10 -11
  313. package/dist/src/core/patch-files.d.ts +5 -6
  314. package/dist/src/core/patch-files.js +5 -6
  315. package/dist/src/core/patch-identifier-suggest.d.ts +7 -12
  316. package/dist/src/core/patch-identifier-suggest.js +14 -19
  317. package/dist/src/core/patch-lint-binary.d.ts +51 -0
  318. package/dist/src/core/patch-lint-binary.js +39 -0
  319. package/dist/src/core/{lint-cache.d.ts → patch-lint-cache.d.ts} +5 -5
  320. package/dist/src/core/{lint-cache.js → patch-lint-cache.js} +21 -23
  321. package/dist/src/core/patch-lint-checkjs.d.ts +16 -16
  322. package/dist/src/core/patch-lint-checkjs.js +41 -20
  323. package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +6 -9
  324. package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -14
  325. package/dist/src/core/patch-lint-creators.d.ts +8 -8
  326. package/dist/src/core/patch-lint-creators.js +8 -8
  327. package/dist/src/core/patch-lint-cross.d.ts +17 -20
  328. package/dist/src/core/patch-lint-cross.js +16 -16
  329. package/dist/src/core/patch-lint-css.d.ts +3 -5
  330. package/dist/src/core/patch-lint-css.js +17 -22
  331. package/dist/src/core/patch-lint-diff-tag.d.ts +14 -16
  332. package/dist/src/core/patch-lint-diff-tag.js +14 -16
  333. package/dist/src/core/patch-lint-jsdoc.d.ts +7 -8
  334. package/dist/src/core/patch-lint-jsdoc.js +26 -19
  335. package/dist/src/core/patch-lint-mozbuild.js +20 -20
  336. package/dist/src/core/patch-lint-observer.d.ts +7 -7
  337. package/dist/src/core/patch-lint-observer.js +7 -7
  338. package/dist/src/core/patch-lint.d.ts +38 -29
  339. package/dist/src/core/patch-lint.js +89 -121
  340. package/dist/src/core/patch-lock.d.ts +1 -1
  341. package/dist/src/core/patch-lock.js +45 -9
  342. package/dist/src/core/patch-manifest-consistency.d.ts +57 -6
  343. package/dist/src/core/patch-manifest-consistency.js +111 -40
  344. package/dist/src/core/patch-manifest-files-affected.d.ts +43 -0
  345. package/dist/src/core/patch-manifest-files-affected.js +77 -0
  346. package/dist/src/core/patch-manifest-io.js +14 -18
  347. package/dist/src/core/patch-manifest-resolve.d.ts +9 -12
  348. package/dist/src/core/patch-manifest-resolve.js +9 -12
  349. package/dist/src/core/patch-manifest-validate.d.ts +6 -1
  350. package/dist/src/core/patch-manifest-validate.js +25 -13
  351. package/dist/src/core/patch-manifest.d.ts +2 -1
  352. package/dist/src/core/patch-manifest.js +2 -1
  353. package/dist/src/core/patch-parse.d.ts +24 -13
  354. package/dist/src/core/patch-parse.js +19 -14
  355. package/dist/src/core/patch-policy.d.ts +2 -2
  356. package/dist/src/core/patch-policy.js +2 -2
  357. package/dist/src/core/patch-registration-refs.d.ts +7 -8
  358. package/dist/src/core/patch-registration-refs.js +9 -9
  359. package/dist/src/core/process-cpu-time.d.ts +12 -0
  360. package/dist/src/core/process-cpu-time.js +52 -0
  361. package/dist/src/core/rebase-session.d.ts +38 -26
  362. package/dist/src/core/rebase-session.js +55 -28
  363. package/dist/src/core/register-browser-content.js +9 -74
  364. package/dist/src/core/{register-test-manifest.js → register-browser-test.js} +7 -42
  365. package/dist/src/core/register-module.js +10 -43
  366. package/dist/src/core/register-scaffold.d.ts +8 -8
  367. package/dist/src/core/register-scaffold.js +10 -10
  368. package/dist/src/core/register-shared-css.d.ts +9 -12
  369. package/dist/src/core/register-shared-css.js +17 -87
  370. package/dist/src/core/register-xpcshell-test.d.ts +6 -7
  371. package/dist/src/core/register-xpcshell-test.js +7 -8
  372. package/dist/src/core/shared-ftl.js +12 -4
  373. package/dist/src/core/state-file.d.ts +45 -0
  374. package/dist/src/core/state-file.js +34 -0
  375. package/dist/src/core/status-binary.d.ts +18 -11
  376. package/dist/src/core/status-binary.js +19 -12
  377. package/dist/src/core/status-classify.d.ts +30 -36
  378. package/dist/src/core/status-classify.js +21 -26
  379. package/dist/src/core/test-changed-prefs.d.ts +30 -0
  380. package/dist/src/core/test-changed-prefs.js +78 -0
  381. package/dist/src/core/test-harness-crash.d.ts +25 -63
  382. package/dist/src/core/test-harness-crash.js +121 -142
  383. package/dist/src/core/test-harness-signature.d.ts +18 -0
  384. package/dist/src/core/test-harness-signature.js +13 -0
  385. package/dist/src/core/test-path-scope.d.ts +12 -15
  386. package/dist/src/core/test-path-scope.js +15 -18
  387. package/dist/src/core/test-stale-check.d.ts +17 -17
  388. package/dist/src/core/test-stale-check.js +50 -43
  389. package/dist/src/core/test-stall-triage.d.ts +51 -0
  390. package/dist/src/core/test-stall-triage.js +126 -0
  391. package/dist/src/core/token-category.js +66 -14
  392. package/dist/src/core/token-coverage.js +9 -9
  393. package/dist/src/core/token-dark-mode.d.ts +9 -11
  394. package/dist/src/core/token-dark-mode.js +29 -13
  395. package/dist/src/core/token-docs.d.ts +2 -0
  396. package/dist/src/core/token-docs.js +3 -1
  397. package/dist/src/core/token-manager.d.ts +10 -2
  398. package/dist/src/core/token-manager.js +17 -8
  399. package/dist/src/core/token-scaffold.d.ts +7 -7
  400. package/dist/src/core/token-scaffold.js +7 -7
  401. package/dist/src/core/token-variant.d.ts +4 -4
  402. package/dist/src/core/token-variant.js +28 -6
  403. package/dist/src/core/toolchain-preflight.d.ts +20 -21
  404. package/dist/src/core/toolchain-preflight.js +28 -31
  405. package/dist/src/core/tree-guard.js +12 -2
  406. package/dist/src/core/tree-store.d.ts +41 -27
  407. package/dist/src/core/tree-store.js +68 -43
  408. package/dist/src/core/typecheck-shim.d.ts +23 -24
  409. package/dist/src/core/typecheck-shim.js +23 -24
  410. package/dist/src/core/typecheck.js +15 -9
  411. package/dist/src/core/wire-destroy.d.ts +3 -3
  412. package/dist/src/core/wire-destroy.js +7 -15
  413. package/dist/src/core/wire-dom-fragment.d.ts +9 -17
  414. package/dist/src/core/wire-dom-fragment.js +11 -44
  415. package/dist/src/core/wire-init.d.ts +2 -3
  416. package/dist/src/core/wire-init.js +8 -19
  417. package/dist/src/core/wire-subscript.d.ts +2 -3
  418. package/dist/src/core/wire-subscript.js +4 -13
  419. package/dist/src/core/wire-utils.d.ts +7 -8
  420. package/dist/src/core/wire-utils.js +7 -8
  421. package/dist/src/core/xpcshell-appdir.d.ts +38 -45
  422. package/dist/src/core/xpcshell-appdir.js +38 -45
  423. package/dist/src/errors/base.d.ts +37 -16
  424. package/dist/src/errors/base.js +37 -16
  425. package/dist/src/errors/build.d.ts +13 -1
  426. package/dist/src/errors/build.js +14 -2
  427. package/dist/src/errors/codes.d.ts +16 -0
  428. package/dist/src/errors/codes.js +16 -0
  429. package/dist/src/errors/furnace.d.ts +4 -4
  430. package/dist/src/errors/git.d.ts +6 -10
  431. package/dist/src/errors/git.js +6 -10
  432. package/dist/src/errors/patch.d.ts +7 -7
  433. package/dist/src/errors/patch.js +7 -7
  434. package/dist/src/errors/rebase.d.ts +4 -4
  435. package/dist/src/errors/rebase.js +4 -4
  436. package/dist/src/index.d.ts +7 -1
  437. package/dist/src/index.js +5 -0
  438. package/dist/src/types/commands/index.d.ts +2 -2
  439. package/dist/src/types/commands/options.d.ts +111 -70
  440. package/dist/src/types/commands/patches.d.ts +24 -34
  441. package/dist/src/types/commands/project.d.ts +5 -34
  442. package/dist/src/types/config.d.ts +25 -23
  443. package/dist/src/types/config.js +6 -1
  444. package/dist/src/types/furnace.d.ts +37 -13
  445. package/dist/src/types/furnace.js +19 -1
  446. package/dist/src/types/index.d.ts +3 -3
  447. package/dist/src/utils/build-info.d.ts +7 -8
  448. package/dist/src/utils/build-info.js +12 -11
  449. package/dist/src/utils/errors.d.ts +6 -8
  450. package/dist/src/utils/errors.js +6 -8
  451. package/dist/src/utils/logger.d.ts +27 -10
  452. package/dist/src/utils/logger.js +28 -16
  453. package/dist/src/utils/machine-output.d.ts +12 -0
  454. package/dist/src/utils/machine-output.js +33 -0
  455. package/dist/src/utils/options.d.ts +31 -14
  456. package/dist/src/utils/options.js +86 -30
  457. package/dist/src/utils/paths.d.ts +10 -8
  458. package/dist/src/utils/paths.js +10 -8
  459. package/dist/src/utils/platform.d.ts +0 -25
  460. package/dist/src/utils/platform.js +1 -42
  461. package/dist/src/utils/process-group.d.ts +9 -4
  462. package/dist/src/utils/process-group.js +19 -5
  463. package/dist/src/utils/process.d.ts +42 -7
  464. package/dist/src/utils/process.js +44 -17
  465. package/dist/src/utils/ps-duration.d.ts +31 -0
  466. package/dist/src/utils/ps-duration.js +70 -0
  467. package/dist/src/utils/regex.d.ts +9 -10
  468. package/dist/src/utils/regex.js +9 -10
  469. package/dist/src/utils/validation.d.ts +58 -28
  470. package/dist/src/utils/validation.js +60 -33
  471. package/package.json +3 -3
  472. package/dist/src/commands/doctor/post-rebase-audit.d.ts +0 -2
  473. package/dist/src/commands/doctor-furnace-manifest-sync.d.ts +0 -18
  474. package/dist/src/core/manifest-helpers.d.ts +0 -38
  475. package/dist/src/core/manifest-helpers.js +0 -120
  476. /package/dist/src/core/{lint-projection.d.ts → patch-lint-projection.d.ts} +0 -0
  477. /package/dist/src/core/{lint-projection.js → patch-lint-projection.js} +0 -0
  478. /package/dist/src/core/{register-test-manifest.d.ts → register-browser-test.d.ts} +0 -0
@@ -99,23 +99,25 @@ export function generateChromeDocXhtml(name, withTitlebar, license) {
99
99
  `;
100
100
  }
101
101
  /**
102
- * browser.xhtml-like scaffold for the document that ships as the fork's
103
- * MAIN BROWSER WINDOW (0.34.0 field report): the generic dialog-shaped
104
- * `<window>` scaffold was wrong for the `tokenHostDocuments[0]` /
105
- * BROWSER_CHROME_URL target — platform C++ reads the root element BEFORE
106
- * any script runs, and expects the `browser.xhtml` shape:
102
+ * browser.xhtml-like scaffold for the document that ships as the fork's MAIN
103
+ * BROWSER WINDOW.
104
+ *
105
+ * The generic dialog-shaped `<window>` scaffold is wrong for the
106
+ * `tokenHostDocuments[0]` / BROWSER_CHROME_URL target: platform C++ reads
107
+ * the root element BEFORE any script runs, and expects the `browser.xhtml`
108
+ * shape:
107
109
  *
108
110
  * - `<html id="main-window">` root (not `<window id="<name>-window">`) —
109
111
  * upstream code from nsXULWindow sizing to session restore looks up
110
112
  * `main-window` by id;
111
113
  * - `windowtype="navigator:browser"`, `chromehidden=""` and the geometry
112
114
  * `persist` allowlist declared as ROOT ATTRIBUTES so the platform's
113
- * pre-script pass (window tracking, XULStore geometry, chrome flags)
114
- * sees them;
115
+ * pre-script pass (window tracking, XULStore geometry, chrome flags) sees
116
+ * them;
115
117
  * - the same head/bootstrap wiring (customElements.js, per-doc subscript,
116
118
  * CSS + Fluent links) and `data-furnace-chrome-doc` sentinel as the
117
- * generic scaffold, so jar.mn registration and the platform-module
118
- * guard pattern are unchanged.
119
+ * generic scaffold, so jar.mn registration and the platform-module guard
120
+ * pattern are unchanged.
119
121
  */
120
122
  export function generateBrowserWindowXhtml(name, license) {
121
123
  return `<?xml version="1.0"?>
@@ -278,14 +280,13 @@ export function jarMnEntriesForChromeDoc(name) {
278
280
  /**
279
281
  * jar.inc.mn entry that registers the scoped CSS under `content/browser/`.
280
282
  *
281
- * The source path is `../shared/<name>-chrome.css` because `jar.inc.mn`
282
- * is included from each theme-specific manifest (`browser/themes/osx/jar.mn`,
283
- * `browser/themes/linux/jar.mn`, `browser/themes/windows/jar.mn`), and every
284
- * existing entry in those manifests resolves paths relative to the including
285
- * manifest's directory. A bare `(shared/…)` path produced
286
- * `obj-.../browser/themes/osx/shared/<name>-chrome.css` which does not exist;
287
- * `(../shared/…)` matches the upstream pattern and resolves under
288
- * `browser/themes/shared/`.
283
+ * The source path is `../shared/<name>-chrome.css` because `jar.inc.mn` is
284
+ * included from each theme-specific manifest (`browser/themes/osx/jar.mn`,
285
+ * `.../linux/`, `.../windows/`), and every existing entry in those manifests
286
+ * resolves paths relative to the INCLUDING manifest's directory. A bare
287
+ * `(shared/…)` path resolves to
288
+ * `obj-.../browser/themes/osx/shared/<name>-chrome.css`, which does not
289
+ * exist.
289
290
  */
290
291
  export function jarIncMnEntryForChromeDoc(name) {
291
292
  return ` content/browser/${name}-chrome.css (../shared/${name}-chrome.css)`;
@@ -293,12 +294,11 @@ export function jarIncMnEntryForChromeDoc(name) {
293
294
  /**
294
295
  * locales/jar.mn entry that registers the `.ftl` under the browser locale
295
296
  * bundle. The source path is resolved by mach-locale-jar relative to the
296
- * per-locale root (e.g. `engine/browser/locales/en-US/`), and the FTL
297
- * file is scaffolded at `browser/${name}.ftl` under that root — the `%`
298
- * prefix means "per-locale content" and the `browser/` subdirectory
299
- * matches the subdir the scaffolder writes into. Before this fix the
300
- * entry emitted `(%${name}.ftl)`, which pointed at `en-US/${name}.ftl`
301
- * and broke the first post-scaffold `fireforge build` with
297
+ * per-locale root (e.g. `engine/browser/locales/en-US/`), and the FTL file
298
+ * is scaffolded at `browser/${name}.ftl` under that root — the `%` prefix
299
+ * means "per-locale content" and the `browser/` subdirectory matches where
300
+ * the scaffolder writes. A bare `(%${name}.ftl)` points at
301
+ * `en-US/${name}.ftl` and breaks the first post-scaffold build with
302
302
  * "jar.mn: Cannot find ${name}.ftl".
303
303
  */
304
304
  export function localeJarMnEntryForChromeDoc(name) {
@@ -3,30 +3,29 @@
3
3
  * Packaging-verification test templates for
4
4
  * `fireforge furnace chrome-doc create --with-tests`.
5
5
  *
6
- * Motivation: an operator who scaffolds a top-level chrome document wants
7
- * to know "did the file actually land in the packaged bundle?" before
8
- * relying on it at runtime. Both natural test harnesses have gaps for
9
- * this question:
6
+ * An operator who scaffolds a top-level chrome document wants to know "did
7
+ * the file actually land in the packaged bundle?" before relying on it at
8
+ * runtime. Both natural test harnesses have gaps for that question:
10
9
  *
11
10
  * - xpcshell's `chrome://browser/*` URI registration lags what the real
12
11
  * browser loads even with `firefox-appdir = "browser"` set, so
13
- * `NetUtil.asyncFetch("chrome://browser/content/<name>.xhtml")` can
14
- * fail with `NS_ERROR_FILE_NOT_FOUND` against a file that IS
15
- * correctly packaged (the motivating case).
12
+ * `NetUtil.asyncFetch("chrome://browser/content/<name>.xhtml")` can fail
13
+ * with `NS_ERROR_FILE_NOT_FOUND` against a file that IS correctly
14
+ * packaged.
16
15
  * - Browser-chrome mochitests require a `tabbrowser`, which a
17
16
  * fork-authored chrome doc that replaces `browser.xhtml` deliberately
18
- * does not carry (the URILoadingHelper crash path).
17
+ * does not carry.
19
18
  *
20
19
  * This scaffold threads the needle by probing the filesystem directly:
21
- * `Services.dirsvc.get("XCurProcD", Ci.nsIFile)` returns the current
22
- * process directory (the browser app dir when `firefox-appdir = "browser"`),
23
- * and the packaged chrome layout for a jar.mn entry
24
- * `content/browser/<name>.xhtml` is stable across platforms at
25
- * `<AppDir>/chrome/browser/content/browser/<name>.xhtml` on an unpacked
26
- * tree (the default for `mach build` without `MOZ_CHROME_MULTILOCALE`
27
- * / omnijar). A tree that packs omni.ja would need a different probe;
28
- * the scaffold notes that out-of-scope case explicitly rather than
29
- * silently producing a test that fails on packed builds.
20
+ * `Services.dirsvc.get("XCurProcD", Ci.nsIFile)` returns the current process
21
+ * directory (the browser app dir when `firefox-appdir = "browser"`), and the
22
+ * packaged chrome layout for a jar.mn entry `content/browser/<name>.xhtml`
23
+ * is stable across platforms at
24
+ * `<AppDir>/chrome/browser/content/browser/<name>.xhtml` on an unpacked tree
25
+ * (the default for `mach build` without `MOZ_CHROME_MULTILOCALE` / omnijar).
26
+ * A tree that packs omni.ja would need a different probe; the scaffold notes
27
+ * that out-of-scope case explicitly rather than silently producing a test
28
+ * that fails on packed builds.
30
29
  */
31
30
  /**
32
31
  * Returns the canonical xpcshell test basename for a chrome doc packaging
@@ -70,17 +69,16 @@ add_task(async function test_${taskSuffix}_files_packaged() {
70
69
  const appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
71
70
 
72
71
  // Probes a pair of candidate layouts for the same packaged file:
73
- // 1) \`<AppDir>/chrome/browser/…\` — the unpacked layout when
74
- // XCurProcD honours \`firefox-appdir = "browser"\` and resolves
75
- // into \`dist/bin/browser/\`.
76
- // 2) \`<AppDir>/browser/chrome/browser/…\` — the macOS .app bundle
77
- // layout and some ESR configurations, where XCurProcD sits one
78
- // level above \`browser/\` even when the appdir directive is set.
72
+ // 1) \`<AppDir>/chrome/browser/…\` — the unpacked layout when XCurProcD
73
+ // honours \`firefox-appdir = "browser"\` and resolves into
74
+ // \`dist/bin/browser/\`.
75
+ // 2) \`<AppDir>/browser/chrome/browser/…\` — the macOS .app bundle layout
76
+ // and some ESR configurations, where XCurProcD sits one level above
77
+ // \`browser/\` even when the appdir directive is set.
79
78
  // If either path exists the file is packaged; the assertion only fails
80
79
  // when BOTH layouts miss, which is the actual stale-build / missing
81
- // jar.mn entry case. Before this dual probe, the eval on macOS
82
- // consistently failed against layout (2) even though the file was
83
- // packaged correctly.
80
+ // jar.mn entry case. A single-layout probe fails on macOS against layout
81
+ // (2) even though the file is packaged correctly.
84
82
  function probeEither(primary, fallback, description) {
85
83
  const primaryFile = appDir.clone();
86
84
  for (const segment of primary) {
@@ -121,9 +119,8 @@ add_task(async function test_${taskSuffix}_files_packaged() {
121
119
  // \`content/browser/<name>-chrome.css\` (see \`chromeDocJarIncMnCssEntry\`
122
120
  // in \`src/commands/furnace/chrome-doc-templates.ts\`), so the packaged
123
121
  // file lands under \`chrome/browser/content/browser/\`, not under
124
- // \`skin/classic/browser/\`. The 2026-04-21 eval's first
125
- // \`fireforge test --build\` against a scaffolded chrome-doc reported
126
- // a false failure because the probe was looking at the skin layout.
122
+ // \`skin/classic/browser/\`. Probing the skin layout reports a false
123
+ // failure on the first \`fireforge test --build\` after a scaffold.
127
124
  probeEither(
128
125
  ["chrome", "browser", "content", "browser", "${name}-chrome.css"],
129
126
  ["browser", "chrome", "browser", "content", "browser", "${name}-chrome.css"],
@@ -2,18 +2,18 @@
2
2
  * `fireforge furnace chrome-doc create <name>` — scaffolds a top-level
3
3
  * chrome document (xhtml + js + css + ftl + jar.mn registrations).
4
4
  *
5
- * Motivation: `furnace create` covers custom elements under
6
- * `toolkit/content/widgets/`, but top-level chrome documents (the
7
- * `mybrowser.xhtml`-class entry points a fork adds alongside or instead
8
- * of `browser.xhtml`) are today hand-authored with error-prone jar.mn +
9
- * jar.inc.mn + locales/jar.mn glue. The `*` preprocessor flag, the
10
- * macOS titlebar-button carve-out, the startup-topic observer, and the
11
- * Fluent linkage each have silent-break failure modes.
5
+ * `furnace create` covers custom elements under `toolkit/content/widgets/`,
6
+ * but top-level chrome documents — the `mybrowser.xhtml`-class entry points
7
+ * a fork adds alongside or instead of `browser.xhtml` — are otherwise
8
+ * hand-authored with error-prone jar.mn + jar.inc.mn + locales/jar.mn glue.
9
+ * The `*` preprocessor flag, the macOS titlebar-button carve-out, the
10
+ * startup-topic observer, and the Fluent linkage each have silent-break
11
+ * failure modes.
12
12
  *
13
- * This command writes the four source files and appends three jar.mn
14
- * entries under a rollback journal identical in shape to `furnace create`.
15
- * A SIGINT mid-scaffold restores every touched file; a successful run
16
- * leaves the tree ready for `fireforge build`.
13
+ * This command writes the four source files and appends three jar.mn entries
14
+ * under a rollback journal identical in shape to `furnace create`. A SIGINT
15
+ * mid-scaffold restores every touched file; a successful run leaves the tree
16
+ * ready for `fireforge build`.
17
17
  */
18
18
  /** Options for `furnace chrome-doc create`. */
19
19
  export interface FurnaceChromeDocCreateOptions {
@@ -27,12 +27,11 @@ export interface FurnaceChromeDocCreateOptions {
27
27
  /**
28
28
  * Scaffold an xpcshell packaging-verification test alongside the chrome
29
29
  * document. The generated test probes `XCurProcD/chrome/browser/...` on
30
- * disk rather than going through `chrome://` URI resolution — that
31
- * bypasses xpcshell's limited browser-chrome manifest set (the
32
- * motivating failure mode where `NetUtil.asyncFetch` returns
33
- * `NS_ERROR_FILE_NOT_FOUND` against a file that IS packaged).
34
- * Registration in `XPCSHELL_TESTS_MANIFESTS` is left to the operator
35
- * because the owning moz.build depends on the fork's layout.
30
+ * disk rather than going through `chrome://` URI resolution, which
31
+ * bypasses xpcshell's limited browser-chrome manifest set — where
32
+ * `NetUtil.asyncFetch` returns `NS_ERROR_FILE_NOT_FOUND` against a file
33
+ * that IS packaged. Registration in `XPCSHELL_TESTS_MANIFESTS` is left to
34
+ * the operator because the owning moz.build depends on the fork's layout.
36
35
  */
37
36
  withTests?: boolean;
38
37
  /** Print the scaffold plan without writing files. */
@@ -3,29 +3,29 @@
3
3
  * `fireforge furnace chrome-doc create <name>` — scaffolds a top-level
4
4
  * chrome document (xhtml + js + css + ftl + jar.mn registrations).
5
5
  *
6
- * Motivation: `furnace create` covers custom elements under
7
- * `toolkit/content/widgets/`, but top-level chrome documents (the
8
- * `mybrowser.xhtml`-class entry points a fork adds alongside or instead
9
- * of `browser.xhtml`) are today hand-authored with error-prone jar.mn +
10
- * jar.inc.mn + locales/jar.mn glue. The `*` preprocessor flag, the
11
- * macOS titlebar-button carve-out, the startup-topic observer, and the
12
- * Fluent linkage each have silent-break failure modes.
6
+ * `furnace create` covers custom elements under `toolkit/content/widgets/`,
7
+ * but top-level chrome documents — the `mybrowser.xhtml`-class entry points
8
+ * a fork adds alongside or instead of `browser.xhtml` — are otherwise
9
+ * hand-authored with error-prone jar.mn + jar.inc.mn + locales/jar.mn glue.
10
+ * The `*` preprocessor flag, the macOS titlebar-button carve-out, the
11
+ * startup-topic observer, and the Fluent linkage each have silent-break
12
+ * failure modes.
13
13
  *
14
- * This command writes the four source files and appends three jar.mn
15
- * entries under a rollback journal identical in shape to `furnace create`.
16
- * A SIGINT mid-scaffold restores every touched file; a successful run
17
- * leaves the tree ready for `fireforge build`.
14
+ * This command writes the four source files and appends three jar.mn entries
15
+ * under a rollback journal identical in shape to `furnace create`. A SIGINT
16
+ * mid-scaffold restores every touched file; a successful run leaves the tree
17
+ * ready for `fireforge build`.
18
18
  */
19
19
  import { join } from 'node:path';
20
20
  import { loadConfig } from '../../core/config.js';
21
21
  import { furnaceConfigExists, loadFurnaceConfig } from '../../core/furnace-config.js';
22
- import { recordFurnaceRollbackFailure, runFurnaceMutation, } from '../../core/furnace-operation.js';
23
- import { createRollbackJournal, recordCreatedDir, restoreRollbackJournalOrThrow, snapshotFile, } from '../../core/furnace-rollback.js';
22
+ import { completeJournalRollback, runFurnaceMutation, } from '../../core/furnace-operation.js';
23
+ import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
24
+ import { createRollbackJournal, recordCreatedDir, snapshotFile, } from '../../core/furnace-rollback.js';
24
25
  import { DEFAULT_LICENSE, getLicenseHeader } from '../../core/license-headers.js';
25
26
  import { InvalidArgumentError } from '../../errors/base.js';
26
27
  import { FurnaceError } from '../../errors/furnace.js';
27
- import { toError } from '../../utils/errors.js';
28
- import { pathExists, readText, writeText } from '../../utils/fs.js';
28
+ import { ensureDir, pathExists, readText, writeText } from '../../utils/fs.js';
29
29
  import { intro, note, outro, warn } from '../../utils/logger.js';
30
30
  import { generateBrowserWindowXhtml, generateChromeDocCss, generateChromeDocFtl, generateChromeDocJs, generateChromeDocXhtml, jarIncMnEntryForChromeDoc, jarMnEntriesForChromeDoc, localeJarMnEntryForChromeDoc, localesFtlWildcardCapturesScaffoldedName, } from './chrome-doc-templates.js';
31
31
  import { chromeDocPackagingTestFileName, generateChromeDocPackagingManifest, generateChromeDocPackagingTest, } from './chrome-doc-tests.js';
@@ -189,7 +189,6 @@ async function performChromeDocMutations(args) {
189
189
  for (const dir of [contentDir, sharedThemeDir, localeDir]) {
190
190
  if (!(await pathExists(dir))) {
191
191
  recordCreatedDir(journal, dir);
192
- const { ensureDir } = await import('../../utils/fs.js');
193
192
  await ensureDir(dir);
194
193
  }
195
194
  }
@@ -230,9 +229,9 @@ async function performChromeDocMutations(args) {
230
229
  // wildcard already pick up the scaffolded FTL automatically — appending
231
230
  // a per-file `locale/...` entry on top is at best dead weight and at
232
231
  // worst a build error when the fork has dropped the `% locale browser`
233
- // registration the per-file entry depends on. The wildcard predicate
234
- // is intentionally narrow: only `%browser/`-rooted globs that end in
235
- // `*.ftl` count as a capture.
232
+ // registration the per-file entry depends on. The wildcard predicate is
233
+ // intentionally narrow: only `%browser/`-rooted globs ending in `*.ftl`
234
+ // count as a capture.
236
235
  if (await pathExists(localeJarMnPath)) {
237
236
  const existingLocaleJar = await readText(localeJarMnPath);
238
237
  if (localesFtlWildcardCapturesScaffoldedName(existingLocaleJar)) {
@@ -256,7 +255,6 @@ async function performChromeDocMutations(args) {
256
255
  if (args.withTests) {
257
256
  const testParentDir = `${args.binaryName}-xpcshell`;
258
257
  const testDir = join(args.engineDir, 'browser/base/content/test', testParentDir, args.name);
259
- const { ensureDir } = await import('../../utils/fs.js');
260
258
  if (!(await pathExists(testDir))) {
261
259
  recordCreatedDir(journal, testDir);
262
260
  }
@@ -274,20 +272,12 @@ async function performChromeDocMutations(args) {
274
272
  }
275
273
  }
276
274
  catch (error) {
277
- // This body owns its rollback end to end, so tell the lifecycle wrapper
278
- // not to restore the same journal again on the way out.
279
- args.operationContext.markRolledBack();
280
- try {
281
- await restoreRollbackJournalOrThrow(journal, `Failed to scaffold chrome-doc "${args.name}"`);
282
- }
283
- catch (rollbackError) {
284
- // Matches the seven sibling mutation sites: when the rollback itself
285
- // fails the engine is in an unknown state, so leave a breadcrumb for
286
- // `doctor --repair-furnace` and let the rollback error win.
287
- await recordFurnaceRollbackFailure(args.projectRoot, 'chrome-doc-rollback', `chrome-doc "${args.name}": ${toError(rollbackError).message}`);
288
- throw rollbackError;
289
- }
290
- throw error;
275
+ return await completeJournalRollback(args.operationContext, journal, error, {
276
+ projectRoot: args.projectRoot,
277
+ operation: 'chrome-doc-rollback',
278
+ failureMessage: `Failed to scaffold chrome-doc "${args.name}"`,
279
+ subject: `chrome-doc "${args.name}"`,
280
+ });
291
281
  }
292
282
  return written;
293
283
  }
@@ -303,18 +293,18 @@ export async function furnaceChromeDocCreateCommand(projectRoot, name, options =
303
293
  const forgeConfig = await loadConfig(projectRoot);
304
294
  const license = forgeConfig.license ?? DEFAULT_LICENSE;
305
295
  const engineDir = join(projectRoot, 'engine');
306
- if (!(await pathExists(engineDir))) {
307
- throw new FurnaceError('Engine directory not found. Run "fireforge download" first to scaffold a chrome-doc.');
308
- }
296
+ await assertFurnaceEngineReady(projectRoot, {
297
+ engineMissingSuffix: ' to scaffold a chrome-doc.',
298
+ });
309
299
  const browserWindow = options.browserWindow ?? false;
310
300
  // The browser-window skeleton always carries its own titlebar markup and
311
301
  // chrome attributes; --no-titlebar only applies to the generic scaffold.
312
302
  const withTitlebar = browserWindow ? true : (options.titlebar ?? true);
313
303
  const withTests = options.withTests ?? false;
314
- // Hint: when the scaffolded document is the configured token-host
315
- // document (the fork's main browser window), the generic dialog-shaped
316
- // scaffold is almost certainly wrong (0.34.0 field report: correct
317
- // jar.mn registrations, wrong document body).
304
+ // Hint: when the scaffolded document is the configured token-host document
305
+ // (the fork's main browser window), the generic dialog-shaped scaffold is
306
+ // almost certainly wrong — correct jar.mn registrations, wrong document
307
+ // body.
318
308
  if (!browserWindow && (await furnaceConfigExists(projectRoot))) {
319
309
  try {
320
310
  const furnaceConfig = await loadFurnaceConfig(projectRoot);
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Browser-chrome test scaffolding for `furnace create --with-tests`,
3
- * including the 0.34.0 `--test-dir` redirect and collision safety
4
- * (existing manifests are appended to; head.js and test implementations
5
- * are never overwritten). Split out of `create.ts` to keep that command
6
- * file within the per-file line budget.
3
+ * including the `--test-dir` redirect and collision safety (existing
4
+ * manifests are appended to; head.js and test implementations are never
5
+ * overwritten). Split out of `create.ts` to keep that command file within
6
+ * the per-file line budget.
7
7
  */
8
8
  import { type RollbackJournal } from '../../core/furnace-rollback.js';
9
9
  import type { ProjectLicense } from '../../types/config.js';
@@ -1,15 +1,15 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
3
  * Browser-chrome test scaffolding for `furnace create --with-tests`,
4
- * including the 0.34.0 `--test-dir` redirect and collision safety
5
- * (existing manifests are appended to; head.js and test implementations
6
- * are never overwritten). Split out of `create.ts` to keep that command
7
- * file within the per-file line budget.
4
+ * including the `--test-dir` redirect and collision safety (existing
5
+ * manifests are appended to; head.js and test implementations are never
6
+ * overwritten). Split out of `create.ts` to keep that command file within
7
+ * the per-file line budget.
8
8
  */
9
9
  import { join } from 'node:path';
10
10
  import { recordCreatedDir, snapshotFile, } from '../../core/furnace-rollback.js';
11
11
  import { getLicenseHeader } from '../../core/license-headers.js';
12
- import { registerTestManifest } from '../../core/manifest-register.js';
12
+ import { registerTestManifest } from '../../core/moz-manifest-register.js';
13
13
  import { InvalidArgumentError } from '../../errors/base.js';
14
14
  import { toError } from '../../utils/errors.js';
15
15
  import { ensureDir, pathExists, readText, writeText } from '../../utils/fs.js';
@@ -74,9 +74,9 @@ export async function scaffoldTestFiles(componentName, license, forgeConfig, pat
74
74
  : strippedName;
75
75
  const underscored = withoutBinaryPrefix.replace(/-/g, '_');
76
76
  const testFileName = `browser_${binaryName}_${underscored}.js`;
77
- // --test-dir redirects the scaffold (0.34.0 field report: the hardcoded
78
- // .../test/<binaryName>/ target collided with a test suite owned by a
79
- // different patch). The manifest-registration name is the path below
77
+ // --test-dir redirects the scaffold: the hardcoded
78
+ // `.../test/<binaryName>/` target can collide with a test suite owned by a
79
+ // different patch. The manifest-registration name is the path below
80
80
  // browser/base/content/test/ (nested manifests are supported).
81
81
  const testDirRel = testDirOverride ?? `${TEST_SCAFFOLD_ROOT}${binaryName}`;
82
82
  const testDirName = testDirRel.slice(TEST_SCAFFOLD_ROOT.length);
@@ -2,13 +2,12 @@
2
2
  * MochiKit (chrome://mochikit) test-harness scaffolder for
3
3
  * `fireforge furnace create --test-style=mochikit`.
4
4
  *
5
- * Motivation: browser-chrome mochitests require a `tabbrowser` to exist in
6
- * the top-level chrome document. Forks with a bespoke chrome document
7
- * (e.g. `mybrowser.xhtml`) that deliberately omits tabbrowser cannot run
8
- * browser-chrome tests today. MochiKit tests load the component module
9
- * directly via `chrome://global/` and assert against `customElements`, so
10
- * they work against any fork that registers the upstream toolkit test
11
- * manifest tree — including those without a tabbrowser.
5
+ * Browser-chrome mochitests require a `tabbrowser` in the top-level chrome
6
+ * document, so forks with a bespoke chrome document that deliberately omits
7
+ * one cannot run them. MochiKit tests load the component module directly via
8
+ * `chrome://global/` and assert against `customElements`, so they work
9
+ * against any fork that registers the upstream toolkit test manifest tree —
10
+ * including those without a tabbrowser.
12
11
  */
13
12
  import { type RollbackJournal } from '../../core/furnace-rollback.js';
14
13
  import type { ProjectLicense } from '../../types/config.js';
@@ -3,13 +3,12 @@
3
3
  * MochiKit (chrome://mochikit) test-harness scaffolder for
4
4
  * `fireforge furnace create --test-style=mochikit`.
5
5
  *
6
- * Motivation: browser-chrome mochitests require a `tabbrowser` to exist in
7
- * the top-level chrome document. Forks with a bespoke chrome document
8
- * (e.g. `mybrowser.xhtml`) that deliberately omits tabbrowser cannot run
9
- * browser-chrome tests today. MochiKit tests load the component module
10
- * directly via `chrome://global/` and assert against `customElements`, so
11
- * they work against any fork that registers the upstream toolkit test
12
- * manifest tree — including those without a tabbrowser.
6
+ * Browser-chrome mochitests require a `tabbrowser` in the top-level chrome
7
+ * document, so forks with a bespoke chrome document that deliberately omits
8
+ * one cannot run them. MochiKit tests load the component module directly via
9
+ * `chrome://global/` and assert against `customElements`, so they work
10
+ * against any fork that registers the upstream toolkit test manifest tree —
11
+ * including those without a tabbrowser.
13
12
  */
14
13
  import { join } from 'node:path';
15
14
  import { recordCreatedDir, snapshotFile, } from '../../core/furnace-rollback.js';
@@ -41,8 +40,8 @@ export async function scaffoldMochikitTestFiles(componentName, license, paths, j
41
40
  const testFileName = mochikitTestFileName(componentName);
42
41
  const testFilePath = join(testDir, testFileName);
43
42
  if (await pathExists(testFilePath)) {
44
- // Never clobber an existing test implementation (0.34.0 collision
45
- // safety, matching the browser-chrome and xpcshell scaffolds).
43
+ // Never clobber an existing test implementation, matching the
44
+ // browser-chrome and xpcshell scaffolds.
46
45
  warn(`toolkit/content/tests/widgets/${testFileName} already exists — keeping the existing file.`);
47
46
  }
48
47
  else {
@@ -4,20 +4,19 @@
4
4
  * budget.
5
5
  */
6
6
  /**
7
- * Asserts that the just-written furnace.json contains the expected
8
- * custom component entry. The eval run's finding #9 observed a
9
- * scenario where `furnace create --allow-prefix-mismatch` reported
10
- * success and wrote the component files, but the subsequent
11
- * `furnace status` found `custom: {}` in furnace.json — an invariant
12
- * violation with no clear smoking gun in the code path. Local repros
13
- * do not trigger it, so the defensive readback is the safest recovery
14
- * contract we can offer: if the new entry is not visible on the next
15
- * load, throw a `FurnaceError` so the rollback journal restores the
16
- * pre-command state and the operator sees the failure instead of a
17
- * phantom success.
7
+ * Asserts that the just-written furnace.json contains the expected custom
8
+ * component entry.
9
+ *
10
+ * A `furnace create` that reports success and writes the component files
11
+ * while the next `furnace status` finds `custom: {}` is an invariant
12
+ * violation with no obvious smoking gun in the code path. This defensive
13
+ * readback is the recovery contract: if the new entry is not visible on the
14
+ * next load, throw a `FurnaceError` so the rollback journal restores the
15
+ * pre-command state and the operator sees the failure instead of a phantom
16
+ * success.
18
17
  *
19
18
  * @param projectRoot - Root of the FireForge project
20
- * @param componentName - Custom-element tag name that must be present
21
- * in `config.custom` after the write. Throws when absent.
19
+ * @param componentName - Custom-element tag name that must be present in
20
+ * `config.custom` after the write. Throws when absent.
22
21
  */
23
22
  export declare function assertCustomEntryPersisted(projectRoot: string, componentName: string): Promise<void>;
@@ -7,21 +7,20 @@
7
7
  import { loadFurnaceConfig } from '../../core/furnace-config.js';
8
8
  import { FurnaceError } from '../../errors/furnace.js';
9
9
  /**
10
- * Asserts that the just-written furnace.json contains the expected
11
- * custom component entry. The eval run's finding #9 observed a
12
- * scenario where `furnace create --allow-prefix-mismatch` reported
13
- * success and wrote the component files, but the subsequent
14
- * `furnace status` found `custom: {}` in furnace.json — an invariant
15
- * violation with no clear smoking gun in the code path. Local repros
16
- * do not trigger it, so the defensive readback is the safest recovery
17
- * contract we can offer: if the new entry is not visible on the next
18
- * load, throw a `FurnaceError` so the rollback journal restores the
19
- * pre-command state and the operator sees the failure instead of a
20
- * phantom success.
10
+ * Asserts that the just-written furnace.json contains the expected custom
11
+ * component entry.
12
+ *
13
+ * A `furnace create` that reports success and writes the component files
14
+ * while the next `furnace status` finds `custom: {}` is an invariant
15
+ * violation with no obvious smoking gun in the code path. This defensive
16
+ * readback is the recovery contract: if the new entry is not visible on the
17
+ * next load, throw a `FurnaceError` so the rollback journal restores the
18
+ * pre-command state and the operator sees the failure instead of a phantom
19
+ * success.
21
20
  *
22
21
  * @param projectRoot - Root of the FireForge project
23
- * @param componentName - Custom-element tag name that must be present
24
- * in `config.custom` after the write. Throws when absent.
22
+ * @param componentName - Custom-element tag name that must be present in
23
+ * `config.custom` after the write. Throws when absent.
25
24
  */
26
25
  export async function assertCustomEntryPersisted(projectRoot, componentName) {
27
26
  const persisted = await loadFurnaceConfig(projectRoot);
@@ -36,19 +36,18 @@ export declare function xpcshellTestFileName(name: string): string;
36
36
  * xpcshell cannot execute a component module that imports
37
37
  * `chrome://global/content/vendor/lit.all.mjs` — the Lit bundle touches
38
38
  * `window` at module-load time and the xpcshell harness has no `window`
39
- * global. Before 0.16.0 the scaffold called `ChromeUtils.importESModule`
40
- * on the component's MJS, which reliably failed with
41
- * `ReferenceError: window is not defined` for every Lit-based fork
42
- * component. FireForge's diagnostics then misrouted the failure to the
43
- * "stale build artifacts" branch, sending operators on a rebuild loop
44
- * that couldn't fix a runtime-environment incompatibility.
39
+ * global. A scaffold that calls `ChromeUtils.importESModule` on the
40
+ * component's MJS therefore fails with `ReferenceError: window is not
41
+ * defined` for every Lit-based fork component, and FireForge's diagnostics
42
+ * misroute that to the "stale build artifacts" branch, sending operators on
43
+ * a rebuild loop that cannot fix a runtime-environment incompatibility.
45
44
  *
46
- * The rewrite here mirrors the chrome-doc packaging test: XCurProcD is
45
+ * This template mirrors the chrome-doc packaging test instead: XCurProcD is
47
46
  * probed at a pair of candidate layouts (dist/bin/browser and the macOS
48
- * .app-bundle / ESR layout) to confirm the `.mjs` and `.css` files
49
- * landed where jar.mn promised. That's the assertion xpcshell CAN make.
50
- * Functional tests that need DOM/shadow-root/keyboard behaviour belong
51
- * in a browser-chrome mochitest — scaffolded via
47
+ * .app-bundle / ESR layout) to confirm the `.mjs` and `.css` files landed
48
+ * where jar.mn promised. That is the assertion xpcshell CAN make. Functional
49
+ * tests that need DOM/shadow-root/keyboard behaviour belong in a
50
+ * browser-chrome mochitest — scaffolded via
52
51
  * `fireforge furnace create --test-style browser-chrome`.
53
52
  */
54
53
  export declare function generateXpcshellTestContent(name: string, header: string): string;
@@ -67,26 +66,21 @@ export declare function mochikitTestFileName(name: string): string;
67
66
  * MochiKit tests load the component module directly via the global chrome
68
67
  * URI and assert that `customElements.get(<tag>)` returns a constructor.
69
68
  * They run on forks whose top-level chrome document lacks a `tabbrowser`
70
- * (the class of bug that forces `--xpcshell` for storage code) because
71
- * they do not traverse `URILoadingHelper.openLinkIn`.
69
+ * because they do not traverse `URILoadingHelper.openLinkIn`.
72
70
  *
73
- * The scaffold here is a smoke test — the component is defined and the
74
- * constructor is a function. Real UI assertions (render output, l10n
75
- * wiring, keyboard interactions) are intentionally left out because they
76
- * depend on the component's shape; operators can extend the test using
77
- * the same SimpleTest APIs upstream toolkit widgets (moz-button, etc.)
78
- * rely on.
71
+ * The scaffold is a smoke test — the component is defined and the
72
+ * constructor is a function. Real UI assertions (render output, l10n wiring,
73
+ * keyboard interactions) are left out because they depend on the
74
+ * component's shape; operators can extend the test using the same SimpleTest
75
+ * APIs upstream toolkit widgets rely on.
79
76
  *
80
77
  * The template deliberately omits `SimpleTest.waitForExplicitFinish()`.
81
- * `add_task` owns the test lifecycle: when every queued task resolves,
82
- * the task harness calls `SimpleTest.finish()` on its own. Combining
83
- * `waitForExplicitFinish()` with `add_task` *and* no explicit
84
- * `SimpleTest.finish()` inside the task body makes the harness wait
85
- * forever, which the 2026-04-21 eval run tripped into as an indefinite
86
- * hang on a `fireforge test --headless` against a scaffolded widget
87
- * test. Leaving `waitForExplicitFinish()` out matches the convention
88
- * upstream toolkit widget tests use (see `test_moz-button.html` and
89
- * siblings under `toolkit/content/tests/widgets/`).
78
+ * `add_task` owns the test lifecycle: when every queued task resolves, the
79
+ * task harness calls `SimpleTest.finish()` itself. Combining
80
+ * `waitForExplicitFinish()` with `add_task` and no explicit
81
+ * `SimpleTest.finish()` in the task body makes the harness wait forever —
82
+ * an indefinite hang on `fireforge test --headless`. Omitting it matches the
83
+ * convention upstream toolkit widget tests use.
90
84
  */
91
85
  export declare function generateMochikitTestContent(name: string): string;
92
86
  /**