@hominis/fireforge 0.34.2 → 0.36.0

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 (360) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +43 -5
  3. package/dist/bin/fireforge.d.ts +4 -0
  4. package/dist/bin/fireforge.js +25 -6
  5. package/dist/src/cli.js +22 -5
  6. package/dist/src/commands/bootstrap-checks.js +0 -1
  7. package/dist/src/commands/bootstrap.d.ts +2 -1
  8. package/dist/src/commands/bootstrap.js +16 -7
  9. package/dist/src/commands/build.js +17 -3
  10. package/dist/src/commands/config.js +30 -10
  11. package/dist/src/commands/discard.js +24 -5
  12. package/dist/src/commands/doctor/post-rebase-audit.js +0 -1
  13. package/dist/src/commands/doctor-check-core.js +0 -1
  14. package/dist/src/commands/doctor-external-toolchains.d.ts +3 -0
  15. package/dist/src/commands/doctor-external-toolchains.js +54 -0
  16. package/dist/src/commands/doctor-furnace-jar.js +0 -1
  17. package/dist/src/commands/doctor-furnace-manifest-sync.js +0 -1
  18. package/dist/src/commands/doctor-furnace.js +2 -2
  19. package/dist/src/commands/doctor-working-tree.js +0 -1
  20. package/dist/src/commands/doctor.js +4 -1
  21. package/dist/src/commands/download.js +51 -15
  22. package/dist/src/commands/export-all.js +5 -3
  23. package/dist/src/commands/export-flow.js +12 -7
  24. package/dist/src/commands/export-placement-gate.js +0 -1
  25. package/dist/src/commands/export-placement-policy.js +0 -1
  26. package/dist/src/commands/export-shared.d.ts +5 -1
  27. package/dist/src/commands/export-shared.js +18 -6
  28. package/dist/src/commands/export.js +15 -10
  29. package/dist/src/commands/furnace/apply.js +22 -6
  30. package/dist/src/commands/furnace/chrome-doc-remove.js +0 -1
  31. package/dist/src/commands/furnace/chrome-doc-templates.js +0 -1
  32. package/dist/src/commands/furnace/chrome-doc-tests.js +0 -1
  33. package/dist/src/commands/furnace/chrome-doc.js +0 -1
  34. package/dist/src/commands/furnace/create-browser-test.js +0 -1
  35. package/dist/src/commands/furnace/create-dry-run.js +0 -1
  36. package/dist/src/commands/furnace/create-features.js +0 -1
  37. package/dist/src/commands/furnace/create-mochikit.js +0 -1
  38. package/dist/src/commands/furnace/create-readback.js +0 -1
  39. package/dist/src/commands/furnace/create-templates.js +0 -1
  40. package/dist/src/commands/furnace/create-validation.js +0 -1
  41. package/dist/src/commands/furnace/create-xpcshell.js +0 -1
  42. package/dist/src/commands/furnace/create.js +0 -1
  43. package/dist/src/commands/furnace/deploy.js +7 -83
  44. package/dist/src/commands/furnace/diff.js +0 -1
  45. package/dist/src/commands/furnace/index.js +59 -25
  46. package/dist/src/commands/furnace/init.js +0 -1
  47. package/dist/src/commands/furnace/list.js +0 -1
  48. package/dist/src/commands/furnace/override.js +0 -1
  49. package/dist/src/commands/furnace/preview.js +3 -3
  50. package/dist/src/commands/furnace/refresh.js +0 -1
  51. package/dist/src/commands/furnace/remove-state.d.ts +15 -0
  52. package/dist/src/commands/furnace/remove-state.js +47 -1
  53. package/dist/src/commands/furnace/remove.js +3 -9
  54. package/dist/src/commands/furnace/rename-browser-test.js +1 -5
  55. package/dist/src/commands/furnace/rename-helpers.d.ts +6 -0
  56. package/dist/src/commands/furnace/rename-helpers.js +30 -1
  57. package/dist/src/commands/furnace/rename-xpcshell.js +7 -6
  58. package/dist/src/commands/furnace/rename.js +15 -36
  59. package/dist/src/commands/furnace/scan.js +0 -1
  60. package/dist/src/commands/furnace/status.js +0 -1
  61. package/dist/src/commands/furnace/sync.js +76 -4
  62. package/dist/src/commands/furnace/validate.js +0 -1
  63. package/dist/src/commands/furnace/validation-output.js +0 -1
  64. package/dist/src/commands/import.js +35 -9
  65. package/dist/src/commands/lint-per-patch.js +19 -7
  66. package/dist/src/commands/lint.js +13 -3
  67. package/dist/src/commands/manifest.js +1 -2
  68. package/dist/src/commands/package.js +2 -1
  69. package/dist/src/commands/patch/compact.js +1 -1
  70. package/dist/src/commands/patch/delete.js +1 -1
  71. package/dist/src/commands/patch/index.js +1 -1
  72. package/dist/src/commands/patch/lint-ignore.js +21 -6
  73. package/dist/src/commands/patch/move-files.js +1 -1
  74. package/dist/src/commands/patch/patch-context.js +0 -1
  75. package/dist/src/commands/patch/rename.js +4 -4
  76. package/dist/src/commands/patch/reorder.js +3 -4
  77. package/dist/src/commands/patch/split-plan.js +2 -1
  78. package/dist/src/commands/patch/split.js +4 -4
  79. package/dist/src/commands/patch/staged-dependency.js +1 -1
  80. package/dist/src/commands/patch/tier.js +18 -5
  81. package/dist/src/commands/re-export-bulk-scan.js +0 -1
  82. package/dist/src/commands/re-export-files.js +1 -1
  83. package/dist/src/commands/re-export-options.js +0 -1
  84. package/dist/src/commands/re-export-scan.js +0 -1
  85. package/dist/src/commands/re-export.js +6 -4
  86. package/dist/src/commands/rebase/abort.js +2 -9
  87. package/dist/src/commands/rebase/confirm.js +0 -1
  88. package/dist/src/commands/rebase/conflict-summary.js +0 -1
  89. package/dist/src/commands/rebase/continue.js +0 -1
  90. package/dist/src/commands/rebase/index.d.ts +1 -1
  91. package/dist/src/commands/rebase/index.js +10 -15
  92. package/dist/src/commands/rebase/patch-loop.js +38 -7
  93. package/dist/src/commands/rebase/summary.js +2 -3
  94. package/dist/src/commands/rebase.js +0 -1
  95. package/dist/src/commands/register.js +1 -1
  96. package/dist/src/commands/reset.js +16 -9
  97. package/dist/src/commands/resolve.js +2 -2
  98. package/dist/src/commands/run.js +18 -6
  99. package/dist/src/commands/setup-support.js +0 -1
  100. package/dist/src/commands/setup.js +1 -2
  101. package/dist/src/commands/source.js +1 -2
  102. package/dist/src/commands/status-output.js +1 -12
  103. package/dist/src/commands/status.js +147 -133
  104. package/dist/src/commands/test-appdir.js +0 -1
  105. package/dist/src/commands/test-diagnose.js +18 -2
  106. package/dist/src/commands/test-modes.d.ts +15 -0
  107. package/dist/src/commands/test-modes.js +61 -0
  108. package/dist/src/commands/test-register.d.ts +4 -0
  109. package/dist/src/commands/test-register.js +64 -0
  110. package/dist/src/commands/test-run.d.ts +23 -7
  111. package/dist/src/commands/test-run.js +15 -14
  112. package/dist/src/commands/test.d.ts +0 -4
  113. package/dist/src/commands/test.js +95 -56
  114. package/dist/src/commands/token-coverage.js +0 -1
  115. package/dist/src/commands/token.js +1 -2
  116. package/dist/src/commands/typecheck.js +1 -1
  117. package/dist/src/commands/verify.js +3 -9
  118. package/dist/src/commands/watch.js +5 -1
  119. package/dist/src/commands/wire.js +1 -1
  120. package/dist/src/core/ast-utils.js +0 -1
  121. package/dist/src/core/brand-validation.js +0 -1
  122. package/dist/src/core/branding.js +0 -1
  123. package/dist/src/core/browser-wire.js +0 -1
  124. package/dist/src/core/build-audit-platform.js +0 -1
  125. package/dist/src/core/build-audit-registration.js +0 -1
  126. package/dist/src/core/build-audit-resolve.js +0 -1
  127. package/dist/src/core/build-audit-transforms.js +0 -1
  128. package/dist/src/core/build-audit.js +0 -1
  129. package/dist/src/core/build-baseline-types.js +0 -1
  130. package/dist/src/core/build-baseline.js +0 -1
  131. package/dist/src/core/build-prepare.js +21 -7
  132. package/dist/src/core/config-mutate.js +0 -1
  133. package/dist/src/core/config-paths.d.ts +2 -2
  134. package/dist/src/core/config-paths.js +6 -1
  135. package/dist/src/core/config-state.js +0 -1
  136. package/dist/src/core/config-validate-patch-policy.js +0 -1
  137. package/dist/src/core/config-validate-test-toolchains.d.ts +8 -0
  138. package/dist/src/core/config-validate-test-toolchains.js +105 -0
  139. package/dist/src/core/config-validate.js +3 -1
  140. package/dist/src/core/config.js +0 -1
  141. package/dist/src/core/destructive.js +0 -1
  142. package/dist/src/core/diff-hunks.js +13 -7
  143. package/dist/src/core/engine-changes.js +0 -1
  144. package/dist/src/core/engine-session-lock.d.ts +12 -0
  145. package/dist/src/core/engine-session-lock.js +45 -0
  146. package/dist/src/core/file-lock.d.ts +8 -0
  147. package/dist/src/core/file-lock.js +157 -48
  148. package/dist/src/core/firefox-archive.d.ts +4 -0
  149. package/dist/src/core/firefox-archive.js +6 -1
  150. package/dist/src/core/firefox-cache.js +67 -8
  151. package/dist/src/core/firefox-download.js +0 -1
  152. package/dist/src/core/firefox-extract.d.ts +21 -1
  153. package/dist/src/core/firefox-extract.js +178 -9
  154. package/dist/src/core/firefox-ignorefile.js +0 -1
  155. package/dist/src/core/firefox.d.ts +12 -0
  156. package/dist/src/core/firefox.js +64 -2
  157. package/dist/src/core/furnace-apply-dry-run.js +0 -1
  158. package/dist/src/core/furnace-apply-ftl.d.ts +7 -3
  159. package/dist/src/core/furnace-apply-ftl.js +10 -5
  160. package/dist/src/core/furnace-apply-helpers.js +0 -1
  161. package/dist/src/core/furnace-apply-output.js +2 -2
  162. package/dist/src/core/furnace-apply.d.ts +7 -1
  163. package/dist/src/core/furnace-apply.js +47 -13
  164. package/dist/src/core/furnace-checksum-utils.js +0 -1
  165. package/dist/src/core/furnace-config-array-utils.js +0 -1
  166. package/dist/src/core/furnace-config-custom.js +0 -1
  167. package/dist/src/core/furnace-config-order.js +0 -1
  168. package/dist/src/core/furnace-config-tokens.js +0 -1
  169. package/dist/src/core/furnace-config-validate.js +0 -1
  170. package/dist/src/core/furnace-config.d.ts +11 -0
  171. package/dist/src/core/furnace-config.js +37 -1
  172. package/dist/src/core/furnace-constants.js +0 -1
  173. package/dist/src/core/furnace-css-fragments.js +0 -1
  174. package/dist/src/core/furnace-graph-utils.js +0 -1
  175. package/dist/src/core/furnace-jsconfig.d.ts +2 -3
  176. package/dist/src/core/furnace-jsconfig.js +25 -18
  177. package/dist/src/core/furnace-marker.js +0 -1
  178. package/dist/src/core/furnace-operation.js +0 -1
  179. package/dist/src/core/furnace-refresh.js +0 -1
  180. package/dist/src/core/furnace-registration-ast.d.ts +14 -0
  181. package/dist/src/core/furnace-registration-ast.js +1 -2
  182. package/dist/src/core/furnace-registration-remove.js +0 -1
  183. package/dist/src/core/furnace-registration-validate.js +1 -5
  184. package/dist/src/core/furnace-registration.js +0 -1
  185. package/dist/src/core/furnace-rollback.js +0 -1
  186. package/dist/src/core/furnace-scanner.js +0 -1
  187. package/dist/src/core/furnace-staleness.js +0 -1
  188. package/dist/src/core/furnace-state-persist.d.ts +72 -0
  189. package/dist/src/core/furnace-state-persist.js +118 -0
  190. package/dist/src/core/furnace-step-errors.d.ts +23 -0
  191. package/dist/src/core/furnace-step-errors.js +25 -0
  192. package/dist/src/core/furnace-stories.js +0 -1
  193. package/dist/src/core/furnace-validate-accessibility.js +0 -1
  194. package/dist/src/core/furnace-validate-checks.js +0 -1
  195. package/dist/src/core/furnace-validate-compatibility.js +0 -1
  196. package/dist/src/core/furnace-validate-helpers.js +0 -1
  197. package/dist/src/core/furnace-validate-registration.js +7 -7
  198. package/dist/src/core/furnace-validate-structure.d.ts +8 -0
  199. package/dist/src/core/furnace-validate-structure.js +11 -2
  200. package/dist/src/core/furnace-validate.js +0 -1
  201. package/dist/src/core/furnace-version-drift.d.ts +6 -3
  202. package/dist/src/core/furnace-version-drift.js +6 -4
  203. package/dist/src/core/git-base.js +0 -1
  204. package/dist/src/core/git-diff.js +0 -1
  205. package/dist/src/core/git-file-ops.js +0 -1
  206. package/dist/src/core/git-status.d.ts +13 -0
  207. package/dist/src/core/git-status.js +32 -2
  208. package/dist/src/core/git.d.ts +10 -1
  209. package/dist/src/core/git.js +65 -8
  210. package/dist/src/core/license-headers.d.ts +16 -0
  211. package/dist/src/core/license-headers.js +19 -1
  212. package/dist/src/core/lint-cache.js +0 -1
  213. package/dist/src/core/lint-projection.js +0 -1
  214. package/dist/src/core/mach-build-artifacts.js +0 -1
  215. package/dist/src/core/mach-error-hints.js +27 -1
  216. package/dist/src/core/mach-mozconfig.js +0 -1
  217. package/dist/src/core/mach-python.js +0 -1
  218. package/dist/src/core/mach-resource-shim.js +0 -1
  219. package/dist/src/core/mach.js +0 -1
  220. package/dist/src/core/manifest-helpers.js +0 -1
  221. package/dist/src/core/manifest-register.js +0 -1
  222. package/dist/src/core/manifest-rules.js +0 -1
  223. package/dist/src/core/manifest-tokenizers.js +0 -1
  224. package/dist/src/core/marionette-port.d.ts +8 -0
  225. package/dist/src/core/marionette-port.js +34 -3
  226. package/dist/src/core/marionette-preflight.js +0 -1
  227. package/dist/src/core/markdown-table.js +0 -1
  228. package/dist/src/core/ownership-table.js +2 -9
  229. package/dist/src/core/parser-fallback.js +0 -1
  230. package/dist/src/core/patch-apply-fuzz.d.ts +27 -9
  231. package/dist/src/core/patch-apply-fuzz.js +71 -34
  232. package/dist/src/core/patch-apply.d.ts +30 -0
  233. package/dist/src/core/patch-apply.js +152 -39
  234. package/dist/src/core/patch-artifact-normalize.d.ts +18 -5
  235. package/dist/src/core/patch-artifact-normalize.js +19 -15
  236. package/dist/src/core/patch-export-coverage.js +0 -1
  237. package/dist/src/core/patch-export-metadata.js +0 -1
  238. package/dist/src/core/patch-export-update.js +2 -3
  239. package/dist/src/core/patch-export.d.ts +2 -6
  240. package/dist/src/core/patch-export.js +24 -48
  241. package/dist/src/core/patch-files.js +0 -1
  242. package/dist/src/core/patch-identifier-suggest.js +0 -1
  243. package/dist/src/core/patch-lint-checkjs.js +0 -1
  244. package/dist/src/core/patch-lint-chrome-jsdoc.js +0 -1
  245. package/dist/src/core/patch-lint-cross.js +0 -1
  246. package/dist/src/core/patch-lint-css.js +0 -1
  247. package/dist/src/core/patch-lint-diff-tag.js +0 -1
  248. package/dist/src/core/patch-lint-diff.d.ts +2 -1
  249. package/dist/src/core/patch-lint-diff.js +17 -32
  250. package/dist/src/core/patch-lint-imports.js +0 -1
  251. package/dist/src/core/patch-lint-jsdoc.js +0 -1
  252. package/dist/src/core/patch-lint-observer.js +0 -1
  253. package/dist/src/core/patch-lint-ownership.js +0 -1
  254. package/dist/src/core/patch-lint-reexports.js +0 -1
  255. package/dist/src/core/patch-lint.d.ts +37 -2
  256. package/dist/src/core/patch-lint.js +48 -24
  257. package/dist/src/core/patch-lock.js +0 -1
  258. package/dist/src/core/patch-manifest-consistency.js +9 -1
  259. package/dist/src/core/patch-manifest-io.d.ts +16 -0
  260. package/dist/src/core/patch-manifest-io.js +37 -12
  261. package/dist/src/core/patch-manifest-query.d.ts +6 -0
  262. package/dist/src/core/patch-manifest-query.js +27 -12
  263. package/dist/src/core/patch-manifest-resolve.js +0 -1
  264. package/dist/src/core/patch-manifest-validate.js +0 -1
  265. package/dist/src/core/patch-manifest.d.ts +1 -1
  266. package/dist/src/core/patch-manifest.js +1 -2
  267. package/dist/src/core/patch-parse.d.ts +59 -0
  268. package/dist/src/core/patch-parse.js +209 -92
  269. package/dist/src/core/patch-policy.js +0 -1
  270. package/dist/src/core/patch-registration-refs.js +16 -26
  271. package/dist/src/core/patch-source-metadata.js +0 -1
  272. package/dist/src/core/patch-transform.d.ts +4 -0
  273. package/dist/src/core/patch-transform.js +30 -38
  274. package/dist/src/core/rebase-session.js +0 -1
  275. package/dist/src/core/register-browser-content.js +0 -1
  276. package/dist/src/core/register-module.js +0 -1
  277. package/dist/src/core/register-result.js +0 -1
  278. package/dist/src/core/register-scaffold.js +0 -1
  279. package/dist/src/core/register-shared-css.js +0 -1
  280. package/dist/src/core/register-test-manifest.js +0 -1
  281. package/dist/src/core/register-xpcshell-test.js +0 -1
  282. package/dist/src/core/shared-ftl.js +0 -1
  283. package/dist/src/core/signal-critical.js +0 -1
  284. package/dist/src/core/smoke-patterns.js +0 -1
  285. package/dist/src/core/state-file.js +0 -1
  286. package/dist/src/core/status-classify.d.ts +16 -0
  287. package/dist/src/core/status-classify.js +24 -16
  288. package/dist/src/core/test-harness-crash.d.ts +64 -7
  289. package/dist/src/core/test-harness-crash.js +196 -15
  290. package/dist/src/core/test-harness-output.js +0 -1
  291. package/dist/src/core/test-path-scope.d.ts +62 -0
  292. package/dist/src/core/test-path-scope.js +148 -0
  293. package/dist/src/core/test-stale-check.js +0 -1
  294. package/dist/src/core/test-stale-symlink.js +0 -1
  295. package/dist/src/core/test-xpcshell-retry.js +0 -1
  296. package/dist/src/core/token-coverage.js +0 -1
  297. package/dist/src/core/token-dark-mode.js +0 -1
  298. package/dist/src/core/token-docs.js +0 -1
  299. package/dist/src/core/token-manager.js +0 -1
  300. package/dist/src/core/token-scaffold.js +0 -1
  301. package/dist/src/core/token-variant.js +0 -1
  302. package/dist/src/core/toolchain-preflight.d.ts +85 -0
  303. package/dist/src/core/toolchain-preflight.js +256 -0
  304. package/dist/src/core/typecheck-shim.d.ts +4 -1
  305. package/dist/src/core/typecheck-shim.js +61 -18
  306. package/dist/src/core/typecheck.js +0 -1
  307. package/dist/src/core/wire-destroy.js +0 -1
  308. package/dist/src/core/wire-dom-fragment.js +0 -1
  309. package/dist/src/core/wire-init.js +0 -1
  310. package/dist/src/core/wire-subscript.js +0 -1
  311. package/dist/src/core/wire-targets.js +0 -1
  312. package/dist/src/core/wire-utils.js +0 -1
  313. package/dist/src/core/xpcshell-appdir.js +1 -4
  314. package/dist/src/errors/base.d.ts +29 -0
  315. package/dist/src/errors/base.js +35 -1
  316. package/dist/src/errors/build.js +0 -1
  317. package/dist/src/errors/codes.d.ts +6 -0
  318. package/dist/src/errors/codes.js +6 -1
  319. package/dist/src/errors/config.js +0 -1
  320. package/dist/src/errors/download.js +2 -1
  321. package/dist/src/errors/furnace.d.ts +11 -1
  322. package/dist/src/errors/furnace.js +6 -5
  323. package/dist/src/errors/git.js +0 -1
  324. package/dist/src/errors/patch.d.ts +17 -0
  325. package/dist/src/errors/patch.js +29 -1
  326. package/dist/src/errors/rebase.js +0 -1
  327. package/dist/src/errors/run.js +1 -1
  328. package/dist/src/index.js +0 -1
  329. package/dist/src/types/cli.js +0 -1
  330. package/dist/src/types/commands/index.js +0 -1
  331. package/dist/src/types/commands/options.d.ts +20 -5
  332. package/dist/src/types/commands/options.js +0 -1
  333. package/dist/src/types/commands/patches.d.ts +8 -0
  334. package/dist/src/types/commands/patches.js +0 -1
  335. package/dist/src/types/commands/project.d.ts +11 -2
  336. package/dist/src/types/commands/project.js +0 -1
  337. package/dist/src/types/config.d.ts +32 -0
  338. package/dist/src/types/config.js +0 -1
  339. package/dist/src/types/furnace.d.ts +10 -0
  340. package/dist/src/types/furnace.js +0 -1
  341. package/dist/src/types/index.js +0 -1
  342. package/dist/src/types/typecheck.js +0 -1
  343. package/dist/src/utils/elapsed.js +0 -1
  344. package/dist/src/utils/errors.js +0 -1
  345. package/dist/src/utils/fs.js +37 -5
  346. package/dist/src/utils/logger.d.ts +7 -0
  347. package/dist/src/utils/logger.js +85 -3
  348. package/dist/src/utils/options.d.ts +15 -0
  349. package/dist/src/utils/options.js +25 -1
  350. package/dist/src/utils/package-root.js +11 -4
  351. package/dist/src/utils/parse.js +0 -1
  352. package/dist/src/utils/paths.js +0 -1
  353. package/dist/src/utils/platform.js +0 -1
  354. package/dist/src/utils/process.d.ts +33 -4
  355. package/dist/src/utils/process.js +183 -28
  356. package/dist/src/utils/regex.d.ts +13 -3
  357. package/dist/src/utils/regex.js +53 -4
  358. package/dist/src/utils/validation.d.ts +0 -12
  359. package/dist/src/utils/validation.js +13 -26
  360. package/package.json +8 -7
