@hominis/fireforge 0.43.1 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/README.md +3 -3
  3. package/dist/bin/fireforge.d.ts +4 -9
  4. package/dist/bin/fireforge.js +42 -40
  5. package/dist/build-info.json +4 -4
  6. package/dist/src/cli.js +74 -8
  7. package/dist/src/commands/bootstrap.js +17 -20
  8. package/dist/src/commands/build.js +25 -32
  9. package/dist/src/commands/config.js +34 -41
  10. package/dist/src/commands/discard.js +8 -9
  11. package/dist/src/commands/doctor-check-core.d.ts +13 -18
  12. package/dist/src/commands/doctor-check-core.js +8 -35
  13. package/dist/src/commands/doctor-external-toolchains.js +2 -2
  14. package/dist/src/commands/doctor-furnace-config-sync.d.ts +18 -0
  15. package/dist/src/commands/{doctor-furnace-manifest-sync.js → doctor-furnace-config-sync.js} +27 -26
  16. package/dist/src/commands/doctor-furnace-jar.d.ts +7 -9
  17. package/dist/src/commands/doctor-furnace-jar.js +7 -9
  18. package/dist/src/commands/doctor-furnace.js +21 -24
  19. package/dist/src/commands/doctor-orphaned-harness.d.ts +16 -20
  20. package/dist/src/commands/doctor-orphaned-harness.js +18 -44
  21. package/dist/src/commands/doctor-patch-manifest.d.ts +8 -0
  22. package/dist/src/commands/doctor-patch-manifest.js +155 -0
  23. package/dist/src/commands/doctor-post-rebase-audit.d.ts +2 -0
  24. package/dist/src/commands/{doctor/post-rebase-audit.js → doctor-post-rebase-audit.js} +3 -3
  25. package/dist/src/commands/doctor-working-tree.d.ts +10 -12
  26. package/dist/src/commands/doctor-working-tree.js +11 -18
  27. package/dist/src/commands/doctor.d.ts +1 -1
  28. package/dist/src/commands/doctor.js +64 -96
  29. package/dist/src/commands/download.js +32 -48
  30. package/dist/src/commands/export-all.js +29 -33
  31. package/dist/src/commands/export-flow.js +6 -6
  32. package/dist/src/commands/export-placement-conflicts.js +10 -9
  33. package/dist/src/commands/export-placement-gate.js +5 -5
  34. package/dist/src/commands/export-shared.d.ts +30 -33
  35. package/dist/src/commands/export-shared.js +45 -43
  36. package/dist/src/commands/export.js +21 -27
  37. package/dist/src/commands/furnace/apply.js +14 -23
  38. package/dist/src/commands/furnace/chrome-doc-remove.js +14 -21
  39. package/dist/src/commands/furnace/chrome-doc-templates.d.ts +23 -23
  40. package/dist/src/commands/furnace/chrome-doc-templates.js +23 -23
  41. package/dist/src/commands/furnace/chrome-doc-tests.js +26 -29
  42. package/dist/src/commands/furnace/chrome-doc.d.ts +16 -17
  43. package/dist/src/commands/furnace/chrome-doc.js +31 -41
  44. package/dist/src/commands/furnace/create-browser-test.d.ts +4 -4
  45. package/dist/src/commands/furnace/create-browser-test.js +8 -8
  46. package/dist/src/commands/furnace/create-mochikit.d.ts +6 -7
  47. package/dist/src/commands/furnace/create-mochikit.js +8 -9
  48. package/dist/src/commands/furnace/create-readback.d.ts +12 -13
  49. package/dist/src/commands/furnace/create-readback.js +12 -13
  50. package/dist/src/commands/furnace/create-templates.d.ts +22 -28
  51. package/dist/src/commands/furnace/create-templates.js +35 -30
  52. package/dist/src/commands/furnace/create-xpcshell.js +2 -2
  53. package/dist/src/commands/furnace/create.js +33 -23
  54. package/dist/src/commands/furnace/deploy.js +16 -24
  55. package/dist/src/commands/furnace/diff.js +15 -10
  56. package/dist/src/commands/furnace/init.js +33 -36
  57. package/dist/src/commands/furnace/override.js +23 -25
  58. package/dist/src/commands/furnace/preview.js +47 -67
  59. package/dist/src/commands/furnace/refresh.js +12 -16
  60. package/dist/src/commands/furnace/remove-mutations.d.ts +3 -6
  61. package/dist/src/commands/furnace/remove-mutations.js +14 -17
  62. package/dist/src/commands/furnace/remove-state.js +1 -1
  63. package/dist/src/commands/furnace/remove.js +33 -38
  64. package/dist/src/commands/furnace/rename-xpcshell.d.ts +8 -11
  65. package/dist/src/commands/furnace/rename-xpcshell.js +8 -11
  66. package/dist/src/commands/furnace/rename.js +59 -69
  67. package/dist/src/commands/furnace/scan.js +19 -33
  68. package/dist/src/commands/furnace/status.js +12 -9
  69. package/dist/src/commands/furnace/sync.js +9 -16
  70. package/dist/src/commands/furnace/validate.js +20 -20
  71. package/dist/src/commands/import.js +48 -37
  72. package/dist/src/commands/lint-per-patch.js +15 -10
  73. package/dist/src/commands/lint-per-run-checkjs.d.ts +13 -13
  74. package/dist/src/commands/lint-per-run-checkjs.js +13 -13
  75. package/dist/src/commands/lint-report.js +6 -7
  76. package/dist/src/commands/lint.d.ts +15 -16
  77. package/dist/src/commands/lint.js +86 -102
  78. package/dist/src/commands/package.js +6 -11
  79. package/dist/src/commands/patch/compact.js +1 -1
  80. package/dist/src/commands/patch/delete.js +24 -33
  81. package/dist/src/commands/patch/index.d.ts +5 -6
  82. package/dist/src/commands/patch/index.js +10 -12
  83. package/dist/src/commands/patch/lint-ignore.js +14 -13
  84. package/dist/src/commands/patch/move-files-create.d.ts +6 -6
  85. package/dist/src/commands/patch/move-files-create.js +8 -8
  86. package/dist/src/commands/patch/move-files-into.d.ts +6 -6
  87. package/dist/src/commands/patch/move-files-into.js +8 -8
  88. package/dist/src/commands/patch/patch-context.d.ts +2 -3
  89. package/dist/src/commands/patch/patch-context.js +2 -3
  90. package/dist/src/commands/patch/rename.d.ts +10 -11
  91. package/dist/src/commands/patch/rename.js +11 -12
  92. package/dist/src/commands/patch/reorder.js +8 -9
  93. package/dist/src/commands/patch/split-plan.js +1 -1
  94. package/dist/src/commands/patch/split.d.ts +8 -10
  95. package/dist/src/commands/patch/split.js +9 -11
  96. package/dist/src/commands/patch/staged-dependency-validate.js +8 -8
  97. package/dist/src/commands/patch/staged-dependency.js +7 -3
  98. package/dist/src/commands/patch/tier.d.ts +9 -9
  99. package/dist/src/commands/patch/tier.js +18 -15
  100. package/dist/src/commands/re-export-adjacent.js +9 -8
  101. package/dist/src/commands/re-export-bulk-scan.d.ts +9 -9
  102. package/dist/src/commands/re-export-bulk-scan.js +22 -21
  103. package/dist/src/commands/re-export-drift.js +10 -10
  104. package/dist/src/commands/re-export-files.d.ts +6 -7
  105. package/dist/src/commands/re-export-files.js +34 -44
  106. package/dist/src/commands/re-export-lint.d.ts +10 -13
  107. package/dist/src/commands/re-export-lint.js +16 -14
  108. package/dist/src/commands/re-export-options.d.ts +6 -6
  109. package/dist/src/commands/re-export-options.js +6 -6
  110. package/dist/src/commands/re-export-register.d.ts +4 -10
  111. package/dist/src/commands/re-export-register.js +5 -11
  112. package/dist/src/commands/re-export-scan.js +1 -1
  113. package/dist/src/commands/re-export-single.d.ts +3 -3
  114. package/dist/src/commands/re-export-single.js +33 -25
  115. package/dist/src/commands/re-export.js +13 -21
  116. package/dist/src/commands/rebase/abort.js +3 -3
  117. package/dist/src/commands/rebase/confirm.js +2 -1
  118. package/dist/src/commands/rebase/continue.d.ts +1 -1
  119. package/dist/src/commands/rebase/continue.js +14 -9
  120. package/dist/src/commands/rebase/index.js +11 -11
  121. package/dist/src/commands/rebase/patch-loop.d.ts +7 -1
  122. package/dist/src/commands/rebase/patch-loop.js +60 -39
  123. package/dist/src/commands/rebase/summary.js +1 -1
  124. package/dist/src/commands/register.js +5 -7
  125. package/dist/src/commands/reset.js +2 -1
  126. package/dist/src/commands/resolve.d.ts +16 -13
  127. package/dist/src/commands/resolve.js +30 -33
  128. package/dist/src/commands/run.js +33 -35
  129. package/dist/src/commands/setup-support.js +15 -19
  130. package/dist/src/commands/setup.js +13 -9
  131. package/dist/src/commands/status-check.d.ts +6 -6
  132. package/dist/src/commands/status-json.d.ts +6 -6
  133. package/dist/src/commands/status-json.js +5 -0
  134. package/dist/src/commands/status-output.d.ts +5 -5
  135. package/dist/src/commands/status-output.js +6 -6
  136. package/dist/src/commands/status-ownership.d.ts +16 -14
  137. package/dist/src/commands/status-ownership.js +16 -14
  138. package/dist/src/commands/status.js +42 -34
  139. package/dist/src/commands/test-build-phase.js +26 -13
  140. package/dist/src/commands/test-diagnose.js +44 -44
  141. package/dist/src/commands/test-register.js +1 -0
  142. package/dist/src/commands/test-run.d.ts +14 -16
  143. package/dist/src/commands/test-run.js +21 -13
  144. package/dist/src/commands/test-stale-gate.d.ts +15 -16
  145. package/dist/src/commands/test-stale-gate.js +15 -16
  146. package/dist/src/commands/test-verdict.d.ts +20 -3
  147. package/dist/src/commands/test-verdict.js +30 -0
  148. package/dist/src/commands/test.js +83 -76
  149. package/dist/src/commands/token-coverage.js +3 -4
  150. package/dist/src/commands/token.js +16 -18
  151. package/dist/src/commands/tree.js +47 -31
  152. package/dist/src/commands/typecheck.d.ts +10 -12
  153. package/dist/src/commands/typecheck.js +24 -27
  154. package/dist/src/commands/verify.js +13 -15
  155. package/dist/src/commands/watch.js +21 -23
  156. package/dist/src/commands/wire.js +52 -62
  157. package/dist/src/core/ast-utils.d.ts +8 -7
  158. package/dist/src/core/ast-utils.js +8 -7
  159. package/dist/src/core/branding.d.ts +9 -14
  160. package/dist/src/core/branding.js +7 -11
  161. package/dist/src/core/browser-wire.d.ts +1 -1
  162. package/dist/src/core/browser-wire.js +14 -19
  163. package/dist/src/core/build-audit-platform.js +25 -33
  164. package/dist/src/core/build-audit-registration.js +17 -25
  165. package/dist/src/core/build-audit-resolve.d.ts +15 -17
  166. package/dist/src/core/build-audit-resolve.js +39 -36
  167. package/dist/src/core/build-audit-transforms.js +18 -19
  168. package/dist/src/core/build-audit.js +28 -42
  169. package/dist/src/core/build-baseline-types.d.ts +29 -35
  170. package/dist/src/core/build-baseline.d.ts +5 -4
  171. package/dist/src/core/build-baseline.js +14 -14
  172. package/dist/src/core/build-overwrite-guard.d.ts +7 -14
  173. package/dist/src/core/build-overwrite-guard.js +17 -27
  174. package/dist/src/core/build-prepare.d.ts +2 -2
  175. package/dist/src/core/build-prepare.js +8 -9
  176. package/dist/src/core/config-mutate.js +20 -19
  177. package/dist/src/core/config-state.js +12 -4
  178. package/dist/src/core/config-validate.js +8 -5
  179. package/dist/src/core/config.d.ts +5 -8
  180. package/dist/src/core/config.js +7 -16
  181. package/dist/src/core/coverage-extend.d.ts +15 -13
  182. package/dist/src/core/coverage-extend.js +15 -13
  183. package/dist/src/core/destructive.d.ts +31 -9
  184. package/dist/src/core/destructive.js +29 -26
  185. package/dist/src/core/diff-hunks.js +10 -12
  186. package/dist/src/core/discard-baseline.d.ts +8 -8
  187. package/dist/src/core/discard-baseline.js +16 -15
  188. package/dist/src/core/display-state.d.ts +12 -14
  189. package/dist/src/core/display-state.js +12 -14
  190. package/dist/src/core/engine-changes.d.ts +2 -4
  191. package/dist/src/core/engine-changes.js +2 -4
  192. package/dist/src/core/engine-precondition.d.ts +28 -13
  193. package/dist/src/core/engine-precondition.js +25 -10
  194. package/dist/src/core/engine-session-lock.d.ts +47 -21
  195. package/dist/src/core/engine-session-lock.js +168 -33
  196. package/dist/src/core/export-moved-code-shape.d.ts +10 -10
  197. package/dist/src/core/export-moved-code-shape.js +10 -10
  198. package/dist/src/core/file-lock.d.ts +62 -5
  199. package/dist/src/core/file-lock.js +196 -59
  200. package/dist/src/core/firefox-cache.js +1 -3
  201. package/dist/src/core/firefox-extract.js +10 -14
  202. package/dist/src/core/firefox.d.ts +7 -5
  203. package/dist/src/core/firefox.js +4 -5
  204. package/dist/src/core/furnace-apply-dry-run.d.ts +2 -2
  205. package/dist/src/core/furnace-apply-dry-run.js +3 -2
  206. package/dist/src/core/furnace-apply-ftl.d.ts +7 -9
  207. package/dist/src/core/furnace-apply-ftl.js +16 -13
  208. package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
  209. package/dist/src/core/furnace-apply-helpers.js +30 -21
  210. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +8 -9
  211. package/dist/src/core/furnace-apply-overwrite-warn.js +8 -9
  212. package/dist/src/core/furnace-apply-undeploy-actions.d.ts +3 -4
  213. package/dist/src/core/furnace-apply-undeploy-actions.js +3 -4
  214. package/dist/src/core/furnace-apply.d.ts +5 -8
  215. package/dist/src/core/furnace-apply.js +19 -24
  216. package/dist/src/core/furnace-checksum-utils.d.ts +14 -0
  217. package/dist/src/core/furnace-checksum-utils.js +16 -0
  218. package/dist/src/core/furnace-config.d.ts +21 -30
  219. package/dist/src/core/furnace-config.js +32 -54
  220. package/dist/src/core/furnace-constants.d.ts +8 -0
  221. package/dist/src/core/furnace-constants.js +10 -2
  222. package/dist/src/core/furnace-css-fragments.d.ts +5 -5
  223. package/dist/src/core/furnace-css-fragments.js +5 -5
  224. package/dist/src/core/furnace-jsconfig.d.ts +11 -12
  225. package/dist/src/core/furnace-jsconfig.js +11 -12
  226. package/dist/src/core/furnace-marker.d.ts +7 -8
  227. package/dist/src/core/furnace-marker.js +7 -8
  228. package/dist/src/core/furnace-operation.d.ts +31 -0
  229. package/dist/src/core/furnace-operation.js +54 -17
  230. package/dist/src/core/furnace-precondition.d.ts +61 -0
  231. package/dist/src/core/furnace-precondition.js +67 -0
  232. package/dist/src/core/furnace-registration-remove.d.ts +5 -6
  233. package/dist/src/core/furnace-registration-remove.js +6 -7
  234. package/dist/src/core/furnace-registration-validate.d.ts +13 -0
  235. package/dist/src/core/furnace-registration-validate.js +20 -1
  236. package/dist/src/core/furnace-registration.d.ts +5 -6
  237. package/dist/src/core/furnace-registration.js +10 -12
  238. package/dist/src/core/furnace-rollback.js +7 -7
  239. package/dist/src/core/furnace-scanner.d.ts +1 -0
  240. package/dist/src/core/furnace-scanner.js +1 -2
  241. package/dist/src/core/furnace-stale-export.d.ts +10 -10
  242. package/dist/src/core/furnace-stale-export.js +10 -10
  243. package/dist/src/core/furnace-state-persist.d.ts +6 -8
  244. package/dist/src/core/furnace-state-persist.js +6 -8
  245. package/dist/src/core/furnace-validate-accessibility.d.ts +22 -0
  246. package/dist/src/core/furnace-validate-accessibility.js +310 -1
  247. package/dist/src/core/furnace-validate-compatibility.js +141 -1
  248. package/dist/src/core/furnace-validate-helpers.d.ts +5 -116
  249. package/dist/src/core/furnace-validate-helpers.js +0 -491
  250. package/dist/src/core/furnace-validate-registration.d.ts +7 -0
  251. package/dist/src/core/furnace-validate-registration.js +115 -41
  252. package/dist/src/core/furnace-validate.d.ts +16 -0
  253. package/dist/src/core/furnace-validate.js +188 -145
  254. package/dist/src/core/furnace-version-drift.d.ts +10 -11
  255. package/dist/src/core/furnace-version-drift.js +10 -11
  256. package/dist/src/core/git-base.d.ts +21 -9
  257. package/dist/src/core/git-base.js +24 -9
  258. package/dist/src/core/git-diff.d.ts +20 -9
  259. package/dist/src/core/git-diff.js +148 -63
  260. package/dist/src/core/git-file-ops.d.ts +19 -19
  261. package/dist/src/core/git-file-ops.js +19 -19
  262. package/dist/src/core/git-readonly-index.d.ts +53 -19
  263. package/dist/src/core/git-readonly-index.js +75 -31
  264. package/dist/src/core/git-status.d.ts +5 -6
  265. package/dist/src/core/git-status.js +5 -6
  266. package/dist/src/core/git.d.ts +9 -10
  267. package/dist/src/core/git.js +57 -71
  268. package/dist/src/core/license-headers.d.ts +17 -23
  269. package/dist/src/core/license-headers.js +17 -23
  270. package/dist/src/core/mach-build-artifacts.d.ts +9 -9
  271. package/dist/src/core/mach-build-artifacts.js +57 -19
  272. package/dist/src/core/mach-error-hints.js +42 -29
  273. package/dist/src/core/mach-known-noise-filter.d.ts +15 -16
  274. package/dist/src/core/mach-known-noise-filter.js +18 -20
  275. package/dist/src/core/mach-mozconfig.d.ts +14 -0
  276. package/dist/src/core/mach-mozconfig.js +30 -0
  277. package/dist/src/core/mach-resource-shim.d.ts +43 -58
  278. package/dist/src/core/mach-resource-shim.js +50 -67
  279. package/dist/src/core/mach.d.ts +37 -41
  280. package/dist/src/core/mach.js +50 -51
  281. package/dist/src/core/marionette-port.d.ts +36 -1
  282. package/dist/src/core/marionette-port.js +96 -31
  283. package/dist/src/core/marionette-preflight.d.ts +8 -12
  284. package/dist/src/core/marionette-preflight.js +86 -52
  285. package/dist/src/core/mochitest-server-port.d.ts +42 -0
  286. package/dist/src/core/mochitest-server-port.js +119 -0
  287. package/dist/src/core/module-resolution-preflight.d.ts +9 -11
  288. package/dist/src/core/module-resolution-preflight.js +9 -11
  289. package/dist/src/core/moz-manifest-helpers.d.ts +79 -0
  290. package/dist/src/core/moz-manifest-helpers.js +163 -0
  291. package/dist/src/core/{manifest-register.d.ts → moz-manifest-register.d.ts} +1 -1
  292. package/dist/src/core/{manifest-register.js → moz-manifest-register.js} +13 -28
  293. package/dist/src/core/{manifest-rules.d.ts → moz-manifest-rules.d.ts} +10 -1
  294. package/dist/src/core/{manifest-rules.js → moz-manifest-rules.js} +31 -24
  295. package/dist/src/core/{manifest-tokenizers.d.ts → moz-manifest-tokenizers.d.ts} +3 -5
  296. package/dist/src/core/{manifest-tokenizers.js → moz-manifest-tokenizers.js} +9 -12
  297. package/dist/src/core/ownership-table.d.ts +14 -16
  298. package/dist/src/core/ownership-table.js +14 -16
  299. package/dist/src/core/parser-fallback.d.ts +15 -1
  300. package/dist/src/core/parser-fallback.js +22 -3
  301. package/dist/src/core/patch-apply-fuzz.d.ts +10 -12
  302. package/dist/src/core/patch-apply-fuzz.js +15 -18
  303. package/dist/src/core/patch-apply.d.ts +13 -34
  304. package/dist/src/core/patch-apply.js +16 -76
  305. package/dist/src/core/patch-artifact-normalize.d.ts +13 -15
  306. package/dist/src/core/patch-artifact-normalize.js +13 -15
  307. package/dist/src/core/patch-export-metadata.d.ts +12 -2
  308. package/dist/src/core/patch-export-metadata.js +13 -4
  309. package/dist/src/core/patch-export-update.d.ts +13 -1
  310. package/dist/src/core/patch-export-update.js +25 -8
  311. package/dist/src/core/patch-export.d.ts +15 -8
  312. package/dist/src/core/patch-export.js +10 -11
  313. package/dist/src/core/patch-files.d.ts +5 -6
  314. package/dist/src/core/patch-files.js +5 -6
  315. package/dist/src/core/patch-identifier-suggest.d.ts +7 -12
  316. package/dist/src/core/patch-identifier-suggest.js +14 -19
  317. package/dist/src/core/patch-lint-binary.d.ts +51 -0
  318. package/dist/src/core/patch-lint-binary.js +39 -0
  319. package/dist/src/core/{lint-cache.d.ts → patch-lint-cache.d.ts} +5 -5
  320. package/dist/src/core/{lint-cache.js → patch-lint-cache.js} +21 -23
  321. package/dist/src/core/patch-lint-checkjs.d.ts +16 -16
  322. package/dist/src/core/patch-lint-checkjs.js +41 -20
  323. package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +6 -9
  324. package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -14
  325. package/dist/src/core/patch-lint-creators.d.ts +8 -8
  326. package/dist/src/core/patch-lint-creators.js +8 -8
  327. package/dist/src/core/patch-lint-cross.d.ts +17 -20
  328. package/dist/src/core/patch-lint-cross.js +16 -16
  329. package/dist/src/core/patch-lint-css.d.ts +3 -5
  330. package/dist/src/core/patch-lint-css.js +17 -22
  331. package/dist/src/core/patch-lint-diff-tag.d.ts +14 -16
  332. package/dist/src/core/patch-lint-diff-tag.js +14 -16
  333. package/dist/src/core/patch-lint-jsdoc.d.ts +7 -8
  334. package/dist/src/core/patch-lint-jsdoc.js +26 -19
  335. package/dist/src/core/patch-lint-mozbuild.js +20 -20
  336. package/dist/src/core/patch-lint-observer.d.ts +7 -7
  337. package/dist/src/core/patch-lint-observer.js +7 -7
  338. package/dist/src/core/patch-lint.d.ts +38 -29
  339. package/dist/src/core/patch-lint.js +89 -121
  340. package/dist/src/core/patch-lock.d.ts +1 -1
  341. package/dist/src/core/patch-lock.js +45 -9
  342. package/dist/src/core/patch-manifest-consistency.d.ts +57 -6
  343. package/dist/src/core/patch-manifest-consistency.js +111 -40
  344. package/dist/src/core/patch-manifest-files-affected.d.ts +43 -0
  345. package/dist/src/core/patch-manifest-files-affected.js +77 -0
  346. package/dist/src/core/patch-manifest-io.js +14 -18
  347. package/dist/src/core/patch-manifest-resolve.d.ts +9 -12
  348. package/dist/src/core/patch-manifest-resolve.js +9 -12
  349. package/dist/src/core/patch-manifest-validate.d.ts +6 -1
  350. package/dist/src/core/patch-manifest-validate.js +25 -13
  351. package/dist/src/core/patch-manifest.d.ts +2 -1
  352. package/dist/src/core/patch-manifest.js +2 -1
  353. package/dist/src/core/patch-parse.d.ts +24 -13
  354. package/dist/src/core/patch-parse.js +19 -14
  355. package/dist/src/core/patch-policy.d.ts +2 -2
  356. package/dist/src/core/patch-policy.js +2 -2
  357. package/dist/src/core/patch-registration-refs.d.ts +7 -8
  358. package/dist/src/core/patch-registration-refs.js +9 -9
  359. package/dist/src/core/process-cpu-time.d.ts +12 -0
  360. package/dist/src/core/process-cpu-time.js +52 -0
  361. package/dist/src/core/rebase-session.d.ts +38 -26
  362. package/dist/src/core/rebase-session.js +55 -28
  363. package/dist/src/core/register-browser-content.js +9 -74
  364. package/dist/src/core/{register-test-manifest.js → register-browser-test.js} +7 -42
  365. package/dist/src/core/register-module.js +10 -43
  366. package/dist/src/core/register-scaffold.d.ts +8 -8
  367. package/dist/src/core/register-scaffold.js +10 -10
  368. package/dist/src/core/register-shared-css.d.ts +9 -12
  369. package/dist/src/core/register-shared-css.js +17 -87
  370. package/dist/src/core/register-xpcshell-test.d.ts +6 -7
  371. package/dist/src/core/register-xpcshell-test.js +7 -8
  372. package/dist/src/core/shared-ftl.js +12 -4
  373. package/dist/src/core/state-file.d.ts +45 -0
  374. package/dist/src/core/state-file.js +34 -0
  375. package/dist/src/core/status-binary.d.ts +18 -11
  376. package/dist/src/core/status-binary.js +19 -12
  377. package/dist/src/core/status-classify.d.ts +30 -36
  378. package/dist/src/core/status-classify.js +21 -26
  379. package/dist/src/core/test-changed-prefs.d.ts +30 -0
  380. package/dist/src/core/test-changed-prefs.js +78 -0
  381. package/dist/src/core/test-harness-crash.d.ts +25 -63
  382. package/dist/src/core/test-harness-crash.js +121 -142
  383. package/dist/src/core/test-harness-signature.d.ts +18 -0
  384. package/dist/src/core/test-harness-signature.js +13 -0
  385. package/dist/src/core/test-path-scope.d.ts +12 -15
  386. package/dist/src/core/test-path-scope.js +15 -18
  387. package/dist/src/core/test-stale-check.d.ts +17 -17
  388. package/dist/src/core/test-stale-check.js +50 -43
  389. package/dist/src/core/test-stall-triage.d.ts +51 -0
  390. package/dist/src/core/test-stall-triage.js +126 -0
  391. package/dist/src/core/token-category.js +66 -14
  392. package/dist/src/core/token-coverage.js +9 -9
  393. package/dist/src/core/token-dark-mode.d.ts +9 -11
  394. package/dist/src/core/token-dark-mode.js +29 -13
  395. package/dist/src/core/token-docs.d.ts +2 -0
  396. package/dist/src/core/token-docs.js +3 -1
  397. package/dist/src/core/token-manager.d.ts +10 -2
  398. package/dist/src/core/token-manager.js +17 -8
  399. package/dist/src/core/token-scaffold.d.ts +7 -7
  400. package/dist/src/core/token-scaffold.js +7 -7
  401. package/dist/src/core/token-variant.d.ts +4 -4
  402. package/dist/src/core/token-variant.js +28 -6
  403. package/dist/src/core/toolchain-preflight.d.ts +20 -21
  404. package/dist/src/core/toolchain-preflight.js +28 -31
  405. package/dist/src/core/tree-guard.js +12 -2
  406. package/dist/src/core/tree-store.d.ts +41 -27
  407. package/dist/src/core/tree-store.js +68 -43
  408. package/dist/src/core/typecheck-shim.d.ts +23 -24
  409. package/dist/src/core/typecheck-shim.js +23 -24
  410. package/dist/src/core/typecheck.js +15 -9
  411. package/dist/src/core/wire-destroy.d.ts +3 -3
  412. package/dist/src/core/wire-destroy.js +7 -15
  413. package/dist/src/core/wire-dom-fragment.d.ts +9 -17
  414. package/dist/src/core/wire-dom-fragment.js +11 -44
  415. package/dist/src/core/wire-init.d.ts +2 -3
  416. package/dist/src/core/wire-init.js +8 -19
  417. package/dist/src/core/wire-subscript.d.ts +2 -3
  418. package/dist/src/core/wire-subscript.js +4 -13
  419. package/dist/src/core/wire-utils.d.ts +7 -8
  420. package/dist/src/core/wire-utils.js +7 -8
  421. package/dist/src/core/xpcshell-appdir.d.ts +38 -45
  422. package/dist/src/core/xpcshell-appdir.js +38 -45
  423. package/dist/src/errors/base.d.ts +37 -16
  424. package/dist/src/errors/base.js +37 -16
  425. package/dist/src/errors/build.d.ts +13 -1
  426. package/dist/src/errors/build.js +14 -2
  427. package/dist/src/errors/codes.d.ts +16 -0
  428. package/dist/src/errors/codes.js +16 -0
  429. package/dist/src/errors/furnace.d.ts +4 -4
  430. package/dist/src/errors/git.d.ts +6 -10
  431. package/dist/src/errors/git.js +6 -10
  432. package/dist/src/errors/patch.d.ts +7 -7
  433. package/dist/src/errors/patch.js +7 -7
  434. package/dist/src/errors/rebase.d.ts +4 -4
  435. package/dist/src/errors/rebase.js +4 -4
  436. package/dist/src/index.d.ts +7 -1
  437. package/dist/src/index.js +5 -0
  438. package/dist/src/types/commands/index.d.ts +2 -2
  439. package/dist/src/types/commands/options.d.ts +111 -70
  440. package/dist/src/types/commands/patches.d.ts +24 -34
  441. package/dist/src/types/commands/project.d.ts +5 -34
  442. package/dist/src/types/config.d.ts +25 -23
  443. package/dist/src/types/config.js +6 -1
  444. package/dist/src/types/furnace.d.ts +37 -13
  445. package/dist/src/types/furnace.js +19 -1
  446. package/dist/src/types/index.d.ts +3 -3
  447. package/dist/src/utils/build-info.d.ts +7 -8
  448. package/dist/src/utils/build-info.js +12 -11
  449. package/dist/src/utils/errors.d.ts +6 -8
  450. package/dist/src/utils/errors.js +6 -8
  451. package/dist/src/utils/logger.d.ts +27 -10
  452. package/dist/src/utils/logger.js +28 -16
  453. package/dist/src/utils/machine-output.d.ts +12 -0
  454. package/dist/src/utils/machine-output.js +33 -0
  455. package/dist/src/utils/options.d.ts +31 -14
  456. package/dist/src/utils/options.js +86 -30
  457. package/dist/src/utils/paths.d.ts +10 -8
  458. package/dist/src/utils/paths.js +10 -8
  459. package/dist/src/utils/platform.d.ts +0 -25
  460. package/dist/src/utils/platform.js +1 -42
  461. package/dist/src/utils/process-group.d.ts +9 -4
  462. package/dist/src/utils/process-group.js +19 -5
  463. package/dist/src/utils/process.d.ts +42 -7
  464. package/dist/src/utils/process.js +44 -17
  465. package/dist/src/utils/ps-duration.d.ts +31 -0
  466. package/dist/src/utils/ps-duration.js +70 -0
  467. package/dist/src/utils/regex.d.ts +9 -10
  468. package/dist/src/utils/regex.js +9 -10
  469. package/dist/src/utils/validation.d.ts +58 -28
  470. package/dist/src/utils/validation.js +60 -33
  471. package/package.json +3 -3
  472. package/dist/src/commands/doctor/post-rebase-audit.d.ts +0 -2
  473. package/dist/src/commands/doctor-furnace-manifest-sync.d.ts +0 -18
  474. package/dist/src/core/manifest-helpers.d.ts +0 -38
  475. package/dist/src/core/manifest-helpers.js +0 -120
  476. /package/dist/src/core/{lint-projection.d.ts → patch-lint-projection.d.ts} +0 -0
  477. /package/dist/src/core/{lint-projection.js → patch-lint-projection.js} +0 -0
  478. /package/dist/src/core/{register-test-manifest.d.ts → register-browser-test.d.ts} +0 -0
