@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
@@ -13,6 +13,7 @@ import { FurnaceError } from '../../errors/furnace.js';
13
13
  import { getNodeErrorCode, toError } from '../../utils/errors.js';
14
14
  import { ensureDir, pathExists, writeText } from '../../utils/fs.js';
15
15
  import { cancel, info, intro, isCancel, note, outro, success, warn } from '../../utils/logger.js';
16
+ import { normalizePathSlashes } from '../../utils/paths.js';
16
17
  /**
17
18
  * File extensions that are definitely FTL resources (not locale
18
19
  * directories). A value ending in one of these is almost certainly the
@@ -38,16 +39,16 @@ function hasFtlFileExtension(value) {
38
39
  /**
39
40
  * Validates an FTL base path before writing it to furnace.json.
40
41
  * Rejects:
41
- * - empty values and null bytes;
42
- * - absolute paths (POSIX or Windows-drive) that escape the engine;
43
- * - `..` segments that escape the engine;
42
+ * - empty values and null bytes
43
+ * - absolute paths (POSIX or Windows-drive) that escape the engine
44
+ * - `..` segments that escape the engine
44
45
  * - file-shaped values ending in `.ftl` / `.properties` / `.dtd`
45
- * (these are locale resources, not directories — the operator
46
- * almost certainly meant to name the parent directory).
46
+ * (these are locale resources, not directories, so the operator
47
+ * almost certainly meant to name the parent directory)
47
48
  *
48
49
  * When {@link engineDir} is provided and exists on disk, the resolved
49
- * `engine/${value}` path is probed: if it exists but is not a
50
- * directory, the same file-shape error fires; if it does not exist yet,
50
+ * `engine/${value}` path is probed. If it exists but is not a
51
+ * directory, the same file-shape error fires. If it does not exist yet,
51
52
  * a non-blocking warning is logged (a fresh project that has not
52
53
  * `fireforge download`-ed yet is the legitimate pre-existence case).
53
54
  */