@@ -111,4 +111,3 @@ export class AmbiguousBuildArtifactsError extends BuildError {
111
111
  ' 3. Run the command again');
112
112
  }
113
113
  }
114
- //# sourceMappingURL=build.js.map
@@ -38,5 +38,11 @@ export declare const ExitCode: {
38
38
  * missing profile, etc.).
39
39
  */
40
40
  readonly SMOKE_LAUNCH_FAILURE: 13;
41
+ /**
42
+ * The user cancelled an interactive prompt. 130 = 128 + SIGINT, the
43
+ * conventional "interrupted by the user" code — scripts and CI can tell
44
+ * a deliberate cancellation apart from a real failure (GENERAL_ERROR).
45
+ */
46
+ readonly USER_CANCELLED: 130;
41
47
  };
42
48
  export type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
@@ -39,5 +39,10 @@ export const ExitCode = {
39
39
  * missing profile, etc.).
40
40
  */
41
41
  SMOKE_LAUNCH_FAILURE: 13,
42
+ /**
43
+ * The user cancelled an interactive prompt. 130 = 128 + SIGINT, the
44
+ * conventional "interrupted by the user" code — scripts and CI can tell
45
+ * a deliberate cancellation apart from a real failure (GENERAL_ERROR).
46
+ */
47
+ USER_CANCELLED: 130,
42
48
  };
