@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
@@ -3,10 +3,10 @@ export declare function extractComponentChecksums(allChecksums: Record<string, s
3
3
  /** Prefixes component checksums so they can be stored in the flattened state format. */
4
4
  export declare function prefixChecksums(checksums: Record<string, string>, type: string, name: string): Record<string, string>;
5
5
  /**
6
- * Returns the filenames present in `previous` that are absent from `current`
7
- * — i.e. files we know we deployed last time but the workspace has since
8
- * deleted. The order of returned names is intentionally stable
9
- * (sorted alphabetically) so test snapshots and CLI output are deterministic.
6
+ * Returns the filenames present in `previous` that are absent from
7
+ * `current`, i.e. files we know we deployed last time but the workspace has
8
+ * since deleted. The order of returned names is stable (sorted
9
+ * alphabetically) so test snapshots and CLI output are deterministic.
10
10
  */
11
11
  export declare function diffDeletedFiles(previous: Record<string, string>, current: Record<string, string>): string[];
12
12
  /**
@@ -15,7 +15,7 @@ export declare function diffDeletedFiles(previous: Record<string, string>, curre
15
15
  * Strips a leading BOM and folds CRLF to LF, so a file that differs from its
16
16
  * deployed copy only by line endings or a byte-order mark is not reported as
17
17
  * drift. Every comparison that decides "has this component changed?" must
18
- * use it — otherwise `furnace status` and `furnace validate` can disagree
18
+ * use it. Otherwise `furnace status` and `furnace validate` can disagree
19
19
  * with `apply`'s skip fast-path about the same pair of files on a CRLF
20
20
  * checkout.
21
21
  *
@@ -22,10 +22,10 @@ export function prefixChecksums(checksums, type, name) {
22
22
  return result;
23
23
  }
24
24
  /**
25
- * Returns the filenames present in `previous` that are absent from `current`
26
- * — i.e. files we know we deployed last time but the workspace has since
27
- * deleted. The order of returned names is intentionally stable
28
- * (sorted alphabetically) so test snapshots and CLI output are deterministic.
25
+ * Returns the filenames present in `previous` that are absent from
26
+ * `current`, i.e. files we know we deployed last time but the workspace has
27
+ * since deleted. The order of returned names is stable (sorted
28
+ * alphabetically) so test snapshots and CLI output are deterministic.
29
29
  */
30
30
  export function diffDeletedFiles(previous, current) {
31
31
  const deleted = [];
@@ -42,7 +42,7 @@ export function diffDeletedFiles(previous, current) {
42
42
  * Strips a leading BOM and folds CRLF to LF, so a file that differs from its
43
43
  * deployed copy only by line endings or a byte-order mark is not reported as
44
44
  * drift. Every comparison that decides "has this component changed?" must
45
- * use it — otherwise `furnace status` and `furnace validate` can disagree
45
+ * use it. Otherwise `furnace status` and `furnace validate` can disagree
46
46
  * with `apply`'s skip fast-path about the same pair of files on a CRLF
47
47
  * checkout.
48
48
  *
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Parser for the `custom` entries in furnace.json. Extracted from
3
3
  * `furnace-config.ts` so the main config module stays under the
4
- * per-file LOC budget — the custom-component schema has grown to
4
+ * per-file LOC budget. The custom-component schema has grown to
5
5
  * carry opt-in fields (`composes`, `keyboardCovered`, `sharedFtl`) that
6
6
  * each add their own validation branch.
7
7
  */
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Parser for the `custom` entries in furnace.json. Extracted from
4
4
  * `furnace-config.ts` so the main config module stays under the
5
- * per-file LOC budget — the custom-component schema has grown to
5
+ * per-file LOC budget. The custom-component schema has grown to
6
6
  * carry opt-in fields (`composes`, `keyboardCovered`, `sharedFtl`) that
7
7
  * each add their own validation branch.
8
8
  */
@@ -65,7 +65,7 @@ export function parseCustomConfig(data, name) {
65
65
  ? { composes: parseStringArray(data['composes'], `${name}.composes`) }
66
66
  : {}),
67
67
  ...(data['keyboardCovered'] === true ? { keyboardCovered: true } : {}),
68
- // Explicit `kind: "element"` is the default; normalize it away so the
68
+ // Explicit `kind: "element"` is the default. Normalize it away so the
69
69
  // stored config carries the field only when it changes behavior.
70
70
  ...(data['kind'] === 'library' ? { kind: 'library' } : {}),
71
71
  ...(sharedFtl !== undefined ? { sharedFtl } : {}),
@@ -60,7 +60,7 @@ function orderComponentMapLikeExisting(existing, next) {
60
60
  export function orderFurnaceConfigForWrite(existing, config) {
61
61
  // FurnaceConfig is plain parsed-JSON data, but as an interface it carries
62
62
  // no index signature, so the compiler cannot verify the JsonObject
63
- // contract structurally — hence the double assertion. This is the one
63
+ // contract structurally, hence the double assertion. This is the one
64
64
  // place a typed furnace config re-enters the raw-document world.
65
65
  // eslint-disable-next-line no-restricted-syntax -- see above
66
66
  const next = config;
@@ -6,12 +6,12 @@
6
6
  /**
7
7
  * Validates a `tokenHostDocuments` raw value. Each entry must be a non-empty
8
8
  * relative path contained in the engine tree. Throws `FurnaceError` on
9
- * violation; does nothing for `undefined` (field is optional).
9
+ * violation. Does nothing for `undefined` (field is optional).
10
10
  */
11
11
  export declare function validateTokenHostDocuments(raw: unknown): void;
12
12
  /**
13
13
  * Validates a `runtimeVariables` raw value. Each entry must start with `--`
14
- * (it is a CSS custom property name). Throws `FurnaceError` on violation;
15
- * does nothing for `undefined` (field is optional).
14
+ * (it is a CSS custom property name). Throws `FurnaceError` on violation.
15
+ * Does nothing for `undefined` (field is optional).
16
16
  */
17
17
  export declare function validateRuntimeVariables(raw: unknown): void;
@@ -10,7 +10,7 @@ import { parseStringArray } from './furnace-config-array-utils.js';
10
10
  /**
11
11
  * Validates a `tokenHostDocuments` raw value. Each entry must be a non-empty
12
12
  * relative path contained in the engine tree. Throws `FurnaceError` on
13
- * violation; does nothing for `undefined` (field is optional).
13
+ * violation. Does nothing for `undefined` (field is optional).
14
14
  */
15
15
  export function validateTokenHostDocuments(raw) {
16
16
  if (raw === undefined)
@@ -27,8 +27,8 @@ export function validateTokenHostDocuments(raw) {
27
27
  }
28
28
  /**
29
29
  * Validates a `runtimeVariables` raw value. Each entry must start with `--`
30
- * (it is a CSS custom property name). Throws `FurnaceError` on violation;
31
- * does nothing for `undefined` (field is optional).
30
+ * (it is a CSS custom property name). Throws `FurnaceError` on violation.
31
+ * Does nothing for `undefined` (field is optional).
32
32
  */
33
33
  export function validateRuntimeVariables(raw) {
34
34
  if (raw === undefined)
@@ -110,8 +110,8 @@ export function applyOptionalFurnaceFields(migrated, config) {
110
110
  }
111
111
  config.ftlBasePath = migrated['ftlBasePath'];
112
112
  }
113
- // Validate optional typecheckJsconfig — consumer-owned jsconfig whose
114
- // chrome-elements `paths` entries Furnace maintains on deploy.
113
+ // Validate optional typecheckJsconfig. This is a consumer-owned jsconfig
114
+ // whose chrome-elements `paths` entries Furnace maintains on deploy.
115
115
  if (migrated['typecheckJsconfig'] !== undefined) {
116
116
  const jsconfigPath = migrated['typecheckJsconfig'];
117
117
  if (!isString(jsconfigPath) || jsconfigPath.includes('..')) {
@@ -6,7 +6,7 @@ export declare const SHARED_FRAGMENTS_DIR = "shared";
6
6
  /**
7
7
  * Paths for furnace-related files and directories.
8
8
  */
9
- interface FurnacePaths {
9
+ export interface FurnacePaths {
10
10
  /** Path to furnace.json */
11
11
  furnaceConfig: string;
12
12
  /** Path to components directory */
@@ -70,8 +70,8 @@ export declare function writeFurnaceConfig(root: string, config: FurnaceConfig):
70
70
  * matching override stamp `doctor` fails Furnace component validation on
71
71
  * every override.
72
72
  *
73
- * The stamp is deliberately unconditional — `fireforge furnace validate` is
74
- * the right tool for "does this override still apply", and rebase has
73
+ * The stamp is unconditional: `fireforge furnace validate` is the right
74
+ * tool for "does this override still apply", and rebase has
75
75
  * already attested that the patch layer re-validated against the new ESR.
76
76
  *
77
77
  * @param root - Root directory of the project
@@ -92,11 +92,11 @@ export declare function stampFurnaceOverrideBaseVersions(root: string, version:
92
92
  * declarations.
93
93
  *
94
94
  * `validateFurnaceConfig` treats `tokenPrefix` as optional, so callers on
95
- * the no-arg call shape still get a valid config without a prefix; the CLI
95
+ * the no-arg call shape still get a valid config without a prefix. The CLI
96
96
  * init path always has a `binaryName` from `fireforge.json` and always sets
97
97
  * one.
98
98
  *
99
- * @param options - Optional init context; pass `{ binaryName }` to derive
99
+ * @param options - Optional init context. Pass `{ binaryName }` to derive
100
100
  * the token prefix.
101
101
  * @returns A valid FurnaceConfig
102
102
  */
@@ -53,25 +53,18 @@ export async function furnaceConfigExists(root) {
53
53
  const paths = getFurnacePaths(root);
54
54
  return pathExists(paths.furnaceConfig);
55
55
  }
56
+ /** True when a recovered record carries at least one entry. */
57
+ function hasEntries(record) {
58
+ return Object.keys(record).length > 0;
59
+ }
56
60
  /** The current (and only) config schema version. */
57
61
  const CURRENT_CONFIG_VERSION = 1;
58
62
  /**
59
- * Migrates a furnace config from an older schema version to the current one.
60
- * Returns the data unchanged if it is already at the current version.
61
- *
62
- * When a future version 2 is introduced, add a `case 1:` that transforms
63
- * v1 data into v2 shape and falls through to validation. The pattern is:
64
- *
65
- * ```
66
- * case 1:
67
- * data = migrateV1ToV2(data);
68
- * // fallthrough
69
- * case 2:
70
- * break;
71
- * ```
63
+ * Rejects a config whose `version` field is not the single schema version that
64
+ * exists. A non-integer or sub-1 value is a malformed document. A value above
65
+ * the current version was written by a newer FireForge and cannot be read here.
72
66
  */
73
- function migrateFurnaceConfig(data) {
74
- const version = data['version'];
67
+ function validateConfigVersion(version) {
75
68
  if (typeof version !== 'number' || !Number.isInteger(version) || version < 1) {
76
69
  throw new FurnaceError(`Furnace config: "version" must be a positive integer (got ${JSON.stringify(version)}). ` +
77
70
  `Current schema version is ${CURRENT_CONFIG_VERSION}.`);
@@ -80,9 +73,6 @@ function migrateFurnaceConfig(data) {
80
73
  throw new FurnaceError(`Furnace config: version ${version} is newer than what this version of FireForge supports (${CURRENT_CONFIG_VERSION}). ` +
81
74
  'Upgrade FireForge to read this config.');
82
75
  }
83
- // Today only version 1 exists, so no migration is needed. When future
84
- // versions are added, migration steps will be chained here.
85
- return data;
86
76
  }
87
77
  /**
88
78
  * Validates a raw config object and returns a typed FurnaceConfig.
@@ -97,39 +87,36 @@ export function validateFurnaceConfig(data) {
97
87
  // Furnace config documents arrive from JSON.parse (loadFurnaceConfig /
98
88
  // writeFurnaceConfig round-trips), which can only produce JSON values,
99
89
  // so the object check above is the only invariant left to establish.
100
- // Run migration before validation so older configs are transparently upgraded.
101
- const migrated = migrateFurnaceConfig(data);
102
- if (migrated['version'] !== CURRENT_CONFIG_VERSION) {
103
- throw new FurnaceError(`Furnace config: "version" must be ${CURRENT_CONFIG_VERSION} after migration`);
104
- }
105
- if (!isString(migrated['componentPrefix'])) {
90
+ const raw = data;
91
+ validateConfigVersion(raw['version']);
92
+ if (!isString(raw['componentPrefix'])) {
106
93
  throw new FurnaceError('Furnace config: "componentPrefix" must be a string');
107
94
  }
108
95
  // Validate optional tokenPrefix
109
- if (migrated['tokenPrefix'] !== undefined && !isString(migrated['tokenPrefix'])) {
96
+ if (raw['tokenPrefix'] !== undefined && !isString(raw['tokenPrefix'])) {
110
97
  throw new FurnaceError('Furnace config: "tokenPrefix" must be a string if provided');
111
98
  }
112
99
  // Validate optional tokenAllowlist
113
- if (migrated['tokenAllowlist'] !== undefined) {
114
- parseStringArray(migrated['tokenAllowlist'], 'tokenAllowlist');
100
+ if (raw['tokenAllowlist'] !== undefined) {
101
+ parseStringArray(raw['tokenAllowlist'], 'tokenAllowlist');
115
102
  }
116
- // Validate optional runtimeVariables — CSS runtime state channels
103
+ // Validate optional runtimeVariables: CSS runtime state channels
117
104
  // (e.g. `--cam-x`) that are exempt from `token-prefix-violation`.
118
- validateRuntimeVariables(migrated['runtimeVariables']);
119
- // Validate optional tokenHostDocuments — list of chrome XHTMLs that the
105
+ validateRuntimeVariables(raw['runtimeVariables']);
106
+ // Validate optional tokenHostDocuments: list of chrome XHTMLs that the
120
107
  // `missing-token-link` validator scans for the tokens CSS link.
121
- validateTokenHostDocuments(migrated['tokenHostDocuments']);
122
- const stock = parseStockList(migrated['stock']);
123
- const overrides = parseNamedComponentMap(migrated['overrides'], 'override', 'overrides', parseOverrideConfig);
124
- const custom = parseNamedComponentMap(migrated['custom'], 'custom', 'custom', parseCustomConfig);
108
+ validateTokenHostDocuments(raw['tokenHostDocuments']);
109
+ const stock = parseStockList(raw['stock']);
110
+ const overrides = parseNamedComponentMap(raw['overrides'], 'override', 'overrides', parseOverrideConfig);
111
+ const custom = parseNamedComponentMap(raw['custom'], 'custom', 'custom', parseCustomConfig);
125
112
  // Detect circular composes references among custom components.
126
113
  detectComposesCycles(custom);
127
114
  // Validate that every composes reference points to a known component.
128
115
  validateComposesReferences(stock, overrides, custom);
129
116
  // Warn when two custom components share a targetPath. Nothing technically
130
117
  // prevents co-location, but per-component removal and orphan detection
131
- // both reason about "files this component deployed into its directory" —
132
- // shared directories make those judgements ambiguous, and can lead to
118
+ // both reason about "files this component deployed into its directory".
119
+ // Shared directories make those judgements ambiguous, and can lead to
133
120
  // `furnace remove` of one component deleting the other's deployed files.
134
121
  const targetPathOwners = new Map();
135
122
  for (const [name, custom_] of Object.entries(custom)) {
@@ -146,12 +133,12 @@ export function validateFurnaceConfig(data) {
146
133
  }
147
134
  const config = {
148
135
  version: CURRENT_CONFIG_VERSION,
149
- componentPrefix: migrated['componentPrefix'],
136
+ componentPrefix: raw['componentPrefix'],
150
137
  stock,
151
138
  overrides,
152
139
  custom,
153
140
  };
154
- applyOptionalFurnaceFields(migrated, config);
141
+ applyOptionalFurnaceFields(raw, config);
155
142
  return config;
156
143
  }
157
144
  /**
@@ -167,8 +154,8 @@ function validateFurnaceState(data) {
167
154
  return result.state;
168
155
  }
169
156
  // Single source of truth: the list the union is derived from. The copy
170
- // this replaced was annotated, not linked — it caught a member REMOVED
171
- // from the union but never one ADDED to it, and listed them in a
157
+ // this replaced was annotated rather than linked, so it caught a member
158
+ // removed from the union but never one added to it, and listed them in a
172
159
  // different order.
173
160
  const PENDING_REPAIR_OPERATIONS = FURNACE_PENDING_REPAIR_OPERATIONS;
174
161
  function parsePendingRepair(data) {
@@ -228,7 +215,7 @@ function sanitizeFurnaceState(data) {
228
215
  }
229
216
  appliedChecksums[filePath] = checksum;
230
217
  }
231
- if (Object.keys(appliedChecksums).length > 0 || !hasInvalidChecksum) {
218
+ if (hasEntries(appliedChecksums) || !hasInvalidChecksum) {
232
219
  state.appliedChecksums = appliedChecksums;
233
220
  recoveredFields.push('appliedChecksums');
234
221
  }
@@ -245,7 +232,7 @@ function sanitizeFurnaceState(data) {
245
232
  engineChecksums[filePath] = checksum;
246
233
  }
247
234
  }
248
- if (Object.keys(engineChecksums).length > 0) {
235
+ if (hasEntries(engineChecksums)) {
249
236
  state.engineChecksums = engineChecksums;
250
237
  recoveredFields.push('engineChecksums');
251
238
  }
@@ -351,14 +338,14 @@ export async function writeFurnaceConfig(root, config) {
351
338
  if (await pathExists(paths.furnaceConfig)) {
352
339
  try {
353
340
  const raw = await readJson(paths.furnaceConfig);
354
- // JSON.parse output is JSON data by construction, so the object
355
- // check is the only invariant left for the JsonObject contract.
341
+ // JSON.parse only produces JSON data, so the object check is the
342
+ // only invariant left for the JsonObject contract.
356
343
  if (isObject(raw))
357
344
  existing = raw;
358
345
  }
359
346
  catch {
360
347
  // A missing or corrupt furnace.json means there is no prior document to
361
- // preserve key order from; the writer falls back to canonical ordering.
348
+ // preserve key order from. The writer falls back to canonical ordering.
362
349
  existing = undefined;
363
350
  }
364
351
  }
@@ -372,8 +359,8 @@ export async function writeFurnaceConfig(root, config) {
372
359
  * matching override stamp `doctor` fails Furnace component validation on
373
360
  * every override.
374
361
  *
375
- * The stamp is deliberately unconditional — `fireforge furnace validate` is
376
- * the right tool for "does this override still apply", and rebase has
362
+ * The stamp is unconditional: `fireforge furnace validate` is the right
363
+ * tool for "does this override still apply", and rebase has
377
364
  * already attested that the patch layer re-validated against the new ESR.
378
365
  *
379
366
  * @param root - Root directory of the project
@@ -409,11 +396,11 @@ export async function stampFurnaceOverrideBaseVersions(root, version) {
409
396
  * declarations.
410
397
  *
411
398
  * `validateFurnaceConfig` treats `tokenPrefix` as optional, so callers on
412
- * the no-arg call shape still get a valid config without a prefix; the CLI
399
+ * the no-arg call shape still get a valid config without a prefix. The CLI
413
400
  * init path always has a `binaryName` from `fireforge.json` and always sets
414
401
  * one.
415
402
  *
416
- * @param options - Optional init context; pass `{ binaryName }` to derive
403
+ * @param options - Optional init context. Pass `{ binaryName }` to derive
417
404
  * the token prefix.
418
405
  * @returns A valid FurnaceConfig
419
406
  */
@@ -481,8 +468,8 @@ export async function updateFurnaceState(root, updates) {
481
468
  * Engine-relative path of the directory `furnace preview` writes its
482
469
  * generated Storybook story files into. Treated as Furnace-managed so
483
470
  * `status` does not flag them as unmanaged and `lint` does not fail on their
484
- * (intentionally bare) license headers — they are tool output, not files an
485
- * operator commits or hand-edits.
471
+ * (intentionally bare) license headers. They are tool output rather than
472
+ * files an operator commits or hand-edits.
486
473
  */
487
474
  const FURNACE_STORYBOOK_STORIES_PREFIX = 'browser/components/storybook/stories/furnace/';
488
475
  /**
@@ -517,8 +504,8 @@ export async function collectFurnaceManagedPrefixes(root) {
517
504
  }
518
505
  // Always include the preview-generated stories prefix when furnace is
519
506
  // initialised. The directory may not exist yet (no preview ever ran),
520
- // but classifying it as furnace-managed is safe even when empty —
521
- // status simply has nothing to bucket.
507
+ // but classifying it as furnace-managed is safe even when empty. Status
508
+ // simply has nothing to bucket.
522
509
  prefixes.add(FURNACE_STORYBOOK_STORIES_PREFIX);
523
510
  return prefixes;
524
511
  }
@@ -5,7 +5,7 @@ export declare const JAR_MN = "toolkit/content/jar.mn";
5
5
  /**
6
6
  * Upstream home of the MozLitElement widget sources.
7
7
  *
8
- * The trailing slash is NOT included: `build-audit-transforms.ts` needs
8
+ * The trailing slash is not included: `build-audit-transforms.ts` needs
9
9
  * `${WIDGETS_DIR}/` and its ordered prefix table depends on that slash, so
10
10
  * appending it at the one site that wants it keeps the others correct.
11
11
  */
@@ -27,15 +27,15 @@ export declare function xpcshellTestParentDir(binaryName: string): string;
27
27
  /**
28
28
  * Resolves the engine-relative directory a browser-chrome scaffold is
29
29
  * written to: the `--test-dir` override when given, else
30
- * `browser/base/content/test/<binaryName>`. The scaffolder AND the
30
+ * `browser/base/content/test/<binaryName>`. The scaffolder and the
31
31
  * dry-run / success formatters resolve through this one function, so the
32
32
  * printed plan cannot disagree with the files that land on disk.
33
33
  */
34
34
  export declare function resolveBrowserChromeTestDir(binaryName: string, override?: string): string;
35
35
  /**
36
36
  * Resolves the engine-relative directory an xpcshell scaffold is written
37
- * to. A `--test-dir` override names the FINAL directory (no per-component
38
- * segment is appended); the default is
37
+ * to. A `--test-dir` override names the final directory (no per-component
38
+ * segment is appended). The default is
39
39
  * `browser/base/content/test/<binaryName>-xpcshell/<componentName>`.
40
40
  */
41
41
  export declare function resolveXpcshellTestDir(binaryName: string, componentName: string, override?: string): string;
@@ -62,8 +62,8 @@ export declare function resolveFtlChromeSubPath(ftlBasePath?: string): string |
62
62
  * given `ftlBasePath`. For the default toolkit tree this yields
63
63
  * `toolkit/locales/jar.mn`.
64
64
  *
65
- * Returns `undefined` when the path does not contain a `locales/` segment —
66
- * callers must treat that as "cannot locate" and degrade gracefully.
65
+ * Returns `undefined` when the path does not contain a `locales/` segment.
66
+ * Callers must treat that as "cannot locate" and degrade gracefully.
67
67
  */
68
68
  export declare function resolveFtlLocaleJarMnPath(ftlBasePath?: string): string | undefined;
69
69
  /**
@@ -1,12 +1,13 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /** Path to customElements.js within the engine source tree */
3
3
  export const CUSTOM_ELEMENTS_JS = 'toolkit/content/customElements.js';
4
+ import { normalizePathSlashes } from '../utils/paths.js';
4
5
  /** Path to jar.mn within the engine source tree (toolkit global) */
5
6
  export const JAR_MN = 'toolkit/content/jar.mn';
6
7
  /**
7
8
  * Upstream home of the MozLitElement widget sources.
8
9
  *
9
- * The trailing slash is NOT included: `build-audit-transforms.ts` needs
10
+ * The trailing slash is not included: `build-audit-transforms.ts` needs
10
11
  * `${WIDGETS_DIR}/` and its ordered prefix table depends on that slash, so
11
12
  * appending it at the one site that wants it keeps the others correct.
12
13
  */
@@ -38,7 +39,7 @@ export function xpcshellTestParentDir(binaryName) {
38
39
  /**
39
40
  * Resolves the engine-relative directory a browser-chrome scaffold is
40
41
  * written to: the `--test-dir` override when given, else
41
- * `browser/base/content/test/<binaryName>`. The scaffolder AND the
42
+ * `browser/base/content/test/<binaryName>`. The scaffolder and the
42
43
  * dry-run / success formatters resolve through this one function, so the
43
44
  * printed plan cannot disagree with the files that land on disk.
44
45
  */
@@ -47,8 +48,8 @@ export function resolveBrowserChromeTestDir(binaryName, override) {
47
48
  }
48
49
  /**
49
50
  * Resolves the engine-relative directory an xpcshell scaffold is written
50
- * to. A `--test-dir` override names the FINAL directory (no per-component
51
- * segment is appended); the default is
51
+ * to. A `--test-dir` override names the final directory (no per-component
52
+ * segment is appended). The default is
52
53
  * `browser/base/content/test/<binaryName>-xpcshell/<componentName>`.
53
54
  */
54
55
  export function resolveXpcshellTestDir(binaryName, componentName, override) {
@@ -78,7 +79,7 @@ export function resolveFtlDir(configuredPath) {
78
79
  * degrade gracefully rather than inventing a path.
79
80
  */
80
81
  export function resolveFtlChromeSubPath(ftlBasePath) {
81
- const path = (ftlBasePath ?? FTL_DIR).replace(/\\/g, '/');
82
+ const path = normalizePathSlashes(ftlBasePath ?? FTL_DIR);
82
83
  const match = /^(.*?)\/locales\/[^/]+\/(.+?)\/?$/.exec(path);
83
84
  if (!match?.[2])
84
85
  return undefined;
@@ -89,11 +90,11 @@ export function resolveFtlChromeSubPath(ftlBasePath) {
89
90
  * given `ftlBasePath`. For the default toolkit tree this yields
90
91
  * `toolkit/locales/jar.mn`.
91
92
  *
92
- * Returns `undefined` when the path does not contain a `locales/` segment —
93
- * callers must treat that as "cannot locate" and degrade gracefully.
93
+ * Returns `undefined` when the path does not contain a `locales/` segment.
94
+ * Callers must treat that as "cannot locate" and degrade gracefully.
94
95
  */
95
96
  export function resolveFtlLocaleJarMnPath(ftlBasePath) {
96
- const path = (ftlBasePath ?? FTL_DIR).replace(/\\/g, '/');
97
+ const path = normalizePathSlashes(ftlBasePath ?? FTL_DIR);
97
98
  const match = /^(.*?)\/locales\/[^/]+\//.exec(path);
98
99
  if (!match?.[1])
99
100
  return undefined;
@@ -9,8 +9,8 @@
9
9
  * @fireforge-include shared-anims.css
10
10
  *
11
11
  * naming a fragment file in `components/shared/`. `furnace deploy` expands
12
- * the fragment into the *deployed* copy only — the workspace source stays
13
- * DRY — fencing the expansion between the directive line and a matching
12
+ * the fragment into the *deployed* copy only (the workspace source stays
13
+ * DRY), fencing the expansion between the directive line and a matching
14
14
  * `@fireforge-end-include` marker so re-deploys can refresh it idempotently.
15
15
  *
16
16
  * Drift contract: the apply fast-path and `furnace validate` compare the
@@ -24,7 +24,7 @@ export { SHARED_FRAGMENTS_DIR } from './furnace-config.js';
24
24
  export declare function listFragmentIncludes(css: string): string[];
25
25
  /**
26
26
  * Collapses fenced fragment expansions back to their bare directives.
27
- * Inverse of {@link expandCssFragments}; used to compare a deployed file
27
+ * Inverse of {@link expandCssFragments}. Used to compare a deployed file
28
28
  * against its workspace source and to re-expand idempotently.
29
29
  */
30
30
  export declare function stripExpandedFragments(css: string): string;
@@ -52,7 +52,7 @@ export declare function expandCssFragments(css: string, sharedDir: string): Prom
52
52
  export declare function extractExpandedFragmentBodies(css: string): Map<string, string>;
53
53
  /**
54
54
  * Deploys one component file: CSS sources carrying include directives are
55
- * written as their fragment-expanded form; everything else is a plain
55
+ * written as their fragment-expanded form. Everything else is a plain
56
56
  * copy. Extracted here so `applyCustomComponent` stays inside the
57
57
  * per-file line budget.
58
58
  *
@@ -73,7 +73,7 @@ export declare function describeFragmentExpansion(src: string): Promise<string>;
73
73
  * @param componentDir - Workspace directory of the component
74
74
  * @param tagName - Component tag name for issue attribution
75
75
  * @param sharedDir - Shared fragments directory
76
- * @param engineTargetDir - Deployed directory in the engine (optional —
77
- * pre-deploy validation skips the staleness check)
76
+ * @param engineTargetDir - Deployed directory in the engine. Optional, and
77
+ * pre-deploy validation skips the staleness check.
78
78
  */
79
79
  export declare function validateCssFragments(componentDir: string, tagName: string, sharedDir: string, engineTargetDir?: string): Promise<ValidationIssue[]>;
@@ -10,8 +10,8 @@
10
10
  * @fireforge-include shared-anims.css
11
11
  *
12
12
  * naming a fragment file in `components/shared/`. `furnace deploy` expands
13
- * the fragment into the *deployed* copy only — the workspace source stays
14
- * DRY — fencing the expansion between the directive line and a matching
13
+ * the fragment into the *deployed* copy only (the workspace source stays
14
+ * DRY), fencing the expansion between the directive line and a matching
15
15
  * `@fireforge-end-include` marker so re-deploys can refresh it idempotently.
16
16
  *
17
17
  * Drift contract: the apply fast-path and `furnace validate` compare the
@@ -24,7 +24,7 @@ import { join } from 'node:path';
24
24
  import { FurnaceError } from '../errors/furnace.js';
25
25
  import { copyFile, pathExists, readText, writeText } from '../utils/fs.js';
26
26
  export { SHARED_FRAGMENTS_DIR } from './furnace-config.js';
27
- // Local copy of the directory name for message text — importing the
27
+ // Local copy of the directory name for message text. Importing the
28
28
  // binding for value use keeps a single source of truth.
29
29
  import { SHARED_FRAGMENTS_DIR } from './furnace-config.js';
30
30
  const INCLUDE_PATTERN = /^\s*\/\*\s*@fireforge-include\s+([\w./-]+)\s*\*\/\s*$/;
@@ -41,7 +41,7 @@ export function listFragmentIncludes(css) {
41
41
  }
42
42
  /**
43
43
  * Collapses fenced fragment expansions back to their bare directives.
44
- * Inverse of {@link expandCssFragments}; used to compare a deployed file
44
+ * Inverse of {@link expandCssFragments}. Used to compare a deployed file
45
45
  * against its workspace source and to re-expand idempotently.
46
46
  */
47
47
  export function stripExpandedFragments(css) {
@@ -54,8 +54,8 @@ export function stripExpandedFragments(css) {
54
54
  if (!inc?.[1])
55
55
  continue;
56
56
  // A bare directive (workspace file) has no fence to strip. Only skip
57
- // the expansion body when a matching end marker actually follows —
58
- // otherwise an unterminated fence would silently eat the rest of the
57
+ // the expansion body when a matching end marker actually follows.
58
+ // Otherwise an unterminated fence would silently eat the rest of the
59
59
  // file.
60
60
  let endIndex = -1;
61
61
  for (let j = i + 1; j < lines.length; j++) {
@@ -141,7 +141,7 @@ export function extractExpandedFragmentBodies(css) {
141
141
  }
142
142
  /**
143
143
  * Deploys one component file: CSS sources carrying include directives are
144
- * written as their fragment-expanded form; everything else is a plain
144
+ * written as their fragment-expanded form. Everything else is a plain
145
145
  * copy. Extracted here so `applyCustomComponent` stays inside the
146
146
  * per-file line budget.
147
147
  *
@@ -180,8 +180,8 @@ export async function describeFragmentExpansion(src) {
180
180
  * @param componentDir - Workspace directory of the component
181
181
  * @param tagName - Component tag name for issue attribution
182
182
  * @param sharedDir - Shared fragments directory
183
- * @param engineTargetDir - Deployed directory in the engine (optional —
184
- * pre-deploy validation skips the staleness check)
183
+ * @param engineTargetDir - Deployed directory in the engine. Optional, and
184
+ * pre-deploy validation skips the staleness check.
185
185
  */
186
186
  export async function validateCssFragments(componentDir, tagName, sharedDir, engineTargetDir) {
187
187
  const issues = [];
@@ -194,8 +194,8 @@ export async function validateCssFragments(componentDir, tagName, sharedDir, eng
194
194
  entries = await readdir(componentDir);
195
195
  }
196
196
  catch {
197
- // An unreadable component directory contributes no fragment issues; return
198
- // what has been collected so far rather than failing validation.
197
+ // An unreadable component directory contributes no fragment issues.
198
+ // Return what has been collected so far rather than failing validation.
199
199
  return issues;
200
200
  }
201
201
  for (const fileName of entries) {
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The minimal `readdir(..., { withFileTypes: true })` entry shape the furnace
3
+ * apply path needs, plus the single predicate that decides whether an entry is
4
+ * a copy candidate. Kept in its own leaf module so both `furnace-apply-helpers`
5
+ * and its dry-run mirror can share one definition without importing each other.
6
+ */
7
+ /** Structural subset of `Dirent` used by the furnace apply/dry-run walkers. */
8
+ export interface DirectoryEntry {
9
+ isFile(): boolean;
10
+ isSymbolicLink?(): boolean;
11
+ name: string;
12
+ }
13
+ /**
14
+ * True for a plain-file directory entry. Symlinks and directories are
15
+ * never copy candidates.
16
+ *
17
+ * @param entry - Directory entry to classify
18
+ * @returns True when the entry is a regular file
19
+ */
20
+ export declare function isRegularFile(entry: DirectoryEntry): boolean;
@@ -0,0 +1,21 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * The minimal `readdir(..., { withFileTypes: true })` entry shape the furnace
4
+ * apply path needs, plus the single predicate that decides whether an entry is
5
+ * a copy candidate. Kept in its own leaf module so both `furnace-apply-helpers`
6
+ * and its dry-run mirror can share one definition without importing each other.
7
+ */
8
+ /**
9
+ * True for a plain-file directory entry. Symlinks and directories are
10
+ * never copy candidates.
11
+ *
12
+ * @param entry - Directory entry to classify
13
+ * @returns True when the entry is a regular file
14
+ */
15
+ export function isRegularFile(entry) {
16
+ if (!entry.isFile())
17
+ return false;
18
+ if (typeof entry.isSymbolicLink === 'function' && entry.isSymbolicLink())
19
+ return false;
20
+ return true;
21
+ }