@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
@@ -5,6 +5,21 @@
5
5
  * Progress callback for download operations.
6
6
  */
7
7
  export type ProgressCallback = (downloaded: number, total: number) => void;
8
+ /**
9
+ * Fetches a URL with timeout and bounded retry for transient failures
10
+ * (429/5xx, network errors, the per-request timeout).
11
+ *
12
+ * Any other response (2xx or a non-retryable failure such as 404) is
13
+ * returned as-is on the first attempt. The caller decides what a given
14
+ * status means for its request. Shared by the tarball download and the
15
+ * SHA256SUMS lookup so both requests the download makes survive the same
16
+ * transient blips: with checksum verification failing closed, an
17
+ * un-retried checksum fetch would throw away a just-landed 600 MB archive
18
+ * over one dropped connection.
19
+ *
20
+ * @throws DownloadError once every attempt has failed with a retryable error
21
+ */
22
+ export declare function fetchWithRetry(url: string): Promise<Response>;
8
23
  /**
9
24
  * Downloads a file from a URL with progress tracking, timeout, and retry.
10
25
  * @param url - URL to download
@@ -7,7 +7,13 @@ import { basename } from 'node:path';
7
7
  import { Readable, Transform } from 'node:stream';
8
8
  import { pipeline } from 'node:stream/promises';
9
9
  import { DownloadError, VersionNotFoundError } from '../errors/download.js';
10
- /** Default request timeout in milliseconds (60 seconds). */
10
+ import { sleep } from '../utils/sleep.js';
11
+ /**
12
+ * Per-attempt request timeout in milliseconds (60 seconds). Every request
13
+ * the download makes (the tarball and the SHA256SUMS lookup in
14
+ * `firefox-cache.ts`) goes through {@link fetchWithRetry} and so shares
15
+ * this abort ceiling.
16
+ */
11
17
  const REQUEST_TIMEOUT_MS = 60_000;
12
18
  /** Maximum number of download attempts. */
13
19
  const MAX_ATTEMPTS = 3;
@@ -15,14 +21,23 @@ const MAX_ATTEMPTS = 3;
15
21
  const RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504]);
16
22
  /** Base delay between retries in milliseconds. */
17
23
  const RETRY_BASE_DELAY_MS = 1_000;
18
- /** Stall detection timeout — abort if no data received for this duration (30 seconds). */
24
+ /** Stall detection timeout: abort if no data received for this duration (30 seconds). */
19
25
  const DOWNLOAD_STALL_TIMEOUT_MS = 30_000;
20
26
  /**
21
- * Fetches a URL with timeout and bounded retry for transient failures.
27
+ * Fetches a URL with timeout and bounded retry for transient failures
28
+ * (429/5xx, network errors, the per-request timeout).
22
29
  *
23
- * Non-retryable errors (e.g. 404) are thrown immediately.
30
+ * Any other response (2xx or a non-retryable failure such as 404) is
31
+ * returned as-is on the first attempt. The caller decides what a given
32
+ * status means for its request. Shared by the tarball download and the
33
+ * SHA256SUMS lookup so both requests the download makes survive the same
34
+ * transient blips: with checksum verification failing closed, an
35
+ * un-retried checksum fetch would throw away a just-landed 600 MB archive
36
+ * over one dropped connection.
37
+ *
38
+ * @throws DownloadError once every attempt has failed with a retryable error
24
39
  */