43
- //# sourceMappingURL=codes.js.map
@@ -58,4 +58,3 @@ export class InvalidFieldError extends ConfigError {
58
58
  this.actualValue = actualValue;
59
59
  }
60
60
  }
61
- //# sourceMappingURL=config.js.map
@@ -65,8 +65,10 @@ export class ExtractionError extends DownloadError {
65
65
  this.archivePath = archivePath;
66
66
  }
67
67
  get userMessage() {
68
+ const reason = this.cause instanceof Error ? `Reason: ${this.cause.message}\n\n` : '';
68
69
  return (`Extraction Error: Failed to extract Firefox source archive.\n\n` +
69
70
  `Archive: ${this.archivePath}\n\n` +
71
+ reason +
70
72
  'To fix this:\n' +
71
73
  ' 1. Delete the corrupted archive and try again\n' +
72
74
  ' 2. Ensure you have enough disk space\n' +
@@ -127,4 +129,3 @@ export class PartialEngineExistsError extends DownloadError {
127
129
  ' 3. Re-run with --verbose for the full underlying error and stack trace');
128
130
  }
129
131
  }
130
- //# sourceMappingURL=download.js.map
@@ -5,6 +5,16 @@ import { FireForgeError } from './base.js';
5
5
  export declare class FurnaceError extends FireForgeError {
6
6
  readonly component?: string | undefined;
7
7
  readonly code: 9;
8
- constructor(message: string, component?: string | undefined, cause?: Error);
8
+ constructor(message: string, component?: string | undefined, cause?: Error, options?: {
9
+ /**
10
+ * Suppresses the "run furnace validate" advice line. Set by callers
11
+ * whose message already tells the user to run validate (or that ARE
12
+ * the validate command) — an explicit flag, because the previous
13
+ * `message.includes('furnace validate')` sniffing dropped the advice
14
+ * from any error that merely MENTIONED the command.
15
+ */
16
+ omitValidateAdvice?: boolean;
17
+ });
18
+ private readonly omitValidateAdvice;
9
19
  get userMessage(): string;
10
20
  }
