@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
@@ -4,47 +4,18 @@
4
4
  /**
5
5
  * Result of a doctor check.
6
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'`.
7
+ * `severity` is the single source of truth; consumers that want a boolean
8
+ * derive it as `severity !== 'error'`.
15
9
  */
16
10
  export interface DoctorCheck {
17
11
  /** Name of the check */
18
12
  name: string;
19
- /** Whether the check passed */
20
- passed: boolean;
21
- /** Severity of the result (authoritative when present — see above) */
22
- severity?: 'ok' | 'warning' | 'error';
13
+ /** Outcome of the check. Authoritative and required. */
14
+ severity: 'ok' | 'warning' | 'error';
23
15
  /** Description of the result */
24
16
  message: string;
25
- /** Suggested fix if check failed */
17
+ /** Suggested fix when the check did not pass */
26
18
  fix?: string;
27
- /** Legacy warning flag for checks that predate `severity` */
28
- warning?: boolean;
29
- }
30
- /**
31
- * Status of the project.
32
- */
33
- export interface ProjectStatus {
34
- /** Whether fireforge.json exists */
35
- hasConfig: boolean;
36
- /** Whether engine/ exists */
37
- hasEngine: boolean;
38
- /** Whether patches/ exists */
39
- hasPatches: boolean;
40
- /** Number of patch files */
41
- patchCount: number;
42
- /** Whether build output exists */
43
- hasBuild: boolean;
44
- /** Firefox version from config */
45
- firefoxVersion?: string;
46
- /** Downloaded Firefox version */
47
- downloadedVersion?: string;
48
19
  }
49
20
  /**
50
21
  * Per-file token coverage breakdown.
@@ -182,11 +182,10 @@ export interface TypecheckConfig {
182
182
  */
183
183
  projectOverrides?: Record<string, string | null>;
184
184
  /**
185
- * How to report undefined free identifiers (TS2304/TS2552). These were
186
- * historically suppressed as shim-gap noise, which also hid genuine
187
- * missing imports until they crashed at runtime. Default
188
- * `'warning'`: visible without failing the gate. `'error'` makes them
189
- * blocking; `'off'` restores the historical suppression.
185
+ * How to report undefined free identifiers (TS2304/TS2552). Default
186
+ * `'warning'`: visible without failing the gate, since shim gaps produce
187
+ * the same diagnostic as a genuine missing import. `'error'` makes them
188
+ * blocking; `'off'` suppresses them.
190
189
  */
191
190
  undefinedIdentifiers?: PatchLintSeverityGate;
192
191
  }
