@hominis/fireforge 0.43.1 → 0.44.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 (470) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +10 -1
  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 +4 -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-post-rebase-audit.d.ts +2 -0
  22. package/dist/src/commands/{doctor/post-rebase-audit.js → doctor-post-rebase-audit.js} +3 -3
  23. package/dist/src/commands/doctor-working-tree.d.ts +10 -12
  24. package/dist/src/commands/doctor-working-tree.js +11 -18
  25. package/dist/src/commands/doctor.js +35 -53
  26. package/dist/src/commands/download.js +32 -48
  27. package/dist/src/commands/export-all.js +29 -33
  28. package/dist/src/commands/export-flow.js +6 -6
  29. package/dist/src/commands/export-placement-conflicts.js +10 -9
  30. package/dist/src/commands/export-placement-gate.js +5 -5
  31. package/dist/src/commands/export-shared.d.ts +30 -33
  32. package/dist/src/commands/export-shared.js +45 -43
  33. package/dist/src/commands/export.js +21 -27
  34. package/dist/src/commands/furnace/apply.js +14 -23
  35. package/dist/src/commands/furnace/chrome-doc-remove.js +14 -21
  36. package/dist/src/commands/furnace/chrome-doc-templates.d.ts +23 -23
  37. package/dist/src/commands/furnace/chrome-doc-templates.js +23 -23
  38. package/dist/src/commands/furnace/chrome-doc-tests.js +26 -29
  39. package/dist/src/commands/furnace/chrome-doc.d.ts +16 -17
  40. package/dist/src/commands/furnace/chrome-doc.js +31 -41
  41. package/dist/src/commands/furnace/create-browser-test.d.ts +4 -4
  42. package/dist/src/commands/furnace/create-browser-test.js +8 -8
  43. package/dist/src/commands/furnace/create-mochikit.d.ts +6 -7
  44. package/dist/src/commands/furnace/create-mochikit.js +8 -9
  45. package/dist/src/commands/furnace/create-readback.d.ts +12 -13
  46. package/dist/src/commands/furnace/create-readback.js +12 -13
  47. package/dist/src/commands/furnace/create-templates.d.ts +22 -28
  48. package/dist/src/commands/furnace/create-templates.js +35 -30
  49. package/dist/src/commands/furnace/create-xpcshell.js +2 -2
  50. package/dist/src/commands/furnace/create.js +33 -23
  51. package/dist/src/commands/furnace/deploy.js +16 -24
  52. package/dist/src/commands/furnace/diff.js +9 -9
  53. package/dist/src/commands/furnace/init.js +33 -36
  54. package/dist/src/commands/furnace/override.js +23 -25
  55. package/dist/src/commands/furnace/preview.js +47 -67
  56. package/dist/src/commands/furnace/refresh.js +12 -16
  57. package/dist/src/commands/furnace/remove-mutations.d.ts +3 -6
  58. package/dist/src/commands/furnace/remove-mutations.js +9 -16
  59. package/dist/src/commands/furnace/remove-state.js +1 -1
  60. package/dist/src/commands/furnace/remove.js +33 -38
  61. package/dist/src/commands/furnace/rename-xpcshell.d.ts +8 -11
  62. package/dist/src/commands/furnace/rename-xpcshell.js +8 -11
  63. package/dist/src/commands/furnace/rename.js +59 -69
  64. package/dist/src/commands/furnace/scan.js +19 -33
  65. package/dist/src/commands/furnace/status.js +12 -9
  66. package/dist/src/commands/furnace/sync.js +9 -16
  67. package/dist/src/commands/furnace/validate.js +20 -20
  68. package/dist/src/commands/import.js +42 -35
  69. package/dist/src/commands/lint-per-patch.js +15 -10
  70. package/dist/src/commands/lint-per-run-checkjs.d.ts +13 -13
  71. package/dist/src/commands/lint-per-run-checkjs.js +13 -13
  72. package/dist/src/commands/lint-report.js +6 -7
  73. package/dist/src/commands/lint.d.ts +15 -16
  74. package/dist/src/commands/lint.js +86 -102
  75. package/dist/src/commands/package.js +6 -11
  76. package/dist/src/commands/patch/compact.js +1 -1
  77. package/dist/src/commands/patch/delete.js +24 -33
  78. package/dist/src/commands/patch/index.d.ts +5 -6
  79. package/dist/src/commands/patch/index.js +10 -12
  80. package/dist/src/commands/patch/lint-ignore.js +14 -13
  81. package/dist/src/commands/patch/move-files-create.d.ts +6 -6
  82. package/dist/src/commands/patch/move-files-create.js +8 -8
  83. package/dist/src/commands/patch/move-files-into.d.ts +6 -6
  84. package/dist/src/commands/patch/move-files-into.js +8 -8
  85. package/dist/src/commands/patch/patch-context.d.ts +2 -3
  86. package/dist/src/commands/patch/patch-context.js +2 -3
  87. package/dist/src/commands/patch/rename.d.ts +10 -11
  88. package/dist/src/commands/patch/rename.js +11 -12
  89. package/dist/src/commands/patch/reorder.js +8 -9
  90. package/dist/src/commands/patch/split-plan.js +1 -1
  91. package/dist/src/commands/patch/split.d.ts +8 -10
  92. package/dist/src/commands/patch/split.js +9 -11
  93. package/dist/src/commands/patch/staged-dependency-validate.js +8 -8
  94. package/dist/src/commands/patch/staged-dependency.js +7 -3
  95. package/dist/src/commands/patch/tier.d.ts +9 -9
  96. package/dist/src/commands/patch/tier.js +18 -15
  97. package/dist/src/commands/re-export-adjacent.js +9 -8
  98. package/dist/src/commands/re-export-bulk-scan.d.ts +9 -9
  99. package/dist/src/commands/re-export-bulk-scan.js +22 -21
  100. package/dist/src/commands/re-export-drift.js +10 -10
  101. package/dist/src/commands/re-export-files.d.ts +6 -7
  102. package/dist/src/commands/re-export-files.js +34 -44
  103. package/dist/src/commands/re-export-lint.d.ts +10 -13
  104. package/dist/src/commands/re-export-lint.js +16 -14
  105. package/dist/src/commands/re-export-options.d.ts +6 -6
  106. package/dist/src/commands/re-export-options.js +6 -6
  107. package/dist/src/commands/re-export-register.d.ts +4 -10
  108. package/dist/src/commands/re-export-register.js +5 -11
  109. package/dist/src/commands/re-export-scan.js +1 -1
  110. package/dist/src/commands/re-export-single.d.ts +3 -3
  111. package/dist/src/commands/re-export-single.js +33 -25
  112. package/dist/src/commands/re-export.js +13 -21
  113. package/dist/src/commands/rebase/abort.js +3 -3
  114. package/dist/src/commands/rebase/confirm.js +2 -1
  115. package/dist/src/commands/rebase/continue.d.ts +1 -1
  116. package/dist/src/commands/rebase/continue.js +14 -9
  117. package/dist/src/commands/rebase/index.js +11 -11
  118. package/dist/src/commands/rebase/patch-loop.d.ts +7 -1
  119. package/dist/src/commands/rebase/patch-loop.js +60 -39
  120. package/dist/src/commands/rebase/summary.js +1 -1
  121. package/dist/src/commands/register.js +5 -7
  122. package/dist/src/commands/reset.js +2 -1
  123. package/dist/src/commands/resolve.d.ts +16 -13
  124. package/dist/src/commands/resolve.js +30 -33
  125. package/dist/src/commands/run.js +33 -35
  126. package/dist/src/commands/setup-support.js +15 -19
  127. package/dist/src/commands/setup.js +13 -9
  128. package/dist/src/commands/status-check.d.ts +6 -6
  129. package/dist/src/commands/status-json.d.ts +6 -6
  130. package/dist/src/commands/status-json.js +5 -0
  131. package/dist/src/commands/status-output.d.ts +5 -5
  132. package/dist/src/commands/status-output.js +6 -6
  133. package/dist/src/commands/status-ownership.d.ts +16 -14
  134. package/dist/src/commands/status-ownership.js +16 -14
  135. package/dist/src/commands/status.js +42 -34
  136. package/dist/src/commands/test-build-phase.js +26 -13
  137. package/dist/src/commands/test-diagnose.js +44 -44
  138. package/dist/src/commands/test-register.js +1 -0
  139. package/dist/src/commands/test-run.d.ts +14 -16
  140. package/dist/src/commands/test-run.js +21 -13
  141. package/dist/src/commands/test-stale-gate.d.ts +15 -16
  142. package/dist/src/commands/test-stale-gate.js +15 -16
  143. package/dist/src/commands/test-verdict.d.ts +20 -3
  144. package/dist/src/commands/test-verdict.js +30 -0
  145. package/dist/src/commands/test.js +83 -76
  146. package/dist/src/commands/token-coverage.js +3 -4
  147. package/dist/src/commands/token.js +16 -18
  148. package/dist/src/commands/tree.js +47 -31
  149. package/dist/src/commands/typecheck.d.ts +10 -12
  150. package/dist/src/commands/typecheck.js +24 -27
  151. package/dist/src/commands/verify.js +13 -15
  152. package/dist/src/commands/watch.js +21 -23
  153. package/dist/src/commands/wire.js +52 -62
  154. package/dist/src/core/ast-utils.d.ts +8 -7
  155. package/dist/src/core/ast-utils.js +8 -7
  156. package/dist/src/core/branding.d.ts +9 -14
  157. package/dist/src/core/branding.js +7 -11
  158. package/dist/src/core/browser-wire.d.ts +1 -1
  159. package/dist/src/core/browser-wire.js +14 -19
  160. package/dist/src/core/build-audit-platform.js +25 -33
  161. package/dist/src/core/build-audit-registration.js +17 -25
  162. package/dist/src/core/build-audit-resolve.d.ts +15 -17
  163. package/dist/src/core/build-audit-resolve.js +27 -33
  164. package/dist/src/core/build-audit-transforms.js +18 -19
  165. package/dist/src/core/build-audit.js +28 -42
  166. package/dist/src/core/build-baseline-types.d.ts +29 -35
  167. package/dist/src/core/build-baseline.d.ts +5 -4
  168. package/dist/src/core/build-baseline.js +14 -14
  169. package/dist/src/core/build-overwrite-guard.d.ts +7 -14
  170. package/dist/src/core/build-overwrite-guard.js +17 -27
  171. package/dist/src/core/build-prepare.d.ts +2 -2
  172. package/dist/src/core/build-prepare.js +8 -9
  173. package/dist/src/core/config-state.js +12 -4
  174. package/dist/src/core/config-validate.js +8 -5
  175. package/dist/src/core/config.d.ts +5 -8
  176. package/dist/src/core/config.js +7 -16
  177. package/dist/src/core/coverage-extend.d.ts +15 -13
  178. package/dist/src/core/coverage-extend.js +15 -13
  179. package/dist/src/core/destructive.d.ts +31 -9
  180. package/dist/src/core/destructive.js +29 -26
  181. package/dist/src/core/diff-hunks.js +10 -12
  182. package/dist/src/core/discard-baseline.d.ts +8 -8
  183. package/dist/src/core/discard-baseline.js +16 -15
  184. package/dist/src/core/display-state.d.ts +12 -14
  185. package/dist/src/core/display-state.js +12 -14
  186. package/dist/src/core/engine-changes.d.ts +2 -4
  187. package/dist/src/core/engine-changes.js +2 -4
  188. package/dist/src/core/engine-precondition.d.ts +28 -13
  189. package/dist/src/core/engine-precondition.js +25 -10
  190. package/dist/src/core/engine-session-lock.d.ts +47 -21
  191. package/dist/src/core/engine-session-lock.js +168 -33
  192. package/dist/src/core/export-moved-code-shape.d.ts +10 -10
  193. package/dist/src/core/export-moved-code-shape.js +10 -10
  194. package/dist/src/core/file-lock.d.ts +62 -5
  195. package/dist/src/core/file-lock.js +196 -59
  196. package/dist/src/core/firefox-cache.js +1 -3
  197. package/dist/src/core/firefox-extract.js +10 -14
  198. package/dist/src/core/firefox.d.ts +7 -5
  199. package/dist/src/core/firefox.js +4 -5
  200. package/dist/src/core/furnace-apply-dry-run.d.ts +2 -2
  201. package/dist/src/core/furnace-apply-dry-run.js +3 -2
  202. package/dist/src/core/furnace-apply-ftl.d.ts +7 -9
  203. package/dist/src/core/furnace-apply-ftl.js +12 -12
  204. package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
  205. package/dist/src/core/furnace-apply-helpers.js +19 -16
  206. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +8 -9
  207. package/dist/src/core/furnace-apply-overwrite-warn.js +8 -9
  208. package/dist/src/core/furnace-apply-undeploy-actions.d.ts +3 -4
  209. package/dist/src/core/furnace-apply-undeploy-actions.js +3 -4
  210. package/dist/src/core/furnace-apply.d.ts +5 -8
  211. package/dist/src/core/furnace-apply.js +19 -24
  212. package/dist/src/core/furnace-checksum-utils.d.ts +14 -0
  213. package/dist/src/core/furnace-checksum-utils.js +16 -0
  214. package/dist/src/core/furnace-config.d.ts +21 -30
  215. package/dist/src/core/furnace-config.js +32 -54
  216. package/dist/src/core/furnace-constants.d.ts +8 -0
  217. package/dist/src/core/furnace-constants.js +10 -2
  218. package/dist/src/core/furnace-css-fragments.d.ts +5 -5
  219. package/dist/src/core/furnace-css-fragments.js +5 -5
  220. package/dist/src/core/furnace-jsconfig.d.ts +11 -12
  221. package/dist/src/core/furnace-jsconfig.js +11 -12
  222. package/dist/src/core/furnace-marker.d.ts +7 -8
  223. package/dist/src/core/furnace-marker.js +7 -8
  224. package/dist/src/core/furnace-operation.d.ts +31 -0
  225. package/dist/src/core/furnace-operation.js +54 -17
  226. package/dist/src/core/furnace-precondition.d.ts +61 -0
  227. package/dist/src/core/furnace-precondition.js +67 -0
  228. package/dist/src/core/furnace-registration-remove.d.ts +5 -6
  229. package/dist/src/core/furnace-registration-remove.js +6 -7
  230. package/dist/src/core/furnace-registration-validate.d.ts +13 -0
  231. package/dist/src/core/furnace-registration-validate.js +20 -1
  232. package/dist/src/core/furnace-registration.d.ts +5 -6
  233. package/dist/src/core/furnace-registration.js +10 -12
  234. package/dist/src/core/furnace-rollback.js +7 -7
  235. package/dist/src/core/furnace-scanner.d.ts +1 -0
  236. package/dist/src/core/furnace-scanner.js +1 -2
  237. package/dist/src/core/furnace-stale-export.d.ts +10 -10
  238. package/dist/src/core/furnace-stale-export.js +10 -10
  239. package/dist/src/core/furnace-state-persist.d.ts +6 -8
  240. package/dist/src/core/furnace-state-persist.js +6 -8
  241. package/dist/src/core/furnace-validate-accessibility.d.ts +22 -0
  242. package/dist/src/core/furnace-validate-accessibility.js +310 -1
  243. package/dist/src/core/furnace-validate-compatibility.js +141 -1
  244. package/dist/src/core/furnace-validate-helpers.d.ts +5 -116
  245. package/dist/src/core/furnace-validate-helpers.js +0 -491
  246. package/dist/src/core/furnace-validate-registration.d.ts +7 -0
  247. package/dist/src/core/furnace-validate-registration.js +115 -41
  248. package/dist/src/core/furnace-validate.d.ts +16 -0
  249. package/dist/src/core/furnace-validate.js +188 -145
  250. package/dist/src/core/furnace-version-drift.d.ts +10 -11
  251. package/dist/src/core/furnace-version-drift.js +10 -11
  252. package/dist/src/core/git-base.d.ts +7 -9
  253. package/dist/src/core/git-base.js +7 -9
  254. package/dist/src/core/git-diff.d.ts +20 -9
  255. package/dist/src/core/git-diff.js +148 -63
  256. package/dist/src/core/git-file-ops.d.ts +19 -19
  257. package/dist/src/core/git-file-ops.js +19 -19
  258. package/dist/src/core/git-readonly-index.d.ts +53 -19
  259. package/dist/src/core/git-readonly-index.js +75 -31
  260. package/dist/src/core/git-status.d.ts +5 -6
  261. package/dist/src/core/git-status.js +5 -6
  262. package/dist/src/core/git.d.ts +9 -10
  263. package/dist/src/core/git.js +54 -70
  264. package/dist/src/core/license-headers.d.ts +17 -23
  265. package/dist/src/core/license-headers.js +17 -23
  266. package/dist/src/core/mach-build-artifacts.d.ts +9 -9
  267. package/dist/src/core/mach-build-artifacts.js +57 -19
  268. package/dist/src/core/mach-error-hints.js +42 -29
  269. package/dist/src/core/mach-known-noise-filter.d.ts +15 -16
  270. package/dist/src/core/mach-known-noise-filter.js +18 -20
  271. package/dist/src/core/mach-mozconfig.d.ts +14 -0
  272. package/dist/src/core/mach-mozconfig.js +30 -0
  273. package/dist/src/core/mach-resource-shim.d.ts +43 -58
  274. package/dist/src/core/mach-resource-shim.js +50 -67
  275. package/dist/src/core/mach.d.ts +37 -41
  276. package/dist/src/core/mach.js +50 -51
  277. package/dist/src/core/marionette-port.d.ts +36 -1
  278. package/dist/src/core/marionette-port.js +96 -31
  279. package/dist/src/core/marionette-preflight.d.ts +8 -12
  280. package/dist/src/core/marionette-preflight.js +86 -52
  281. package/dist/src/core/mochitest-server-port.d.ts +42 -0
  282. package/dist/src/core/mochitest-server-port.js +119 -0
  283. package/dist/src/core/module-resolution-preflight.d.ts +9 -11
  284. package/dist/src/core/module-resolution-preflight.js +9 -11
  285. package/dist/src/core/moz-manifest-helpers.d.ts +79 -0
  286. package/dist/src/core/moz-manifest-helpers.js +163 -0
  287. package/dist/src/core/{manifest-register.d.ts → moz-manifest-register.d.ts} +1 -1
  288. package/dist/src/core/{manifest-register.js → moz-manifest-register.js} +13 -28
  289. package/dist/src/core/{manifest-rules.d.ts → moz-manifest-rules.d.ts} +10 -1
  290. package/dist/src/core/{manifest-rules.js → moz-manifest-rules.js} +31 -24
  291. package/dist/src/core/{manifest-tokenizers.d.ts → moz-manifest-tokenizers.d.ts} +3 -5
  292. package/dist/src/core/{manifest-tokenizers.js → moz-manifest-tokenizers.js} +9 -12
  293. package/dist/src/core/ownership-table.d.ts +14 -16
  294. package/dist/src/core/ownership-table.js +14 -16
  295. package/dist/src/core/parser-fallback.d.ts +15 -1
  296. package/dist/src/core/parser-fallback.js +22 -3
  297. package/dist/src/core/patch-apply-fuzz.d.ts +10 -12
  298. package/dist/src/core/patch-apply-fuzz.js +15 -18
  299. package/dist/src/core/patch-apply.d.ts +13 -34
  300. package/dist/src/core/patch-apply.js +16 -76
  301. package/dist/src/core/patch-artifact-normalize.d.ts +13 -15
  302. package/dist/src/core/patch-artifact-normalize.js +13 -15
  303. package/dist/src/core/patch-export-metadata.d.ts +12 -2
  304. package/dist/src/core/patch-export-metadata.js +13 -4
  305. package/dist/src/core/patch-export-update.d.ts +13 -1
  306. package/dist/src/core/patch-export-update.js +25 -8
  307. package/dist/src/core/patch-export.d.ts +15 -8
  308. package/dist/src/core/patch-export.js +10 -11
  309. package/dist/src/core/patch-files.d.ts +5 -6
  310. package/dist/src/core/patch-files.js +5 -6
  311. package/dist/src/core/patch-identifier-suggest.d.ts +7 -12
  312. package/dist/src/core/patch-identifier-suggest.js +14 -19
  313. package/dist/src/core/patch-lint-binary.d.ts +51 -0
  314. package/dist/src/core/patch-lint-binary.js +39 -0
  315. package/dist/src/core/{lint-cache.d.ts → patch-lint-cache.d.ts} +5 -5
  316. package/dist/src/core/{lint-cache.js → patch-lint-cache.js} +21 -23
  317. package/dist/src/core/patch-lint-checkjs.d.ts +16 -16
  318. package/dist/src/core/patch-lint-checkjs.js +16 -16
  319. package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +6 -9
  320. package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -14
  321. package/dist/src/core/patch-lint-creators.d.ts +8 -8
  322. package/dist/src/core/patch-lint-creators.js +8 -8
  323. package/dist/src/core/patch-lint-cross.d.ts +17 -20
  324. package/dist/src/core/patch-lint-cross.js +16 -16
  325. package/dist/src/core/patch-lint-css.d.ts +3 -5
  326. package/dist/src/core/patch-lint-css.js +17 -22
  327. package/dist/src/core/patch-lint-diff-tag.d.ts +14 -16
  328. package/dist/src/core/patch-lint-diff-tag.js +14 -16
  329. package/dist/src/core/patch-lint-jsdoc.d.ts +7 -8
  330. package/dist/src/core/patch-lint-jsdoc.js +26 -19
  331. package/dist/src/core/patch-lint-mozbuild.js +20 -20
  332. package/dist/src/core/patch-lint-observer.d.ts +7 -7
  333. package/dist/src/core/patch-lint-observer.js +7 -7
  334. package/dist/src/core/patch-lint.d.ts +38 -29
  335. package/dist/src/core/patch-lint.js +89 -121
  336. package/dist/src/core/patch-lock.d.ts +1 -1
  337. package/dist/src/core/patch-lock.js +45 -9
  338. package/dist/src/core/patch-manifest-consistency.d.ts +2 -1
  339. package/dist/src/core/patch-manifest-consistency.js +25 -27
  340. package/dist/src/core/patch-manifest-io.js +14 -18
  341. package/dist/src/core/patch-manifest-resolve.d.ts +9 -12
  342. package/dist/src/core/patch-manifest-resolve.js +9 -12
  343. package/dist/src/core/patch-manifest-validate.d.ts +6 -1
  344. package/dist/src/core/patch-manifest-validate.js +25 -13
  345. package/dist/src/core/patch-parse.d.ts +24 -13
  346. package/dist/src/core/patch-parse.js +19 -14
  347. package/dist/src/core/patch-policy.d.ts +2 -2
  348. package/dist/src/core/patch-policy.js +2 -2
  349. package/dist/src/core/patch-registration-refs.d.ts +7 -8
  350. package/dist/src/core/patch-registration-refs.js +9 -9
  351. package/dist/src/core/process-cpu-time.d.ts +12 -0
  352. package/dist/src/core/process-cpu-time.js +52 -0
  353. package/dist/src/core/rebase-session.d.ts +38 -26
  354. package/dist/src/core/rebase-session.js +55 -28
  355. package/dist/src/core/register-browser-content.js +9 -74
  356. package/dist/src/core/{register-test-manifest.js → register-browser-test.js} +7 -42
  357. package/dist/src/core/register-module.js +10 -43
  358. package/dist/src/core/register-scaffold.d.ts +8 -8
  359. package/dist/src/core/register-scaffold.js +10 -10
  360. package/dist/src/core/register-shared-css.d.ts +9 -12
  361. package/dist/src/core/register-shared-css.js +17 -87
  362. package/dist/src/core/register-xpcshell-test.d.ts +6 -7
  363. package/dist/src/core/register-xpcshell-test.js +7 -8
  364. package/dist/src/core/shared-ftl.js +12 -4
  365. package/dist/src/core/state-file.d.ts +45 -0
  366. package/dist/src/core/state-file.js +34 -0
  367. package/dist/src/core/status-binary.d.ts +18 -11
  368. package/dist/src/core/status-binary.js +19 -12
  369. package/dist/src/core/status-classify.d.ts +30 -36
  370. package/dist/src/core/status-classify.js +21 -26
  371. package/dist/src/core/test-changed-prefs.d.ts +30 -0
  372. package/dist/src/core/test-changed-prefs.js +78 -0
  373. package/dist/src/core/test-harness-crash.d.ts +25 -63
  374. package/dist/src/core/test-harness-crash.js +121 -142
  375. package/dist/src/core/test-harness-signature.d.ts +18 -0
  376. package/dist/src/core/test-harness-signature.js +13 -0
  377. package/dist/src/core/test-path-scope.d.ts +12 -15
  378. package/dist/src/core/test-path-scope.js +15 -18
  379. package/dist/src/core/test-stale-check.d.ts +17 -17
  380. package/dist/src/core/test-stale-check.js +50 -43
  381. package/dist/src/core/test-stall-triage.d.ts +51 -0
  382. package/dist/src/core/test-stall-triage.js +126 -0
  383. package/dist/src/core/token-category.js +5 -7
  384. package/dist/src/core/token-coverage.js +9 -9
  385. package/dist/src/core/token-dark-mode.d.ts +9 -11
  386. package/dist/src/core/token-dark-mode.js +9 -11
  387. package/dist/src/core/token-docs.d.ts +2 -0
  388. package/dist/src/core/token-docs.js +2 -0
  389. package/dist/src/core/token-manager.d.ts +10 -2
  390. package/dist/src/core/token-manager.js +17 -8
  391. package/dist/src/core/token-scaffold.d.ts +7 -7
  392. package/dist/src/core/token-scaffold.js +7 -7
  393. package/dist/src/core/token-variant.d.ts +4 -4
  394. package/dist/src/core/token-variant.js +4 -4
  395. package/dist/src/core/toolchain-preflight.d.ts +20 -21
  396. package/dist/src/core/toolchain-preflight.js +28 -31
  397. package/dist/src/core/tree-guard.js +12 -2
  398. package/dist/src/core/tree-store.d.ts +41 -27
  399. package/dist/src/core/tree-store.js +63 -42
  400. package/dist/src/core/typecheck-shim.d.ts +23 -24
  401. package/dist/src/core/typecheck-shim.js +23 -24
  402. package/dist/src/core/typecheck.js +8 -8
  403. package/dist/src/core/wire-destroy.d.ts +3 -3
  404. package/dist/src/core/wire-destroy.js +7 -15
  405. package/dist/src/core/wire-dom-fragment.d.ts +9 -17
  406. package/dist/src/core/wire-dom-fragment.js +11 -44
  407. package/dist/src/core/wire-init.d.ts +2 -3
  408. package/dist/src/core/wire-init.js +8 -19
  409. package/dist/src/core/wire-subscript.d.ts +2 -3
  410. package/dist/src/core/wire-subscript.js +4 -13
  411. package/dist/src/core/wire-utils.d.ts +7 -8
  412. package/dist/src/core/wire-utils.js +7 -8
  413. package/dist/src/core/xpcshell-appdir.d.ts +38 -45
  414. package/dist/src/core/xpcshell-appdir.js +38 -45
  415. package/dist/src/errors/base.d.ts +37 -16
  416. package/dist/src/errors/base.js +37 -16
  417. package/dist/src/errors/build.d.ts +13 -1
  418. package/dist/src/errors/build.js +14 -2
  419. package/dist/src/errors/codes.d.ts +16 -0
  420. package/dist/src/errors/codes.js +16 -0
  421. package/dist/src/errors/furnace.d.ts +4 -4
  422. package/dist/src/errors/git.d.ts +6 -10
  423. package/dist/src/errors/git.js +6 -10
  424. package/dist/src/errors/patch.d.ts +7 -7
  425. package/dist/src/errors/patch.js +7 -7
  426. package/dist/src/errors/rebase.d.ts +4 -4
  427. package/dist/src/errors/rebase.js +4 -4
  428. package/dist/src/index.d.ts +7 -1
  429. package/dist/src/index.js +5 -0
  430. package/dist/src/types/commands/index.d.ts +2 -2
  431. package/dist/src/types/commands/options.d.ts +88 -70
  432. package/dist/src/types/commands/patches.d.ts +24 -34
  433. package/dist/src/types/commands/project.d.ts +5 -34
  434. package/dist/src/types/config.d.ts +25 -23
  435. package/dist/src/types/config.js +6 -1
  436. package/dist/src/types/furnace.d.ts +37 -13
  437. package/dist/src/types/furnace.js +19 -1
  438. package/dist/src/types/index.d.ts +3 -3
  439. package/dist/src/utils/build-info.d.ts +7 -8
  440. package/dist/src/utils/build-info.js +12 -11
  441. package/dist/src/utils/errors.d.ts +6 -8
  442. package/dist/src/utils/errors.js +6 -8
  443. package/dist/src/utils/logger.d.ts +27 -10
  444. package/dist/src/utils/logger.js +28 -16
  445. package/dist/src/utils/machine-output.d.ts +12 -0
  446. package/dist/src/utils/machine-output.js +33 -0
  447. package/dist/src/utils/options.d.ts +31 -14
  448. package/dist/src/utils/options.js +86 -30
  449. package/dist/src/utils/paths.d.ts +10 -8
  450. package/dist/src/utils/paths.js +10 -8
  451. package/dist/src/utils/platform.d.ts +0 -25
  452. package/dist/src/utils/platform.js +1 -42
  453. package/dist/src/utils/process-group.d.ts +9 -4
  454. package/dist/src/utils/process-group.js +19 -5
  455. package/dist/src/utils/process.d.ts +42 -7
  456. package/dist/src/utils/process.js +44 -17
  457. package/dist/src/utils/ps-duration.d.ts +31 -0
  458. package/dist/src/utils/ps-duration.js +70 -0
  459. package/dist/src/utils/regex.d.ts +9 -10
  460. package/dist/src/utils/regex.js +9 -10
  461. package/dist/src/utils/validation.d.ts +58 -28
  462. package/dist/src/utils/validation.js +60 -33
  463. package/package.json +2 -2
  464. package/dist/src/commands/doctor/post-rebase-audit.d.ts +0 -2
  465. package/dist/src/commands/doctor-furnace-manifest-sync.d.ts +0 -18
  466. package/dist/src/core/manifest-helpers.d.ts +0 -38
  467. package/dist/src/core/manifest-helpers.js +0 -120
  468. /package/dist/src/core/{lint-projection.d.ts → patch-lint-projection.d.ts} +0 -0
  469. /package/dist/src/core/{lint-projection.js → patch-lint-projection.js} +0 -0
  470. /package/dist/src/core/{register-test-manifest.d.ts → register-browser-test.d.ts} +0 -0