@@ -7,22 +7,23 @@ import { ExitCode } from './codes.js';
7
7
  export class FurnaceError extends FireForgeError {
8
8
  component;
9
9
  code = ExitCode.FURNACE_ERROR;
10
- constructor(message, component, cause) {
10
+ constructor(message, component, cause, options) {
11
11
  super(message, cause);
12
12
  this.component = component;
13
+ this.omitValidateAdvice =
14
+ options?.omitValidateAdvice ?? message.includes('Run "fireforge furnace validate"');
13
15
  }
16
+ omitValidateAdvice;
14
17
  get userMessage() {
15
18
  let msg = this.component
16
19
  ? `Furnace Error (${this.component}): ${this.message}`
17
20
  : `Furnace Error: ${this.message}`;
18
21
  msg += '\n\nTo fix this:\n';
19
22
  msg += ' 1. Check the error message above for specifics\n';
20
- // Avoid circular advice when the error is thrown during validation itself.
21
- if (!this.message.includes('furnace validate')) {
23
+ if (!this.omitValidateAdvice) {
22
24
  msg += ' 2. Run "fireforge furnace validate" to diagnose issues\n';
23
25
  }
24
- msg += ` ${this.message.includes('furnace validate') ? '2' : '3'}. Use "fireforge doctor --repair-furnace" if state is inconsistent`;
26
+ msg += ` ${this.omitValidateAdvice ? '2' : '3'}. Use "fireforge doctor --repair-furnace" if state is inconsistent`;
25
27
  return msg;
26
28
  }
27
29
  }
28
- //# sourceMappingURL=furnace.js.map
@@ -135,4 +135,3 @@ export class GitIndexingTimeoutError extends GitError {
135
135
  ' 3. If the problem persists, check disk throughput and free space; Firefox source indexing on a cold SSD typically completes in 1–3 minutes.');
136
136
  }
137
137
  }