@@ -5,13 +5,23 @@ import { FurnaceError } from '../errors/furnace.js';
5
5
  import { toError } from '../utils/errors.js';
6
6
  import { pathExists, readText, writeText } from '../utils/fs.js';
7
7
  import { info, warn } from '../utils/logger.js';
8
- import { validateTokenName } from '../utils/validation.js';
8
+ import { describeTokenNameProblem, makeEnumGuard } from '../utils/validation.js';
9
9
  import { getProjectPaths, loadConfig } from './config.js';
10
10
  import { loadFurnaceConfig } from './furnace-config.js';
11
11
  import { assertTokenCategoryExists, categoryHeaderExists, declareCategoryBanner, findCategorySection, findTokenDeclarationInRoot, } from './token-category.js';
12
12
  import { findDarkMediaCloseIndex, findDarkRootInsertionIndex } from './token-dark-mode.js';
13
13
  import { addTokenToDocs } from './token-docs.js';
14
14
  import { insertVariantDeclaration, validateVariantSelector, variantBlockExists, variantBlockHasToken, } from './token-variant.js';
15
+ /**
16
+ * Dark mode behaviour for a token.
17
+ *
18
+ * Derived from {@link TOKEN_MODES} so the runtime allowlist and the type
19
+ * cannot drift: adding a member here without updating the list (or the
20
+ * reverse) is no longer possible, because there is only one list.
21
+ */
22
+ export const TOKEN_MODES = ['auto', 'static', 'override'];
23
+ /** Narrows an arbitrary string to a {@link TokenMode}. */
24
+ export const isTokenMode = makeEnumGuard(TOKEN_MODES);
15
25
  /** Returns the token CSS path relative to engine root for a given binary name. */