@@ -64,7 +65,7 @@ async function validateFtlBasePath(value, engineDir) {
64
65
  // Normalize with the POSIX rules regardless of host: `normalize` on Windows
65
66
  // emits backslashes, so a `../`-prefix test against the platform `normalize`
66
67
  // silently passes every traversal attempt there.
67
- const normalized = posix.normalize(value.replace(/\\/g, '/'));
68
+ const normalized = posix.normalize(normalizePathSlashes(value));
68
69
  if (normalized === '..' || normalized.startsWith('../')) {
69
70
  throw new FurnaceError(`ftlBasePath "${value}" must not escape the engine checkout via parent-directory segments.`);
70
71
  }
@@ -86,16 +87,16 @@ async function validateFtlBasePath(value, engineDir) {
86
87
  }
87
88
  catch (error) {
88
89
  // FurnaceError (from the `isDirectory()` branch above) is a real
89
- // shape failure — re-throw so the operator sees it.
90
+ // shape failure, so re-throw and let the operator see it.
90
91
  if (error instanceof FurnaceError)
91
92
  throw error;
92
93
  // ENOENT is expected on a fresh project before `fireforge
93
- // download` has populated engine/; only warn.
94
+ // download` has populated engine/. Only warn.
94
95
  const code = getNodeErrorCode(error);
95
96
  if (code === 'ENOENT') {
96
97
  warn(`ftlBasePath "${value}" does not yet exist at ${resolved}. This is fine if you have not run "fireforge download" yet; rerun "fireforge furnace init --force" after the engine is extracted to re-validate.`);
97
98
  }
98
- // Any other stat error is also best-effort ignored here — a
99
+ // Any other stat error is also ignored here as best-effort: a
99
100
  // permission issue or malformed engine checkout will surface on
100
101
  // the next command that actually reads the FTL tree.
101
102
  }
@@ -115,7 +116,7 @@ export async function furnaceInitCommand(projectRoot, options = {}) {
115
116
  const paths = getProjectPaths(projectRoot);
116
117
  // Seed the default furnace config with a tokenPrefix derived from
117
118
  // fireforge.json's binaryName so `token coverage` sees real tokens on the
118
- // very first run — without the prefix default, a fresh init → token add →
119
+ // very first run. Without the prefix default, a fresh init → token add →
119
120
  // coverage sequence reports `0 tokens / N unknown` because the scan has
120
121
  // nothing to key off. Loading fireforge.json here is best-effort: a
121
122
  // project without one (mid-setup) falls through to the prefix-less
@@ -196,8 +197,8 @@ export async function furnaceInitCommand(projectRoot, options = {}) {
196
197
  * Scaffolds the default tokens CSS file under the engine and registers
197
198
  * its path in `fireforge.json`'s `patchLint.rawColorAllowlist`. Both
198
199
  * operations are skipped silently when the engine directory does not
199
- * yet exist (a fresh project that hasn't `fireforge download`ed yet);
200
- * the scaffold is re-driven on the next `furnace init --force`.
200
+ * yet exist (a fresh project that hasn't `fireforge download`ed yet).
201
+ * The scaffold is re-driven on the next `furnace init --force`.
201
202
  *
202
203
  * Returns the scaffolded path when the file was actually created, so
203
204
  * the init command can surface it in the summary note.
@@ -257,12 +258,12 @@ async function scaffoldTokensCss(projectRoot) {
257
258
  // is owned end-to-end by tooling. Scaffolding and allowlisting it without
258
259
  // registering leaves the very next `fireforge status` correctly flagging
259
260
  // it as unmanaged + unregistered while `furnace deploy --dry-run` reports
260
- // nothing to deploy — a documented init command turning a clean project
261
+ // nothing to deploy, a documented init command turning a clean project
261
262
  // unclean. The CSS lives at the canonical
262
263
  // `browser/themes/shared/<binaryName>-tokens.css` path the shared-CSS rule
263
264
  // already targets, so it gets the same
264
265
  // `skin/classic/browser/<name>.css (../shared/<name>.css)` entry as any
265
- // other shared CSS. Idempotent — `furnace init --force` against a
266
+ // other shared CSS. It is idempotent: `furnace init --force` against a
266
267
  // registered tree is a no-op.
267
268
  try {
268
269
  const fileBase = `${forgeConfig.binaryName}-tokens.css`;
@@ -22,8 +22,8 @@ async function getHealthIndicator(componentDir, type, name, appliedChecksums) {
22
22
  }
23
23
  catch {
24
24
  // A race with `furnace remove`, filesystem permission change, or a
25
- // transient IO failure must not crash the entire `list -v` output —
26
- // render a degraded state so the rest of the table still shows.
25
+ // transient IO failure must not crash the entire `list -v` output, so
26
+ // render a degraded state and the rest of the table still shows.
27
27
  return formatErrorText('unavailable');
28
28
  }
29
29
  }
@@ -8,7 +8,7 @@ import type { FurnaceOverrideOptions } from '../../types/commands/index.js';
8
8
  export declare function furnaceOverrideCommand(projectRoot: string, name?: string, options?: FurnaceOverrideOptions): Promise<void>;
9
9
  /**
10
10
  * Creates multiple overrides in a single invocation. Each component is validated
11
- * and created sequentially; failures on one component do not block the rest.
11
+ * and created sequentially. Failures on one component do not block the rest.
12
12
  * @param projectRoot - Root directory of the project
13
13
  * @param names - Component tag names to override
14
14
  * @param options - CLI options applied to all overrides
@@ -4,7 +4,7 @@ import { dirname, join } from 'node:path';
4
4
  import { select, text } from '@clack/prompts';
5
5
  import { getProjectPaths, loadConfig, loadState } from '../../core/config.js';
6
6
  import { stdioIsInteractive } from '../../core/destructive.js';
7
- import { createDefaultFurnaceConfig, furnaceConfigExists, getFurnacePaths, loadFurnaceConfig, writeFurnaceConfig, } from '../../core/furnace-config.js';
7
+ import { getFurnacePaths, writeFurnaceConfig } from '../../core/furnace-config.js';
8
8
  import { resolveFtlDir } from '../../core/furnace-constants.js';
9
9
  import { completeJournalRollback, runFurnaceMutation } from '../../core/furnace-operation.js';
10
10
  import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
@@ -16,25 +16,14 @@ import { FurnaceError } from '../../errors/furnace.js';
16
16
  import { toError } from '../../utils/errors.js';
17
17
  import { copyFile, ensureDir, pathExists, writeJson } from '../../utils/fs.js';
18
18
  import { cancel, info, intro, isCancel, note, outro, warn } from '../../utils/logger.js';
19
- async function loadAuthoringFurnaceConfig(projectRoot) {
20
- if (await furnaceConfigExists(projectRoot)) {
21
- return loadFurnaceConfig(projectRoot);
22
- }
23
- return createDefaultFurnaceConfig();
24
- }
19
+ import { loadAuthoringFurnaceConfig } from './authoring-config.js';
25
20
  /**
26
21
  * Copies the source files needed for a new override into the workspace.
27
- * @param engineDir - Absolute path to the engine checkout
28
- * @param srcDir - Original component directory in the engine checkout
29
- * @param destDir - Destination override directory in the workspace
30
- * @param componentName - Custom element tag name being overridden
31
- * @param hasFTL - Whether the component ships a localized `.ftl` file
32
- * @param overrideType - Requested override mode
33
- * @param ftlDir - Engine-relative directory the shared `.ftl` deploys into
34
- * @param journal - Rollback journal every write is recorded in
22
+ * @param options - See {@link CopyOverrideFilesOptions}
35
23
  * @returns Filenames copied into the override directory
36
24
  */
37
- async function copyOverrideFiles(engineDir, srcDir, destDir, componentName, hasFTL, overrideType, ftlDir, journal) {
25
+ async function copyOverrideFiles(options) {
26
+ const { engineDir, srcDir, destDir, componentName, hasFTL, overrideType, ftlDir, journal } = options;
38
27
  await ensureDir(destDir);
39
28
  const entries = await readdir(srcDir, { withFileTypes: true });
40
29
  const copiedFiles = [];
@@ -90,10 +79,11 @@ async function copyOverrideFiles(engineDir, srcDir, destDir, componentName, hasF
90
79
  * override entry. Re-reads the current on-disk furnace.json inside the
91
80
  * operation lock and splices the new entry onto the fresh state, so two
92
81
  * concurrent `furnace override` commands cannot race their read-modify-write
93
- * cycles into a single surviving entry — otherwise both report success and
82
+ * cycles into a single surviving entry. Otherwise both report success and
94
83
  * furnace.json keeps only the second writer's.
95
84
  */
96
- async function saveOverrideConfig(projectRoot, destDir, componentName, overrideType, description, details, firefoxVersion, journal, baseCommit) {
85
+ async function saveOverrideConfig(options) {
86
+ const { projectRoot, destDir, componentName, overrideType, description, details, firefoxVersion, journal, baseCommit, } = options;
97
87
  const overrideJson = {
98
88
  type: overrideType,
99
89
  description,
@@ -106,8 +96,8 @@ async function saveOverrideConfig(projectRoot, destDir, componentName, overrideT
106
96
  await writeJson(overrideJsonPath, overrideJson);
107
97
  // Re-read the current furnace.json inside the lock. The outer caller
108
98
  // loaded a snapshot before entering `runFurnaceMutation`, but another
109
- // furnace mutation (override / init / sync) may have landed in between
110
- // — writing back the stale snapshot would drop that concurrent write.
99
+ // furnace mutation (override / init / sync) may have landed in between,
100
+ // and writing back the stale snapshot would drop that concurrent write.
111
101
  const freshConfig = await loadAuthoringFurnaceConfig(projectRoot);
112
102
  freshConfig.overrides[componentName] = {
113
103
  type: overrideType,
@@ -138,9 +128,28 @@ async function performOverrideMutations(args) {
138
128
  ctx.registerJournal(journal);
139
129
  recordCreatedDir(journal, args.destDir);
140
130
  try {
141
- const filesCopied = await copyOverrideFiles(args.engineDir, args.srcDir, args.destDir, args.componentName, args.details.hasFTL, args.overrideType, args.ftlDir, journal);
131
+ const filesCopied = await copyOverrideFiles({
132
+ engineDir: args.engineDir,
133
+ srcDir: args.srcDir,
134
+ destDir: args.destDir,
135
+ componentName: args.componentName,
136
+ hasFTL: args.details.hasFTL,
137
+ overrideType: args.overrideType,
138
+ ftlDir: args.ftlDir,
139
+ journal,
140
+ });
142
141
  await snapshotFile(journal, args.furnacePaths.furnaceConfig);
143
- await saveOverrideConfig(args.projectRoot, args.destDir, args.componentName, args.overrideType, args.description, args.details, args.firefoxVersion, journal, args.baseCommit);
142
+ await saveOverrideConfig({
143
+ projectRoot: args.projectRoot,
144
+ destDir: args.destDir,
145
+ componentName: args.componentName,
146
+ overrideType: args.overrideType,
147
+ description: args.description,
148
+ details: args.details,
149
+ firefoxVersion: args.firefoxVersion,
150
+ journal,
151
+ baseCommit: args.baseCommit,
152
+ });
144
153
  return filesCopied;
145
154
  }
146
155
  catch (error) {
@@ -155,11 +164,11 @@ async function performOverrideMutations(args) {
155
164
  }
156
165
  /**
157
166
  * Throws if `componentName` is already classified as something `override`
158
- * cannot coexist with. A stock-bucket entry is NOT a hard conflict — the
159
- * whole point of `override` is to fork a component out of the stock bucket
160
- * into the overrides bucket, and requiring manual `furnace.json` surgery
161
- * first was a pure footgun. `promoteStockToOverrideIfNeeded` handles the
162
- * transition in-memory; this guard only rejects the other two cases where
167
+ * cannot coexist with. A stock-bucket entry is not a hard conflict:
168
+ * `override` exists to fork a component out of the stock bucket into the
169
+ * overrides bucket, and requiring manual `furnace.json` surgery first was
170
+ * a footgun. `promoteStockToOverrideIfNeeded` handles the
171
+ * transition in-memory. This guard only rejects the other two cases where
163
172
  * a rename actually contradicts existing state.
164
173
  */
165
174
  function assertNoComponentCollision(config, componentName) {
@@ -176,7 +185,7 @@ function assertNoComponentCollision(config, componentName) {
176
185
  * the subsequent `writeFurnaceConfig` inside the mutation phase persists
177
186
  * the stock → override promotion atomically alongside the new override
178
187
  * entry. Returns true when a promotion happened so the caller can emit a
179
- * one-line note; false when the component was not stock.
188
+ * one-line note. Returns false when the component was not stock.
180
189
  */
181
190
  function promoteStockToOverrideIfNeeded(config, componentName) {
182
191
  const index = config.stock.indexOf(componentName);
@@ -194,9 +203,9 @@ function promoteStockToOverrideIfNeeded(config, componentName) {
194
203
  export async function furnaceOverrideCommand(projectRoot, name, options = {}) {
195
204
  const isInteractive = stdioIsInteractive();
196
205
  intro('Furnace Override');
197
- // --- Validate config-independent inputs BEFORE auto-creating furnace.json
206
+ // --- Validate config-independent inputs before auto-creating furnace.json
198
207
  // so a failed authoring command never strands a fresh config in the
199
- // project root. CLI-supplied name is checked here; the engine directory
208
+ // project root. CLI-supplied name is checked here. The engine directory
200
209
  // and component-resolution checks below also have no config dependency.
201
210
  const paths = getProjectPaths(projectRoot);
202
211
  if (name !== undefined && !CUSTOM_ELEMENT_TAG_PATTERN.test(name)) {
@@ -217,7 +226,7 @@ export async function furnaceOverrideCommand(projectRoot, name, options = {}) {
217
226
  // --- Resolve component name ---
218
227
  let componentName = name;
219
228
  if (!componentName) {
220
- // Interactive prompt path; non-interactive missing-name was rejected above.
229
+ // Interactive prompt path. Non-interactive missing-name was rejected above.
221
230
  const allComponents = await scanWidgetsDirectory(paths.engine, ftlDir);
222
231
  const available = allComponents.filter((c) => !(c.tagName in config.overrides));
223
232
  if (available.length === 0) {
@@ -327,7 +336,7 @@ export async function furnaceOverrideCommand(projectRoot, name, options = {}) {
327
336
  }
328
337
  /**
329
338
  * Creates multiple overrides in a single invocation. Each component is validated
330
- * and created sequentially; failures on one component do not block the rest.
339
+ * and created sequentially. Failures on one component do not block the rest.
331
340
  * @param projectRoot - Root directory of the project
332
341
  * @param names - Component tag names to override
333
342
  * @param options - CLI options applied to all overrides
@@ -353,8 +362,8 @@ export async function furnaceBatchOverrideCommand(projectRoot, names, options =
353
362
  const state = await loadState(projectRoot);
354
363
  // Check for duplicates and pre-existing classifications across every
355
364
  // bucket in furnace.json. A stock-bucket entry is promoted in-memory
356
- // here (see `promoteStockToOverrideIfNeeded`) rather than rejected —
357
- // the operator's intent is to fork that specific stock component. The
365
+ // here (see `promoteStockToOverrideIfNeeded`) rather than rejected,
366
+ // since the operator's intent is to fork that specific stock component. The
358
367
  // collision guard still rejects name conflicts that would double-
359
368
  // classify a tag in a way `writeFurnaceConfig` cannot safely produce
360
369
  // (two overrides, or an override + custom).
@@ -13,8 +13,8 @@ import { toError } from '../../utils/errors.js';
13
13
  import { pathExists } from '../../utils/fs.js';
14
14
  import { info, intro, outro, spinner, warn } from '../../utils/logger.js';
15
15
  /**
16
- * Runs the two teardown steps — `cleanStories` and the rollback-journal
17
- * restore — independently, collecting whatever errors either step throws.
16
+ * Runs the two teardown steps (`cleanStories` and the rollback-journal
17
+ * restore) independently, collecting whatever errors either step throws.
18
18
  * Both steps must run regardless of the other's outcome, because each
19
19
  * operates on a different part of engine state and skipping one leaves
20
20
  * the engine in a worse position than a single-step failure.
@@ -72,10 +72,10 @@ function reportPreviewStagingFailures(stageResult) {
72
72
  }
73
73
  /**
74
74
  * Filenames emitted by the Firefox build backend (not by Storybook's npm
75
- * package set) — their absence means `mach build` has not produced its
75
+ * package set). Their absence means `mach build` has not produced its
76
76
  * post-configure artifacts, which is a different failure mode from a missing
77
77
  * Storybook workspace dependency tree. A
78
- * `FileNotFoundError: [...] chrome-map.json` AFTER a successful Storybook
78
+ * `FileNotFoundError: [...] chrome-map.json` after a successful Storybook
79
79
  * `npm install` is the case a dep-focused heuristic misdiagnoses, sending
80
80
  * the operator back to `--install`. The pattern list is narrow on purpose so
81
81
  * the backend-rebuild hint only fires when it is confident.
@@ -101,7 +101,7 @@ export function buildStorybookFailureMessage(output, installRequested) {
101
101
  ? 'Try running "python3 ./mach storybook upgrade" manually in the engine directory.'
102
102
  : 'Run "fireforge furnace preview --install" to bootstrap Storybook dependencies, or run "python3 ./mach storybook upgrade" manually in engine/.';
103
103
  const hasFileNotFoundSignal = /(ENOENT|No such file or directory|FileNotFoundError)/i.test(output);
104
- // Check backend-artifact signal first — a missing chrome-map.json looks
104
+ // Check the backend-artifact signal first: a missing chrome-map.json looks
105
105
  // like any other "No such file" error to a naïve regex, but the fix is
106
106
  // to rerun `fireforge build`, not to reinstall Storybook dependencies.
107
107
  if (hasFileNotFoundSignal && BACKEND_ARTIFACT_PATTERNS.some((p) => p.test(output))) {
@@ -122,7 +122,7 @@ export function buildStorybookFailureMessage(output, installRequested) {
122
122
  * Preflights the Firefox build + toolchain prerequisites `mach storybook`
123
123
  * quietly assumes. Without it, preview stages components and launches a
124
124
  * ~1000-package `mach storybook upgrade` npm install before the backend
125
- * surfaces a "missing chrome-map.json" / Cargo-config failure; this refuses
125
+ * surfaces a "missing chrome-map.json" / Cargo-config failure. This refuses
126
126
  * fast and leaves the workspace untouched.
127
127
  *
128
128
  * @param engineDir - Resolved engine directory
@@ -143,7 +143,7 @@ async function assertPreviewPrerequisites(engineDir) {
143
143
  // follow the remediation instruction ("run bootstrap then rerun preview")
144
144
  // hit the same refusal on the retry, because `fireforge bootstrap` alone
145
145
  // produces only `.in`. Either name is sufficient to prove the Rust
146
- // toolchain is registered; the stronger `hasBuildArtifacts` check above
146
+ // toolchain is registered. The stronger `hasBuildArtifacts` check above
147
147
  // already guards against a completely un-configured tree.
148
148
  const cargoConfigPath = join(engineDir, '.cargo', 'config.toml');
149
149
  const cargoConfigInPath = join(engineDir, '.cargo', 'config.toml.in');
@@ -158,10 +158,10 @@ async function assertPreviewPrerequisites(engineDir) {
158
158
  /**
159
159
  * Emits a framing banner when the Storybook workspace has not yet had its npm
160
160
  * dependencies installed. `mach storybook` drives the install internally and
161
- * prints ELSPROBLEMS / UNMET DEPENDENCY lines verbatim; without this banner
161
+ * prints ELSPROBLEMS / UNMET DEPENDENCY lines verbatim. Without this banner
162
162
  * operators reliably read the npm output as a failure.
163
163
  *
164
- * Skipped when `--install` was explicitly requested — that path already runs
164
+ * Skipped when `--install` was explicitly requested, since that path runs
165
165
  * `mach storybook upgrade` before the preview launches, so the npm output
166
166
  * for the subsequent `mach storybook` invocation is a no-op.
167
167
  */
@@ -177,9 +177,9 @@ async function announceStorybookFirstRunIfNeeded(engineDir, installRequested) {
177
177
  /**
178
178
  * Surfaces an explicit success banner after a clean mach-storybook
179
179
  * exit so the operator's scrollback visually terminates the npm noise
180
- * from the first-run install. Only fires on expected exit codes — non-
181
- * zero cases fall through to the existing
182
- * `buildStorybookFailureMessage` classification.
180
+ * from the first-run install. Only fires on expected exit codes. Non-zero
181
+ * cases fall through to the existing `buildStorybookFailureMessage`
182
+ * classification.
183
183
  */
184
184
  function announceStorybookCleanExitIfApplicable(exitCode) {
185
185
  if (exitCode === 0 || exitCode === 130 || exitCode === 143) {
@@ -212,9 +212,9 @@ export async function furnacePreviewCommand(projectRoot, options = {}) {
212
212
  await assertPreviewPrerequisites(paths.engine);
213
213
  let previewResult;
214
214
  // True once we are about to (or have) written to engine/.../stories/furnace.
215
- // Intentionally set BEFORE `syncStories` is awaited so a mid-sync failure
216
- // still triggers `cleanStories` during teardown. `cleanStories` is a
217
- // full-directory wipe, so it is correct to run against partial state —
215
+ // Set before `syncStories` is awaited so a mid-sync failure still
216
+ // triggers `cleanStories` during teardown. `cleanStories` is a
217
+ // full-directory wipe, so it is correct to run against partial state,
218
218
  // including state with zero files, where it is a cheap no-op.
219
219
  let storiesCleanupRequired = false;
220
220
  let previewJournal;
@@ -264,7 +264,7 @@ export async function furnacePreviewCommand(projectRoot, options = {}) {
264
264
  stageSpinner.stop(`Staged ${stageResult.applied.length} component${stageResult.applied.length === 1 ? '' : 's'} for preview`);
265
265
  }
266
266
  // Sync story files. Set the cleanup flag before the await so a partial
267
- // write failure still triggers the teardown wipe — `syncStories` writes
267
+ // write failure still triggers the teardown wipe. `syncStories` writes
268
268
  // files incrementally with no internal cleanup of its own.
269
269
  const syncSpinner = spinner('Syncing component stories...');
270
270
  storiesCleanupRequired = true;
@@ -299,7 +299,7 @@ export async function furnacePreviewCommand(projectRoot, options = {}) {
299
299
  // cleanStories must not prevent the journal restore, and vice versa.
300
300
  // Running teardown in a `finally` that calls
301
301
  // `restoreRollbackJournalOrThrow` throws synchronously, bypassing the
302
- // primary error and skipping downstream handling — the engine is left
302
+ // primary error and skipping downstream handling, so the engine is left
303
303
  // with staged files and the user gets a teardown message with no
304
304
  // guidance. Both failures are collected instead and, if anything went
305
305
  // wrong, a `pendingRepair` marker is persisted for `fireforge doctor` to
@@ -90,8 +90,8 @@ async function refreshSingleOverride(projectRoot, name, options = {}) {
90
90
  }
91
91
  return { results: [], currentVersion };
92
92
  }
93
- // Prefer the per-override baseCommit (survives download --force); fall back
94
- // to the project-wide value for overrides created before this field existed.
93
+ // Prefer the per-override baseCommit (survives download --force). Fall
94
+ // back to the project-wide value for overrides created before this field existed.
95
95
  const baseCommit = overrideConfig.baseCommit ?? state.baseCommit;
96
96
  if (!baseCommit) {
97
97
  throw new FurnaceError('Cannot refresh: baseCommit not found. Re-run "fireforge download" to establish a baseline, ' +
@@ -126,7 +126,15 @@ async function refreshSingleOverride(projectRoot, name, options = {}) {
126
126
  for (const entry of overrideFiles) {
127
127
  const overridePath = join(overrideDir, entry.name);
128
128
  const engineRelPath = getOverrideEngineTargetPath(paths.engine, overrideConfig, entry.name, ftlDir).slice(paths.engine.length + 1);
129
- const result = await refreshOverrideFile(paths.engine, overridePath, engineRelPath, baseCommit, entry.name, dryRun, strategy);
129
+ const result = await refreshOverrideFile({
130
+ engineDir: paths.engine,
131
+ overridePath,
132
+ engineRelPath,
133
+ baseCommit,
134
+ fileName: entry.name,
135
+ dryRun,
136
+ strategy,
137
+ });
130
138
  fileResults.push(result);
131
139
  }
132
140
  // Update baseVersion and baseCommit on clean merge (not dry-run, no conflicts)
@@ -145,7 +153,7 @@ async function refreshSingleOverride(projectRoot, name, options = {}) {
145
153
  return fileResults;
146
154
  }
147
155
  catch (error) {
148
- // A dry run wrote nothing, so there is no journal to restore — it
156
+ // A dry run wrote nothing, so there is no journal to restore. It
149
157
  // rethrows without touching the lifecycle wrapper.
150
158
  if (!dryRun) {
151
159
  return await completeJournalRollback(ctx, journal, error, {
@@ -163,7 +171,7 @@ async function refreshSingleOverride(projectRoot, name, options = {}) {
163
171
  /**
164
172
  * Refreshes every override sequentially, tallying merged/conflict/
165
173
  * unchanged file counts. Per-override errors are expected (warned and
166
- * recorded as failures) and do not abort the batch; only an error that
174
+ * recorded as failures) and do not abort the batch. Only an error that
167
175
  * escapes this function entirely warrants the caller's journal rollback.
168
176
  */
169
177
  async function runBatchRefresh(projectRoot, overrideNames, options) {
@@ -224,7 +232,7 @@ export async function furnaceRefreshCommand(projectRoot, name, options = {}) {
224
232
  if (name && refreshAll) {
225
233
  throw new FurnaceError('Cannot specify both a component name and --all. Use one or the other.');
226
234
  }
227
- // Verify engine exists — refresh reads engine files for three-way merge
235
+ // Verify engine exists: refresh reads engine files for three-way merge
228
236
  // and --reset-base reads engine HEAD. Without this check, the user gets
229
237
  // an obscure git error instead of a clear precondition message.
230
238
  await assertFurnaceEngineReady(projectRoot);
@@ -257,7 +265,7 @@ export async function furnaceRefreshCommand(projectRoot, name, options = {}) {
257
265
  }
258
266
  // Snapshot furnace.json before the batch loop so an unexpected failure
259
267
  // (process crash, unhandled error) can be recovered from. Per-component
260
- // errors caught below are expected and do not trigger a restore — only
268
+ // errors caught below are expected and do not trigger a restore. Only
261
269
  // an error that escapes the loop entirely warrants rolling back.
262
270
  const batchJournal = dryRun ? undefined : createRollbackJournal();
263
271
  if (batchJournal) {
@@ -1,9 +1,8 @@
1
- import type { loadFurnaceConfig } from '../../core/furnace-config.js';
2
- import { getFurnacePaths } from '../../core/furnace-config.js';
1
+ import type { FurnacePaths } from '../../core/furnace-config.js';
3
2
  import type { RollbackJournal } from '../../core/furnace-rollback.js';
4
- import type { FurnaceState } from '../../types/furnace.js';
3
+ import type { FurnaceConfig, FurnaceState } from '../../types/furnace.js';
5
4
  /**
6
- * Engine-side and workspace-side removal for an OVERRIDE component.
5
+ * Engine-side and workspace-side removal for an override component.
7
6
  *
8
7
  * Runs inside the caller's rollback journal rather than opening its own, so
9
8
  * a failure anywhere in the remove still restores the whole operation as a
@@ -14,15 +13,15 @@ export declare function performOverrideRemovalMutations(args: {
14
13
  paths: {
15
14
  engine: string;
16
15
  };
17
- furnacePaths: ReturnType<typeof getFurnacePaths>;
18
- freshConfig: Awaited<ReturnType<typeof loadFurnaceConfig>>;
16
+ furnacePaths: FurnacePaths;
17
+ freshConfig: FurnaceConfig;
19
18
  freshState: FurnaceState;
20
19
  ftlDir: string;
21
20
  journal: RollbackJournal;
22
21
  }): Promise<void>;
23
22
  /**
24
- * Engine-side and workspace-side removal for a CUSTOM component.
25
- * Sibling of {@link performOverrideRemovalMutations}; see its note.
23
+ * Engine-side and workspace-side removal for a custom component.
24
+ * Sibling of {@link performOverrideRemovalMutations}. See its note.
26
25
  */
27
26
  export declare function performCustomRemovalMutations(args: {
28
27
  projectRoot: string;
@@ -30,8 +29,8 @@ export declare function performCustomRemovalMutations(args: {
30
29
  paths: {
31
30
  engine: string;
32
31
  };
33
- furnacePaths: ReturnType<typeof getFurnacePaths>;
34
- freshConfig: Awaited<ReturnType<typeof loadFurnaceConfig>>;
32
+ furnacePaths: FurnacePaths;
33
+ freshConfig: FurnaceConfig;
35
34
  ftlDir: string;
36
35
  journal: RollbackJournal;
37
36
  }): Promise<void>;
@@ -7,7 +7,7 @@
7
7
  * `furnaceRemoveCommand` at the per-function cap. Extracting them inside the
8
8
  * same file would trade a function-length problem for a file-length one.
9
9
  *
10
- * Both run inside the CALLER's rollback journal rather than opening their
10
+ * Both run inside the caller's rollback journal rather than opening their
11
11
  * own, so a failure anywhere in the remove still restores the whole
12
12
  * operation as a single unit.
13
13
  */
@@ -16,7 +16,6 @@ import { join } from 'node:path';
16
16
  import { removeCustomFtlJarMnEntry } from '../../core/furnace-apply-ftl.js';
17
17
  import { getOverrideEngineTargetPath, isOverrideCopyCandidate, restoreOverrideFileToBaseline, } from '../../core/furnace-apply-helpers.js';
18
18
  import { extractComponentChecksums } from '../../core/furnace-checksum-utils.js';
19
- import { getFurnacePaths } from '../../core/furnace-config.js';
20
19
  import { removeCustomElementRegistration, removeJarMnEntries, } from '../../core/furnace-registration.js';
21
20
  import { snapshotDir, snapshotFile } from '../../core/furnace-rollback.js';
22
21
  import { isGitRepository } from '../../core/git.js';
@@ -28,12 +27,12 @@ import { removeDeployedCustomFiles } from './remove-state.js';
28
27
  /**
29
28
  * Restores every override-deployed file in `engine/` to its pristine HEAD
30
29
  * state, inverting what `applyOverrideComponent` would have written. Files that
31
- * existed in HEAD are restored via `git restore`; files the override
30
+ * existed in HEAD are restored via `git restore`. Files the override
32
31
  * introduced (not in HEAD) are deleted outright.
33
32
  *
34
- * The restore set is the **union** of (a) files currently in the override
35
- * workspace directory and (b) filenames recorded in `previousChecksumKeys`
36
- * — i.e. files we know we deployed last time, even if the developer has
33
+ * The restore set is the union of (a) files currently in the override
34
+ * workspace directory and (b) filenames recorded in `previousChecksumKeys`,
35
+ * i.e. files we know we deployed last time, even if the developer has
37
36
  * since deleted them from the workspace. Without (b), a workspace deletion
38
37
  * leaves an orphaned engine copy that `furnace remove` would never see.
39
38
  *
@@ -44,14 +43,15 @@ import { removeDeployedCustomFiles } from './remove-state.js';
44
43
  async function restoreOverrideEngineFiles(engineDir, overrideDir, overrideConfig, previousChecksumKeys, ftlDir, journal) {
45
44
  // Engine-as-git is a hard precondition for restoration: git HEAD is the only
46
45
  // honest oracle for "what was there before the override". If the engine is
47
- // not a git repo we refuse rather than silently leaving files behind — the
48
- // previous warn-and-continue behaviour is exactly what this fix removes.
46
+ // not a git repo we refuse rather than silently leaving files behind. The
47
+ // previous behaviour was to warn and continue, which is what this fix
48
+ // removes.
49
49
  if (!(await isGitRepository(engineDir))) {
50
50
  throw new FurnaceError('Cannot restore override files: engine is not a git repository. Run "fireforge download" to initialise it.');
51
51
  }
52
52
  // Build the union of "files we still see on disk" and "files state.json
53
53
  // claims we deployed". The state set is the only authority for files that
54
- // were deployed and later deleted from the workspace; the workspace set is
54
+ // were deployed and later deleted from the workspace. The workspace set is
55
55
  // the only authority for files added since last apply that have not yet
56
56
  // been recorded in state. We need both.
57
57
  const fileSet = new Set();
@@ -81,7 +81,7 @@ async function restoreOverrideEngineFiles(engineDir, overrideDir, overrideConfig
81
81
  return { restored, removed };
82
82
  }
83
83
  /**
84
- * Engine-side and workspace-side removal for an OVERRIDE component.
84
+ * Engine-side and workspace-side removal for an override component.
85
85
  *
86
86
  * Runs inside the caller's rollback journal rather than opening its own, so
87
87
  * a failure anywhere in the remove still restores the whole operation as a
@@ -91,10 +91,10 @@ export async function performOverrideRemovalMutations(args) {
91
91
  const { name, paths, furnacePaths, freshConfig, freshState, ftlDir, journal } = args;
92
92
  const overrideConfig = freshConfig.overrides[name];
93
93
  const dir = join(furnacePaths.overridesDir, name);
94
- // Restore deployed engine files BEFORE removing the workspace
94
+ // Restore deployed engine files before removing the workspace
95
95
  // directory. The restore set is the union of (a) files currently in
96
- // the workspace and (b) files state.json says we deployed last time
97
- // — without (b), source-side deletions would orphan engine copies
96
+ // the workspace and (b) files state.json says we deployed last time.
97
+ // Without (b), source-side deletions would orphan engine copies
98
98
  // that this command can never see again.
99
99
  if (overrideConfig?.basePath) {
100
100
  const previousKeys = Object.keys(extractComponentChecksums(freshState.appliedChecksums, 'override', name));
@@ -113,8 +113,8 @@ export async function performOverrideRemovalMutations(args) {
113
113
  }
114
114
  }
115
115
  /**
116
- * Engine-side and workspace-side removal for a CUSTOM component.
117
- * Sibling of {@link performOverrideRemovalMutations}; see its note.
116
+ * Engine-side and workspace-side removal for a custom component.
117
+ * Sibling of {@link performOverrideRemovalMutations}. See its note.
118
118
  */
119
119
  export async function performCustomRemovalMutations(args) {
120
120
  const { projectRoot, name, paths, furnacePaths, freshConfig, ftlDir, journal } = args;
@@ -141,12 +141,12 @@ export async function performCustomRemovalMutations(args) {
141
141
  await removeDir(dir);
142
142
  info(`Deleted components/custom/${name}/`);
143
143
  }
144
- // Clean up deployed files in engine (per-file — see helper doc).
144
+ // Clean up deployed files in engine (per-file, see helper doc).
145
145
  if (customConfig?.targetPath) {
146
146
  await removeDeployedCustomFiles(projectRoot, paths.engine, name, customConfig.targetPath, journal);
147
147
  }
148
148
  // Localized components deploy a .ftl outside targetPath into the
149
- // shared Fluent tree; apply writes it, so remove must delete it too
149
+ // shared Fluent tree. Apply writes it, so remove must delete it too
150
150
  // or the locale payload is orphaned.
151
151
  if (customConfig?.localized) {
152
152
  const ftlRel = join(ftlDir, `${name}.ftl`);
@@ -155,12 +155,12 @@ export async function performCustomRemovalMutations(args) {
155
155
  await snapshotFile(journal, ftlPath);
156
156
  await removeFile(ftlPath);
157
157
  // `ftlRel` is a native join, so on Windows an interpolated
158
- // `engine/${ftlRel}` renders as `engine/toolkit\locales\...` — one
158
+ // `engine/${ftlRel}` renders as `engine/toolkit\locales\...`, one
159
159
  // message with both separators. Print the engine-relative form.
160
160
  info(`Deleted localized file engine/${normalizePathSlashes(ftlRel)}`);
161
161
  }
162
162
  // Drop the locale jar.mn chrome registration that `applyCustomFtlFile`
163
- // wrote during deploy — otherwise the engine is left with a
163
+ // wrote during deploy. Otherwise the engine is left with a
164
164
  // `locale/.../${name}.ftl` entry pointing at a file just deleted, which
165
165
  // breaks the next package-manifest validation.
166
166
  await removeCustomFtlJarMnEntry(paths.engine, `${name}.ftl`, ftlDir, customConfig, journal);
@@ -10,7 +10,7 @@ export declare function dropChecksumsByPrefix(state: FurnaceState, prefix: strin
10
10
  * Per-file, never a recursive `removeDir` of the whole directory: nothing
11
11
  * stops two components from sharing a targetPath (or a hand-edited config
12
12
  * from pointing at an upstream-shared directory), and the recursive delete
13
- * permanently destroyed the co-located files on success — the rollback
13
+ * permanently destroyed the co-located files on success. The rollback
14
14
  * journal only protects the failure path. Deployed files come from the
15
15
  * component's state checksums, falling back to the conventional
16
16
  * `<name>.{mjs,css,ftl}` set when state carries no record (cleared by a
@@ -24,7 +24,7 @@ export function dropChecksumsByPrefix(state, prefix) {
24
24
  * Per-file, never a recursive `removeDir` of the whole directory: nothing
25
25
  * stops two components from sharing a targetPath (or a hand-edited config
26
26
  * from pointing at an upstream-shared directory), and the recursive delete
27
- * permanently destroyed the co-located files on success — the rollback
27
+ * permanently destroyed the co-located files on success. The rollback
28
28
  * journal only protects the failure path. Deployed files come from the
29
29
  * component's state checksums, falling back to the conventional
30
30
  * `<name>.{mjs,css,ftl}` set when state carries no record (cleared by a