138
- //# sourceMappingURL=git.js.map
@@ -1,4 +1,21 @@
1
1
  import { FireForgeError } from './base.js';
2
+ /**
3
+ * Error thrown when `patches.json` exists but cannot be parsed or validated.
4
+ *
5
+ * This must be a HARD error on every mutating path. The historical behavior
6
+ * collapsed "corrupt" into "absent" (`loadPatchesManifest` returned null for
7
+ * both), so the next `fireforge export` would rebuild the manifest containing
8
+ * only the new patch — silently destroying every other patch's metadata
9
+ * (tiers, descriptions, lintIgnore, staged dependencies) — and a failed
10
+ * export's rollback would then delete `patches.json` outright because the
11
+ * "before" state looked absent (2026-07-05 review, finding H2).
12
+ */
13
+ export declare class PatchManifestCorruptError extends FireForgeError {
14
+ readonly manifestPath: string;
15
+ readonly code: 6;
16
+ constructor(manifestPath: string, cause?: Error);
17
+ get userMessage(): string;
18
+ }
2
19
  /**
3
20
  * Error thrown when patch operations fail.
4
21
  */
@@ -1,6 +1,35 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  import { FireForgeError } from './base.js';
3
3
  import { ExitCode } from './codes.js';
4
+ /**
5
+ * Error thrown when `patches.json` exists but cannot be parsed or validated.
6
+ *
7
+ * This must be a HARD error on every mutating path. The historical behavior
8
+ * collapsed "corrupt" into "absent" (`loadPatchesManifest` returned null for
9
+ * both), so the next `fireforge export` would rebuild the manifest containing
10
+ * only the new patch — silently destroying every other patch's metadata
11
+ * (tiers, descriptions, lintIgnore, staged dependencies) — and a failed
12
+ * export's rollback would then delete `patches.json` outright because the
13
+ * "before" state looked absent (2026-07-05 review, finding H2).
14
+ */
15
+ export class PatchManifestCorruptError extends FireForgeError {
16
+ manifestPath;
17
+ code = ExitCode.PATCH_ERROR;
18
+ constructor(manifestPath, cause) {
19
+ super(`patches.json exists but could not be parsed: ${cause?.message ?? 'unknown parse error'}`, cause);
20
+ this.manifestPath = manifestPath;
21
+ }
22
+ get userMessage() {
23
+ return (`Patch Manifest Error: ${this.message}\n\n` +
24
+ `Manifest: ${this.manifestPath}\n\n` +
25
+ 'FireForge refuses to modify the patch queue while patches.json is unreadable — ' +
26
+ 'rewriting it now would silently discard the metadata of every patch it lists.\n\n' +
27
+ 'To fix this:\n' +
28
+ ' 1. Open patches.json and repair the syntax error (a recent hand-edit is the usual cause)\n' +
29
+ ' 2. Or restore patches.json from version control\n' +
30
+ ' 3. Then re-run the command');
31
+ }
32
+ }
4
33
  /**
5
34
  * Error thrown when patch operations fail.
6
35
  */