16
26
  export function getTokensCssPath(binaryName) {
17
27
  return `browser/themes/shared/${binaryName}-tokens.css`;
@@ -59,7 +69,7 @@ async function validateTokenPrefix(root, options) {
59
69
  }
60
70
  }
61
71
  function validateTokenNameSyntax(tokenName) {
62
- const error = validateTokenName(tokenName);
72
+ const error = describeTokenNameProblem(tokenName);
63
73
  if (error) {
64
74
  throw new InvalidArgumentError(error, 'tokenName');
65
75
  }
@@ -117,11 +127,10 @@ async function addVariantTokenToCSS(engineDir, options, tokensCssPath, variant)
117
127
  return { added: true };
118
128
  }
119
129
  /**
120
- * Evaluates base-`:root` idempotency for one add: a token
121
- * already declared in the TARGET category skips; a token declared
122
- * anywhere else in the base block refuses loud — the pre-0.40.0
123
- * whole-file substring check silently skipped (and discarded
124
- * `--create-category`) in that case, exit 0.
130
+ * Evaluates base-`:root` idempotency for one add: a token already declared
131
+ * in the TARGET category skips; a token declared anywhere else in the base
132
+ * block refuses loud. A whole-file substring check instead skips silently —
133
+ * discarding `--create-category` — and exits 0.
125
134
  */