@@ -2,7 +2,8 @@
2
2
  import { readdir } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
4
  import { getProjectPaths } from '../../core/config.js';
5
- import { furnaceConfigExists, getFurnacePaths, loadFurnaceConfig, } from '../../core/furnace-config.js';
5
+ import { getFurnacePaths, loadFurnaceConfig } from '../../core/furnace-config.js';
6
+ import { assertFurnaceReady } from '../../core/furnace-precondition.js';
6
7
  import { addCustomElementRegistration, addJarMnEntries, pruneStaleJarMnEntries, } from '../../core/furnace-registration.js';
7
8
  import { validateAllComponents, validateComponent } from '../../core/furnace-validate.js';
8
9
  import { FurnaceError } from '../../errors/furnace.js';
@@ -43,9 +44,9 @@ async function autoFixIssues(projectRoot, issues) {
43
44
  jarMnFixesByComponent.set(issue.component, existing);
44
45
  }
45
46
  }
46
- // Prune stale jar.mn registrations (lines pointing at removed/renamed
47
- // component files — 0.34.0 field report: these broke packaging while
48
- // validate --fix reported success without touching them).
47
+ // Prune stale jar.mn registrations (lines pointing at removed or renamed
48
+ // component files). These break packaging, and validate --fix must not
49
+ // report success without touching them.
49
50
  if (issues.some((issue) => issue.check === 'stale-jar-registration')) {
50
51
  try {
51
52
  const pruned = await pruneStaleJarMnEntries(engineDir, furnacePaths.customDir, Object.keys(config.custom));
@@ -84,12 +85,11 @@ async function autoFixIssues(projectRoot, issues) {
84
85
  // Repair components missing from customElements.js entirely (reported by
85
86
  // validate as `missing-custom-element-registration`).
86
87
  //
87
- // Scoped to the components named in `issues`. Until 0.41.0 this iterated
88
- // every entry in `config.custom`, so `furnace validate <one-component> --fix`
89
- // wrote customElements.js registrations for EVERY custom component — outside
90
- // the issue list it was handed, and invisibly, since `fixed` was never
91
- // incremented here. The block's own comment already claimed this scoping;
92
- // the code did not implement it.
88
+ // Scoped to the components named in `issues`: iterating every entry in
89
+ // `config.custom` makes `furnace validate <one-component> --fix` write
90
+ // customElements.js registrations for EVERY custom component, outside the
91
+ // issue list it was handed and invisibly, since `fixed` is never
92
+ // incremented here.
93
93
  const componentsWithIssues = new Set(issues.map((issue) => issue.component));
94
94
  for (const componentName of componentsWithIssues) {
95
95
  const customConfig = config.custom[componentName];
@@ -123,10 +123,10 @@ async function autoFixIssues(projectRoot, issues) {
123
123
  */
124
124
  export async function furnaceValidateCommand(projectRoot, name, options = {}) {
125
125
  intro('Furnace Validate');
126
- if (!(await furnaceConfigExists(projectRoot))) {
127
- throw new FurnaceError('No furnace.json found. Run "fireforge furnace create" or "fireforge furnace override" to get started.');
128
- }
129
- const config = await loadFurnaceConfig(projectRoot);
126
+ // Gains the engine rung here: this was the one site in the family that
127
+ // checked furnace.json alone, so a validate against a missing engine
128
+ // produced downstream noise instead of the shared precondition refusal.
129
+ const { config } = await assertFurnaceReady(projectRoot);
130
130
  const furnacePaths = getFurnacePaths(projectRoot);
131
131
  let totalErrors = 0;
132
132
  let totalWarnings = 0;
@@ -193,12 +193,12 @@ export async function furnaceValidateCommand(projectRoot, name, options = {}) {
193
193
  }
194
194
  }
195
195
  }
196
- // Auto-fix fixable issues when --fix is passed. The auto-fix counter
197
- // returned by `autoFixIssues` only counts function calls that did not
198
- // throw — a write that succeeded but did not actually resolve the issue
199
- // (e.g. addJarMnEntries appended to a file mach later ignores) would
200
- // still bump the count. Re-validate the affected components and compute
201
- // the *actual* drop in fixable issues so the reported number is honest.
196
+ // Auto-fix fixable issues when --fix is passed. The counter returned by
197
+ // `autoFixIssues` only counts function calls that did not throw — a write
198
+ // that succeeded but did not actually resolve the issue (addJarMnEntries
199
+ // appending to a file mach later ignores) would still bump it. Re-validate
200
+ // the affected components and compute the *actual* drop in fixable issues
201
+ // so the reported number is honest.
202
202
  if (options.fix && allIssues.length > 0) {
203
203
  const fixableIssues = allIssues.filter((issue) => FIXABLE_CHECKS.has(issue.check));
204
204
  if (fixableIssues.length > 0) {
@@ -3,6 +3,8 @@ import { join } from 'node:path';
3
3
  import { confirm } from '@clack/prompts';
4
4
  import { Command } from 'commander';
5
5
  import { getProjectPaths, loadConfig, loadState, updateState } from '../core/config.js';
6
+ import { stdioIsInteractive } from '../core/destructive.js';
7
+ import { assertEngineExists } from '../core/engine-precondition.js';
6
8
  import { getHead } from '../core/git.js';
7
9
  import { getDirtyFiles } from '../core/git-status.js';
8
10
  import { applyPatchesWithContinue, countPatches, createPatchedContentContext, discoverPatches, extractAffectedFiles, matchesUntilFilename, PatchError, } from '../core/patch-apply.js';
@@ -84,14 +86,13 @@ async function checkUncommittedPatchFiles(engineDir, patchesDir, forceImport) {
84
86
  if (dirtyFiles.length > 0) {
85
87
  const unmanagedDirtyFiles = await getUnmanagedDirtyFiles(engineDir, patchesDir, dirtyFiles);
86
88
  if (unmanagedDirtyFiles.length === 0) {
87
- // Common path here: operator just ran `fireforge resolve` to
89
+ // Common path here: the operator just ran `fireforge resolve` to
88
90
  // regenerate a patch from manual conflict edits, so the engine
89
- // already carries the patch's effects. The import below will
90
- // still re-apply each patch (a no-op for files whose contents
91
- // already match), so phrase the line as "no resync needed"
92
- // rather than "patches already applied" — the latter contradicts
93
- // the "Applied N patch(es)" summary `applyPatchesWithContinue`
94
- // prints next, which the 2026-04-25 eval flagged as ambiguous.
91
+ // already carries the patch's effects. The import below still
92
+ // re-applies each patch (a no-op for files whose contents already
93
+ // match), so phrase the line as "no resync needed" rather than
94
+ // "patches already applied" — the latter contradicts the "Applied N
95
+ // patch(es)" summary `applyPatchesWithContinue` prints next.
95
96
  info('Patch-touched files already match the stored patch stack — no engine resync needed before re-applying.');
96
97
  }
97
98
  else if (!forceImport) {
@@ -110,12 +111,12 @@ async function checkUncommittedPatchFiles(engineDir, patchesDir, forceImport) {
110
111
  async function handlePatchFailures(summary, projectRoot) {
111
112
  const firstFailed = summary.failed[0];
112
113
  if (firstFailed) {
113
- // Transactional update rather than `loadState` + mutate + `saveState`. The
114
- // caller captures `state` at the start of the import run, and the run can
115
- // span a long window (drift-check prompt, patch apply loop). A concurrent
116
- // command (`fireforge download`, `rebase`, another state mutation) writing
117
- // unrelated fields during that window would be silently clobbered when the
118
- // stale state object was written back.
114
+ // Transactional update rather than `loadState` + mutate + `saveState`.
115
+ // The caller captures `state` at the start of the import run, and the run
116
+ // can span a long window (drift-check prompt, patch apply loop). A
117
+ // concurrent command (`fireforge download`, `rebase`, another state
118
+ // mutation) writing unrelated fields during that window would be silently
119
+ // clobbered when the stale state object was written back.
119
120
  await updateState(projectRoot, (current) => ({
120
121
  ...current,
121
122
  pendingResolution: {
@@ -155,19 +156,22 @@ async function handlePatchFailures(summary, projectRoot) {
155
156
  info(' 2. Run "fireforge resolve" to update the patch file with your manual fixes and continue.');
156
157
  throw new PatchError(`Failed to apply ${summary.failed.length} patch(es)`, firstFailed?.patch.filename);
157
158
  }
158
- async function checkEngineDrift(engineDir, baseCommit, forceImport) {
159
+ async function checkEngineDrift(engineDir, baseCommit, forceImport, acceptPrompts) {
159
160
  const currentHead = await getHead(engineDir);
160
161
  if (currentHead === baseCommit)
161
162
  return true;
162
- if (!(process.stdin.isTTY && process.stdout.isTTY)) {
163
- if (!forceImport) {
164
- throw new GeneralError('Engine HEAD has drifted from base commit. Re-run with --force to bypass drift check.');
163
+ // `--yes` and `--force` both answer this prompt; only `--force` also
164
+ // waives the patch-integrity gate further down.
165
+ const promptAnswered = forceImport || acceptPrompts;
166
+ if (!stdioIsInteractive()) {
167
+ if (!promptAnswered) {
168
+ throw new GeneralError('Engine HEAD has drifted from base commit. Re-run with --yes to accept the drift, or --force to also bypass the patch-integrity gate.');
165
169
  }
166
- warn('Engine HEAD has drifted from base commit. Continuing because --force was provided in non-interactive mode.');
170
+ warn(`Engine HEAD has drifted from base commit. Continuing because ${forceImport ? '--force' : '--yes'} was provided in non-interactive mode.`);
167
171
  }
168
172
  else {
169
- if (forceImport) {
170
- warn('Engine HEAD has drifted from base commit. Continuing because --force was provided.');
173
+ if (promptAnswered) {
174
+ warn(`Engine HEAD has drifted from base commit. Continuing because ${forceImport ? '--force' : '--yes'} was provided.`);
171
175
  }
172
176
  else {
173
177
  warn('Warning: Engine is not at the baseline commit.');
@@ -200,10 +204,10 @@ function buildUntilFilenameSet(patches, until) {
200
204
  return set;
201
205
  // Resolve the identifier with the SAME matcher the apply loop uses
202
206
  // (`matchesUntilFilename` accepts filenames, extension-less names, AND
203
- // bare ordinals). The previous filename-only match meant
204
- // `import --until 5` produced an EMPTY scope set — the UI previewed
205
- // "0 patches", the integrity gates filtered every in-range issue away —
206
- // and then the apply loop happily applied patches 1..5 anyway.
207
+ // bare ordinals). A filename-only match makes `import --until 5` produce
208
+ // an EMPTY scope set — the UI previews "0 patches", the integrity gates
209
+ // filter every in-range issue away — and the apply loop then applies
210
+ // patches 1..5 anyway.
207
211
  const target = patches.find((p) => matchesUntilFilename(p.filename, until));
208
212
  if (!target)
209
213
  return set;
@@ -280,7 +284,7 @@ async function gateImportIntegrity(paths, untilFilenameSet, until, forceImport)
280
284
  if (forceImport) {
281
285
  warn('Continuing because --force was provided. Integrity issues were not resolved.\n');
282
286
  }
283
- else if (!(process.stdin.isTTY && process.stdout.isTTY)) {
287
+ else if (!stdioIsInteractive()) {
284
288
  throw new GeneralError(`Refusing to import while ${integrityIssues.length} patch integrity issue(s) are unresolved. ` +
285
289
  `Fix the issues reported above (see "fireforge doctor") or re-run with --force to continue anyway.`);
286
290
  }
@@ -326,15 +330,14 @@ export async function importCommand(projectRoot, options = {}) {
326
330
  intro(isDryRun ? 'FireForge Import (dry run)' : 'FireForge Import');
327
331
  const continueOnFailure = options.continue ?? false;
328
332
  const forceImport = options.force ?? false;
333
+ const acceptPrompts = options.yes ?? false;
329
334
  const paths = getProjectPaths(projectRoot);
330
335
  // Check if engine exists
331
- if (!(await pathExists(paths.engine))) {
332
- throw new GeneralError('Firefox source not found. Run "fireforge download" first.');
333
- }
336
+ await assertEngineExists(paths.engine);
334
337
  // Engine consistency check before applying patches
335
338
  const state = await loadState(projectRoot);
336
339
  if (state.baseCommit && !isDryRun) {
337
- const shouldContinue = await checkEngineDrift(paths.engine, state.baseCommit, forceImport);
340
+ const shouldContinue = await checkEngineDrift(paths.engine, state.baseCommit, forceImport, acceptPrompts);
338
341
  if (!shouldContinue)
339
342
  return;
340
343
  }
@@ -364,15 +367,14 @@ export async function importCommand(projectRoot, options = {}) {
364
367
  await assertScopedManifestConsistency(paths.patches, untilFilenameSet, options.until);
365
368
  await warnVersionCompatibility(projectRoot, manifest, untilFilenameSet, options.until);
366
369
  // Validate patch integrity (detect orphaned modification patches). Warn
367
- // and prompt the operator to confirm before proceeding — the legacy
368
- // warn-and-continue behaviour hid the real root cause because import
369
- // would later fail during patch application with a secondary, unrelated
370
- // error that made diagnosis harder.
370
+ // and prompt the operator to confirm before proceeding: warn-and-continue
371
+ // hides the real root cause, because import then fails during patch
372
+ // application with a secondary, unrelated error.
371
373
  //
372
374
  // Scope the surfaced issues to the `--until` range: a later patch with
373
375
  // integrity problems should not block importing an earlier good subset,
374
- // which is exactly what operators reach for when the tail of the queue
375
- // is broken and they want to keep working against an earlier checkpoint.
376
+ // which is exactly what operators reach for when the tail of the queue is
377
+ // broken and they want to keep working against an earlier checkpoint.
376
378
  const integrityOk = await gateImportIntegrity(paths, untilFilenameSet, options.until, forceImport);
377
379
  if (!integrityOk)
378
380
  return;
@@ -426,6 +428,11 @@ export function registerImport(program, { getProjectRoot, withErrorHandling }) {
426
428
  .description('Apply patches from the patches directory')
427
429
  .option('--continue', 'Continue applying patches even if one fails')
428
430
  .option('-f, --force', 'Proceed despite engine drift and overwrite unmanaged changes in patch-touched files')
431
+ // NOT an alias of --force. `--force` waives two orthogonal things: the
432
+ // drift prompt AND the patch-integrity gate. `--yes` waives only the
433
+ // prompt, so a scripted import can run unattended while the integrity
434
+ // refusal stays armed — which is the guard you actually want in CI.
435
+ .option('-y, --yes', 'Answer the drift prompt non-interactively. Unlike --force, this does NOT waive the patch-integrity gate.')
429
436
  .option('--until <patch>', 'Apply patches only up to and including this patch (alias: --stop-at)')
430
437
  .option('--stop-at <patch>', 'Alias for --until')
431
438
  .option('--dry-run', 'Preview which patches would be applied without modifying the engine')
@@ -3,8 +3,8 @@ import { join } from 'node:path';
3
3
  import { getProjectPaths, loadConfig } from '../core/config.js';
4
4
  import { getDiffForFilesAgainstHead } from '../core/git-diff.js';
5
5
  import { withPrivateGitIndex } from '../core/git-readonly-index.js';
6
- import { buildPerPatchLintCacheKey, getCachedPerPatchLintIssues, getPerPatchLintCacheHeadSha, loadPerPatchLintCache, savePerPatchLintCache, setCachedPerPatchLintIssues, } from '../core/lint-cache.js';
7
6
  import { buildPatchQueueContext, countNonBinaryDiffLines, formatPatchLintIssue, lintExportedPatch, lintPatchQueue, resolvePatchSizeTier, } from '../core/patch-lint.js';
7
+ import { buildPerPatchLintCacheKey, getCachedPerPatchLintIssues, getPerPatchLintCacheHeadSha, loadPerPatchLintCache, savePerPatchLintCache, setCachedPerPatchLintIssues, } from '../core/patch-lint-cache.js';
8
8
  import { loadPatchesManifest } from '../core/patch-manifest.js';
9
9
  import { evaluatePatchPolicy } from '../core/patch-policy.js';
10
10
  import { GeneralError } from '../errors/base.js';
@@ -106,7 +106,12 @@ async function lintQueuedPatch(patch, lintCtx) {
106
106
  }
107
107
  lintOptions.precomputedCheckJs = precomputedCheckJs;
108
108
  }
109
- const patchIssues = await lintExportedPatch(paths.engine, existing, diff, config, ctx, ignore, patch.tier, lintOptions);
109
+ const patchIssues = await lintExportedPatch(paths.engine, existing, diff, config, {
110
+ ...lintOptions,
111
+ patchQueueCtx: ctx,
112
+ ...(ignore ? { ignoreChecks: ignore } : {}),
113
+ ...(patch.tier ? { patchTier: patch.tier } : {}),
114
+ });
110
115
  const result = {
111
116
  status: 'linted',
112
117
  existingFiles: existing,
@@ -155,10 +160,10 @@ async function applyPerPatchResults(subset, results, issues, checkJs, cache) {
155
160
  // Run-level checkJs errors are emitted once, before the first
156
161
  // non-skipped patch's own issues — matching the serial emit point.
157
162
  // Deliberately NOT gated on `result.usedCheckJs`: global findings are
158
- // run-level, never cached, and an all-cache-hit run previously dropped
159
- // them entirely, letting a warm run report fewer errors than a cold
160
- // one (hardening). PerRunCheckJs builds its program lazily,
161
- // so the cost only materialises when checkJs is configured.
163
+ // run-level and never cached, so gating drops them entirely on an
164
+ // all-cache-hit run and lets a warm run report fewer errors than a cold
165
+ // one. PerRunCheckJs builds its program lazily, so the cost only
166
+ // materialises when checkJs is configured.
162
167
  if (checkJs && !globalCheckJsEmitted) {
163
168
  globalCheckJsEmitted = true;
164
169
  issues.push(...(await checkJs.getGlobal()));
@@ -170,10 +175,10 @@ async function applyPerPatchResults(subset, results, issues, checkJs, cache) {
170
175
  for (const issue of result.rawIssues) {
171
176
  issues.push({ ...issue, file: `${patch.filename} :: ${issue.file}` });
172
177
  }
173
- // A waived size finding still reports its MEASUREMENT:
174
- // the finding stays suppressed (no exit-code / --max-warnings effect)
175
- // but the current count is readable from the tool that enforces it,
176
- // so a waiver's cited size can be calibrated without hand-measuring.
178
+ // A waived size finding still reports its MEASUREMENT: the finding stays
179
+ // suppressed (no exit-code / --max-warnings effect) but the current count
180
+ // is readable from the tool that enforces it, so a waiver's cited size
181
+ // can be calibrated without hand-measuring.
177
182
  for (const suppressedIssue of result.suppressedIssues) {
178
183
  if (!SUPPRESSED_SIZE_CHECKS.has(suppressedIssue.check))
179
184
  continue;
@@ -3,22 +3,22 @@
3
3
  * `re-export`.
4
4
  *
5
5
  * The dominant fixed cost of patch lint is one `ts.createProgram` over the
6
- * queue's patch-owned `.sys.mjs` files (~37 s on a 290-patch consumer
7
- * queue). This controller builds that program at most ONCE per command
8
- * invocation (lazily, promise-memoised) and lets callers slice per-patch
9
- * findings out of the grouped result. Three levers keep the cost paid only
10
- * when it buys something:
6
+ * queue's patch-owned `.sys.mjs` files — tens of seconds on a large queue.
7
+ * This controller builds that program at most ONCE per command invocation
8
+ * (lazily, promise-memoised) and lets callers slice per-patch findings out of
9
+ * the grouped result. Three levers keep the cost paid only when it buys
10
+ * something:
11
11
  *
12
12
  * - **Lazy build**: nothing is built until the first cache miss asks.
13
13
  * - **Root scoping** (`rootScopePatches`): with `--patches <subset>` the
14
- * program's roots are only the subset's owned files; the full queue
15
- * stays resolvable, so cross-patch imports type-check identically while
16
- * unrelated files are never parsed.
17
- * - **Warm-run probe**: run-level ("global") checkJs findings come only
18
- * from a missing `typescript` package or an unreadable shim — never
19
- * from the built program — so an all-cache-hit run satisfies "warm
20
- * never reports less than cold" via
21
- * `probeCheckJsGlobalIssues` instead of building anything.
14
+ * program's roots are only the subset's owned files; the full queue stays
15
+ * resolvable, so cross-patch imports type-check identically while
16
+ * unrelated files are never parsed.
17
+ * - **Warm-run probe**: run-level ("global") checkJs findings come only from
18
+ * a missing `typescript` package or an unreadable shim — never from the
19
+ * built program — so an all-cache-hit run satisfies "warm never reports
20
+ * less than cold" via `probeCheckJsGlobalIssues` instead of building
21
+ * anything.
22
22
  */
23
23
  import type { getProjectPaths, loadConfig } from '../core/config.js';
24
24
  import { type GroupedCheckJsResult } from '../core/patch-lint-checkjs.js';
@@ -4,22 +4,22 @@
4
4
  * `re-export`.
5
5
  *
6
6
  * The dominant fixed cost of patch lint is one `ts.createProgram` over the
7
- * queue's patch-owned `.sys.mjs` files (~37 s on a 290-patch consumer
8
- * queue). This controller builds that program at most ONCE per command
9
- * invocation (lazily, promise-memoised) and lets callers slice per-patch
10
- * findings out of the grouped result. Three levers keep the cost paid only
11
- * when it buys something:
7
+ * queue's patch-owned `.sys.mjs` files — tens of seconds on a large queue.
8
+ * This controller builds that program at most ONCE per command invocation
9
+ * (lazily, promise-memoised) and lets callers slice per-patch findings out of
10
+ * the grouped result. Three levers keep the cost paid only when it buys
11
+ * something:
12
12
  *
13
13
  * - **Lazy build**: nothing is built until the first cache miss asks.
14
14
  * - **Root scoping** (`rootScopePatches`): with `--patches <subset>` the
15
- * program's roots are only the subset's owned files; the full queue
16
- * stays resolvable, so cross-patch imports type-check identically while
17
- * unrelated files are never parsed.
18
- * - **Warm-run probe**: run-level ("global") checkJs findings come only
19
- * from a missing `typescript` package or an unreadable shim — never
20
- * from the built program — so an all-cache-hit run satisfies "warm
21
- * never reports less than cold" via
22
- * `probeCheckJsGlobalIssues` instead of building anything.
15
+ * program's roots are only the subset's owned files; the full queue stays
16
+ * resolvable, so cross-patch imports type-check identically while
17
+ * unrelated files are never parsed.
18
+ * - **Warm-run probe**: run-level ("global") checkJs findings come only from
19
+ * a missing `typescript` package or an unreadable shim — never from the
20
+ * built program — so an all-cache-hit run satisfies "warm never reports
21
+ * less than cold" via `probeCheckJsGlobalIssues` instead of building
22
+ * anything.
23
23
  */
24
24
  import { invokePatchLintCheckJsGrouped, probeCheckJsGlobalIssues, runCheckJsTestFilesGrouped, } from '../core/patch-lint-checkjs.js';
25
25
  import { isTestScriptFile, resolvePatchOwnedSysMjs, resolvePatchOwnedTestScripts, } from '../core/patch-lint-ownership.js';
@@ -1,14 +1,13 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
3
  * Machine-readable per-patch lint report (`lint --per-patch --report
4
- * <path>`, + G10). One mechanism serves both observability
5
- * gaps: consumers get each patch's size metrics against the SAME
6
- * thresholds the size rules fire on (no more mirroring
7
- * `countNonBinaryDiffLines`), and lintIgnore-suppressed issues stay
8
- * visible with their measurements instead of vanishing.
4
+ * <path>`). One mechanism serves two observability gaps: consumers get each
5
+ * patch's size metrics against the SAME thresholds the size rules fire on,
6
+ * instead of mirroring `countNonBinaryDiffLines`, and lintIgnore-suppressed
7
+ * issues stay visible with their measurements rather than vanishing.
9
8
  *
10
- * Helper module consumed by lint-per-patch.ts; no registrar is exported
11
- * and none is wanted.
9
+ * Helper module consumed by lint-per-patch.ts; no registrar is exported and
10
+ * none is wanted.
12
11
  */
13
12
  import { getPatchSizeThresholds, resolvePatchSizeTier, } from '../core/patch-lint.js';
14
13
  import { writeJson } from '../utils/fs.js';
@@ -11,25 +11,24 @@ export interface AggregateLintIgnoreResult {
11
11
  dropped: number;
12
12
  }
13
13
  /**
14
- * Filters aggregate-mode lint issues against per-patch `lintIgnore`
15
- * lists drawn from the manifest. An issue is dropped when at least one
16
- * patch whose `filesAffected` covers `issue.file` lists `issue.check`
17
- * in its `lintIgnore`.
14
+ * Filters aggregate-mode lint issues against per-patch `lintIgnore` lists
15
+ * drawn from the manifest. An issue is dropped when at least one patch whose
16
+ * `filesAffected` covers `issue.file` lists `issue.check` in its
17
+ * `lintIgnore`.
18
18
  *
19
- * Mirrors the per-patch contract: `--per-patch` mode threads each
20
- * patch's `lintIgnore` directly into `lintExportedPatch`, so a check
21
- * the operator explicitly waived in `patches.json` does not surface.
22
- * Aggregate `--since` mode previously rediscovered the suppressed
23
- * warning every CI run because the diff was treated as a single unit
24
- * with no patch-level scope. Attributing each issue's file to its
19
+ * Mirrors the per-patch contract: `--per-patch` mode threads each patch's
20
+ * `lintIgnore` directly into `lintExportedPatch`, so a check the operator
21
+ * explicitly waived in `patches.json` does not surface. Aggregate `--since`
22
+ * mode has no patch-level scope of its own and would otherwise rediscover
23
+ * the suppressed warning every CI run. Attributing each issue's file to its
25
24
  * owning patch via `filesAffected` re-establishes the same suppression
26
- * semantics. Cross-patch findings (forward-import, duplicate-creation)
27
- * still attribute via `issue.file` because the `file` field is the
28
- * offending site, which is owned by some patch.
25
+ * semantics. Cross-patch findings (forward-import, duplicate-creation) also
26
+ * attribute via `issue.file`, which is the offending site and is owned by
27
+ * some patch.
29
28
  *
30
- * Multiple owners: an issue is dropped if **any** owning patch waived
31
- * the rule. Conservative — never adds new findings, only drops
32
- * already-explicitly-waived ones.
29
+ * Multiple owners: an issue is dropped if **any** owning patch waived the
30
+ * rule. Conservative — never adds new findings, only drops already-waived
31
+ * ones.
33
32
  *
34
33
  * @param issues - Issues collected from the aggregate lint run.
35
34
  * @param ctx - Patch queue context used to attribute file → patch.