@@ -23,4 +52,3 @@ export class PatchError extends FireForgeError {
23
52
  return msg;
24
53
  }
25
54
  }
26
- //# sourceMappingURL=patch.js.map
@@ -32,4 +32,3 @@ export class NoRebaseSessionError extends RebaseError {
32
32
  super('No rebase session in progress. Start one with "fireforge rebase".');
33
33
  }
34
34
  }
35
- //# sourceMappingURL=rebase.js.map
@@ -1,5 +1,6 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  import { FireForgeError } from './base.js';
3
+ import { ExitCode } from './codes.js';
3
4
  /**
4
5
  * Error raised by `fireforge run --smoke-exit` when the captured console
5
6
  * stream produced one or more error lines that did NOT match the
@@ -19,4 +20,3 @@ export class SmokeRunError extends FireForgeError {
19
20
  return `Smoke run failed: ${this.message}`;
20
21
  }
21
22
  }
22
- //# sourceMappingURL=run.js.map
package/dist/src/index.js CHANGED
@@ -18,4 +18,3 @@ export { validateAllComponents, validateComponent } from './core/furnace-validat
18
18
  export { addToken, getTokensCssPath, validateTokenAdd } from './core/token-manager.js';
19
19
  export { CancellationError, CommandError, FireForgeError, GeneralError, InvalidArgumentError, ResolutionError, } from './errors/base.js';
20
20
  export { ExitCode } from './errors/codes.js';
21
- //# sourceMappingURL=index.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=cli.js.map
@@ -3,4 +3,3 @@
3
3
  * Re-exports all command-related types from focused sub-modules.
4
4
  */
5
5
  export {};
6
- //# sourceMappingURL=index.js.map
@@ -299,11 +299,6 @@ export interface PatchStagedDependencyOptions {
299
299
  /** Skip the confirmation prompt (required for non-TTY). */
300
300
  yes?: boolean;
301
301
  }
302
- /**
303
- * Options for the preview-only `fireforge patch move-files` subcommand.
304
- * It validates an ownership transfer and prints the explicit
305
- * `re-export --files` commands needed to perform it.
306
- */
307
302
  /**
308
303
  * Options for the `patch split` command.
309
304
  */
@@ -331,6 +326,11 @@ export interface PatchSplitOptions {
331
326
  /** Skip per-patch lint of the projected bodies. */
332
327
  skipLint?: boolean;
333
328
  }