126
135
  function evaluateBaseTokenIdempotency(lines, options, tokensCssPath) {
127
136
  const existing = findTokenDeclarationInRoot(lines, options.tokenName);
@@ -241,7 +250,7 @@ export async function addToken(root, options) {
241
250
  * pair the media query with `:root[data-theme="dark"]` /
242
251
  * `:root[data-theme="light"]` blocks (viewer-toggle theming) require every
243
252
  * themed list to declare identical token sets, so an override add that only
244
- * wrote the media block was a guaranteed half-finished edit.
253
+ * wrote the media block would be a guaranteed half-finished edit.
245
254
  */
246
255
  const THEME_ATTRIBUTE_VARIANTS = [
247
256
  { variant: '[data-theme="dark"]', pick: 'dark' },
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * Scaffolds the default tokens CSS file consumed by `fireforge token add`.
3
3
  *
4
- * Before 0.16.0 `fireforge furnace init` wrote `furnace.json` but not the
5
- * tokens CSS — every project's first `fireforge token add` hit
4
+ * Without it, `fireforge furnace init` writes `furnace.json` but not the
5
+ * tokens CSS, and every project's first `fireforge token add` hits
6
6
  * `Token CSS file not found: browser/themes/shared/<binaryName>-tokens.css`.
7
- * The 0.16.0 init now calls into this module to write a canonical
8
- * `:root { … }` shell with a seed set of category headers that
9
- * `assertTokenCategoryExists` recognises, and registers the tokens CSS
10
- * path in `patchLint.rawColorAllowlist` so the first token that's an
11
- * actual color value does not instantly fail `fireforge lint`.
7
+ * Init calls into this module to write a canonical `:root { … }` shell with
8
+ * a seed set of category headers that `assertTokenCategoryExists`
9
+ * recognises, and registers the tokens CSS path in
10
+ * `patchLint.rawColorAllowlist` so the first token that is an actual color
11
+ * value does not instantly fail `fireforge lint`.
12
12
  */
13
13
  import type { ProjectLicense } from '../types/config.js';
14
14
  /**
@@ -2,14 +2,14 @@
2
2
  /**
3
3
  * Scaffolds the default tokens CSS file consumed by `fireforge token add`.
4
4
  *
5
- * Before 0.16.0 `fireforge furnace init` wrote `furnace.json` but not the
6
- * tokens CSS — every project's first `fireforge token add` hit
5
+ * Without it, `fireforge furnace init` writes `furnace.json` but not the
6
+ * tokens CSS, and every project's first `fireforge token add` hits
7
7
  * `Token CSS file not found: browser/themes/shared/<binaryName>-tokens.css`.
8
- * The 0.16.0 init now calls into this module to write a canonical
9
- * `:root { … }` shell with a seed set of category headers that
10
- * `assertTokenCategoryExists` recognises, and registers the tokens CSS
11
- * path in `patchLint.rawColorAllowlist` so the first token that's an
12
- * actual color value does not instantly fail `fireforge lint`.
8
+ * Init calls into this module to write a canonical `:root { … }` shell with
9
+ * a seed set of category headers that `assertTokenCategoryExists`
10
+ * recognises, and registers the tokens CSS path in
11
+ * `patchLint.rawColorAllowlist` so the first token that is an actual color
12
+ * value does not instantly fail `fireforge lint`.
13
13
  */
14
14
  import { getLicenseHeader } from './license-headers.js';
15
15
  /**
@@ -2,10 +2,10 @@
2
2
  * Attribute-variant block helpers for the tokens CSS scaffold.
3
3
  *
4
4
  * `fireforge token add --mode` can author the base `:root { }` block and the
5
- * dark `@media (prefers-color-scheme: dark)` block, but there was no way to
6
- * target an attribute-keyed selector such as `:root[data-skin="precision"]`
7
- * or `:root[data-private]` — forcing those override blocks to be hand-edited.
8
- * These helpers locate (or compute the insertion point for) a top-level
5
+ * dark `@media (prefers-color-scheme: dark)` block, but not an
6
+ * attribute-keyed selector such as `:root[data-skin="precision"]` or
7
+ * `:root[data-private]`, which would otherwise have to be hand-edited. These
8
+ * helpers locate (or compute the insertion point for) a top-level
9
9
  * `:root<variant>` block so `token-manager.ts` can splice a declaration into
10
10
  * it, keeping all token authoring in the CLI.
11
11
  */
@@ -3,10 +3,10 @@
3
3
  * Attribute-variant block helpers for the tokens CSS scaffold.
4
4
  *
5
5
  * `fireforge token add --mode` can author the base `:root { }` block and the
6
- * dark `@media (prefers-color-scheme: dark)` block, but there was no way to
7
- * target an attribute-keyed selector such as `:root[data-skin="precision"]`
8
- * or `:root[data-private]` — forcing those override blocks to be hand-edited.
9
- * These helpers locate (or compute the insertion point for) a top-level
6
+ * dark `@media (prefers-color-scheme: dark)` block, but not an
7
+ * attribute-keyed selector such as `:root[data-skin="precision"]` or
8
+ * `:root[data-private]`, which would otherwise have to be hand-edited. These
9
+ * helpers locate (or compute the insertion point for) a top-level
10
10
  * `:root<variant>` block so `token-manager.ts` can splice a declaration into
11
11
  * it, keeping all token authoring in the CLI.
12
12
  */
@@ -52,6 +52,28 @@ export function validateVariantSelector(raw) {
52
52
  function canonicalSelector(selector) {
53
53
  return selector.replace(/\s+/g, '').replace(/["']/g, '');
54
54
  }
55
+ /**
56
+ * The `:root[…]` selector fragment on `line`, spanning to the LAST `]` that
57
+ * precedes the block's opening brace, or `null` when the line carries none.
58
+ *
59
+ * Index arithmetic rather than `/:root\[[^{]*\]/`: `[^{]` also matches `]`,
60
+ * so that pattern backtracks quadratically on a line repeating `:root[`
61
+ * (CodeQL `js/polynomial-redos`). Taking the last `]` — not the first —
62
+ * preserves the greedy regex's reach, so a multi-attribute selector still
63
+ * compares as the whole fragment and does not collide with a single-attribute
64
+ * variant that happens to be its prefix.
65
+ */
66
+ function rootAttributeSelector(line) {
67
+ const start = line.indexOf(':root[');
68
+ if (start === -1)
69
+ return null;
70
+ const brace = line.indexOf('{', start);
71
+ const limit = brace === -1 ? line.length : brace;
72
+ const close = line.lastIndexOf(']', limit - 1);
73
+ if (close <= start + ':root['.length - 1)
74
+ return null;
75
+ return line.slice(start, close + 1);
76
+ }
55
77
  /**
56
78
  * Finds the top-level `:root<variant>` block whose attribute selector
57
79
  * matches `variant` (compared canonically). Returns the opening-brace and
@@ -66,8 +88,8 @@ function findVariantBlock(lines, variant) {
66
88
  const want = canonicalSelector(`:root${variant}`);
67
89
  for (let i = 0; i < stripped.length; i++) {
68
90
  const line = stripped[i] ?? '';
69
- const match = /:root\[[^{]*\]/.exec(line);
70
- if (!match || canonicalSelector(match[0]) !== want)
91
+ const selector = rootAttributeSelector(line);
92
+ if (selector === null || canonicalSelector(selector) !== want)
71
93
  continue;
72
94
  let openLine = /\{/.test(line) ? i : -1;
73
95
  if (openLine === -1) {
@@ -1,30 +1,29 @@
1
1
  /**
2
2
  * Toolchain-minimum awareness for Firefox source hops.
3
3
  *
4
- * When `fireforge download --force` moves the engine to a new Firefox
5
- * MAJOR version, the tree's declared toolchain minimums (cbindgen, Rust)
6
- * frequently move with it — and the first `fireforge build` then dies a
7
- * few seconds into `mach configure` with a message whose remediation
8
- * text names `./mach bootstrap`, the wrong tool for a FireForge-managed
9
- * repo (152.0b7 → 153.0b8 source-refresh drill: `ERROR: cbindgen version
10
- * 0.29.1 is too old. At least version 0.29.4 is required.`).
4
+ * When `fireforge download --force` moves the engine to a new Firefox MAJOR
5
+ * version, the tree's declared toolchain minimums (cbindgen, Rust)
6
+ * frequently move with it — and the first `fireforge build` then dies a few
7
+ * seconds into `mach configure` with a message whose remediation text names
8
+ * `./mach bootstrap`, the wrong tool for a FireForge-managed repo (e.g.
9
+ * `ERROR: cbindgen version 0.29.1 is too old. At least version 0.29.4 is
10
+ * required.`).
11
11
  *
12
12
  * Two layers:
13
- * 1. {@link formatMajorVersionHopNotice} — a post-download nudge when
14
- * the downloaded major differs from the previously downloaded one.
15
- * 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing
16
- * the minimums the tree itself declares against the host binaries
13
+ * 1. {@link formatMajorVersionHopNotice} — a post-download nudge when the
14
+ * downloaded major differs from the previously downloaded one.
15
+ * 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing the
16
+ * minimums the tree itself declares against the host binaries
17
17
  * `mach configure` will resolve, probing configure's own candidate
18
- * order: env override first, then the `~/.mozbuild` state-directory
19
- * copy bootstrap installs, then PATH (0.35.0 probed env-or-PATH
20
- * only, blocking builds whose current tool lived in the state dir
21
- * behind a stale PATH copy). Deliberately FAIL-SOFT: it reports a
22
- * mismatch only when a minimum was positively parsed AND at least
23
- * one candidate resolved AND every resolved candidate is
24
- * definitively lower. Any uncertainty (file moved upstream,
25
- * unparseable output, no candidate found) skips silently — the
26
- * mach-error-hints translator still catches the real configure
27
- * failure downstream.
18
+ * order: env override first, then the `~/.mozbuild` state-directory copy
19
+ * bootstrap installs, then PATH. Probing env-or-PATH alone blocks builds
20
+ * whose current tool lives in the state dir behind a stale PATH copy.
21
+ * Deliberately FAIL-SOFT: it reports a mismatch only when a minimum was
22
+ * positively parsed AND at least one candidate resolved AND every
23
+ * resolved candidate is definitively lower. Any uncertainty (file moved
24
+ * upstream, unparseable output, no candidate found) skips silently — the
25
+ * mach-error-hints translator still catches the real configure failure
26
+ * downstream.
28
27
  */
29
28
  /** Tools the preflight knows how to probe. */
30
29
  export type ToolchainTool = 'cbindgen' | 'rustc';
@@ -2,30 +2,29 @@
2
2
  /**
3
3
  * Toolchain-minimum awareness for Firefox source hops.
4
4
  *
5
- * When `fireforge download --force` moves the engine to a new Firefox
6
- * MAJOR version, the tree's declared toolchain minimums (cbindgen, Rust)
7
- * frequently move with it — and the first `fireforge build` then dies a
8
- * few seconds into `mach configure` with a message whose remediation
9
- * text names `./mach bootstrap`, the wrong tool for a FireForge-managed
10
- * repo (152.0b7 → 153.0b8 source-refresh drill: `ERROR: cbindgen version
11
- * 0.29.1 is too old. At least version 0.29.4 is required.`).
5
+ * When `fireforge download --force` moves the engine to a new Firefox MAJOR
6
+ * version, the tree's declared toolchain minimums (cbindgen, Rust)
7
+ * frequently move with it — and the first `fireforge build` then dies a few
8
+ * seconds into `mach configure` with a message whose remediation text names
9
+ * `./mach bootstrap`, the wrong tool for a FireForge-managed repo (e.g.
10
+ * `ERROR: cbindgen version 0.29.1 is too old. At least version 0.29.4 is
11
+ * required.`).
12
12
  *
13
13
  * Two layers:
14
- * 1. {@link formatMajorVersionHopNotice} — a post-download nudge when
15
- * the downloaded major differs from the previously downloaded one.
16
- * 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing
17
- * the minimums the tree itself declares against the host binaries
14
+ * 1. {@link formatMajorVersionHopNotice} — a post-download nudge when the
15
+ * downloaded major differs from the previously downloaded one.
16
+ * 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing the
17
+ * minimums the tree itself declares against the host binaries
18
18
  * `mach configure` will resolve, probing configure's own candidate
19
- * order: env override first, then the `~/.mozbuild` state-directory
20
- * copy bootstrap installs, then PATH (0.35.0 probed env-or-PATH
21
- * only, blocking builds whose current tool lived in the state dir
22
- * behind a stale PATH copy). Deliberately FAIL-SOFT: it reports a
23
- * mismatch only when a minimum was positively parsed AND at least
24
- * one candidate resolved AND every resolved candidate is
25
- * definitively lower. Any uncertainty (file moved upstream,
26
- * unparseable output, no candidate found) skips silently — the
27
- * mach-error-hints translator still catches the real configure
28
- * failure downstream.
19
+ * order: env override first, then the `~/.mozbuild` state-directory copy
20
+ * bootstrap installs, then PATH. Probing env-or-PATH alone blocks builds
21
+ * whose current tool lives in the state dir behind a stale PATH copy.
22
+ * Deliberately FAIL-SOFT: it reports a mismatch only when a minimum was
23
+ * positively parsed AND at least one candidate resolved AND every
24
+ * resolved candidate is definitively lower. Any uncertainty (file moved
25
+ * upstream, unparseable output, no candidate found) skips silently — the
26
+ * mach-error-hints translator still catches the real configure failure
27
+ * downstream.
29
28
  */
30
29
  import { execFile } from 'node:child_process';
31
30
  import { homedir } from 'node:os';
@@ -61,16 +60,14 @@ const MINIMUM_DECLARATIONS = {
61
60
  /**
62
61
  * How each tool's host binary is resolved and its version parsed.
63
62
  *
64
- * `stateDirRelPaths` are the mach-state-directory locations `fireforge
65
- * bootstrap` (via mozboot) installs the tool to. mach's configure tries
66
- * the state directory BEFORE the PATH candidates (bindgen.configure's
67
- * toolchain search path lists `~/.mozbuild/cbindgen/cbindgen` first — a
68
- * configure log shows `trying cbindgen: ~/.mozbuild/cbindgen/cbindgen`
69
- * ahead of PATH), so the probe must too. 0.35.0 probed only env-or-PATH,
70
- * which failed a build configure would have accepted whenever an old
71
- * `~/.cargo/bin/cbindgen` shadowed a current bootstrap-installed copy
72
- * (field report: PATH 0.29.1 vs mozbuild 0.29.4, minimum 0.29.4). Rust
73
- * has no state-dir install — rustup owns it — so its list is empty.
63
+ * `stateDirRelPaths` are the mach-state-directory locations
64
+ * `fireforge bootstrap` (via mozboot) installs the tool to. mach's configure
65
+ * tries the state directory BEFORE the PATH candidates —
66
+ * bindgen.configure's toolchain search path lists `~/.mozbuild/cbindgen/
67
+ * cbindgen` first — so the probe must too. Probing only env-or-PATH fails a
68
+ * build configure would have accepted whenever an old `~/.cargo/bin/
69
+ * cbindgen` shadows a current bootstrap-installed copy. Rust has no
70
+ * state-dir install — rustup owns it — so its list is empty.
74
71
  */
75
72
  const HOST_PROBES = {
76
73
  // `mach configure` honours the CBINDGEN env option (bindgen.configure's
@@ -15,7 +15,7 @@
15
15
  import { existsSync } from 'node:fs';
16
16
  import { dirname, join, resolve } from 'node:path';
17
17
  import { GeneralError } from '../errors/base.js';
18
- import { getTreeMarkerPath, readTreeMarkerState, } from './tree-store.js';
18
+ import { getTreeMarkerPath, readTreeMarker, } from './tree-store.js';
19
19
  /**
20
20
  * Per-command verdicts. `allowed` runs unconditionally; `refused` never
21
21
  * runs in a tree; `conditional` consults `TREE_CONDITIONAL_CHECKS` with
@@ -135,7 +135,7 @@ export async function runTreeGuardHook(rootCommandName, actionCommand) {
135
135
  let current = resolve(process.cwd());
136
136
  for (let depth = 0; depth < 50; depth++) {
137
137
  if (existsSync(join(current, 'fireforge.json'))) {
138
- return { root: current, state: await readTreeMarkerState(current) };
138
+ return { root: current, state: await readTreeMarker(current) };
139
139
  }
140
140
  const parent = dirname(current);
141
141
  if (parent === current)
@@ -153,6 +153,16 @@ export async function runTreeGuardHook(rootCommandName, actionCommand) {
153
153
  // evidence that we cannot tell. Treating it as "not a tree" would grant the
154
154
  // full mutating command set to a snapshot on the strength of a file that
155
155
  // failed to parse, which is exactly backwards for a default-deny guard.
156
+ // A marker from a NEWER FireForge is not damaged, so the corrupt branch's
157
+ // remedies — recreate the tree, delete the stray marker — are actively
158
+ // wrong for it. Refuse with the upgrade instruction instead, and do NOT
159
+ // offer --ignore-corrupt-tree-marker: proceeding would mean acting on a
160
+ // marker whose fields this build does not understand.
161
+ if (state.kind === 'unsupported') {
162
+ if (TREE_COMMAND_VERDICTS[commandName] === 'allowed')
163
+ return;
164
+ throw new GeneralError(`Refusing "${[commandName, ...subcommands].join(' ')}": ${state.reason}`);
165
+ }
156
166
  if (state.kind === 'corrupt') {
157
167
  if (options['ignoreCorruptTreeMarker'] === true)
158
168
  return;
@@ -33,13 +33,13 @@ export declare function withTreeLifecycleLock<T>(primaryRoot: string, operation:
33
33
  * Outcome of reading a tree marker.
34
34
  *
35
35
  * The three states must stay distinct because they carry opposite safety
36
- * meanings. `absent` means "this directory is not a tree", which is what lets
37
- * every mutating command run. `corrupt` means "this directory claims to be a
38
- * tree but we cannot read the claim" — collapsing it into `absent` (as a bare
39
- * `undefined` return does) hands a snapshot the full mutating command set on
40
- * the strength of a file we failed to parse, inverting `tree-guard.ts`'s
41
- * default-deny design. Deleting one field from a marker was enough to run
42
- * `reset` inside a clone.
36
+ * meanings. `absent` means "this directory is not a tree", which is what
37
+ * lets every mutating command run. `corrupt` means "this directory claims to
38
+ * be a tree but we cannot read the claim" — collapsing it into `absent` (as
39
+ * a bare `undefined` return does) hands a snapshot the full mutating command
40
+ * set on the strength of a file we failed to parse, inverting
41
+ * `tree-guard.ts`'s default-deny design. Deleting one field from a marker is
42
+ * enough to make `reset` runnable inside a clone.
43
43
  */
44
44
  export type TreeMarkerRead = {
45
45
  kind: 'absent';
@@ -49,31 +49,45 @@ export type TreeMarkerRead = {
49
49
  } | {
50
50
  kind: 'corrupt';
51
51
  reason: string;
52
+ }
53
+ /**
54
+ * Written by a NEWER FireForge. Distinct from `corrupt` because the remedy
55
+ * is the opposite: upgrade, do not delete.
56
+ */
57
+ | {
58
+ kind: 'unsupported';
59
+ reason: string;
52
60
  };
53
61
  /** Absolute path of a root's tree marker. */
54
62
  export declare function getTreeMarkerPath(root: string): string;
55
63
  /**
56
64
  * Reads the tree marker for a project root, distinguishing "not a tree" from
57
- * "a tree whose marker we could not read". Callers that make a safety decision
58
- * (the guard hook, the no-nesting refusal) must use this rather than
59
- * {@link readTreeMarker}.
65
+ * "a tree whose marker we could not read". Callers that make a safety
66
+ * decision (the guard hook, the no-nesting refusal) must use this rather
67
+ * than {@link tryReadTreeMarker}.
60
68
  *
61
69
  * Only ENOENT/ENOTDIR mean `absent`: any other probe failure (EACCES on the
62
70
  * `.fireforge` directory, EIO, …) reports `corrupt`, because "we cannot read
63
71
  * the marker" is not evidence that there is no marker — a `pathExists`
64
- * pre-check here classified a tree with an unreadable `.fireforge` as
65
- * `absent` and handed it the full mutating command set.
72
+ * pre-check classifies a tree with an unreadable `.fireforge` as `absent`
73
+ * and hands it the full mutating command set.
66
74
  */
67
- export declare function readTreeMarkerState(root: string): Promise<TreeMarkerRead>;
75
+ /**
76
+ * Naming convention for state-file readers:
77
+ * - `readX(): Promise<XRead>` — the TRI-STATE read: absent, corrupt, or
78
+ * valid.
79
+ * - `tryReadX(): Promise<X | undefined>` — collapses absent and corrupt.
80
+ */
81
+ export declare function readTreeMarker(root: string): Promise<TreeMarkerRead>;
68
82
  /**
69
83
  * Reads the tree marker for a project root, or undefined when it is absent
70
84
  * OR unreadable.
71
85
  *
72
86
  * For display and best-effort paths only (`tree list` renders an unreadable
73
87
  * marker as staleness 'unknown'). Anything that decides whether a mutation may
74
- * proceed must call {@link readTreeMarkerState} and handle `corrupt`.
88
+ * proceed must call {@link readTreeMarker} and handle `corrupt`.
75
89
  */
76
- export declare function readTreeMarker(root: string): Promise<TreeMarker | undefined>;
90
+ export declare function tryReadTreeMarker(root: string): Promise<TreeMarker | undefined>;
77
91
  /**
78
92
  * Refuses a build-less in-tree `test` when the objdir preflight found is not
79
93
  * the one this tree's marker vouched for as rewritten-and-reconfigured. A
@@ -92,18 +106,18 @@ export declare function computePrimaryFingerprint(primaryRoot: string): Promise<
92
106
  /** Validates a tree name: one path segment, no traversal. */
93
107
  export declare function assertValidTreeName(name: string): void;
94
108
  /**
95
- * Materialises the tree at `treeRoot` from `primaryRoot` using
96
- * `capability` ('none' = plain copy, already gated on --force-copy by
97
- * the caller). The engine is cloned one TOP-LEVEL entry at a time so unwanted
98
- * `obj-*` directories are never traversed or materialised. That distinction
99
- * is substantial on Firefox trees: even CoW-cloning and deleting an objdir
100
- * touches metadata for millions of build outputs. With `withObjdir` exactly
101
- * that objdir is included — after {@link assertCloneSafeObjdir}
102
- * refuses symlinked or engine-escaping objdirs before any copying —
103
- * rewritten to the tree (see below), and
104
- * reconfigured in-tree via the caller-supplied `reconfigure` hook. A
105
- * fresh `.fireforge/` is created with only `state.json` (when present),
106
- * the last-build baseline (withObjdir only), and the tree marker.
109
+ * Materialises the tree at `treeRoot` from `primaryRoot` using `capability`
110
+ * ('none' = plain copy, already gated on --force-copy by the caller).
111
+ *
112
+ * The engine is cloned one TOP-LEVEL entry at a time so unwanted `obj-*`
113
+ * directories are never traversed or materialised — on a Firefox tree, even
114
+ * CoW-cloning and then deleting an objdir touches metadata for millions of
115
+ * build outputs. With `withObjdir` exactly that objdir is included (after
116
+ * {@link assertCloneSafeObjdir} refuses symlinked or engine-escaping objdirs
117
+ * before any copying), rewritten to the tree, and reconfigured in-tree via
118
+ * the caller-supplied `reconfigure` hook. A fresh `.fireforge/` is created
119
+ * with only `state.json` (when present), the last-build baseline (withObjdir
120
+ * only), and the tree marker.
107
121
  */
108
122
  export declare function cloneTree(args: {
109
123
  primaryRoot: string;