@@ -235,9 +234,9 @@ export interface PatchLintConfig {
235
234
  checkJs?: boolean;
236
235
  /**
237
236
  * When true with `checkJs: true`, run checkJs with `strict` and
238
- * `noImplicitAny` enabled (CI-style). Default false preserves the
239
- * historical loose preset. Optional {@link checkJsCompilerOptions}
240
- * can relax individual strict flags (e.g. `strictNullChecks: false`).
237
+ * `noImplicitAny` enabled (CI-style). Default false uses the loose preset.
238
+ * Optional {@link checkJsCompilerOptions} can relax individual strict
239
+ * flags (e.g. `strictNullChecks: false`).
241
240
  */
242
241
  checkJsStrict?: boolean;
243
242
  /**
@@ -249,27 +248,26 @@ export interface PatchLintConfig {
249
248
  * Project-relative path to an additional `.d.ts` file whose contents
250
249
  * are concatenated to the built-in `FIREFOX_GLOBALS_SHIM` for the
251
250
  * `patchLint.checkJs` pass. Same semantics as `typecheck.extraShim`
252
- * but scoped to the patch-hygiene flow. Default unset = current
253
- * behaviour (built-in shim only).
251
+ * but scoped to the patch-hygiene flow. Default unset: built-in shim only.
254
252
  */
255
253
  checkJsExtraShim?: string;
256
254
  /**
257
255
  * Extend the checkJs pass to patch-owned test `.js` files
258
256
  * (`browser_*` / `test_*` / `xpcshell_*` basenames and files under a
259
- * `/test/` path), each checked as its own small script-scope program
260
- * with same-directory patch-owned `head*.js` helpers included (FORGE
261
- * G5 — a harness global that does not exist should fail at the patch
262
- * boundary where the test was authored, not in a downstream
263
- * jsconfig-project run). Opt-in: it is a new failure surface with
264
- * nonzero compile cost. Requires `checkJs: true`.
257
+ * `/test/` path), each checked as its own small script-scope program with
258
+ * same-directory patch-owned `head*.js` helpers included, so a call to a
259
+ * harness global that does not exist fails at the patch boundary where the
260
+ * test was authored rather than in a downstream jsconfig-project run.
261
+ * Opt-in: it is a new failure surface with nonzero compile cost. Requires
262
+ * `checkJs: true`.
265
263
  */
266
264
  checkJsTestFiles?: boolean;
267
265
  /**
268
266
  * Project-relative `.d.ts` appended to the built-in test-harness shim
269
267
  * (loose `TestUtils`/`BrowserTestUtils`/`add_task`/… declarations) for
270
- * the `checkJsTestFiles` pass — a consumer-typed `TestUtils` here is
271
- * what turns a call to a nonexistent harness member into a TS2339 at
272
- * export time. Requires `checkJsTestFiles: true`.
268
+ * the `checkJsTestFiles` pass. A consumer-typed `TestUtils` here is what
269
+ * turns a call to a nonexistent harness member into a TS2339 at export
270
+ * time. Requires `checkJsTestFiles: true`.
273
271
  */
274
272
  checkJsTestShim?: string;
275
273
  /** File paths exempt from the raw-color-value check (exact or basename match) */
@@ -291,16 +289,20 @@ export interface PatchLintConfig {
291
289
  chromeScriptJsDoc?: PatchLintSeverityGate;
292
290
  /**
293
291
  * How the checkJs pass reports undefined free identifiers
294
- * (TS2304/TS2552). Same semantics as `typecheck.undefinedIdentifiers`
295
- *; the two flows share the suppression policy so a patch
292
+ * (TS2304/TS2552). Same semantics as `typecheck.undefinedIdentifiers`;
293
+ * the two flows share the suppression policy so a patch
296
294
  * cannot pass one and fail the other. Default: 'warning'.
297
295
  */
298
296
  undefinedIdentifiers?: PatchLintSeverityGate;
299
297
  }
300
298
  /**
301
- * Build mode for mach.
299
+ * Build modes for mach.
300
+ *
301
+ * Derived from the list so the runtime allowlist cannot drift from the type.
302
302
  */
303
- export type BuildMode = 'dev' | 'debug' | 'release';
303
+ export declare const BUILD_MODES: readonly ["dev", "debug", "release"];
304
+ /** Build mode for mach. */
305
+ export type BuildMode = (typeof BUILD_MODES)[number];
304
306
  /**
305
307
  * Runtime state stored in .fireforge/state.json.
306
308
  */
@@ -1 +1,6 @@
1
- export {};
1
+ /**
2
+ * Build modes for mach.
3
+ *
4
+ * Derived from the list so the runtime allowlist cannot drift from the type.
5
+ */
6
+ export const BUILD_MODES = ['dev', 'debug', 'release'];
@@ -117,11 +117,10 @@ export interface FurnaceConfig {
117
117
  tokenAllowlist?: string[];
118
118
  /**
119
119
  * CSS custom-property prefixes that identify upstream / platform
120
- * variables the fork does not own. `token coverage` counts matches
121
- * as `allowlisted` rather than `unknown` so a copied upstream
122
- * baseline doesn't drag fork-owned coverage percentages down.
123
- * Defaults to `['--moz-']` when unset. Pass an explicit empty array
124
- * to restore the pre-0.18.0 strict contract.
120
+ * variables the fork does not own. `token coverage` counts matches as
121
+ * `allowlisted` rather than `unknown` so a copied upstream baseline does
122
+ * not drag fork-owned coverage percentages down. Defaults to `['--moz-']`
123
+ * when unset; pass an explicit empty array to count every prefix.
125
124
  */
126
125
  platformPrefixes?: string[];
127
126
  /**
@@ -176,7 +175,13 @@ export interface FurnaceConfig {
176
175
  * state before clearing authoring markers. The string is surfaced in doctor's
177
176
  * failure message verbatim, so new entries should be self-explanatory.
178
177
  */
179
- export type FurnacePendingRepairOperation = 'preview-teardown' | 'apply-rollback' | 'deploy-rollback' | 'remove-rollback' | 'create-rollback' | 'override-rollback' | 'scan-rollback' | 'rename-rollback' | 'refresh-rollback' | 'chrome-doc-rollback';
178
+ export declare const FURNACE_PENDING_REPAIR_OPERATIONS: readonly ["preview-teardown", "apply-rollback", "deploy-rollback", "remove-rollback", "create-rollback", "override-rollback", "scan-rollback", "rename-rollback", "refresh-rollback", "chrome-doc-rollback"];
179
+ /**
180
+ * Operations that can leave a pending-repair marker when they fail to roll
181
+ * back cleanly. Derived from the list above so the runtime allowlist in
182
+ * `furnace-config.ts` cannot drift from the union.
183
+ */
184
+ export type FurnacePendingRepairOperation = (typeof FURNACE_PENDING_REPAIR_OPERATIONS)[number];
180
185
  /**
181
186
  * Marker persisted into `.fireforge/furnace-state.json` when a furnace
182
187
  * mutation failed to roll back cleanly. Its presence tells the next
@@ -222,13 +227,10 @@ export interface StepError {
222
227
  step: string;
223
228
  error: string;
224
229
  /**
225
- * Advisory step errors are reported as warnings and never trigger
226
- * rollback or a non-zero exit. Used by the `.ftl` helpers, whose module
227
- * contract is graceful degradation: a missing locale jar.mn on a fork
228
- * without a locale package must not block a working `.mjs`/`.css` from
229
- * shipping. Before this flag existed the contract was contradicted in
230
- * practice — any FTL step error rolled back the entire apply, so a
231
- * localized component on such a fork could never be applied at all.
230
+ * Advisory step errors are reported as warnings and never trigger rollback
231
+ * or a non-zero exit. Used by the `.ftl` helpers, whose module contract is
232
+ * graceful degradation: a missing locale jar.mn on a fork without a locale
233
+ * package must not block a working `.mjs`/`.css` from shipping.
232
234
  */
233
235
  advisory?: boolean;
234
236
  }
@@ -318,3 +320,25 @@ export interface ValidationIssue {
318
320
  }
319
321
  /** Resolved test-harness selection for a `furnace create` run. */
320
322
  export type ResolvedTestStyle = 'mochikit' | 'browser-chrome' | 'xpcshell' | 'none';
323
+ /**
324
+ * The four paths and the name that every per-component apply, dry-run, FTL
325
+ * and drift helper needs some subset of.
326
+ *
327
+ * Passing these positionally is unsafe: they are all `string`, so any
328
+ * permutation typechecks against any other and a swap surfaces as a
329
+ * wrong-directory read at runtime. Helpers take
330
+ * `Pick<ComponentApplyContext, …>` of exactly the members they read, so a
331
+ * caller is never asked to invent a value it does not have.
332
+ */
333
+ export interface ComponentApplyContext {
334
+ /** Project root — what registration consistency resolves against. */
335
+ root: string;
336
+ /** Firefox source directory the component deploys into. */
337
+ engineDir: string;
338
+ /** Component name as it appears in `furnace.json`. */
339
+ name: string;
340
+ /** Absolute path to the component's authoring directory. */
341
+ componentDir: string;
342
+ /** Engine-relative locale directory holding the component's `.ftl`. */
343
+ ftlDir: string;
344
+ }
@@ -1 +1,19 @@
1
- export {};
1
+ /**
2
+ * Operations that can leave a pending-repair marker when they fail to roll
3
+ * back cleanly. The marker is consumed by `fireforge doctor`, which either
4
+ * re-runs apply for engine-side failures or validates the current authoring
5
+ * state before clearing authoring markers. The string is surfaced in doctor's
6
+ * failure message verbatim, so new entries should be self-explanatory.
7
+ */
8
+ export const FURNACE_PENDING_REPAIR_OPERATIONS = [
9
+ 'preview-teardown',
10
+ 'apply-rollback',
11
+ 'deploy-rollback',
12
+ 'remove-rollback',
13
+ 'create-rollback',
14
+ 'override-rollback',
15
+ 'scan-rollback',
16
+ 'rename-rollback',
17
+ 'refresh-rollback',
18
+ 'chrome-doc-rollback',
19
+ ];
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Re-exports all type definitions.
3
3
  */
4
- export type { BuildOptions, DiscardOptions, DoctorCheck, DownloadOptions, ExportOptions, FurnaceCreateOptions, FurnaceOverrideOptions, FurnaceRemoveOptions, GlobalOptions, ImportOptions, ImportSummary, PackageOptions, PatchCategory, PatchesManifest, PatchInfo, PatchLintIssue, PatchMetadata, PatchResult, ProjectStatus, ReExportOptions, ResetOptions, RunOptions, SetupOptions, TestOptions, TokenCoverageFileEntry, TokenCoverageReport, } from './commands/index.js';
5
- export type { BuildConfig, BuildMode, FireForgeConfig, FireForgeState, FirefoxConfig, FirefoxProduct, ProjectLicense, ProjectPaths, WireConfig, } from './config.js';
6
- export type { ApplyResult, ComponentType, CustomComponentConfig, DryRunAction, FurnaceConfig, FurnaceState, OverrideComponentConfig, OverrideType, RegistrationStatus, ScannedComponent, StepError, SyncResult, ValidationIssue, } from './furnace.js';
4
+ export type {} from './commands/index.js';
5
+ export type { BuildConfig, FireForgeConfig, FirefoxConfig, FirefoxProduct, ProjectLicense, ProjectPaths, WireConfig, } from './config.js';
6
+ export type { ApplyResult, ComponentType, CustomComponentConfig, DryRunAction, FurnaceConfig, FurnaceState, OverrideComponentConfig, OverrideType, StepError, ValidationIssue, } from './furnace.js';
@@ -3,14 +3,13 @@ export interface BuildIdentity {
3
3
  shortCommit: string;
4
4
  dirty: boolean;
5
5
  /**
6
- * Content hash of the uncommitted diff, present only for a DIRTY
7
- * installed build. Two packs from the same HEAD with
8
- * different uncommitted content share `shortCommit` and the `.dirty`
9
- * marker, so without this they report byte-identical `--version`
10
- * strings — which is what made a field report against
11
- * `0.41.0+g<sha>.dirty` impossible to trace back to a specific pack.
12
- * Absent in a git checkout: identity there comes from live git, and
13
- * hashing the full diff on every `--version` call is not worth it.
6
+ * Content hash of the uncommitted diff, present only for a DIRTY installed
7
+ * build. Two packs from the same HEAD with different uncommitted content
8
+ * share `shortCommit` and the `.dirty` marker, so without this they report
9
+ * byte-identical `--version` strings and a report against
10
+ * `<semver>+g<sha>.dirty` cannot be traced back to a specific pack. Absent
11
+ * in a git checkout: identity there comes from live git, and hashing the
12
+ * full diff on every `--version` call is not worth it.
14
13
  */
15
14
  dirtyHash?: string;
16
15
  }
@@ -1,20 +1,21 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
- * Build identity for `--version`. Three distinct builds
4
- * shipped as plain "0.41.0" — consumers had to fingerprint tarballs by
5
- * sha256 to know which build a claim was verified against. `--version`
6
- * now reports `<semver>+g<short-sha>[.dirty[.<content-hash>]]`:
3
+ * Build identity for `--version`.
7
4
  *
8
- * - In a git checkout (dev runs via tsx), identity comes from live git —
9
- * a stale `dist/build-info.json` from an old build must never win.
10
- * - In an installed package, it comes from `dist/build-info.json`,
11
- * stamped by scripts/generate-build-info.mjs at build/pack time.
5
+ * Distinct builds shipping as the same plain semver leave consumers
6
+ * fingerprinting tarballs by sha256 to know which build a claim was verified
7
+ * against. `--version` reports `<semver>+g<short-sha>[.dirty[.<content-hash>]]`:
8
+ *
9
+ * - In a git checkout (dev runs via tsx), identity comes from live git — a
10
+ * stale `dist/build-info.json` from an old build must never win.
11
+ * - In an installed package, it comes from `dist/build-info.json`, stamped
12
+ * by scripts/generate-build-info.mjs at build/pack time.
12
13
  * - When neither yields an identity, `--version` degrades to the plain
13
14
  * semver. Reading identity must never throw.
14
15
  *
15
- * Deliberately NOT wired into the per-patch lint cache key: identity
16
- * would churn the cache on every commit at the same semver for no
17
- * correctness gain (`getPackageVersion` stays the cache input).
16
+ * Deliberately NOT wired into the per-patch lint cache key: identity would
17
+ * churn the cache on every commit at the same semver for no correctness gain
18
+ * (`getPackageVersion` stays the cache input).
18
19
  */
19
20
  import { execFileSync } from 'node:child_process';
20
21
  import { existsSync, readFileSync } from 'node:fs';
@@ -20,9 +20,8 @@ export declare function toError(error: unknown): Error;
20
20
  * The check is deliberately structural rather than `error instanceof Error`:
21
21
  * a plain object carrying `.code` — exactly the shape {@link toError} exists
22
22
  * to normalise — reaches errno consumers through rejected promises and
23
- * cross-realm throws. Nine hand-rolled copies of this predicate existed
24
- * before 0.41.0, four of them (in `utils/fs.ts`) gated on `instanceof Error`
25
- * and so misclassified that shape as "no code".
23
+ * cross-realm throws, and an `instanceof Error` gate misclassifies it as "no
24
+ * code".
26
25
  */
27
26
  export declare function getNodeErrorCode(error: unknown): string | undefined;
28
27
  /**
@@ -32,10 +31,9 @@ export declare function getNodeErrorCode(error: unknown): string | undefined;
32
31
  * Only `ESRCH` ("no such process") means dead. **`EPERM` means ALIVE**: the
33
32
  * process exists but is owned by another uid, which happens routinely with
34
33
  * root-owned builds, `sudo`, shared CI runners and container UID mismatches.
35
- * Two copies of this predicate (`tree-store.ts`, `doctor-furnace.ts`) read
36
- * EPERM as dead before 0.41.0, and both gated a recursive delete — a live
37
- * build's tree clone and a live furnace lock were removed out from under
38
- * their owner. Any other errno is treated as "unknown, assume alive", which
39
- * is the safe direction for every caller: it refuses rather than destroys.
34
+ * Reading EPERM as dead in a predicate that gates a recursive delete removes
35
+ * a live build's tree clone or a live furnace lock out from under its owner.
36
+ * Any other errno is treated as "unknown, assume alive", the safe direction
37
+ * for every caller: it refuses rather than destroys.
40
38
  */
41
39
  export declare function isProcessAlive(pid: number): boolean;
@@ -32,9 +32,8 @@ export function toError(error) {
32
32
  * The check is deliberately structural rather than `error instanceof Error`:
33
33
  * a plain object carrying `.code` — exactly the shape {@link toError} exists
34
34
  * to normalise — reaches errno consumers through rejected promises and
35
- * cross-realm throws. Nine hand-rolled copies of this predicate existed
36
- * before 0.41.0, four of them (in `utils/fs.ts`) gated on `instanceof Error`
37
- * and so misclassified that shape as "no code".
35
+ * cross-realm throws, and an `instanceof Error` gate misclassifies it as "no
36
+ * code".
38
37
  */
39
38
  export function getNodeErrorCode(error) {
40
39
  if (typeof error === 'object' &&
@@ -52,11 +51,10 @@ export function getNodeErrorCode(error) {
52
51
  * Only `ESRCH` ("no such process") means dead. **`EPERM` means ALIVE**: the
53
52
  * process exists but is owned by another uid, which happens routinely with
54
53
  * root-owned builds, `sudo`, shared CI runners and container UID mismatches.
55
- * Two copies of this predicate (`tree-store.ts`, `doctor-furnace.ts`) read
56
- * EPERM as dead before 0.41.0, and both gated a recursive delete — a live
57
- * build's tree clone and a live furnace lock were removed out from under
58
- * their owner. Any other errno is treated as "unknown, assume alive", which
59
- * is the safe direction for every caller: it refuses rather than destroys.
54
+ * Reading EPERM as dead in a predicate that gates a recursive delete removes
55
+ * a live build's tree clone or a live furnace lock out from under its owner.
56
+ * Any other errno is treated as "unknown, assume alive", the safe direction
57
+ * for every caller: it refuses rather than destroys.
60
58
  */
61
59
  export function isProcessAlive(pid) {
62
60
  try {
@@ -12,6 +12,25 @@ export declare function setMachineOutputMode(enabled: boolean): void;
12
12
  export declare function isMachineOutputMode(): boolean;
13
13
  /** Seals (or unseals) stdout after a machine-readable final line. */
14
14
  export declare function setStdoutSealed(sealed: boolean): void;
15
+ /**
16
+ * True when a machine-readable payload already owns stdout.
17
+ *
18
+ * The CLI error boundary consults this before emitting a `--json` error
19
+ * envelope: a command that wrote its payload and THEN refused (e.g.
20
+ * `status --json --fail-on`) must not have a second JSON document appended,
21
+ * which would break the "exactly one document" half of the contract in
22
+ * docs/machine-output.md.
23
+ */
24
+ export declare function isStdoutSealed(): boolean;
25
+ /**
26
+ * Checks if verbose mode is enabled.
27
+ *
28
+ * Exported so the CLI error boundary can decide whether to walk an error's
29
+ * `cause` chain.
30
+ *
31
+ * @returns True if verbose mode is enabled
32
+ */
33
+ export declare function isVerbose(): boolean;
15
34
  /**
16
35
  * Displays a verbose/debug message (only shown if verbose mode is enabled).
17
36
  * @param message - Message to display
@@ -49,13 +68,13 @@ export declare const NOTICE_PREFIX = "[FireForge] NOTICE:";
49
68
  *
50
69
  * These lines are not warnings about the operator's code — they explain a
51
70
  * decision FireForge just made (escalating an incremental build to a full
52
- * one, sharding a run, skipping a step). Emitted through `info` they were
71
+ * one, sharding a run, skipping a step). Emitted through `info` they are
53
72
  * silently dropped by agent-facing output filters that keep only warnings
54
73
  * and errors, leaving a multi-minute build with no explanation and reading
55
74
  * as a hang. There are very few such lines and they are exactly the ones a
56
- * non-interactive operator needs, so they ride the warning channel and
57
- * carry {@link NOTICE_PREFIX} so a reader can still tell them apart from a
58
- * real warning.
75
+ * non-interactive operator needs, so they ride the warning channel and carry
76
+ * {@link NOTICE_PREFIX} so a reader can still tell them apart from a real
77
+ * warning.
59
78
  */
60
79
  export declare function notice(message: string): void;
61
80
  /** Logs an error message. */
@@ -80,12 +99,10 @@ export declare function cancel(message: string): void;
80
99
  * Checks whether a prompt result represents a user cancellation.
81
100
  *
82
101
  * Narrows to `symbol` — clack returns its cancel sentinel as a symbol and
83
- * `p.isCancel` is itself a type predicate. This wrapper erased that narrowing
84
- * by returning plain `boolean` until 0.41.0, which forced eleven `as string`
85
- * / `as PatchCategory` / `as OverrideType` casts across six command modules
86
- * on the *non*-cancelled branch, where the value is already known not to be
87
- * the sentinel. Keep the predicate form: it is the single highest-leverage
88
- * signature in the codebase for escape-hatch count.
102
+ * `p.isCancel` is itself a type predicate. Returning plain `boolean` erases
103
+ * that narrowing and forces `as string` / `as PatchCategory` casts across
104
+ * the command modules on the *non*-cancelled branch, where the value is
105
+ * already known not to be the sentinel. Keep the predicate form.
89
106
  */
90
107
  export declare function isCancel(value: unknown): value is symbol;
91
108
  /** Displays a titled note block for follow-up details. */
@@ -9,11 +9,9 @@ let verboseMode = false;
9
9
  * In machine mode, stdout belongs EXCLUSIVELY to the machine-readable
10
10
  * payload: all human-facing diagnostics (intro/outro banners, info, warn,
11
11
  * error, steps, notes) are routed to stderr as plain unstyled lines.
12
- * Before this mode existed, clack's log helpers wrote styled warnings to
13
- * stdout *before* the JSON body — a truncated-directory warning during
14
- * `status --json` broke every `JSON.parse(stdout)` consumer, and error
15
- * objects on the machine contract were followed by a styled duplicate on
16
- * the same stream.
12
+ * Otherwise clack's log helpers write styled warnings to stdout *before* the
13
+ * JSON body — a truncated-directory warning during `status --json` breaks
14
+ * every `JSON.parse(stdout)` consumer.
17
15
  */
18
16
  let machineOutputMode = false;
19
17
  /**
@@ -50,6 +48,18 @@ let stdoutSealed = false;
50
48
  export function setStdoutSealed(sealed) {
51
49
  stdoutSealed = sealed;
52
50
  }
51
+ /**
52
+ * True when a machine-readable payload already owns stdout.
53
+ *
54
+ * The CLI error boundary consults this before emitting a `--json` error
55
+ * envelope: a command that wrote its payload and THEN refused (e.g.
56
+ * `status --json --fail-on`) must not have a second JSON document appended,
57
+ * which would break the "exactly one document" half of the contract in
58
+ * docs/machine-output.md.
59
+ */
60
+ export function isStdoutSealed() {
61
+ return stdoutSealed;
62
+ }
53
63
  /** True when human output must avoid stdout. */
54
64
  function routeToStderr() {
55
65
  return machineOutputMode || stdoutSealed;
@@ -60,9 +70,13 @@ function writeDiagnostic(prefix, message) {
60
70
  }
61
71
  /**
62
72
  * Checks if verbose mode is enabled.
73
+ *
74
+ * Exported so the CLI error boundary can decide whether to walk an error's
75
+ * `cause` chain.
76
+ *
63
77
  * @returns True if verbose mode is enabled
64
78
  */
65
- function isVerbose() {
79
+ export function isVerbose() {
66
80
  return verboseMode;
67
81
  }
68
82
  /**
@@ -128,13 +142,13 @@ export const NOTICE_PREFIX = '[FireForge] NOTICE:';
128
142
  *
129
143
  * These lines are not warnings about the operator's code — they explain a
130
144
  * decision FireForge just made (escalating an incremental build to a full
131
- * one, sharding a run, skipping a step). Emitted through `info` they were
145
+ * one, sharding a run, skipping a step). Emitted through `info` they are
132
146
  * silently dropped by agent-facing output filters that keep only warnings
133
147
  * and errors, leaving a multi-minute build with no explanation and reading
134
148
  * as a hang. There are very few such lines and they are exactly the ones a
135
- * non-interactive operator needs, so they ride the warning channel and
136
- * carry {@link NOTICE_PREFIX} so a reader can still tell them apart from a
137
- * real warning.
149
+ * non-interactive operator needs, so they ride the warning channel and carry
150
+ * {@link NOTICE_PREFIX} so a reader can still tell them apart from a real
151
+ * warning.
138
152
  */
139
153
  export function notice(message) {
140
154
  if (routeToStderr()) {
@@ -238,12 +252,10 @@ export function cancel(message) {
238
252
  * Checks whether a prompt result represents a user cancellation.
239
253
  *
240
254
  * Narrows to `symbol` — clack returns its cancel sentinel as a symbol and
241
- * `p.isCancel` is itself a type predicate. This wrapper erased that narrowing
242
- * by returning plain `boolean` until 0.41.0, which forced eleven `as string`
243
- * / `as PatchCategory` / `as OverrideType` casts across six command modules
244
- * on the *non*-cancelled branch, where the value is already known not to be
245
- * the sentinel. Keep the predicate form: it is the single highest-leverage
246
- * signature in the codebase for escape-hatch count.
255
+ * `p.isCancel` is itself a type predicate. Returning plain `boolean` erases
256
+ * that narrowing and forces `as string` / `as PatchCategory` casts across
257
+ * the command modules on the *non*-cancelled branch, where the value is
258
+ * already known not to be the sentinel. Keep the predicate form.
247
259
  */
248
260
  export function isCancel(value) {
249
261
  return p.isCancel(value);
@@ -0,0 +1,12 @@
1
+ import { ExitCode } from '../errors/codes.js';
2
+ /** Current envelope version. Bump only with a documented migration. */
3
+ export declare const MACHINE_OUTPUT_SCHEMA_VERSION = 1;
4
+ /**
5
+ * Writes the machine-readable error envelope to stdout and throws the
6
+ * sentinel that carries the exit code to the entrypoint. Never returns.
7
+ *
8
+ * @param code - Stable machine-readable reason tag, e.g. `engine-missing`
9
+ * @param message - Human-readable explanation, identical to the non-JSON text
10
+ * @param exitCode - Exit code to terminate with
11
+ */
12
+ export declare function emitMachineError(code: string, message: string, exitCode?: ExitCode): never;
@@ -0,0 +1,33 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * The `--json` envelope contract, in one place.
4
+ *
5
+ * Without a single owner, machine-readable output drifts into unrelated
6
+ * shapes: two commands sharing a `schemaVersion: 1` envelope can still
7
+ * disagree on failure, so a scripted consumer gets a parseable refusal from
8
+ * one and a bare non-zero exit from the other.
9
+ *
10
+ * The contract, documented in `docs/machine-output.md`:
11
+ * 1. Success writes exactly one JSON document to stdout.
12
+ * 2. Failure writes exactly one `{ schemaVersion, error, code }` document
13
+ * to stdout, then exits non-zero.
14
+ * 3. Machine mode is engaged BEFORE any output, so every diagnostic —
15
+ * including one rendered later by `withErrorHandling` — routes to
16
+ * stderr and cannot corrupt the payload.
17
+ */
18
+ import { CommandError } from '../errors/base.js';
19
+ import { ExitCode } from '../errors/codes.js';
20
+ /** Current envelope version. Bump only with a documented migration. */
21
+ export const MACHINE_OUTPUT_SCHEMA_VERSION = 1;
22
+ /**
23
+ * Writes the machine-readable error envelope to stdout and throws the
24
+ * sentinel that carries the exit code to the entrypoint. Never returns.
25
+ *
26
+ * @param code - Stable machine-readable reason tag, e.g. `engine-missing`
27
+ * @param message - Human-readable explanation, identical to the non-JSON text
28
+ * @param exitCode - Exit code to terminate with
29
+ */
30
+ export function emitMachineError(code, message, exitCode = ExitCode.GENERAL_ERROR) {
31
+ process.stdout.write(`${JSON.stringify({ schemaVersion: MACHINE_OUTPUT_SCHEMA_VERSION, error: message, code })}\n`);
32
+ throw new CommandError(exitCode);
33
+ }