329
+ /**
330
+ * Options for the preview-only `fireforge patch move-files` subcommand.
331
+ * It validates an ownership transfer and prints the explicit
332
+ * `re-export --files` commands needed to perform it.
333
+ */
334
334
  export interface PatchMoveFilesOptions {
335
335
  /** File paths relative to engine/ to move from the source patch to the target patch. */
336
336
  file?: string[];
@@ -389,6 +389,13 @@ export interface RunOptions {
389
389
  * inspect the raw stream after smoke-exit returns.
390
390
  */
391
391
  captureConsole?: string;
392
+ /**
393
+ * Launch the browser with `--headless` (forwarded to the binary via
394
+ * `mach run`). Primarily for smoke mode on shared desktops: a headed
395
+ * smoke window absorbs live keyboard/mouse input, and the resulting
396
+ * console errors contaminate the capture and can fail the run.
397
+ */
398
+ headless?: boolean;
392
399
  }
393
400
  /**
394
401
  * Options for the test command.
@@ -398,6 +405,8 @@ export interface TestOptions {
398
405
  headless?: boolean;
399
406
  /** Run incremental UI build before testing */
400
407
  build?: boolean;
408
+ /** Forward mach's pathless auto-selection mode. Valid only with no explicit paths. */
409
+ auto?: boolean;
401
410
  /**
402
411
  * Run a marionette preflight before tests. Reports PASS/FAIL in under a
403
412
  * minute. When test paths are supplied, a FAIL aborts before mach test is
@@ -421,6 +430,12 @@ export interface TestOptions {
421
430
  * stale process holds the default port or CI uses another port.
422
431
  */
423
432
  marionettePort?: number;
433
+ /** Kill a recognized stale browser process holding the Marionette port, then continue. */
434
+ killStaleMarionette?: boolean;
435
+ /** Permit tests against packageable engine edits newer than the last successful build. */
436
+ allowStaleBuild?: boolean;
437
+ /** Run the configured short harness canary. `true` means use `fireforge.json`'s test.canaryPath. */
438
+ canary?: string | boolean;
424
439
  /**
425
440
  * Retry budget for recognized harness crashes (resource-monitor
426
441
  * tracebacks, pre-test no-output hangs, post-green shutdown re-entry).
@@ -3,4 +3,3 @@
3
3
  * Command option types for CLI commands.
4
4
  */
5
5
  export {};
6
- //# sourceMappingURL=options.js.map
@@ -31,6 +31,14 @@ export interface PatchResult {
31
31
  conflictingFiles?: string[];
32
32
  /** Whether the patch was auto-resolved (new file vs existing file conflict) */
33
33
  autoResolved?: boolean;
34
+ /**
35
+ * Pre-existing content of files the auto-resolve overwrote, keyed by
36
+ * engine-relative path. Kept for the RUN's duration (not just the retry):
37
+ * if a later patch fails and `rollbackPatches` reverse-applies this one,
38
+ * reversing a new-file patch DELETES the file — these snapshots are the
39
+ * only way to restore what was there before the auto-resolve.
40
+ */
41
+ autoResolvedOriginals?: Map<string, string>;
34
42
  }
35
43
  /**
36
44
  * Extended patch information with metadata.
@@ -3,4 +3,3 @@
3
3
  * Types for the patch system: patch metadata, manifests, lint, and import results.
4
4
  */
5
5
  export {};
6
- //# sourceMappingURL=patches.js.map
@@ -3,19 +3,28 @@
3
3
  */
4
4
  /**
5
5
  * Result of a doctor check.
6
+ *
7
+ * Field precedence (consumers and producers must agree):
8
+ * 1. `severity`, when present, is authoritative — `'error'` counts as a
9
+ * failure and `'warning'` as a warning REGARDLESS of `passed`.
10
+ * 2. Without `severity`, `passed: false` is a failure unless
11
+ * `warning: true` downgrades it to a warning.
12
+ * Producers should prefer setting `severity` explicitly; `warning` exists
13
+ * for older checks that predate the field. Do not emit contradictory
14
+ * combinations like `passed: true, severity: 'error'`.
6
15
  */
7
16
  export interface DoctorCheck {
8
17
  /** Name of the check */
9
18
  name: string;
10
19
  /** Whether the check passed */
11
20
  passed: boolean;
12
- /** Severity of the result */
21
+ /** Severity of the result (authoritative when present — see above) */
13
22
  severity?: 'ok' | 'warning' | 'error';
14
23
  /** Description of the result */
15
24
  message: string;
16
25
  /** Suggested fix if check failed */
17
26
  fix?: string;
18
- /** Whether this check passed with a warning */
27
+ /** Legacy warning flag for checks that predate `severity` */
19
28
  warning?: boolean;
20
29
  }
21
30
  /**
@@ -3,4 +3,3 @@
3
3
  * Project diagnostics, status, and token coverage types.
4
4
  */
5
5
  export {};
6
- //# sourceMappingURL=project.js.map
@@ -24,6 +24,34 @@ export interface BuildConfig {
24
24
  /** Number of parallel jobs for mach build */
25
25
  jobs?: number;
26
26
  }
27
+ /** Test command defaults stored in fireforge.json. */
28
+ export interface TestConfig {
29
+ /**
30
+ * Engine-relative browser-chrome canary file used by `fireforge test --canary`
31
+ * when the command does not receive an explicit canary path.
32
+ */
33
+ canaryPath?: string;
34
+ /** Short no-output ceiling for `fireforge test --canary`, in seconds. */
35
+ canaryTimeoutSeconds?: number;
36
+ }
37
+ /** A single external executable required by a project-specific toolchain. */
38
+ export interface ExternalToolRequirement {
39
+ /** Tool name as shown in doctor output, and PATH/xcrun lookup key when no path is set. */
40
+ name: string;
41
+ /** Absolute or project-relative executable path. */
42
+ path?: string;
43
+ /** Resolve the tool with `xcrun -find <name>` instead of PATH. */
44
+ xcrun?: boolean;
45
+ /** Missing tool is an error by default; set false for advisory probes. */
46
+ required?: boolean;
47
+ }
48
+ /** Named group of project-specific external asset/build tools. */
49
+ export interface ExternalToolchainConfig {
50
+ /** Human-readable toolchain name, e.g. "seasonal-branding". */
51
+ name: string;
52
+ /** Tools this toolchain needs. */
53
+ tools: ExternalToolRequirement[];
54
+ }
27
55
  /** Enforcement mode for patch policy violations during mutating commands. */
28
56
  export type PatchPolicyMutationMode = 'error' | 'warn' | 'force';
29
57
  /** A category-owned numeric range in the patch queue. */
@@ -89,6 +117,10 @@ export interface FireForgeConfig {
89
117
  firefox: FirefoxConfig;
90
118
  /** Build settings */
91
119
  build?: BuildConfig;
120
+ /** Test command defaults */
121
+ test?: TestConfig;
122
+ /** Optional project-specific external toolchains checked by doctor. */
123
+ externalToolchains?: ExternalToolchainConfig[];
92
124
  /** Project license SPDX identifier */
93
125
  license?: ProjectLicense;
94
126
  /** Wire command configuration */
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=config.js.map
@@ -208,6 +208,16 @@ export interface FurnaceState {
208
208
  export interface StepError {
209
209
  step: string;
210
210
  error: string;
211
+ /**
212
+ * Advisory step errors are reported as warnings and never trigger
213
+ * rollback or a non-zero exit. Used by the `.ftl` helpers, whose module
214
+ * contract is graceful degradation: a missing locale jar.mn on a fork
215
+ * without a locale package must not block a working `.mjs`/`.css` from
216
+ * shipping. Before this flag existed the contract was contradicted in
217
+ * practice — any FTL step error rolled back the entire apply, so a
218
+ * localized component on such a fork could never be applied at all.
219
+ */
220
+ advisory?: boolean;
211
221
  }
212
222
  /**
213
223
  * Result of applying all components to the engine source tree.
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=furnace.js.map
@@ -3,4 +3,3 @@
3
3
  * Re-exports all type definitions.
4
4
  */
5
5
  export {};
6
- //# sourceMappingURL=index.js.map
@@ -12,4 +12,3 @@
12
12
  * code fields that have no meaning for patch-hygiene rules.
13
13
  */
14
14
  export {};
15
- //# sourceMappingURL=typecheck.js.map
@@ -12,4 +12,3 @@ function formatElapsed(ms) {
12
12
  export function elapsedSince(startedAt) {
13
13
  return formatElapsed(Date.now() - startedAt);
14
14
  }
15
- //# sourceMappingURL=elapsed.js.map
@@ -12,4 +12,3 @@ export function toError(error) {
12
12
  }
13
13
  return new Error(typeof error === 'string' ? error : String(error), { cause: error });
14
14
  }
15
- //# sourceMappingURL=errors.js.map
@@ -1,8 +1,9 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { access, chmod, copyFile as fsCopyFile, lstat, mkdir, open, readdir, readFile, rename, rm, stat, statfs, } from 'node:fs/promises';
4
- import { dirname, join } from 'node:path';
4
+ import { basename, dirname, join } from 'node:path';
5
5
  const RETRIABLE_REMOVE_ERRORS = new Set(['ENOTEMPTY', 'EBUSY', 'EPERM']);
6
+ const RETRIABLE_RENAME_ERRORS = new Set(['EPERM', 'EACCES', 'EBUSY']);
6
7
  function sleep(ms) {
7
8
  return new Promise((resolve) => {
8
9
  setTimeout(resolve, ms);
@@ -199,7 +200,7 @@ export async function writeFileAtomic(path, content) {
199
200
  if (existingMode !== undefined) {
200
201
  await chmod(tempPath, existingMode);
201
202
  }
202
- await rename(tempPath, path);
203
+ await renameWithRetries(tempPath, path);
203
204
  await syncParentDir(path);
204
205
  }
205
206
  catch (error) {
@@ -207,6 +208,31 @@ export async function writeFileAtomic(path, content) {
207
208
  throw error;
208
209
  }
209
210
  }
211
+ /**
212
+ * Renames the temp file over its destination, retrying transient sharing
213
+ * violations. On Windows, a rename onto a target that another writer is
214
+ * concurrently replacing — or that an antivirus/indexer briefly holds open —
215
+ * fails with EPERM/EACCES/EBUSY even though the same rename succeeds a moment
216
+ * later; POSIX renames never hit this. Non-retriable codes and exhausted
217
+ * budgets rethrow, so a genuine permission problem still surfaces.
218
+ */
219
+ async function renameWithRetries(from, to) {
220
+ for (let attempt = 0;; attempt++) {
221
+ try {
222
+ await rename(from, to);
223
+ return;
224
+ }
225
+ catch (error) {
226
+ const code = error instanceof Error && 'code' in error && typeof error.code === 'string'
227
+ ? error.code
228
+ : undefined;
229
+ if (!code || !RETRIABLE_RENAME_ERRORS.has(code) || attempt === 4) {
230
+ throw error;
231
+ }
232
+ await sleep(25 * (attempt + 1));
233
+ }
234
+ }
235
+ }
210
236
  async function syncParentDir(path) {
211
237
  let directoryHandle;
212
238
  try {
@@ -270,7 +296,10 @@ export const FIREFORGE_TMP_PATH_PATTERN = /(^|\/)\.[^/]+\.fireforge-tmp-\d+-[0-9
270
296
  */
271
297
  function createAtomicTempPath(path) {
272
298
  const directory = dirname(path);
273
- const filename = path.slice(directory.length + 1);
299
+ // basename, not slice(dirname.length + 1): when dirname ends with the
300
+ // separator (filesystem/drive roots, e.g. dirname('/foo') === '/'), the
301
+ // slice arithmetic chopped the first filename character ('/foo' → 'oo').
302
+ const filename = basename(path);
274
303
  return join(directory, `.${filename}.fireforge-tmp-${process.pid}-${randomUUID()}`);
275
304
  }
276
305
  /**
@@ -287,7 +316,11 @@ function createAtomicTempPath(path) {
287
316
  export async function checkDiskSpace(path, minBytes, onLowSpace) {
288
317
  try {
289
318
  const stats = await statfs(path);
290
- const availableBytes = stats.bfree * stats.bsize;
319
+ // bavail = blocks available to UNPRIVILEGED users; bfree includes the
320
+ // root-reserved blocks (typically 5% on ext4), so it over-reported free
321
+ // space and silently suppressed the low-space warning exactly when it
322
+ // mattered.
323
+ const availableBytes = stats.bavail * stats.bsize;
291
324
  if (availableBytes < minBytes) {
292
325
  const availableGB = (availableBytes / (1024 * 1024 * 1024)).toFixed(1);
293
326
  const requiredGB = (minBytes / (1024 * 1024 * 1024)).toFixed(1);
@@ -302,4 +335,3 @@ export async function checkDiskSpace(path, minBytes, onLowSpace) {
302
335
  return undefined;
303
336
  }
304
337
  }
305
- //# sourceMappingURL=fs.js.map
@@ -3,6 +3,13 @@
3
3
  * @param enabled - Whether to enable verbose output
4
4
  */
5
5
  export declare function setVerbose(enabled: boolean): void;
6
+ /**
7
+ * Switches the logger into (or out of) machine-output mode. Commands with
8
+ * `--json`/`--raw` flags call this before producing any output.
9
+ */
10
+ export declare function setMachineOutputMode(enabled: boolean): void;
11
+ /** True when machine-output mode is active. */
12
+ export declare function isMachineOutputMode(): boolean;
6
13
  /**
7
14
  * Displays a verbose/debug message (only shown if verbose mode is enabled).
8
15
  * @param message - Message to display