25
- async function fetchWithRetry(url) {
40
+ export async function fetchWithRetry(url) {
26
41
  let lastError;
27
42
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
28
43
  const controller = new AbortController();
@@ -31,23 +46,12 @@ async function fetchWithRetry(url) {
31
46
  }, REQUEST_TIMEOUT_MS);
32
47
  try {
33
48
  const response = await fetch(url, { signal: controller.signal });
34
- if (response.status === 404) {
35
- throw new VersionNotFoundError(basename(url).replace('.source.tar.xz', ''));
36
- }
37
- if (RETRYABLE_STATUS_CODES.has(response.status)) {
38
- lastError = new DownloadError(`HTTP ${response.status}: ${response.statusText}`, url);
39
- }
40
- else if (!response.ok) {
41
- throw new DownloadError(`HTTP ${response.status}: ${response.statusText}`, url);
42
- }
43
- else {
49
+ if (!RETRYABLE_STATUS_CODES.has(response.status)) {
44
50
  return response;
45
51
  }
52
+ lastError = new DownloadError(`HTTP ${response.status}: ${response.statusText}`, url);
46
53
  }
47
54
  catch (error) {
48
- if (error instanceof VersionNotFoundError || error instanceof DownloadError) {
49
- throw error;
50
- }
51
55
  // Network / timeout errors are retryable
52
56
  lastError = error;
53
57
  }
@@ -55,9 +59,7 @@ async function fetchWithRetry(url) {
55
59
  clearTimeout(timer);
56
60
  }
57
61
  if (attempt < MAX_ATTEMPTS - 1) {
58
- await new Promise((resolve) => {
59
- setTimeout(resolve, RETRY_BASE_DELAY_MS * (attempt + 1) ** 2);
60
- });
62
+ await sleep(RETRY_BASE_DELAY_MS * (attempt + 1) ** 2);
61
63
  }
62
64
  }
63
65
  if (lastError instanceof DownloadError) {
@@ -65,6 +67,20 @@ async function fetchWithRetry(url) {
65
67
  }
66
68
  throw new DownloadError(lastError instanceof Error ? lastError.message : 'Download failed after retries', url, lastError instanceof Error ? lastError : undefined);
67
69
  }
70
+ /**
71
+ * Fetches the archive itself: a 404 is the release not existing
72
+ * (`VersionNotFoundError`), any other non-2xx is a `DownloadError`.
73
+ */
74
+ async function fetchArchive(url) {
75
+ const response = await fetchWithRetry(url);
76
+ if (response.status === 404) {
77
+ throw new VersionNotFoundError(basename(url).replace('.source.tar.xz', ''));
78
+ }
79
+ if (!response.ok) {
80
+ throw new DownloadError(`HTTP ${response.status}: ${response.statusText}`, url);
81
+ }
82
+ return response;
83
+ }
68
84
  /**
69
85
  * Creates a Transform stream that aborts if no data is received within the stall timeout.
70
86
  * The timer resets on each chunk. If it fires, the stream is destroyed with a DownloadError.
@@ -110,7 +126,7 @@ function createStallDetector(url, timeoutMs = DOWNLOAD_STALL_TIMEOUT_MS) {
110
126
  * @returns The content-length if available, otherwise undefined
111
127
  */
112
128
  export async function downloadFile(url, destPath, onProgress) {
113
- const response = await fetchWithRetry(url);
129
+ const response = await fetchArchive(url);
114
130
  if (!response.body) {
115
131
  throw new DownloadError('No response body received', url);
116
132
  }
@@ -2,24 +2,25 @@
2
2
  * Firefox source extraction and installed version detection.
3
3
  */
4
4
  /**
5
- * Validates entry names from a `tar -tf` listing.
5
+ * Validates entry names from a `tar -tf` listing: escaping paths and
6
+ * `.git` members are both rejected.
6
7
  * @param names - Listing lines (one member name per line)
7
- * @returns The first unsafe member name, or null when all are safe
8
+ * @returns The first unsafe member name, or undefined when all are safe
8
9
  */
9
- export declare function findUnsafeArchiveEntryName(names: readonly string[]): string | null;
10
+ export declare function findUnsafeArchiveEntryName(names: readonly string[]): string | undefined;
10
11
  /**
11
12
  * Validates symlink and hardlink targets from a `tar -tvf` listing.
12
13
  *
13
14
  * A relative link target without `..` segments can only resolve inside the
14
15
  * extraction root, so only absolute or `..`-containing targets are rejected.
15
- * Symlinks are `l`-typed lines with a ` -> target` suffix (the LAST arrow is
16
+ * Symlinks are `l`-typed lines with a ` -> target` suffix (the last arrow is
16
17
  * taken, so a link whose own name contains ` -> ` still parses to its real
17
- * target); hardlinks print ` link to target` on GNU tar and bsdtar alike.
18
+ * target). Hardlinks print ` link to target` on GNU tar and bsdtar alike.
18
19
  *
19
20
  * @param verboseLines - `tar -tvf` listing lines
20
- * @returns A description of the first unsafe link found, or null
21
+ * @returns A description of the first unsafe link found, or undefined
21
22
  */
22
- export declare function findUnsafeArchiveLink(verboseLines: readonly string[]): string | null;
23
+ export declare function findUnsafeArchiveLink(verboseLines: readonly string[]): string | undefined;
23
24
  /**
24
25
  * Extracts a tar.xz archive after a listing preflight that rejects
25
26
  * path-traversal member names and escaping link targets.
@@ -20,31 +20,54 @@ function isUnsafeArchivePath(path) {
20
20
  return path.split(/[\\/]/).includes('..');
21
21
  }
22
22
  /**
23
- * Validates entry names from a `tar -tf` listing.
23
+ * Returns true when an archive member path has a `.git` segment at any
24
+ * depth (`.git`, `.git/config`, `foo/.git/hooks/pre-commit`). Such a member
25
+ * lands inside the extraction root, so the traversal check passes it, but
26
+ * the extracted tree is immediately turned into a git repository and
27
+ * committed, and git honours a pre-seeded `.git/config` (`core.fsmonitor`,
28
+ * `core.hooksPath`) or `.git/hooks/*` on that first commit. Only the `.git`
29
+ * directory/file is rejected. `.gitmodules`, `.gitignore` and the like are
30
+ * legitimate upstream files.
31
+ */
32
+ function hasGitSegment(path) {
33
+ return path.split(/[\\/]/).some((segment) => segment.toLowerCase() === '.git');
34
+ }
35
+ /**
36
+ * Returns true when an archive member name must be rejected: an escaping
37
+ * path, or a `.git` segment (see {@link hasGitSegment}). Link targets use
38
+ * the narrower {@link isUnsafeArchivePath}: a target can only be reached
39
+ * through a member name that was checked here.
40
+ */
41
+ function isUnsafeArchiveMemberName(name) {
42
+ return isUnsafeArchivePath(name) || hasGitSegment(name);
43
+ }
44
+ /**
45
+ * Validates entry names from a `tar -tf` listing: escaping paths and
46
+ * `.git` members are both rejected.
24
47
  * @param names - Listing lines (one member name per line)
25
- * @returns The first unsafe member name, or null when all are safe
48
+ * @returns The first unsafe member name, or undefined when all are safe
26
49
  */
27
50
  export function findUnsafeArchiveEntryName(names) {
28
51
  for (const raw of names) {
29
52
  const name = raw.trim();
30
53
  if (name.length === 0)
31
54
  continue;
32
- if (isUnsafeArchivePath(name))
55
+ if (isUnsafeArchiveMemberName(name))
33
56
  return name;
34
57
  }
35
- return null;
58
+ return undefined;
36
59
  }
37
60
  /**
38
61
  * Validates symlink and hardlink targets from a `tar -tvf` listing.
39
62
  *
40
63
  * A relative link target without `..` segments can only resolve inside the
41
64
  * extraction root, so only absolute or `..`-containing targets are rejected.
42
- * Symlinks are `l`-typed lines with a ` -> target` suffix (the LAST arrow is
65
+ * Symlinks are `l`-typed lines with a ` -> target` suffix (the last arrow is
43
66
  * taken, so a link whose own name contains ` -> ` still parses to its real
44
- * target); hardlinks print ` link to target` on GNU tar and bsdtar alike.
67
+ * target). Hardlinks print ` link to target` on GNU tar and bsdtar alike.
45
68
  *
46
69
  * @param verboseLines - `tar -tvf` listing lines
47
- * @returns A description of the first unsafe link found, or null
70
+ * @returns A description of the first unsafe link found, or undefined
48
71
  */
49
72
  export function findUnsafeArchiveLink(verboseLines) {
50
73
  for (const line of verboseLines) {
@@ -64,19 +87,19 @@ export function findUnsafeArchiveLink(verboseLines) {
64
87
  return `hardlink target: ${target}`;
65
88
  }
66
89
  }
67
- return null;
90
+ return undefined;
68
91
  }
69
92
  /**
70
93
  * Lists the archive and rejects members that could escape the extraction
71
94
  * root before anything is written to disk: absolute names, `..` traversal,
72
95
  * and symlink/hardlink targets that are absolute or `..`-escaping. Modern
73
- * GNU tar / bsdtar refuse most of these at extraction time; the preflight
96
+ * GNU tar / bsdtar refuse most of these at extraction time. The preflight
74
97
  * makes the guarantee explicit and independent of the host tar's defaults.
75
98
  *
76
99
  * Two listings are needed because they answer different questions and
77
100
  * neither is safe to derive from the other: member names come from `-tf`,
78
- * where the whole line IS the name, while link targets only appear in
79
- * `-tvf`. Names are deliberately NOT parsed out of the `-tvf` columns — the
101
+ * where the whole line is the name, while link targets only appear in
102
+ * `-tvf`. Names are not parsed out of the `-tvf` columns, on purpose: the
80
103
  * adjacent uname/gname fields are attacker-controlled in a crafted archive,
81
104
  * so a date-shaped owner name could shift the column boundary and hide an
82
105
  * absolute member name from the check. Each listing pass costs one full
@@ -111,23 +134,23 @@ function createLineScanner(onLine) {
111
134
  }
112
135
  /**
113
136
  * Runs one tar listing pass, streaming lines through `checkLine` and
114
- * returning the first unsafe finding (or null) plus the exit code.
137
+ * returning the first unsafe finding (or undefined) plus the exit code.
115
138
  *
116
139
  * Streaming matters for safety, not just memory: a buffered `exec` collector
117
140
  * silently truncates at 50 MB, and a full Firefox `-tvf` listing already
118
- * sits in the 40–50 MB range — so a buffered implementation scans only the
141
+ * sits in the 40-50 MB range, so a buffered implementation scans only the
119
142
  * head of the listing while reporting the archive safe. A crafted archive
120
- * could exploit exactly that by padding benign entries first and hiding a
143
+ * could exploit that by padding benign entries first and hiding a
121
144
  * traversal name or absolute link target past the cap. Per-line streaming
122
- * scans EVERY entry with bounded memory.
145
+ * scans every entry with bounded memory.
123
146
  */
124
147
  async function runListingScan(archivePath, tarFlag, checkLine) {
125
148
  // LC_ALL=C keeps the -tvf column format stable for the link parse.
126
149
  const listEnv = { LC_ALL: 'C', LANG: 'C' };
127
- let unsafe = null;
150
+ let unsafe;
128
151
  let stderrTail = '';
129
152
  const scanner = createLineScanner((line) => {
130
- if (unsafe === null) {
153
+ if (unsafe === undefined) {
131
154
  unsafe = checkLine(line);
132
155
  }
133
156
  });
@@ -137,7 +160,7 @@ async function runListingScan(archivePath, tarFlag, checkLine) {
137
160
  scanner.push(chunk);
138
161
  },
139
162
  onStderr: (chunk) => {
140
- // Keep a small diagnostic tail; the listing itself is the big stream.
163
+ // Keep a small diagnostic tail. The listing itself is the big stream.
141
164
  stderrTail = (stderrTail + chunk).slice(-4096);
142
165
  },
143
166
  });
@@ -146,24 +169,19 @@ async function runListingScan(archivePath, tarFlag, checkLine) {
146
169
  }
147
170
  async function preflightArchiveEntries(archivePath) {
148
171
  const [nameScan, linkScan] = await Promise.all([
149
- runListingScan(archivePath, '-tf', (line) => {
150
- const name = line.trim();
151
- if (name.length === 0)
152
- return null;
153
- return isUnsafeArchivePath(name) ? name : null;
154
- }),
172
+ runListingScan(archivePath, '-tf', (line) => findUnsafeArchiveEntryName([line])),
155
173
  runListingScan(archivePath, '-tvf', (line) => findUnsafeArchiveLink([line])),
156
174
  ]);
157
175
  if (nameScan.exitCode !== 0) {
158
176
  throw new ExtractionError(archivePath, new Error(`tar -tf preflight exited with code ${nameScan.exitCode}:\n${nameScan.stderrTail}`));
159
177
  }
160
- if (nameScan.unsafe !== null) {
161
- throw new ExtractionError(archivePath, new Error(`Archive rejected: member name could escape the extraction root: ${nameScan.unsafe}`));
178
+ if (nameScan.unsafe !== undefined) {
179
+ throw new ExtractionError(archivePath, new Error(`Archive rejected: member name could escape the extraction root or seed .git: ${nameScan.unsafe}`));
162
180
  }
163
181
  if (linkScan.exitCode !== 0) {
164
182
  throw new ExtractionError(archivePath, new Error(`tar -tvf preflight exited with code ${linkScan.exitCode}:\n${linkScan.stderrTail}`));
165
183
  }
166
- if (linkScan.unsafe !== null) {
184
+ if (linkScan.unsafe !== undefined) {
167
185
  throw new ExtractionError(archivePath, new Error(`Archive rejected: link could escape the extraction root (${linkScan.unsafe})`));
168
186
  }
169
187
  }
@@ -5,26 +5,9 @@
5
5
  * {@link downloadFirefoxSource} orchestrator.
6
6
  */
7
7
  import type { FirefoxProduct } from '../types/config.js';
8
+ import type { ArchiveIntegrityOptions } from './firefox-cache.js';
8
9
  import type { ProgressCallback } from './firefox-download.js';
9
- export { resolveArchive } from './firefox-archive.js';
10
- export type { ProgressCallback } from './firefox-download.js';
11
10
  export { formatBytes, getFirefoxVersion } from './firefox-extract.js';
12
- /**
13
- * Gets the download URL for a Firefox source tarball.
14
- * @param version - Firefox version (e.g., "140.9.0esr")
15
- * @param product - Firefox product type
16
- * @param candidate - Optional release-candidate build directory (e.g. "build2")
17
- * @returns Full URL to the source tarball
18
- */
19
- export declare function getDownloadUrl(version: string, product?: FirefoxProduct, candidate?: string): string;
20
- /**
21
- * Gets the filename for a Firefox source tarball.
22
- * @param version - Firefox version
23
- * @param product - Firefox product type
24
- * @param candidate - Optional release-candidate build directory (e.g. "build2")
25
- * @returns Tarball filename
26
- */
27
- export declare function getTarballFilename(version: string, product?: FirefoxProduct, candidate?: string): string;
28
11
  /**
29
12
  * Lifecycle phase reported by {@link downloadFirefoxSource}. The download
30
13
  * CLI command uses this to swap spinners between the bytes-on-the-wire phase
@@ -41,28 +24,43 @@ export type FirefoxSourceProgressCallback = (message: string) => void;
41
24
  * Sweeps orphaned working directories left behind by interrupted downloads
42
25
  * (`<engine>.tmp-*` from extraction, `<engine>.replacement-*` from --force
43
26
  * replacement). Both hold multi-GB partial trees, are worthless after the
44
- * owning process died, and nothing else ever reclaimed them. Deliberately
45
- * does NOT touch `<engine>.backup-*`: a backup may hold the operator's
46
- * previous engine after a failed forced replacement and is their recovery
47
- * copy — callers should surface its existence instead.
27
+ * owning process died, and nothing else ever reclaimed them. Does not
28
+ * touch `<engine>.backup-*`: a backup may hold the operator's previous
29
+ * engine after a failed forced replacement and is their recovery copy, so
30
+ * callers should surface its existence instead.
48
31
  *
49
32
  * @returns names of the directories that were removed
50
33
  */
51
34
  export declare function sweepOrphanedEngineWorkDirs(destDir: string): Promise<string[]>;
35
+ /** Inputs for {@link downloadFirefoxSource}. */
36
+ export interface DownloadFirefoxSourceOptions {
37
+ /** Firefox version to fetch, e.g. `140.9.0esr`. */
38
+ version: string;
39
+ /** Product channel the version belongs to. */
40
+ product: FirefoxProduct;
41
+ /** Directory the extracted source tree is moved into. */
42
+ destDir: string;
43
+ /** Directory holding downloaded tarballs between runs. */
44
+ cacheDir: string;
45
+ /** Called with byte progress for the whole transfer. */
46
+ onProgress?: ProgressCallback | undefined;
47
+ /** Called when the run moves from downloading to extracting. */
48
+ onPhase?: FirefoxSourcePhaseCallback | undefined;
49
+ /** Expected archive checksum, verified after download when supplied. */
50
+ expectedSha256?: string | undefined;
51
+ /** Called with byte progress within the current phase. */
52
+ onPhaseProgress?: FirefoxSourceProgressCallback | undefined;
53
+ /**
54
+ * Release-candidate build directory (e.g. `build2`), resolving the archive
55
+ * under `candidates/` instead of `releases/`.
56
+ */
57
+ candidate?: string | undefined;
58
+ /** Integrity-check defaults for unpinned downloads. */
59
+ integrity?: ArchiveIntegrityOptions | undefined;
60
+ }
52
61
  /**
53
62
  * Downloads and extracts Firefox source.
54
- * @param version - Firefox version to download
55
- * @param product - Firefox product type
56
- * @param destDir - Destination directory for extracted source
57
- * @param cacheDir - Directory to store downloaded tarball
58
- * @param onProgress - Optional progress callback for the download byte stream
59
- * @param onPhase - Optional callback fired when the function transitions
60
- * between phases (`'download'` → `'extract'`). Fires exactly once per
61
- * phase even if the cached archive path skips the wire entirely.
62
- * @param expectedSha256 - Expected archive checksum; verified after download when supplied
63
- * @param onPhaseProgress - Called with byte progress within the current phase
64
- * @param candidate - Optional release-candidate build directory (e.g.
65
- * "build2") resolving the archive under `candidates/` instead of
66
- * `releases/`.
63
+ *
64
+ * @param options - See {@link DownloadFirefoxSourceOptions}.
67
65
  */
68
- export declare function downloadFirefoxSource(version: string, product: FirefoxProduct, destDir: string, cacheDir: string, onProgress?: ProgressCallback, onPhase?: FirefoxSourcePhaseCallback, expectedSha256?: string, onPhaseProgress?: FirefoxSourceProgressCallback, candidate?: string): Promise<void>;
66
+ export declare function downloadFirefoxSource(options: DownloadFirefoxSourceOptions): Promise<void>;
@@ -14,33 +14,12 @@ import { resolveArchive } from './firefox-archive.js';
14
14
  import { ensureCachedArchive, invalidateArchiveCache } from './firefox-cache.js';
15
15
  import { extractTarXz } from './firefox-extract.js';
16
16
  // ── Re-exports (preserve public API) ──
17
- export { resolveArchive } from './firefox-archive.js';
18
17
  export { formatBytes, getFirefoxVersion } from './firefox-extract.js';
19
- /**
20
- * Gets the download URL for a Firefox source tarball.
21
- * @param version - Firefox version (e.g., "140.9.0esr")
22
- * @param product - Firefox product type
23
- * @param candidate - Optional release-candidate build directory (e.g. "build2")
24
- * @returns Full URL to the source tarball
25
- */
26
- export function getDownloadUrl(version, product = 'firefox', candidate) {
27
- return resolveArchive(version, product, candidate).url;
28
- }
29
- /**
30
- * Gets the filename for a Firefox source tarball.
31
- * @param version - Firefox version
32
- * @param product - Firefox product type
33
- * @param candidate - Optional release-candidate build directory (e.g. "build2")
34
- * @returns Tarball filename
35
- */
36
- export function getTarballFilename(version, product = 'firefox', candidate) {
37
- return resolveArchive(version, product, candidate).filename;
38
- }
39
18
  /**
40
19
  * Classifies an extraction failure as archive corruption (invalidate the
41
20
  * cache and re-download) versus an environmental problem (keep the cached
42
- * archive; the retry can reuse it). Environmental signatures are the
43
- * conservative list — anything unrecognized is treated as corruption so a
21
+ * archive so the retry can reuse it). Environmental signatures are the
22
+ * conservative list. Anything unrecognized is treated as corruption so a
44
23
  * genuinely bad archive can never survive in the cache.
45
24
  */
46
25
  function isLikelyArchiveCorruptionError(error) {
@@ -53,7 +32,7 @@ function isLikelyArchiveCorruptionError(error) {
53
32
  return false;
54
33
  }
55
34
  // Missing tar binary / preflight refusing an unsafe archive both carry
56
- // ExtractionError text that names the condition; a missing tar is
35
+ // ExtractionError text that names the condition. A missing tar is
57
36
  // environmental, an unsafe-entry rejection indicts the archive.
58
37
  if (/"tar" command was not found/i.test(message)) {
59
38
  return false;
@@ -64,10 +43,10 @@ function isLikelyArchiveCorruptionError(error) {
64
43
  * Sweeps orphaned working directories left behind by interrupted downloads
65
44
  * (`<engine>.tmp-*` from extraction, `<engine>.replacement-*` from --force
66
45
  * replacement). Both hold multi-GB partial trees, are worthless after the
67
- * owning process died, and nothing else ever reclaimed them. Deliberately
68
- * does NOT touch `<engine>.backup-*`: a backup may hold the operator's
69
- * previous engine after a failed forced replacement and is their recovery
70
- * copy — callers should surface its existence instead.
46
+ * owning process died, and nothing else ever reclaimed them. Does not
47
+ * touch `<engine>.backup-*`: a backup may hold the operator's previous
48
+ * engine after a failed forced replacement and is their recovery copy, so
49
+ * callers should surface its existence instead.
71
50
  *
72
51
  * @returns names of the directories that were removed
73
52
  */
@@ -95,27 +74,17 @@ export async function sweepOrphanedEngineWorkDirs(destDir) {
95
74
  }
96
75
  /**
97
76
  * Downloads and extracts Firefox source.
98
- * @param version - Firefox version to download
99
- * @param product - Firefox product type
100
- * @param destDir - Destination directory for extracted source
101
- * @param cacheDir - Directory to store downloaded tarball
102
- * @param onProgress - Optional progress callback for the download byte stream
103
- * @param onPhase - Optional callback fired when the function transitions
104
- * between phases (`'download'` → `'extract'`). Fires exactly once per
105
- * phase even if the cached archive path skips the wire entirely.
106
- * @param expectedSha256 - Expected archive checksum; verified after download when supplied
107
- * @param onPhaseProgress - Called with byte progress within the current phase
108
- * @param candidate - Optional release-candidate build directory (e.g.
109
- * "build2") resolving the archive under `candidates/` instead of
110
- * `releases/`.
77
+ *
78
+ * @param options - See {@link DownloadFirefoxSourceOptions}.
111
79
  */
112
- export async function downloadFirefoxSource(version, product, destDir, cacheDir, onProgress, onPhase, expectedSha256, onPhaseProgress, candidate) {
80
+ export async function downloadFirefoxSource(options) {
81
+ const { version, product, destDir, cacheDir, onProgress, onPhase, expectedSha256, onPhaseProgress, candidate, integrity, } = options;
113
82
  const archive = resolveArchive(version, product, candidate);
114
83
  const tarballPath = join(cacheDir, archive.filename);
115
84
  // Ensure cache directory exists
116
85
  await ensureDir(cacheDir);
117
86
  onPhase?.('download');
118
- await ensureCachedArchive(archive, cacheDir, onProgress, expectedSha256, onPhaseProgress);
87
+ await ensureCachedArchive(archive, cacheDir, onProgress, expectedSha256, onPhaseProgress, integrity);
119
88
  // Extract to a unique temporary directory so concurrent downloads for
120
89
  // the same destination do not clobber each other.
121
90
  onPhase?.('extract');
@@ -126,7 +95,7 @@ export async function downloadFirefoxSource(version, product, destDir, cacheDir,
126
95
  catch (error) {
127
96
  await removeDir(tempDir);
128
97
  // Only throw away the ~600 MB cached archive when the failure indicts
129
- // the ARCHIVE, not the environment. ENOSPC, a permission problem in
98
+ // the archive, not the environment. ENOSPC, a permission problem in
130
99
  // destDir, or tar disappearing mid-run used to invalidate a perfectly
131
100
  // good download and force a full re-fetch on retry.
132
101
  if (isLikelyArchiveCorruptionError(error)) {
@@ -4,14 +4,9 @@
4
4
  * stay within the per-file line budget. Consumed only by that module.
5
5
  */
6
6
  import type { ComponentApplyContext, CustomComponentConfig, DryRunAction, StepError } from '../types/furnace.js';
7
- interface DirectoryEntry {
8
- isFile(): boolean;
9
- isSymbolicLink?(): boolean;
10
- name: string;
11
- }
7
+ import { type DirectoryEntry } from './furnace-dir-entry.js';
12
8
  /** Computes the planned dry-run actions (and pre-flight step errors) for a custom component. */
13
9
  export declare function buildCustomDryRunActions(ctx: Pick<ComponentApplyContext, 'engineDir' | 'name' | 'componentDir' | 'ftlDir'>, config: CustomComponentConfig, targetDir: string, entries: DirectoryEntry[]): Promise<{
14
10
  actions: DryRunAction[];
15
11
  stepErrors: StepError[];
16
12
  }>;
17
- export {};
@@ -9,14 +9,8 @@ import { toError } from '../utils/errors.js';
9
9
  import { pathExists } from '../utils/fs.js';
10
10
  import { describeLocaleFtlJarMnRegistration, describeSharedFtlPrune } from './furnace-apply-ftl.js';
11
11
  import { describeFragmentExpansion } from './furnace-css-fragments.js';
12
+ import { isRegularFile } from './furnace-dir-entry.js';
12
13
  import { validateCustomElementRegistration, validateJarMnInsertionForFiles, } from './furnace-registration.js';
13
- function isRegularFile(entry) {
14
- if (!entry.isFile())
15
- return false;
16
- if (typeof entry.isSymbolicLink === 'function' && entry.isSymbolicLink())
17
- return false;
18
- return true;
19
- }
20
14
  /** Computes the planned dry-run actions (and pre-flight step errors) for a custom component. */
21
15
  export async function buildCustomDryRunActions(ctx, config, targetDir, entries) {
22
16
  const { engineDir, name, componentDir, ftlDir } = ctx;
@@ -58,7 +52,7 @@ export async function buildCustomDryRunActions(ctx, config, targetDir, entries)
58
52
  }
59
53
  }
60
54
  }
61
- // A sharedFtl widget owns its strings via the shared bundle; surface the
55
+ // A sharedFtl widget owns its strings via the shared bundle. Surface the
62
56
  // removal of any dangling per-widget locale jar.mn entry so the dry-run
63
57
  // plan matches what apply will do (and explains the unblocked build).
64
58
  const pruneAction = await describeSharedFtlPrune(ctx, config);
@@ -4,9 +4,9 @@
4
4
  * per-file LOC budget.
5
5
  *
6
6
  * Every helper here degrades gracefully: if the locale jar.mn is missing or
7
- * the FTL tree is non-standard, apply logs an ADVISORY `stepError`
7
+ * the FTL tree is non-standard, apply logs an advisory `stepError`
8
8
  * (`advisory: true`) rather than aborting the whole command. Advisory step
9
- * errors are reported as warnings and never trigger rollback — a missing
9
+ * errors are reported as warnings and never trigger rollback: a missing
10
10
  * jar.mn on a fork without a locale package must not block a working
11
11
  * `.mjs`/`.css` from shipping.
12
12
  */
@@ -29,8 +29,8 @@ export declare function describeSharedFtlPrune(ctx: Pick<ComponentApplyContext,
29
29
  * in the locale jar.mn.
30
30
  *
31
31
  * Failure modes (missing jar.mn, regex write error) are captured as
32
- * stepErrors rather than thrown — a well-formed `.mjs`/`.css` must never be
33
- * blocked by a broken locale path.
32
+ * stepErrors rather than thrown, since a well-formed `.mjs`/`.css` must
33
+ * never be blocked by a broken locale path.
34
34
  */
35
35
  export declare function applyCustomFtlFile(ctx: Pick<ComponentApplyContext, 'engineDir' | 'name' | 'componentDir' | 'ftlDir'>, affectedPaths: string[], stepErrors: StepError[], rollbackJournal?: RollbackJournal): Promise<void>;
36
36
  /**
@@ -41,7 +41,7 @@ export declare function applyCustomFtlFile(ctx: Pick<ComponentApplyContext, 'eng
41
41
  export declare function describeLocaleFtlJarMnRegistration(name: string, ftlDir: string, ftlFile: string): DryRunAction | undefined;
42
42
  /**
43
43
  * Drops the locale jar.mn entry for `fileName` when it's a `.ftl` whose
44
- * source workspace file has been deleted. Idempotent — absent entries are a
44
+ * source workspace file has been deleted. Idempotent: absent entries are a
45
45
  * no-op. Early-returns for `sharedFtl` components: the shared bundle is
46
46
  * owned elsewhere, and dropping its jar.mn line on our component's delete
47
47
  * would orphan every other participant.
@@ -5,9 +5,9 @@
5
5
  * per-file LOC budget.
6
6
  *
7
7
  * Every helper here degrades gracefully: if the locale jar.mn is missing or
8
- * the FTL tree is non-standard, apply logs an ADVISORY `stepError`
8
+ * the FTL tree is non-standard, apply logs an advisory `stepError`
9
9
  * (`advisory: true`) rather than aborting the whole command. Advisory step
10
- * errors are reported as warnings and never trigger rollback — a missing
10
+ * errors are reported as warnings and never trigger rollback: a missing
11
11
  * jar.mn on a fork without a locale package must not block a working
12
12
  * `.mjs`/`.css` from shipping.
13
13
  */
@@ -44,12 +44,12 @@ function resolveSharedFtlPruneTarget(name, ftlDir) {
44
44
  *
45
45
  * A `localized: true` widget that opts into a feature-scoped `sharedFtl`
46
46
  * bundle (its strings live under `browser/...` and load via
47
- * `insertFTLIfNeeded`) must NOT carry a per-widget
47
+ * `insertFTLIfNeeded`) must not carry a per-widget
48
48
  * `locale/@AB_CD@/<chromeSubPath>/<name>.ftl` line. Such a line points at a
49
49
  * `.ftl` that does not exist, so `mach build` fails hard (`Cannot find
50
50
  * <chromeSubPath>/<name>.ftl`) and blocks every build.
51
51
  *
52
- * The pruned line is the per-widget toolkit entry only; the shared bundle's
52
+ * The pruned line is the per-widget toolkit entry only. The shared bundle's
53
53
  * own line (a different chrome sub-path / base name) is never matched, so
54
54
  * pruning one widget cannot orphan the shared bundle. Idempotent: when no
55
55
  * dangling entry exists the file is left untouched (no journal churn).
@@ -120,8 +120,8 @@ export async function describeSharedFtlPrune(ctx, config) {
120
120
  * in the locale jar.mn.
121
121
  *
122
122
  * Failure modes (missing jar.mn, regex write error) are captured as
123
- * stepErrors rather than thrown — a well-formed `.mjs`/`.css` must never be
124
- * blocked by a broken locale path.
123
+ * stepErrors rather than thrown, since a well-formed `.mjs`/`.css` must
124
+ * never be blocked by a broken locale path.
125
125
  */
126
126
  export async function applyCustomFtlFile(ctx, affectedPaths, stepErrors, rollbackJournal) {
127
127
  const { engineDir, name, componentDir, ftlDir } = ctx;
@@ -134,7 +134,7 @@ export async function applyCustomFtlFile(ctx, affectedPaths, stepErrors, rollbac
134
134
  await snapshotFile(rollbackJournal, ftlDest);
135
135
  }
136
136
  await copyFile(ftlSrc, ftlDest);
137
- // Sibling pushes on this list are POSIX literals (`localeJarRel`); keep
137
+ // Sibling pushes on this list are POSIX literals (`localeJarRel`). Keep
138
138
  // the computed one in the same spelling.
139
139
  affectedPaths.push(normalizePathSlashes(relative(engineDir, ftlDest)));
140
140
  const chromeSubPath = resolveFtlChromeSubPath(ftlDir);
@@ -185,7 +185,7 @@ export function describeLocaleFtlJarMnRegistration(name, ftlDir, ftlFile) {
185
185
  }
186
186
  /**
187
187
  * Drops the locale jar.mn entry for `fileName` when it's a `.ftl` whose
188
- * source workspace file has been deleted. Idempotent — absent entries are a
188
+ * source workspace file has been deleted. Idempotent: absent entries are a
189
189
  * no-op. Early-returns for `sharedFtl` components: the shared bundle is
190
190
  * owned elsewhere, and dropping its jar.mn line on our component's delete
191
191
  * would orphan every other participant.