@hominis/fireforge 0.45.0 → 0.46.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (662) hide show
  1. package/CHANGELOG.md +409 -446
  2. package/dist/bin/fireforge.d.ts +1 -1
  3. package/dist/bin/fireforge.js +21 -15
  4. package/dist/build-info.json +4 -4
  5. package/dist/src/cli-usage-error.d.ts +46 -0
  6. package/dist/src/cli-usage-error.js +81 -0
  7. package/dist/src/cli.d.ts +7 -2
  8. package/dist/src/cli.js +47 -47
  9. package/dist/src/commands/bootstrap-checks.js +2 -1
  10. package/dist/src/commands/bootstrap.js +3 -4
  11. package/dist/src/commands/build.js +27 -17
  12. package/dist/src/commands/config.js +9 -9
  13. package/dist/src/commands/destructive-decision.d.ts +19 -0
  14. package/dist/src/commands/destructive-decision.js +31 -0
  15. package/dist/src/commands/discard.js +5 -5
  16. package/dist/src/commands/doctor-check-core.d.ts +4 -10
  17. package/dist/src/commands/doctor-check-core.js +0 -8
  18. package/dist/src/commands/doctor-external-toolchains.js +2 -2
  19. package/dist/src/commands/doctor-furnace-config-sync.d.ts +2 -2
  20. package/dist/src/commands/doctor-furnace-config-sync.js +20 -20
  21. package/dist/src/commands/doctor-furnace-jar.d.ts +1 -1
  22. package/dist/src/commands/doctor-furnace-jar.js +1 -1
  23. package/dist/src/commands/doctor-furnace.js +22 -22
  24. package/dist/src/commands/doctor-orphaned-harness.d.ts +10 -17
  25. package/dist/src/commands/doctor-orphaned-harness.js +14 -23
  26. package/dist/src/commands/doctor-patch-manifest.d.ts +2 -1
  27. package/dist/src/commands/doctor-patch-manifest.js +7 -6
  28. package/dist/src/commands/doctor-post-rebase-audit.js +3 -3
  29. package/dist/src/commands/doctor-source-pin.d.ts +12 -12
  30. package/dist/src/commands/doctor-source-pin.js +14 -14
  31. package/dist/src/commands/doctor-working-tree.d.ts +3 -3
  32. package/dist/src/commands/doctor-working-tree.js +3 -3
  33. package/dist/src/commands/doctor.d.ts +3 -1
  34. package/dist/src/commands/doctor.js +15 -16
  35. package/dist/src/commands/download.js +50 -37
  36. package/dist/src/commands/export-all.js +29 -12
  37. package/dist/src/commands/export-flow.d.ts +5 -5
  38. package/dist/src/commands/export-flow.js +29 -59
  39. package/dist/src/commands/export-placement-conflicts.d.ts +3 -3
  40. package/dist/src/commands/export-placement-conflicts.js +12 -12
  41. package/dist/src/commands/export-placement-gate.d.ts +2 -2
  42. package/dist/src/commands/export-placement-gate.js +7 -13
  43. package/dist/src/commands/export-placement-policy.d.ts +1 -1
  44. package/dist/src/commands/export-placement-policy.js +4 -6
  45. package/dist/src/commands/export-shared.d.ts +51 -32
  46. package/dist/src/commands/export-shared.js +17 -32
  47. package/dist/src/commands/export.js +14 -5
  48. package/dist/src/commands/furnace/apply.js +16 -16
  49. package/dist/src/commands/furnace/authoring-config.d.ts +13 -0
  50. package/dist/src/commands/furnace/authoring-config.js +19 -0
  51. package/dist/src/commands/furnace/chrome-doc-remove.d.ts +1 -1
  52. package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
  53. package/dist/src/commands/furnace/chrome-doc-templates.d.ts +14 -14
  54. package/dist/src/commands/furnace/chrome-doc-templates.js +17 -17
  55. package/dist/src/commands/furnace/chrome-doc-tests.d.ts +2 -2
  56. package/dist/src/commands/furnace/chrome-doc-tests.js +4 -4
  57. package/dist/src/commands/furnace/chrome-doc.d.ts +8 -8
  58. package/dist/src/commands/furnace/chrome-doc.js +18 -18
  59. package/dist/src/commands/furnace/create-browser-test.d.ts +1 -1
  60. package/dist/src/commands/furnace/create-browser-test.js +7 -12
  61. package/dist/src/commands/furnace/create-dry-run.d.ts +4 -4
  62. package/dist/src/commands/furnace/create-dry-run.js +6 -9
  63. package/dist/src/commands/furnace/create-features.d.ts +2 -2
  64. package/dist/src/commands/furnace/create-features.js +2 -2
  65. package/dist/src/commands/furnace/create-mochikit.d.ts +4 -4
  66. package/dist/src/commands/furnace/create-mochikit.js +7 -7
  67. package/dist/src/commands/furnace/create-templates.d.ts +31 -15
  68. package/dist/src/commands/furnace/create-templates.js +20 -19
  69. package/dist/src/commands/furnace/create-xpcshell.d.ts +5 -5
  70. package/dist/src/commands/furnace/create-xpcshell.js +8 -8
  71. package/dist/src/commands/furnace/create.d.ts +1 -1
  72. package/dist/src/commands/furnace/create.js +35 -29
  73. package/dist/src/commands/furnace/deploy.js +15 -6
  74. package/dist/src/commands/furnace/diff.js +7 -7
  75. package/dist/src/commands/furnace/index.js +1 -1
  76. package/dist/src/commands/furnace/init.js +17 -16
  77. package/dist/src/commands/furnace/list.js +2 -2
  78. package/dist/src/commands/furnace/override.d.ts +1 -1
  79. package/dist/src/commands/furnace/override.js +43 -34
  80. package/dist/src/commands/furnace/preview.js +17 -17
  81. package/dist/src/commands/furnace/refresh.js +15 -7
  82. package/dist/src/commands/furnace/remove-mutations.d.ts +9 -10
  83. package/dist/src/commands/furnace/remove-mutations.js +19 -19
  84. package/dist/src/commands/furnace/remove-state.d.ts +1 -1
  85. package/dist/src/commands/furnace/remove-state.js +1 -1
  86. package/dist/src/commands/furnace/remove.js +4 -8
  87. package/dist/src/commands/furnace/rename-browser-test.js +10 -15
  88. package/dist/src/commands/furnace/rename-xpcshell.d.ts +2 -2
  89. package/dist/src/commands/furnace/rename-xpcshell.js +3 -3
  90. package/dist/src/commands/furnace/rename.js +36 -36
  91. package/dist/src/commands/furnace/scan.js +3 -3
  92. package/dist/src/commands/furnace/status.js +19 -16
  93. package/dist/src/commands/furnace/sync.js +6 -6
  94. package/dist/src/commands/furnace/test-file-name.d.ts +28 -0
  95. package/dist/src/commands/furnace/test-file-name.js +39 -0
  96. package/dist/src/commands/furnace/validate.js +11 -12
  97. package/dist/src/commands/furnace/validation-output.d.ts +21 -9
  98. package/dist/src/commands/furnace/validation-output.js +3 -8
  99. package/dist/src/commands/import.js +22 -29
  100. package/dist/src/commands/lint-per-patch.d.ts +2 -2
  101. package/dist/src/commands/lint-per-patch.js +27 -12
  102. package/dist/src/commands/lint-per-run-checkjs.d.ts +14 -15
  103. package/dist/src/commands/lint-per-run-checkjs.js +14 -15
  104. package/dist/src/commands/lint-report.d.ts +3 -3
  105. package/dist/src/commands/lint-report.js +4 -4
  106. package/dist/src/commands/lint.d.ts +5 -4
  107. package/dist/src/commands/lint.js +36 -36
  108. package/dist/src/commands/manifest.d.ts +4 -4
  109. package/dist/src/commands/manifest.js +1 -1
  110. package/dist/src/commands/package.js +4 -6
  111. package/dist/src/commands/patch/compact.d.ts +2 -2
  112. package/dist/src/commands/patch/compact.js +19 -20
  113. package/dist/src/commands/patch/delete.d.ts +1 -1
  114. package/dist/src/commands/patch/delete.js +23 -33
  115. package/dist/src/commands/patch/entry-projection.d.ts +13 -0
  116. package/dist/src/commands/patch/entry-projection.js +24 -0
  117. package/dist/src/commands/patch/lint-ignore.d.ts +3 -12
  118. package/dist/src/commands/patch/lint-ignore.js +33 -44
  119. package/dist/src/commands/patch/move-files-create.d.ts +2 -2
  120. package/dist/src/commands/patch/move-files-create.js +29 -15
  121. package/dist/src/commands/patch/move-files-into.d.ts +2 -2
  122. package/dist/src/commands/patch/move-files-into.js +41 -37
  123. package/dist/src/commands/patch/move-files.js +5 -14
  124. package/dist/src/commands/patch/patch-context.d.ts +1 -1
  125. package/dist/src/commands/patch/rename.d.ts +4 -4
  126. package/dist/src/commands/patch/rename.js +35 -49
  127. package/dist/src/commands/patch/reorder.js +35 -48
  128. package/dist/src/commands/patch/split-plan.d.ts +7 -8
  129. package/dist/src/commands/patch/split-plan.js +10 -13
  130. package/dist/src/commands/patch/split.d.ts +2 -2
  131. package/dist/src/commands/patch/split.js +50 -48
  132. package/dist/src/commands/patch/staged-dependency-validate.d.ts +1 -1
  133. package/dist/src/commands/patch/staged-dependency-validate.js +3 -3
  134. package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
  135. package/dist/src/commands/patch/staged-dependency.js +22 -28
  136. package/dist/src/commands/patch/tier.d.ts +2 -2
  137. package/dist/src/commands/patch/tier.js +20 -30
  138. package/dist/src/commands/patch-rename-map.d.ts +19 -0
  139. package/dist/src/commands/patch-rename-map.js +36 -0
  140. package/dist/src/commands/pending-resolution.d.ts +15 -0
  141. package/dist/src/commands/pending-resolution.js +25 -0
  142. package/dist/src/commands/re-export-adjacent.d.ts +25 -3
  143. package/dist/src/commands/re-export-adjacent.js +40 -24
  144. package/dist/src/commands/re-export-bulk-scan.d.ts +3 -3
  145. package/dist/src/commands/re-export-bulk-scan.js +23 -27
  146. package/dist/src/commands/re-export-drift.d.ts +10 -10
  147. package/dist/src/commands/re-export-drift.js +33 -33
  148. package/dist/src/commands/re-export-files.d.ts +2 -3
  149. package/dist/src/commands/re-export-files.js +52 -44
  150. package/dist/src/commands/re-export-lint.d.ts +29 -30
  151. package/dist/src/commands/re-export-lint.js +36 -29
  152. package/dist/src/commands/re-export-options.d.ts +1 -1
  153. package/dist/src/commands/re-export-options.js +1 -1
  154. package/dist/src/commands/re-export-register.d.ts +1 -1
  155. package/dist/src/commands/re-export-register.js +1 -1
  156. package/dist/src/commands/re-export-scan.d.ts +1 -1
  157. package/dist/src/commands/re-export-scan.js +12 -9
  158. package/dist/src/commands/re-export-single.d.ts +23 -4
  159. package/dist/src/commands/re-export-single.js +39 -31
  160. package/dist/src/commands/re-export.js +35 -17
  161. package/dist/src/commands/rebase/abort.js +9 -14
  162. package/dist/src/commands/rebase/continue.js +20 -19
  163. package/dist/src/commands/rebase/index.d.ts +1 -1
  164. package/dist/src/commands/rebase/index.js +5 -5
  165. package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
  166. package/dist/src/commands/rebase/patch-loop.js +20 -24
  167. package/dist/src/commands/register.js +5 -5
  168. package/dist/src/commands/reset.js +1 -1
  169. package/dist/src/commands/resolve.d.ts +2 -2
  170. package/dist/src/commands/resolve.js +21 -13
  171. package/dist/src/commands/run.d.ts +0 -13
  172. package/dist/src/commands/run.js +38 -51
  173. package/dist/src/commands/setup-support.d.ts +16 -4
  174. package/dist/src/commands/setup-support.js +20 -20
  175. package/dist/src/commands/setup.js +4 -10
  176. package/dist/src/commands/source.js +9 -2
  177. package/dist/src/commands/status-check.d.ts +3 -3
  178. package/dist/src/commands/status-check.js +6 -6
  179. package/dist/src/commands/status-json.d.ts +14 -13
  180. package/dist/src/commands/status-json.js +9 -8
  181. package/dist/src/commands/status-output.d.ts +3 -3
  182. package/dist/src/commands/status-output.js +5 -5
  183. package/dist/src/commands/status-ownership.d.ts +3 -3
  184. package/dist/src/commands/status-ownership.js +3 -3
  185. package/dist/src/commands/status.js +25 -26
  186. package/dist/src/commands/test-build-phase.d.ts +3 -3
  187. package/dist/src/commands/test-build-phase.js +48 -24
  188. package/dist/src/commands/test-diagnose.d.ts +1 -1
  189. package/dist/src/commands/test-diagnose.js +20 -20
  190. package/dist/src/commands/test-modes.d.ts +4 -4
  191. package/dist/src/commands/test-modes.js +4 -5
  192. package/dist/src/commands/test-register.js +5 -3
  193. package/dist/src/commands/test-run.d.ts +11 -11
  194. package/dist/src/commands/test-run.js +40 -33
  195. package/dist/src/commands/test-stale-gate.d.ts +12 -12
  196. package/dist/src/commands/test-stale-gate.js +17 -17
  197. package/dist/src/commands/test-verdict.d.ts +19 -5
  198. package/dist/src/commands/test-verdict.js +26 -11
  199. package/dist/src/commands/test.d.ts +3 -3
  200. package/dist/src/commands/test.js +73 -36
  201. package/dist/src/commands/token-coverage.js +3 -3
  202. package/dist/src/commands/token-list.d.ts +26 -0
  203. package/dist/src/commands/token-list.js +153 -0
  204. package/dist/src/commands/token.js +26 -10
  205. package/dist/src/commands/tree.js +26 -21
  206. package/dist/src/commands/typecheck.d.ts +6 -6
  207. package/dist/src/commands/typecheck.js +16 -16
  208. package/dist/src/commands/verify.d.ts +3 -3
  209. package/dist/src/commands/verify.js +10 -10
  210. package/dist/src/commands/watch.js +11 -11
  211. package/dist/src/commands/wire.js +17 -16
  212. package/dist/src/core/ast-utils.d.ts +7 -7
  213. package/dist/src/core/ast-utils.js +8 -8
  214. package/dist/src/core/branding.d.ts +5 -12
  215. package/dist/src/core/branding.js +6 -5
  216. package/dist/src/core/browser-wire.d.ts +1 -1
  217. package/dist/src/core/browser-wire.js +10 -7
  218. package/dist/src/core/build-audit-platform.d.ts +32 -3
  219. package/dist/src/core/build-audit-platform.js +153 -13
  220. package/dist/src/core/build-audit-registration.d.ts +5 -5
  221. package/dist/src/core/build-audit-registration.js +10 -9
  222. package/dist/src/core/build-audit-resolve.d.ts +5 -5
  223. package/dist/src/core/build-audit-resolve.js +6 -6
  224. package/dist/src/core/build-audit-skip.d.ts +57 -0
  225. package/dist/src/core/build-audit-skip.js +112 -0
  226. package/dist/src/core/build-audit-transforms.d.ts +2 -2
  227. package/dist/src/core/build-audit-transforms.js +3 -3
  228. package/dist/src/core/build-audit.d.ts +21 -8
  229. package/dist/src/core/build-audit.js +142 -40
  230. package/dist/src/core/build-baseline-types.d.ts +19 -18
  231. package/dist/src/core/build-baseline-types.js +1 -1
  232. package/dist/src/core/build-baseline.d.ts +48 -31
  233. package/dist/src/core/build-baseline.js +20 -43
  234. package/dist/src/core/build-jar-escalation.d.ts +8 -8
  235. package/dist/src/core/build-jar-escalation.js +18 -17
  236. package/dist/src/core/build-overwrite-guard.d.ts +4 -4
  237. package/dist/src/core/build-overwrite-guard.js +14 -14
  238. package/dist/src/core/build-prepare.d.ts +4 -12
  239. package/dist/src/core/build-prepare.js +22 -26
  240. package/dist/src/core/config-mutate.js +4 -4
  241. package/dist/src/core/config-paths.d.ts +2 -6
  242. package/dist/src/core/config-paths.js +4 -2
  243. package/dist/src/core/config-state.d.ts +0 -6
  244. package/dist/src/core/config-state.js +3 -21
  245. package/dist/src/core/config-validate-build-audit.d.ts +8 -0
  246. package/dist/src/core/config-validate-build-audit.js +80 -0
  247. package/dist/src/core/config-validate-file-size.d.ts +1 -1
  248. package/dist/src/core/config-validate-file-size.js +3 -3
  249. package/dist/src/core/config-validate-patch-policy.d.ts +2 -2
  250. package/dist/src/core/config-validate-patch-policy.js +3 -3
  251. package/dist/src/core/config-validate-test-toolchains.d.ts +2 -2
  252. package/dist/src/core/config-validate-test-toolchains.js +4 -5
  253. package/dist/src/core/config-validate.js +22 -12
  254. package/dist/src/core/config.d.ts +12 -12
  255. package/dist/src/core/config.js +21 -25
  256. package/dist/src/core/coverage-extend.d.ts +16 -16
  257. package/dist/src/core/coverage-extend.js +20 -20
  258. package/dist/src/core/destructive.d.ts +14 -14
  259. package/dist/src/core/destructive.js +9 -9
  260. package/dist/src/core/diff-hunks.d.ts +2 -2
  261. package/dist/src/core/diff-hunks.js +7 -7
  262. package/dist/src/core/discard-baseline.d.ts +10 -10
  263. package/dist/src/core/discard-baseline.js +22 -23
  264. package/dist/src/core/display-state.d.ts +11 -11
  265. package/dist/src/core/display-state.js +12 -12
  266. package/dist/src/core/engine-changes.d.ts +2 -2
  267. package/dist/src/core/engine-changes.js +2 -2
  268. package/dist/src/core/engine-precondition.d.ts +5 -13
  269. package/dist/src/core/engine-precondition.js +5 -10
  270. package/dist/src/core/engine-session-lock.d.ts +18 -18
  271. package/dist/src/core/engine-session-lock.js +50 -54
  272. package/dist/src/core/export-moved-code-shape.d.ts +7 -7
  273. package/dist/src/core/export-moved-code-shape.js +10 -10
  274. package/dist/src/core/file-lock-owner.d.ts +103 -0
  275. package/dist/src/core/file-lock-owner.js +259 -0
  276. package/dist/src/core/file-lock.d.ts +14 -19
  277. package/dist/src/core/file-lock.js +90 -128
  278. package/dist/src/core/firefox-cache.d.ts +13 -1
  279. package/dist/src/core/firefox-cache.js +61 -36
  280. package/dist/src/core/firefox-download.d.ts +15 -0
  281. package/dist/src/core/firefox-download.js +38 -22
  282. package/dist/src/core/firefox-extract.d.ts +8 -7
  283. package/dist/src/core/firefox-extract.js +45 -27
  284. package/dist/src/core/firefox.d.ts +34 -36
  285. package/dist/src/core/firefox.js +13 -44
  286. package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
  287. package/dist/src/core/furnace-apply-dry-run.js +2 -8
  288. package/dist/src/core/furnace-apply-ftl.d.ts +5 -5
  289. package/dist/src/core/furnace-apply-ftl.js +8 -8
  290. package/dist/src/core/furnace-apply-helpers.d.ts +9 -20
  291. package/dist/src/core/furnace-apply-helpers.js +28 -39
  292. package/dist/src/core/furnace-apply-output.js +1 -1
  293. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +9 -9
  294. package/dist/src/core/furnace-apply-overwrite-warn.js +13 -11
  295. package/dist/src/core/furnace-apply-undeploy-actions.d.ts +1 -1
  296. package/dist/src/core/furnace-apply-undeploy-actions.js +1 -1
  297. package/dist/src/core/furnace-apply.d.ts +4 -4
  298. package/dist/src/core/furnace-apply.js +50 -29
  299. package/dist/src/core/furnace-checksum-utils.d.ts +5 -5
  300. package/dist/src/core/furnace-checksum-utils.js +5 -5
  301. package/dist/src/core/furnace-config-custom.d.ts +1 -1
  302. package/dist/src/core/furnace-config-custom.js +2 -2
  303. package/dist/src/core/furnace-config-order.js +1 -1
  304. package/dist/src/core/furnace-config-tokens.d.ts +3 -3
  305. package/dist/src/core/furnace-config-tokens.js +3 -3
  306. package/dist/src/core/furnace-config-validate.js +2 -2
  307. package/dist/src/core/furnace-config.d.ts +5 -5
  308. package/dist/src/core/furnace-config.js +40 -53
  309. package/dist/src/core/furnace-constants.d.ts +6 -6
  310. package/dist/src/core/furnace-constants.js +9 -8
  311. package/dist/src/core/furnace-css-fragments.d.ts +6 -6
  312. package/dist/src/core/furnace-css-fragments.js +11 -11
  313. package/dist/src/core/furnace-dir-entry.d.ts +20 -0
  314. package/dist/src/core/furnace-dir-entry.js +21 -0
  315. package/dist/src/core/furnace-jsconfig.d.ts +7 -7
  316. package/dist/src/core/furnace-jsconfig.js +22 -20
  317. package/dist/src/core/furnace-operation.d.ts +22 -19
  318. package/dist/src/core/furnace-operation.js +38 -34
  319. package/dist/src/core/furnace-precondition.d.ts +10 -10
  320. package/dist/src/core/furnace-precondition.js +8 -8
  321. package/dist/src/core/furnace-refresh.d.ts +18 -6
  322. package/dist/src/core/furnace-refresh.js +5 -8
  323. package/dist/src/core/furnace-registration-ast.d.ts +2 -3
  324. package/dist/src/core/furnace-registration-ast.js +9 -12
  325. package/dist/src/core/furnace-registration-remove.d.ts +4 -4
  326. package/dist/src/core/furnace-registration-remove.js +6 -6
  327. package/dist/src/core/furnace-registration-validate.d.ts +2 -2
  328. package/dist/src/core/furnace-registration-validate.js +2 -2
  329. package/dist/src/core/furnace-registration.d.ts +7 -6
  330. package/dist/src/core/furnace-registration.js +29 -36
  331. package/dist/src/core/furnace-rollback.d.ts +1 -1
  332. package/dist/src/core/furnace-rollback.js +5 -5
  333. package/dist/src/core/furnace-scanner.js +3 -6
  334. package/dist/src/core/furnace-stale-export.d.ts +17 -16
  335. package/dist/src/core/furnace-stale-export.js +16 -15
  336. package/dist/src/core/furnace-staleness.d.ts +2 -2
  337. package/dist/src/core/furnace-staleness.js +2 -2
  338. package/dist/src/core/furnace-state-persist.d.ts +12 -12
  339. package/dist/src/core/furnace-state-persist.js +10 -10
  340. package/dist/src/core/furnace-step-errors.d.ts +6 -6
  341. package/dist/src/core/furnace-step-errors.js +6 -6
  342. package/dist/src/core/furnace-validate-accessibility.js +14 -14
  343. package/dist/src/core/furnace-validate-compatibility.js +9 -9
  344. package/dist/src/core/furnace-validate-registration.d.ts +2 -2
  345. package/dist/src/core/furnace-validate-registration.js +18 -20
  346. package/dist/src/core/furnace-validate-structure.d.ts +1 -1
  347. package/dist/src/core/furnace-validate-structure.js +4 -4
  348. package/dist/src/core/furnace-validate.js +9 -9
  349. package/dist/src/core/furnace-version-drift.d.ts +5 -5
  350. package/dist/src/core/furnace-version-drift.js +5 -5
  351. package/dist/src/core/git-base.d.ts +6 -4
  352. package/dist/src/core/git-base.js +29 -7
  353. package/dist/src/core/git-diff-new-file.d.ts +40 -0
  354. package/dist/src/core/git-diff-new-file.js +119 -0
  355. package/dist/src/core/git-diff.d.ts +13 -13
  356. package/dist/src/core/git-diff.js +121 -189
  357. package/dist/src/core/git-file-ops.d.ts +6 -13
  358. package/dist/src/core/git-file-ops.js +11 -35
  359. package/dist/src/core/git-readonly-index.d.ts +12 -14
  360. package/dist/src/core/git-readonly-index.js +12 -16
  361. package/dist/src/core/git-status.d.ts +9 -2
  362. package/dist/src/core/git-status.js +23 -11
  363. package/dist/src/core/git.d.ts +3 -9
  364. package/dist/src/core/git.js +28 -57
  365. package/dist/src/core/harness-orphans.d.ts +17 -17
  366. package/dist/src/core/harness-orphans.js +28 -27
  367. package/dist/src/core/history-log.d.ts +19 -0
  368. package/dist/src/core/history-log.js +29 -0
  369. package/dist/src/core/license-headers.d.ts +19 -18
  370. package/dist/src/core/license-headers.js +29 -28
  371. package/dist/src/core/mach-build-artifacts.d.ts +21 -21
  372. package/dist/src/core/mach-build-artifacts.js +23 -23
  373. package/dist/src/core/mach-error-hints.d.ts +5 -10
  374. package/dist/src/core/mach-error-hints.js +14 -14
  375. package/dist/src/core/mach-known-noise-filter.d.ts +42 -38
  376. package/dist/src/core/mach-known-noise-filter.js +57 -56
  377. package/dist/src/core/mach-mozconfig.d.ts +6 -6
  378. package/dist/src/core/mach-mozconfig.js +17 -16
  379. package/dist/src/core/mach-python.d.ts +3 -0
  380. package/dist/src/core/mach-python.js +13 -7
  381. package/dist/src/core/mach-resource-shim.d.ts +24 -12
  382. package/dist/src/core/mach-resource-shim.js +124 -21
  383. package/dist/src/core/mach.d.ts +59 -73
  384. package/dist/src/core/mach.js +47 -115
  385. package/dist/src/core/marionette-port.d.ts +15 -30
  386. package/dist/src/core/marionette-port.js +46 -89
  387. package/dist/src/core/marionette-preflight.d.ts +6 -6
  388. package/dist/src/core/marionette-preflight.js +32 -50
  389. package/dist/src/core/markdown-table.d.ts +9 -9
  390. package/dist/src/core/markdown-table.js +14 -14
  391. package/dist/src/core/mochitest-server-port.d.ts +8 -8
  392. package/dist/src/core/mochitest-server-port.js +17 -17
  393. package/dist/src/core/module-resolution-preflight.d.ts +8 -8
  394. package/dist/src/core/module-resolution-preflight.js +11 -11
  395. package/dist/src/core/moz-manifest-helpers.d.ts +7 -7
  396. package/dist/src/core/moz-manifest-helpers.js +7 -7
  397. package/dist/src/core/moz-manifest-register.d.ts +1 -1
  398. package/dist/src/core/moz-manifest-register.js +2 -2
  399. package/dist/src/core/moz-manifest-rules.js +46 -42
  400. package/dist/src/core/moz-manifest-tokenizers.js +1 -1
  401. package/dist/src/core/ownership-table.d.ts +5 -5
  402. package/dist/src/core/ownership-table.js +7 -7
  403. package/dist/src/core/parser-fallback.d.ts +3 -3
  404. package/dist/src/core/parser-fallback.js +3 -3
  405. package/dist/src/core/patch-apply-fuzz.d.ts +5 -5
  406. package/dist/src/core/patch-apply-fuzz.js +13 -13
  407. package/dist/src/core/patch-apply.d.ts +13 -14
  408. package/dist/src/core/patch-apply.js +36 -42
  409. package/dist/src/core/patch-export-coverage.d.ts +0 -9
  410. package/dist/src/core/patch-export-coverage.js +1 -30
  411. package/dist/src/core/patch-export-update.d.ts +21 -4
  412. package/dist/src/core/patch-export-update.js +7 -6
  413. package/dist/src/core/patch-export.d.ts +20 -30
  414. package/dist/src/core/patch-export.js +55 -77
  415. package/dist/src/core/patch-files.d.ts +0 -4
  416. package/dist/src/core/patch-files.js +0 -11
  417. package/dist/src/core/patch-identifier-suggest.d.ts +1 -1
  418. package/dist/src/core/patch-identifier-suggest.js +4 -4
  419. package/dist/src/core/patch-lint-binary.d.ts +12 -18
  420. package/dist/src/core/patch-lint-cache.d.ts +18 -2
  421. package/dist/src/core/patch-lint-cache.js +16 -19
  422. package/dist/src/core/patch-lint-checkjs.d.ts +55 -38
  423. package/dist/src/core/patch-lint-checkjs.js +78 -64
  424. package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +8 -9
  425. package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -11
  426. package/dist/src/core/patch-lint-creators.d.ts +5 -9
  427. package/dist/src/core/patch-lint-creators.js +3 -3
  428. package/dist/src/core/patch-lint-cross.d.ts +27 -19
  429. package/dist/src/core/patch-lint-cross.js +67 -110
  430. package/dist/src/core/patch-lint-css.d.ts +1 -1
  431. package/dist/src/core/patch-lint-css.js +15 -11
  432. package/dist/src/core/patch-lint-diff-tag.d.ts +5 -5
  433. package/dist/src/core/patch-lint-diff-tag.js +5 -5
  434. package/dist/src/core/patch-lint-diff.d.ts +4 -4
  435. package/dist/src/core/patch-lint-diff.js +4 -4
  436. package/dist/src/core/patch-lint-file-size.d.ts +3 -3
  437. package/dist/src/core/patch-lint-file-size.js +6 -6
  438. package/dist/src/core/patch-lint-forward-registration.d.ts +58 -0
  439. package/dist/src/core/patch-lint-forward-registration.js +210 -0
  440. package/dist/src/core/patch-lint-jsdoc.d.ts +2 -2
  441. package/dist/src/core/patch-lint-jsdoc.js +46 -46
  442. package/dist/src/core/patch-lint-module-registration.d.ts +3 -9
  443. package/dist/src/core/patch-lint-module-registration.js +1 -1
  444. package/dist/src/core/patch-lint-mozbuild.d.ts +1 -1
  445. package/dist/src/core/patch-lint-mozbuild.js +10 -10
  446. package/dist/src/core/patch-lint-observer.d.ts +3 -3
  447. package/dist/src/core/patch-lint-observer.js +7 -7
  448. package/dist/src/core/patch-lint-ownership.d.ts +6 -6
  449. package/dist/src/core/patch-lint-ownership.js +6 -6
  450. package/dist/src/core/patch-lint-prettier.d.ts +6 -6
  451. package/dist/src/core/patch-lint-prettier.js +7 -7
  452. package/dist/src/core/patch-lint-queue-types.d.ts +60 -0
  453. package/dist/src/core/patch-lint-queue-types.js +12 -0
  454. package/dist/src/core/patch-lint-staged-registration.d.ts +61 -0
  455. package/dist/src/core/patch-lint-staged-registration.js +90 -0
  456. package/dist/src/core/patch-lint-unmanaged-companion.d.ts +23 -23
  457. package/dist/src/core/patch-lint-unmanaged-companion.js +26 -26
  458. package/dist/src/core/patch-lint.d.ts +41 -35
  459. package/dist/src/core/patch-lint.js +52 -49
  460. package/dist/src/core/patch-lock.d.ts +1 -1
  461. package/dist/src/core/patch-lock.js +11 -11
  462. package/dist/src/core/patch-manifest-consistency.d.ts +7 -7
  463. package/dist/src/core/patch-manifest-consistency.js +16 -17
  464. package/dist/src/core/patch-manifest-files-affected.d.ts +1 -1
  465. package/dist/src/core/patch-manifest-files-affected.js +3 -3
  466. package/dist/src/core/patch-manifest-io.d.ts +14 -14
  467. package/dist/src/core/patch-manifest-io.js +35 -34
  468. package/dist/src/core/patch-manifest-query.d.ts +1 -1
  469. package/dist/src/core/patch-manifest-query.js +4 -4
  470. package/dist/src/core/patch-manifest-resolve.d.ts +5 -5
  471. package/dist/src/core/patch-manifest-resolve.js +7 -7
  472. package/dist/src/core/patch-manifest-validate.js +3 -3
  473. package/dist/src/core/patch-manifest.d.ts +2 -2
  474. package/dist/src/core/patch-manifest.js +2 -2
  475. package/dist/src/core/patch-parse.d.ts +32 -21
  476. package/dist/src/core/patch-parse.js +40 -15
  477. package/dist/src/core/patch-policy.js +15 -27
  478. package/dist/src/core/patch-registration-refs.d.ts +4 -4
  479. package/dist/src/core/patch-registration-refs.js +7 -7
  480. package/dist/src/core/patch-source-metadata.d.ts +1 -3
  481. package/dist/src/core/patch-source-metadata.js +0 -4
  482. package/dist/src/core/patch-transform.d.ts +8 -16
  483. package/dist/src/core/patch-transform.js +13 -23
  484. package/dist/src/core/process-cpu-time.d.ts +1 -1
  485. package/dist/src/core/process-cpu-time.js +6 -6
  486. package/dist/src/core/rebase-session.d.ts +9 -15
  487. package/dist/src/core/rebase-session.js +13 -25
  488. package/dist/src/core/register-browser-content.js +3 -2
  489. package/dist/src/core/register-browser-test.js +2 -1
  490. package/dist/src/core/register-module.js +2 -1
  491. package/dist/src/core/register-result.d.ts +1 -1
  492. package/dist/src/core/register-result.js +1 -1
  493. package/dist/src/core/register-scaffold.d.ts +2 -2
  494. package/dist/src/core/register-scaffold.js +8 -7
  495. package/dist/src/core/register-shared-css.d.ts +3 -3
  496. package/dist/src/core/register-shared-css.js +6 -5
  497. package/dist/src/core/register-xpcshell-test.d.ts +2 -2
  498. package/dist/src/core/register-xpcshell-test.js +2 -2
  499. package/dist/src/core/run-log-redact.d.ts +38 -0
  500. package/dist/src/core/run-log-redact.js +69 -0
  501. package/dist/src/core/run-log.d.ts +21 -10
  502. package/dist/src/core/run-log.js +76 -27
  503. package/dist/src/core/shared-ftl.d.ts +2 -2
  504. package/dist/src/core/shared-ftl.js +6 -6
  505. package/dist/src/core/signal-critical.d.ts +2 -2
  506. package/dist/src/core/signal-critical.js +4 -6
  507. package/dist/src/core/smoke-patterns.d.ts +5 -6
  508. package/dist/src/core/smoke-patterns.js +15 -20
  509. package/dist/src/core/state-file.d.ts +15 -4
  510. package/dist/src/core/state-file.js +14 -1
  511. package/dist/src/core/status-binary.d.ts +8 -8
  512. package/dist/src/core/status-binary.js +12 -12
  513. package/dist/src/core/status-classify.d.ts +17 -17
  514. package/dist/src/core/status-classify.js +13 -12
  515. package/dist/src/core/test-changed-prefs.d.ts +12 -12
  516. package/dist/src/core/test-changed-prefs.js +40 -25
  517. package/dist/src/core/test-harness-crash.d.ts +39 -39
  518. package/dist/src/core/test-harness-crash.js +69 -69
  519. package/dist/src/core/test-harness-output.d.ts +7 -7
  520. package/dist/src/core/test-harness-output.js +7 -7
  521. package/dist/src/core/test-harness-verdict-notes.d.ts +13 -14
  522. package/dist/src/core/test-harness-verdict-notes.js +4 -4
  523. package/dist/src/core/test-path-scope.d.ts +8 -8
  524. package/dist/src/core/test-path-scope.js +11 -11
  525. package/dist/src/core/test-stale-check.d.ts +22 -23
  526. package/dist/src/core/test-stale-check.js +31 -30
  527. package/dist/src/core/test-stale-symlink.d.ts +1 -1
  528. package/dist/src/core/test-stale-symlink.js +1 -1
  529. package/dist/src/core/test-stall-triage.d.ts +9 -9
  530. package/dist/src/core/test-stall-triage.js +22 -22
  531. package/dist/src/core/test-xpcshell-retry.d.ts +26 -7
  532. package/dist/src/core/test-xpcshell-retry.js +14 -11
  533. package/dist/src/core/token-category.d.ts +35 -2
  534. package/dist/src/core/token-category.js +67 -58
  535. package/dist/src/core/token-coverage.js +4 -5
  536. package/dist/src/core/token-dark-mode.d.ts +9 -9
  537. package/dist/src/core/token-dark-mode.js +13 -25
  538. package/dist/src/core/token-docs.d.ts +1 -1
  539. package/dist/src/core/token-inventory.d.ts +56 -0
  540. package/dist/src/core/token-inventory.js +109 -0
  541. package/dist/src/core/token-manager.d.ts +4 -4
  542. package/dist/src/core/token-manager.js +22 -22
  543. package/dist/src/core/token-scaffold.d.ts +4 -4
  544. package/dist/src/core/token-scaffold.js +4 -4
  545. package/dist/src/core/token-variant.d.ts +14 -14
  546. package/dist/src/core/token-variant.js +52 -53
  547. package/dist/src/core/toolchain-preflight.d.ts +15 -15
  548. package/dist/src/core/toolchain-preflight.js +23 -23
  549. package/dist/src/core/tree-cow.d.ts +3 -5
  550. package/dist/src/core/tree-cow.js +8 -8
  551. package/dist/src/core/tree-guard.d.ts +3 -3
  552. package/dist/src/core/tree-guard.js +23 -23
  553. package/dist/src/core/tree-store.d.ts +15 -15
  554. package/dist/src/core/tree-store.js +39 -38
  555. package/dist/src/core/typecheck-shim.d.ts +16 -15
  556. package/dist/src/core/typecheck-shim.js +26 -25
  557. package/dist/src/core/typecheck.d.ts +12 -12
  558. package/dist/src/core/typecheck.js +33 -33
  559. package/dist/src/core/wire-destroy.d.ts +2 -2
  560. package/dist/src/core/wire-destroy.js +5 -5
  561. package/dist/src/core/wire-dom-fragment.d.ts +3 -3
  562. package/dist/src/core/wire-dom-fragment.js +12 -23
  563. package/dist/src/core/wire-init.d.ts +2 -2
  564. package/dist/src/core/wire-init.js +7 -7
  565. package/dist/src/core/wire-subscript.d.ts +1 -1
  566. package/dist/src/core/wire-subscript.js +3 -3
  567. package/dist/src/core/wire-utils.d.ts +9 -9
  568. package/dist/src/core/wire-utils.js +16 -28
  569. package/dist/src/core/xpcshell-appdir.d.ts +20 -20
  570. package/dist/src/core/xpcshell-appdir.js +28 -30
  571. package/dist/src/core/xpcshell-profile-dir.d.ts +3 -3
  572. package/dist/src/core/xpcshell-profile-dir.js +7 -7
  573. package/dist/src/errors/base.d.ts +69 -16
  574. package/dist/src/errors/base.js +95 -26
  575. package/dist/src/errors/build.d.ts +6 -6
  576. package/dist/src/errors/build.js +26 -34
  577. package/dist/src/errors/codes.d.ts +10 -10
  578. package/dist/src/errors/codes.js +10 -10
  579. package/dist/src/errors/config.d.ts +0 -14
  580. package/dist/src/errors/config.js +13 -34
  581. package/dist/src/errors/download.d.ts +13 -0
  582. package/dist/src/errors/download.js +53 -24
  583. package/dist/src/errors/furnace.d.ts +2 -2
  584. package/dist/src/errors/furnace.js +8 -9
  585. package/dist/src/errors/git.d.ts +9 -9
  586. package/dist/src/errors/git.js +21 -31
  587. package/dist/src/errors/patch.d.ts +3 -3
  588. package/dist/src/errors/patch.js +11 -13
  589. package/dist/src/errors/rebase.d.ts +1 -1
  590. package/dist/src/errors/rebase.js +8 -8
  591. package/dist/src/errors/run.d.ts +1 -1
  592. package/dist/src/errors/run.js +1 -1
  593. package/dist/src/index.d.ts +4 -4
  594. package/dist/src/index.js +4 -4
  595. package/dist/src/types/commands/options.d.ts +155 -200
  596. package/dist/src/types/commands/patches.d.ts +19 -19
  597. package/dist/src/types/commands/project.d.ts +3 -3
  598. package/dist/src/types/config.d.ts +52 -19
  599. package/dist/src/types/furnace.d.ts +17 -17
  600. package/dist/src/types/index.d.ts +0 -1
  601. package/dist/src/types/json.d.ts +3 -3
  602. package/dist/src/types/json.js +2 -2
  603. package/dist/src/types/typecheck.d.ts +3 -3
  604. package/dist/src/utils/assert.d.ts +4 -16
  605. package/dist/src/utils/assert.js +7 -24
  606. package/dist/src/utils/build-info.d.ts +6 -6
  607. package/dist/src/utils/build-info.js +6 -6
  608. package/dist/src/utils/child-env.d.ts +7 -6
  609. package/dist/src/utils/child-env.js +5 -5
  610. package/dist/src/utils/concurrency.d.ts +2 -2
  611. package/dist/src/utils/concurrency.js +2 -2
  612. package/dist/src/utils/elapsed.js +10 -1
  613. package/dist/src/utils/errors.d.ts +8 -8
  614. package/dist/src/utils/errors.js +8 -8
  615. package/dist/src/utils/fs.d.ts +1 -1
  616. package/dist/src/utils/fs.js +15 -20
  617. package/dist/src/utils/hash.d.ts +12 -0
  618. package/dist/src/utils/hash.js +16 -0
  619. package/dist/src/utils/line-dispatch.d.ts +15 -0
  620. package/dist/src/utils/line-dispatch.js +48 -0
  621. package/dist/src/utils/logger.d.ts +4 -4
  622. package/dist/src/utils/logger.js +11 -11
  623. package/dist/src/utils/machine-output.js +2 -2
  624. package/dist/src/utils/options.d.ts +14 -20
  625. package/dist/src/utils/options.js +26 -27
  626. package/dist/src/utils/package-root.js +5 -14
  627. package/dist/src/utils/paths.d.ts +4 -4
  628. package/dist/src/utils/paths.js +4 -4
  629. package/dist/src/utils/platform.d.ts +0 -4
  630. package/dist/src/utils/process-group.d.ts +10 -9
  631. package/dist/src/utils/process-group.js +37 -36
  632. package/dist/src/utils/process.d.ts +70 -55
  633. package/dist/src/utils/process.js +129 -179
  634. package/dist/src/utils/ps-duration.d.ts +4 -4
  635. package/dist/src/utils/ps-duration.js +9 -9
  636. package/dist/src/utils/regex.d.ts +4 -4
  637. package/dist/src/utils/regex.js +7 -7
  638. package/dist/src/utils/sleep.d.ts +26 -0
  639. package/dist/src/utils/sleep.js +31 -0
  640. package/dist/src/utils/stdio-drain.d.ts +7 -7
  641. package/dist/src/utils/stdio-drain.js +8 -8
  642. package/dist/src/utils/validation.d.ts +12 -49
  643. package/dist/src/utils/validation.js +26 -36
  644. package/docs/README.md +2 -2
  645. package/docs/configuration.md +163 -69
  646. package/docs/exit-codes.md +66 -49
  647. package/docs/furnace.md +20 -19
  648. package/docs/lifecycle-invariants.md +414 -247
  649. package/docs/machine-output.md +58 -34
  650. package/docs/patch-workflow.md +48 -44
  651. package/docs/run-logs.md +72 -28
  652. package/docs/testing.md +105 -98
  653. package/docs/verification-trees.md +23 -22
  654. package/package.json +7 -6
  655. package/dist/src/commands/rebase.d.ts +0 -4
  656. package/dist/src/commands/rebase.js +0 -5
  657. package/dist/src/core/patch-artifact-normalize.d.ts +0 -21
  658. package/dist/src/core/patch-artifact-normalize.js +0 -24
  659. package/dist/src/core/patch-lint-reexports.d.ts +0 -7
  660. package/dist/src/core/patch-lint-reexports.js +0 -8
  661. package/dist/src/core/wire-targets.d.ts +0 -7
  662. package/dist/src/core/wire-targets.js +0 -8
@@ -2,9 +2,19 @@ import type { PatchCategory, PatchesManifest, PatchInfo, PatchMetadata } from '.
2
2
  import type { FireForgeConfig } from '../types/config.js';
3
3
  import { type SupersedeCoverageDetail } from './patch-export-coverage.js';
4
4
  import type { PatchDirectoryLockOptions } from './patch-lock.js';
5
- export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, findSupersededPatches, isPatchFullyCovered, type SupersedeCoverageDetail, } from './patch-export-coverage.js';
5
+ export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
6
6
  export { mutatePatchMetadata, updatePatchMetadata } from './patch-export-metadata.js';
7
7
  export { updatePatchAndMetadata } from './patch-export-update.js';
8
+ /**
9
+ * Projects the planning subset out of a wider export input (commit input,
10
+ * dry-run preview input): the fields `planExport` /
11
+ * `computeExportPlanUnderLock` read. Optional fields are copied only when
12
+ * present so the plan input never carries explicit `undefined` keys, which
13
+ * would otherwise leak into the written metadata via spread. The commit
14
+ * path and the dry-run preview both go through this one projection so
15
+ * they cannot drift field by field.
16
+ */
17
+ export declare function buildPlanExportInput(input: PlanExportInput): PlanExportInput;
8
18
  /**
9
19
  * Gets the next patch number for a new patch.
10
20
  * @param patchesDir - Path to the patches directory
@@ -23,7 +33,7 @@ export declare function getNextPatchNumber(patchesDir: string): Promise<string>;
23
33
  export declare function sanitizeName(name: string): string;
24
34
  /**
25
35
  * Strips a leading `NNN-<category>-` prefix from a sanitized name slug.
26
- * Operators frequently pass the DESIRED FILENAME stem to `--name`
36
+ * Operators frequently pass the desired filename stem to `--name`
27
37
  * (`--name 203-ui-foo --category ui`), which would otherwise double-prefix
28
38
  * into `203-ui-203-ui-foo.patch`. The filename builders prepend the order
29
39
  * and category themselves, so a matching prefix in the name is always
@@ -35,7 +45,7 @@ export declare function stripRedundantCategoryPrefix(sanitizedName: string, cate
35
45
  * Sanitizes a patch name and drops redundant category/full-stem prefixes.
36
46
  *
37
47
  * A single trailing `.patch` extension is stripped before sanitisation:
38
- * operators frequently pass a full patch FILENAME where a name is expected
48
+ * operators frequently pass a full patch filename where a name is expected
39
49
  * (`move-files <from> 348-ui-foo.patch --create`, `rename --to foo.patch`),
40
50
  * and slugging the extension produces double-suffixed `...-patch.patch`
41
51
  * files. A name that deliberately ends in a literal `-patch` slug segment
@@ -91,26 +101,6 @@ export interface CommitExportedPatchResult {
91
101
  * to filename allocation or supersede detection lands in both automatically.
92
102
  */
93
103
  export declare function commitExportedPatch(input: CommitExportedPatchInput): Promise<CommitExportedPatchResult>;
94
- /**
95
- * Parses a patch filename to extract order, category, and name.
96
- * Supports both new format (001-category-name.patch) and legacy (001-name.patch).
97
- */
98
- export declare function parseFilename(filename: string): {
99
- order: number;
100
- category: PatchCategory | null;
101
- name: string;
102
- };
103
- /**
104
- * Finds an existing patch that contains the specified file.
105
- * Returns the most recent (highest order) patch if multiple exist.
106
- * @param patchesDir - Path to the patches directory
107
- * @param filePath - File path to search for
108
- * @returns The patch info and metadata, or null if not found
109
- */
110
- export declare function findExistingPatchForFile(patchesDir: string, filePath: string): Promise<{
111
- patch: PatchInfo;
112
- metadata: PatchMetadata;
113
- } | null>;
114
104
  /**
115
105
  * Updates the content of a patch file.
116
106
  * @param patchPath - Path to the patch file
@@ -125,7 +115,7 @@ export declare function updatePatch(patchPath: string, newContent: string): Prom
125
115
  * Dry-run and the real write both go through {@link computeExportPlanUnderLock}
126
116
  * so their filename allocation, supersede detection, and projected
127
117
  * post-write manifest cannot drift. `planExport` exposes the rich coverage
128
- * form for preview rendering; {@link commitExportedPatch} consumes the bare
118
+ * form for preview rendering. {@link commitExportedPatch} consumes the bare
129
119
  * `PatchInfo[]` form of the same underlying data.
130
120
  */
131
121
  export interface ExportPlan {
@@ -155,13 +145,13 @@ export interface PlanExportInput {
155
145
  /**
156
146
  * Optional `PatchMetadata.tier` opt-in carried from the CLI flag.
157
147
  * Only `"branding"` is currently recognised. When provided the field
158
- * is written into the new patch's metadata; when absent the field
148
+ * is written into the new patch's metadata. When absent the field
159
149
  * stays unset and tier resolution falls back to auto-detection.
160
150
  */
161
151
  tier?: 'branding';
162
152
  /**
163
153
  * Optional `PatchMetadata.lintIgnore` carried from the CLI flag.
164
- * Empty arrays are treated as "field absent" — the validator only
154
+ * Empty arrays are treated as "field absent": the validator only
165
155
  * preserves the field when it has at least one entry.
166
156
  */
167
157
  lintIgnore?: string[];
@@ -169,16 +159,16 @@ export interface PlanExportInput {
169
159
  config?: FireForgeConfig;
170
160
  }
171
161
  /**
172
- * Read-only planning function — computes everything a real export would
162
+ * Read-only planning function. Computes everything a real export would
173
163
  * do without writing anything to disk. Takes the patch directory lock
174
164
  * briefly, runs {@link computeExportPlanUnderLock}, releases the lock,
175
165
  * and returns the plan for preview rendering.
176
166
  *
177
167
  * Shares {@link computeExportPlanUnderLock} with {@link commitExportedPatch}
178
168
  * so the dry-run preview cannot drift from the real write. The real write
179
- * path does NOT reuse a prior plan object (another export may have landed
180
- * between dry-run and commit, which would stale the filename allocation);
181
- * it re-runs the same helper under a fresh lock. The guarantee is "same
169
+ * path does not reuse a prior plan object (another export may have landed
170
+ * between dry-run and commit, which would stale the filename allocation).
171
+ * It re-runs the same helper under a fresh lock. The guarantee is "same
182
172
  * code, possibly different data," not "same plan object."
183
173
  */
184
174
  export declare function planExport(input: PlanExportInput): Promise<ExportPlan>;
@@ -3,17 +3,39 @@ import { join } from 'node:path';
3
3
  import { toError } from '../utils/errors.js';
4
4
  import { pathExists, readText, removeFile, writeText } from '../utils/fs.js';
5
5
  import { warn } from '../utils/logger.js';
6
- import { PATCH_CATEGORIES } from '../utils/validation.js';
7
6
  import { discoverPatches, withPatchDirectoryLock } from './patch-apply.js';
8
- import { normalizePatchArtifact } from './patch-artifact-normalize.js';
9
7
  import { findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
10
- import { addPatchToManifest, findPatchesAffectingFile, loadPatchesManifestForWrite, PATCHES_MANIFEST, savePatchesManifest, } from './patch-manifest.js';
11
- import { requirePatchOrder } from './patch-parse.js';
8
+ import { addPatchToManifest, loadPatchesManifestForWrite, PATCHES_MANIFEST, savePatchesManifest, } from './patch-manifest.js';
9
+ import { formatPatchOrder, requirePatchOrder } from './patch-parse.js';
12
10
  import { allocatePolicyOrder, enforcePatchPolicy } from './patch-policy.js';
13
- export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, findSupersededPatches, isPatchFullyCovered, } from './patch-export-coverage.js';
11
+ export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
14
12
  import { escapeRegex } from '../utils/regex.js';
15
13
  export { mutatePatchMetadata, updatePatchMetadata } from './patch-export-metadata.js';
16
14
  export { updatePatchAndMetadata } from './patch-export-update.js';
15
+ /**
16
+ * Projects the planning subset out of a wider export input (commit input,
17
+ * dry-run preview input): the fields `planExport` /
18
+ * `computeExportPlanUnderLock` read. Optional fields are copied only when
19
+ * present so the plan input never carries explicit `undefined` keys, which
20
+ * would otherwise leak into the written metadata via spread. The commit
21
+ * path and the dry-run preview both go through this one projection so
22
+ * they cannot drift field by field.
23
+ */
24
+ export function buildPlanExportInput(input) {
25
+ return {
26
+ patchesDir: input.patchesDir,
27
+ category: input.category,
28
+ name: input.name,
29
+ description: input.description,
30
+ filesAffected: input.filesAffected,
31
+ sourceEsrVersion: input.sourceEsrVersion,
32
+ ...(input.sourceProduct !== undefined ? { sourceProduct: input.sourceProduct } : {}),
33
+ ...(input.sourceVersion !== undefined ? { sourceVersion: input.sourceVersion } : {}),
34
+ ...(input.tier !== undefined ? { tier: input.tier } : {}),
35
+ ...(input.lintIgnore !== undefined ? { lintIgnore: input.lintIgnore } : {}),
36
+ ...(input.config !== undefined ? { config: input.config } : {}),
37
+ };
38
+ }
17
39
  /**
18
40
  * Gets the next patch number for a new patch.
19
41
  * @param patchesDir - Path to the patches directory
@@ -49,7 +71,7 @@ export function sanitizeName(name) {
49
71
  }
50
72
  /**
51
73
  * Strips a leading `NNN-<category>-` prefix from a sanitized name slug.
52
- * Operators frequently pass the DESIRED FILENAME stem to `--name`
74
+ * Operators frequently pass the desired filename stem to `--name`
53
75
  * (`--name 203-ui-foo --category ui`), which would otherwise double-prefix
54
76
  * into `203-ui-203-ui-foo.patch`. The filename builders prepend the order
55
77
  * and category themselves, so a matching prefix in the name is always
@@ -78,7 +100,7 @@ export function stripRedundantCategoryPrefix(sanitizedName, category) {
78
100
  * Sanitizes a patch name and drops redundant category/full-stem prefixes.
79
101
  *
80
102
  * A single trailing `.patch` extension is stripped before sanitisation:
81
- * operators frequently pass a full patch FILENAME where a name is expected
103
+ * operators frequently pass a full patch filename where a name is expected
82
104
  * (`move-files <from> 348-ui-foo.patch --create`, `rename --to foo.patch`),
83
105
  * and slugging the extension produces double-suffixed `...-patch.patch`
84
106
  * files. A name that deliberately ends in a literal `-patch` slug segment
@@ -110,19 +132,7 @@ export async function getNextPatchFilename(patchesDir, category, name) {
110
132
  */
111
133
  export async function commitExportedPatch(input) {
112
134
  return withPatchDirectoryLock(input.patchesDir, async () => {
113
- const plan = await computeExportPlanUnderLock({
114
- patchesDir: input.patchesDir,
115
- category: input.category,
116
- name: input.name,
117
- description: input.description,
118
- filesAffected: input.filesAffected,
119
- sourceEsrVersion: input.sourceEsrVersion,
120
- ...(input.sourceProduct !== undefined ? { sourceProduct: input.sourceProduct } : {}),
121
- ...(input.sourceVersion !== undefined ? { sourceVersion: input.sourceVersion } : {}),
122
- ...(input.tier !== undefined ? { tier: input.tier } : {}),
123
- ...(input.lintIgnore !== undefined ? { lintIgnore: input.lintIgnore } : {}),
124
- ...(input.config !== undefined ? { config: input.config } : {}),
125
- });
135
+ const plan = await computeExportPlanUnderLock(buildPlanExportInput(input));
126
136
  if (input.config !== undefined) {
127
137
  enforcePatchPolicy({
128
138
  config: input.config,
@@ -140,7 +150,20 @@ export async function commitExportedPatch(input) {
140
150
  }
141
151
  }
142
152
  try {
143
- await writeText(patchPath, normalizePatchArtifact(input.diff));
153
+ // Patch bodies are written byte-for-byte as git produced them, including the
154
+ // single-space rendering of a blank context line.
155
+ //
156
+ // Do not add a whitespace-trimming pass here or at any other write site.
157
+ // Stripping marker lines whose payload is pure whitespace (`/^[ +-]\s+$/` →
158
+ // bare marker) corrupts real content: Firefox sources contain whitespace-only
159
+ // lines, so a ` `/`-` line whose payload was two spaces no longer matches the
160
+ // pristine tree and the freshly exported patch fails `git apply --check`,
161
+ // while a `+` line silently changes what the patch produces. The repository
162
+ // whitespace check already exempts `patches/*.patch`
163
+ // (scripts/check-worktree-whitespace.mjs), and the byte-fidelity contract is
164
+ // pinned end-to-end by `git-diff-latin1-roundtrip.test.ts` and
165
+ // `re-export.integration.test.ts`.
166
+ await writeText(patchPath, input.diff);
144
167
  await addPatchToManifest(input.patchesDir, plan.metadata, plan.supersededPatches.map((p) => p.filename));
145
168
  for (const oldPatch of plan.supersededPatches) {
146
169
  await removeFile(oldPatch.path);
@@ -188,70 +211,25 @@ export async function commitExportedPatch(input) {
188
211
  };
189
212
  }, input.lockOptions ?? {});
190
213
  }
191
- /**
192
- * Parses a patch filename to extract order, category, and name.
193
- * Supports both new format (001-category-name.patch) and legacy (001-name.patch).
194
- */
195
- export function parseFilename(filename) {
196
- // New format: 001-ui-sidebar.patch
197
- const newMatch = /^(\d+)-([a-z]+)-(.+)\.patch$/.exec(filename);
198
- if (newMatch?.[1] && newMatch[2] && newMatch[3]) {
199
- const orderStr = newMatch[1];
200
- const category = newMatch[2];
201
- const name = newMatch[3];
202
- if (PATCH_CATEGORIES.includes(category)) {
203
- return {
204
- order: parseInt(orderStr, 10),
205
- category,
206
- name,
207
- };
208
- }
209
- }
210
- // Legacy format: 001-name.patch
211
- const legacyMatch = /^(\d+)-(.+)\.patch$/.exec(filename);
212
- if (legacyMatch?.[1] && legacyMatch[2]) {
213
- return {
214
- order: parseInt(legacyMatch[1], 10),
215
- category: null,
216
- name: legacyMatch[2],
217
- };
218
- }
219
- return { order: Infinity, category: null, name: filename };
220
- }
221
- /**
222
- * Finds an existing patch that contains the specified file.
223
- * Returns the most recent (highest order) patch if multiple exist.
224
- * @param patchesDir - Path to the patches directory
225
- * @param filePath - File path to search for
226
- * @returns The patch info and metadata, or null if not found
227
- */
228
- export async function findExistingPatchForFile(patchesDir, filePath) {
229
- const affectingPatches = await findPatchesAffectingFile(patchesDir, filePath);
230
- if (affectingPatches.length === 0) {
231
- return null;
232
- }
233
- // Return the most recent (highest order) patch
234
- return affectingPatches[affectingPatches.length - 1] ?? null;
235
- }
236
214
  /**
237
215
  * Updates the content of a patch file.
238
216
  * @param patchPath - Path to the patch file
239
217
  * @param newContent - New patch content
240
218
  */
241
219
  export async function updatePatch(patchPath, newContent) {
242
- await writeText(patchPath, normalizePatchArtifact(newContent));
220
+ await writeText(patchPath, newContent);
243
221
  }
244
222
  /**
245
- * Internal planning helper. Does NOT take the patch directory lock — the
246
- * caller must already hold it — because the two public entry points
223
+ * Internal planning helper. It does not take the patch directory lock (the
224
+ * caller must already hold it), because the two public entry points
247
225
  * ({@link planExport} and {@link commitExportedPatch}) each take their own
248
226
  * lock for the full operation. Sharing this single pure computation is how
249
- * dry-run previews and real writes stay in lockstep by construction
250
- * instead of by parallel implementations that can drift.
227
+ * dry-run previews and real writes stay in lockstep, instead of relying on
228
+ * parallel implementations that can drift.
251
229
  */
252
230
  async function computeExportPlanUnderLock(input) {
253
231
  // ForWrite: a corrupt manifest read as null here would produce a
254
- // manifestAfter containing ONLY the new patch — committing that plan
232
+ // manifestAfter containing only the new patch. Committing that plan
255
233
  // wipes the queue metadata, and the rollback path would then delete
256
234
  // patches.json entirely because manifestBefore looked absent.
257
235
  const manifestBefore = await loadPatchesManifestForWrite(input.patchesDir);
@@ -259,7 +237,7 @@ async function computeExportPlanUnderLock(input) {
259
237
  ? allocatePolicyOrder(input.config, manifestBefore?.patches ?? [], input.category)
260
238
  : null;
261
239
  const patchFilename = policyOrder !== null
262
- ? `${String(policyOrder).padStart(3, '0')}-${input.category}-${patchNameSlug(input.name, input.category)}.patch`
240
+ ? `${formatPatchOrder(policyOrder)}-${input.category}-${patchNameSlug(input.name, input.category)}.patch`
263
241
  : await getNextPatchFilename(input.patchesDir, input.category, input.name);
264
242
  const patchPath = join(input.patchesDir, patchFilename);
265
243
  const metadata = {
@@ -302,16 +280,16 @@ async function computeExportPlanUnderLock(input) {
302
280
  };
303
281
  }
304
282
  /**
305
- * Read-only planning function — computes everything a real export would
283
+ * Read-only planning function. Computes everything a real export would
306
284
  * do without writing anything to disk. Takes the patch directory lock
307
285
  * briefly, runs {@link computeExportPlanUnderLock}, releases the lock,
308
286
  * and returns the plan for preview rendering.
309
287
  *
310
288
  * Shares {@link computeExportPlanUnderLock} with {@link commitExportedPatch}
311
289
  * so the dry-run preview cannot drift from the real write. The real write
312
- * path does NOT reuse a prior plan object (another export may have landed
313
- * between dry-run and commit, which would stale the filename allocation);
314
- * it re-runs the same helper under a fresh lock. The guarantee is "same
290
+ * path does not reuse a prior plan object (another export may have landed
291
+ * between dry-run and commit, which would stale the filename allocation).
292
+ * It re-runs the same helper under a fresh lock. The guarantee is "same
315
293
  * code, possibly different data," not "same plan object."
316
294
  */
317
295
  export async function planExport(input) {
@@ -3,10 +3,6 @@ import type { PatchInfo } from '../types/commands/index.js';
3
3
  export declare function discoverPatches(patchesDir: string): Promise<PatchInfo[]>;
4
4
  /** Counts the patch files currently present in a patch directory. */
5
5
  export declare function countPatches(patchesDir: string): Promise<number>;
6
- /** Checks whether a patch creates a new file rather than modifying an existing one. */
7
- export declare function isNewFilePatch(patchPath: string): Promise<boolean>;
8
- /** Returns the first target file path referenced by a patch, if any. */
9
- export declare function getTargetFileFromPatch(patchPath: string): Promise<string | null>;
10
6
  /**
11
7
  * Returns all target file paths referenced by a multi-file patch.
12
8
  *
@@ -24,17 +24,6 @@ export async function countPatches(patchesDir) {
24
24
  const patches = await discoverPatches(patchesDir);
25
25
  return patches.length;
26
26
  }
27
- /** Checks whether a patch creates a new file rather than modifying an existing one. */
28
- export async function isNewFilePatch(patchPath) {
29
- const content = await readText(patchPath);
30
- return content.includes('new file mode') && content.includes('--- /dev/null');
31
- }
32
- /** Returns the first target file path referenced by a patch, if any. */
33
- export async function getTargetFileFromPatch(patchPath) {
34
- const content = await readText(patchPath);
35
- const match = /^\+\+\+ b\/(.+)$/m.exec(content);
36
- return match?.[1] ?? null;
37
- }
38
27
  /**
39
28
  * Returns all target file paths referenced by a multi-file patch.
40
29
  *
@@ -15,6 +15,6 @@ import type { PatchMetadata } from '../types/commands/index.js';
15
15
  * Formats the user-facing "patch not found" error message used by
16
16
  * `patch delete`, `patch reorder`, `patch tier`, and
17
17
  * `patch lint-ignore`. Returns a single string suitable for the
18
- * `InvalidArgumentError` body — never the full queue enumeration.
18
+ * `InvalidArgumentError` body, never the full queue enumeration.
19
19
  */
20
20
  export declare function formatPatchNotFoundError(identifier: string, patches: readonly PatchMetadata[]): string;
@@ -22,7 +22,7 @@ const MIN_PREFIX_MATCH_LENGTH = 4;
22
22
  const SUGGESTION_LIMIT = 3;
23
23
  /**
24
24
  * Computes the Levenshtein edit distance between two strings. Used by
25
- * `formatPatchNotFoundError` to rank candidate identifiers; the small
25
+ * `formatPatchNotFoundError` to rank candidate identifiers. The small
26
26
  * upper bound on input lengths (filenames, ordinals, names) makes the
27
27
  * O(m*n) implementation trivially fast.
28
28
  */
@@ -87,13 +87,13 @@ function rankSuggestions(identifier, candidates) {
87
87
  return candidates
88
88
  .map((candidate) => {
89
89
  const lower = candidate.toLowerCase();
90
- // Prefix relation in EITHER direction is a stronger signal than edit
90
+ // Prefix relation in either direction is a stronger signal than edit
91
91
  // distance and is not bounded by it: a partial ordinal or an
92
92
  // abbreviated slug ("ui-foo" for "002-ui-foo.patch") is many edits away
93
93
  // from the full identifier yet is obviously the intended target.
94
94
  // `lower.startsWith(needle)`: the operator typed an abbreviation of a
95
95
  // real identifier. The reverse relation is only meaningful when the
96
- // candidate is substantial — otherwise the single-character ordinal
96
+ // candidate is substantial. Otherwise the single-character ordinal
97
97
  // "9" would "match" every input starting with a 9.
98
98
  const prefixMatch = needle.length >= MIN_PREFIX_MATCH_LENGTH &&
99
99
  (lower.startsWith(needle) ||
@@ -115,7 +115,7 @@ function rankSuggestions(identifier, candidates) {
115
115
  * Formats the user-facing "patch not found" error message used by
116
116
  * `patch delete`, `patch reorder`, `patch tier`, and
117
117
  * `patch lint-ignore`. Returns a single string suitable for the
118
- * `InvalidArgumentError` body — never the full queue enumeration.
118
+ * `InvalidArgumentError` body, never the full queue enumeration.
119
119
  */
120
120
  export function formatPatchNotFoundError(identifier, patches) {
121
121
  const accepted = collectAcceptedIdentifiers(patches);
@@ -2,39 +2,33 @@
2
2
  * Queue-wide lint for binary patch bodies that cannot recreate their file.
3
3
  *
4
4
  * `git diff` has two ways to render a binary change. `git diff --binary`
5
- * emits a `GIT binary patch` section carrying the literal/delta payload —
6
- * that body can be replayed by `git apply`. Plain `git diff` emits only the
7
- * informational `Binary files a/x and b/x differ`, which records THAT the
8
- * bytes changed and carries none of them.
5
+ * emits a `GIT binary patch` section carrying the literal/delta payload,
6
+ * and that body can be replayed by `git apply`. Plain `git diff` emits only
7
+ * the informational `Binary files a/x and b/x differ`, which records that
8
+ * the bytes changed and carries none of them.
9
9
  *
10
10
  * The stub form is dangerous rather than merely lossy because it still
11
11
  * carries a correct `index <old>..<new>` line. Every identity-shaped check in
12
- * the codebase — worktree classification, foreign-drift detection — keys on
12
+ * the codebase (worktree classification, foreign-drift detection) keys on
13
13
  * that hash, matches it against the live file, and concludes the patch is
14
14
  * backed. So a queue can hold a patch that provably cannot rebuild its own
15
15
  * file while every gate reports green, and the loss surfaces only at the next
16
16
  * clean-room apply. This rule is the one check that reads the body itself and
17
17
  * fails closed, whichever command wrote it.
18
18
  *
19
- * Body-only by design: it needs no engine checkout, so it runs anywhere the
19
+ * Body-only: it needs no engine checkout, so it runs anywhere the
20
20
  * queue context is available and never pulls an engine dependency into the
21
21
  * cross-patch lint graph.
22
22
  */
23
23
  import type { PatchLintIssue } from '../types/commands/index.js';
24
+ import type { PatchQueueBodyEntry, PatchQueueView } from './patch-lint-queue-types.js';
24
25
  /**
25
- * The slice of a queue entry this rule reads. Declared structurally rather
26
- * than importing `PatchQueueEntry` from `patch-lint-cross.ts`, which imports
27
- * this module back — the local shape keeps the dependency edge one-way and
28
- * `dpdm` clean, matching `patch-lint-module-registration.ts`.
26
+ * Queue view accepted by {@link lintPatchQueueBinaryBodies}. Described
27
+ * structurally rather than by importing `PatchQueueContext` from
28
+ * `patch-lint-cross.ts`, which imports this module back. The shared leaf
29
+ * type keeps the dependency edge one-way and `dpdm` clean.
29
30
  */
30
- interface BinaryBodyQueueEntry {
31
- filename: string;
32
- diff: string;
33
- }
34
- /** Queue view accepted by {@link lintPatchQueueBinaryBodies}. */
35
- interface BinaryBodyQueueContext {
36
- entries: readonly BinaryBodyQueueEntry[];
37
- }
31
+ type BinaryBodyQueueContext = PatchQueueView<PatchQueueBodyEntry>;
38
32
  /** Lint check identifier emitted by {@link lintPatchQueueBinaryBodies}. */
39
33
  export declare const BINARY_BODY_CHECK = "binary-body-not-reconstructable";
40
34
  /**
@@ -53,10 +53,26 @@ export interface CachedPerPatchLint {
53
53
  }
54
54
  /**
55
55
  * Returns the cached lint payload for a patch when the stored key still
56
- * matches AND the entry was computed under the same lint-ignore waiver set.
56
+ * matches and the entry was computed under the same lint-ignore waiver set.
57
57
  * A waiver change makes a replayed verdict actively wrong, so the waiver set
58
58
  * is compared explicitly rather than trusted to the key.
59
59
  */
60
60
  export declare function getCachedPerPatchLintIssues(cache: PerPatchLintCacheFile, patchFilename: string, key: string, lintIgnore?: Iterable<string>): CachedPerPatchLint | undefined;
61
+ export interface SetCachedPerPatchLintIssuesInput {
62
+ /** Cache file to mutate in place. */
63
+ cache: PerPatchLintCacheFile;
64
+ /** Patch the payload belongs to, and also the cache entry key. */
65
+ patchFilename: string;
66
+ /** Fingerprint the payload is valid for. */
67
+ key: string;
68
+ /** Reported issues, stored as copies. */
69
+ issues: PatchLintIssue[];
70
+ /** Issues suppressed by `lintIgnore`, stored as copies. */
71
+ suppressed: PatchLintIssue[];
72
+ /** Line count the run measured. */
73
+ lineCount: number;
74
+ /** Suppression ids in force for the run, normalized on store. */
75
+ lintIgnore?: Iterable<string> | undefined;
76
+ }
61
77
  /** Stores the per-patch lint payload after a successful lint calculation. */
62
- export declare function setCachedPerPatchLintIssues(cache: PerPatchLintCacheFile, patchFilename: string, key: string, issues: PatchLintIssue[], suppressed: PatchLintIssue[], lineCount: number, lintIgnore?: Iterable<string>): void;
78
+ export declare function setCachedPerPatchLintIssues(input: SetCachedPerPatchLintIssuesInput): void;
@@ -1,25 +1,25 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
- import { createHash } from 'node:crypto';
3
2
  import { readFile } from 'node:fs/promises';
4
3
  import { join, resolve } from 'node:path';
5
4
  import { pathExists, readJson, writeJson } from '../utils/fs.js';
5
+ import { sha256Hex } from '../utils/hash.js';
6
6
  import { getPackageVersion } from '../utils/package-root.js';
7
7
  import { getFurnacePaths } from './furnace-config.js';
8
8
  import { git } from './git-base.js';
9
9
  import { collectNewFileCreatorsByPath } from './patch-lint.js';
10
10
  // Schema 2: entries additionally carry the lintIgnore-suppressed issues and
11
11
  // the measured non-binary line count, so a warm run can report waived size
12
- // measurements identically to a cold one — a cache hit must never surface
13
- // LESS than a fresh lint.
12
+ // measurements identically to a cold one. A cache hit must never surface
13
+ // less than a fresh lint.
14
14
  // Schema 3: the key additionally content-hashes the
15
15
  // `patchLint.checkJsTestShim` file exactly as `checkJsExtraShim`'s already
16
- // was; without it, editing the test shim in place replays every cached
16
+ // was. Without it, editing the test shim in place replays every cached
17
17
  // verdict.
18
- // Schema 4: each entry RECORDS the lint-ignore waiver set that produced it,
18
+ // Schema 4: each entry records the lint-ignore waiver set that produced it,
19
19
  // and a lookup whose effective waiver set differs is refused even when the
20
20
  // key matches. The key already hashes `patch.lintIgnore`, so this is
21
21
  // belt-and-braces on purpose: a waiver change is the one mutation that makes
22
- // a replayed verdict actively WRONG (an operator writes a waiver, re-runs,
22
+ // a replayed verdict actively wrong (an operator writes a waiver, re-runs,
23
23
  // and is shown the finding they just waived), and the class must not depend
24
24
  // on every future key input staying complete. Bumping the schema also
25
25
  // discards every pre-4 entry, which is itself the cure for a cache that
@@ -42,10 +42,6 @@ function stableJson(value) {
42
42
  .map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`)
43
43
  .join(',')}}`;
44
44
  }
45
- /** Computes a SHA-256 hex digest for text or binary content. */
46
- function sha256Hex(content) {
47
- return createHash('sha256').update(content).digest('hex');
48
- }
49
45
  /** Computes a stable SHA-256 digest for JSON-compatible data. */
50
46
  function stableHash(value) {
51
47
  return sha256Hex(stableJson(value));
@@ -100,7 +96,7 @@ function buildOwnershipFingerprint(files, ctx) {
100
96
  export async function buildPerPatchLintCacheKey(input) {
101
97
  // Hash in parallel, then insert in sorted order. The sort is load-bearing:
102
98
  // `stableHash` below serialises this record, so insertion order is part of
103
- // the cache key — assigning as results land would make the key
99
+ // the cache key, and assigning as results land would make the key
104
100
  // nondeterministic.
105
101
  const sortedFiles = [...input.existingFiles].sort((a, b) => a.localeCompare(b));
106
102
  const hashes = await Promise.all(sortedFiles.map((file) => fileHash(join(input.engineDir, file))));
@@ -114,8 +110,8 @@ export async function buildPerPatchLintCacheKey(input) {
114
110
  const shimHashOf = async (shimPath) => shimPath === undefined
115
111
  ? null
116
112
  : { path: shimPath, hash: await fileHash(resolve(input.projectRoot, shimPath)) };
117
- // Both shims feed compiled checkJs programs, so both are content-hashed —
118
- // the config block alone only carries their PATHS, and an in-place edit
113
+ // Both shims feed compiled checkJs programs, so both are content-hashed.
114
+ // The config block alone only carries their paths, and an in-place edit
119
115
  // must invalidate the programs it feeds.
120
116
  const [extraShim, testShim] = await Promise.all([
121
117
  shimHashOf(input.config.patchLint?.checkJsExtraShim),
@@ -125,9 +121,9 @@ export async function buildPerPatchLintCacheKey(input) {
125
121
  cacheSchemaVersion: LINT_CACHE_SCHEMA_VERSION,
126
122
  engineHeadSha: input.engineHeadSha ?? null,
127
123
  lintImplementationVersion: LINT_IMPLEMENTATION_VERSION,
128
- // Deliberately the PLAIN semver, not the +g<sha> build identity:
129
- // identity churns every commit at the same version and
130
- // would invalidate the cache for no correctness gain.
124
+ // The plain semver, not the +g<sha> build identity: that identity
125
+ // churns every commit at the same version and would invalidate the
126
+ // cache for no correctness gain.
131
127
  packageVersion: input.packageVersion ?? getPackageVersion(),
132
128
  patchFile: await fileHash(join(input.patchesDir, input.patch.filename)),
133
129
  patchMetadata: normalizePatchMetadata(input.patch),
@@ -181,7 +177,7 @@ export async function loadPerPatchLintCache(projectRoot) {
181
177
  }
182
178
  catch {
183
179
  // Any unreadable or malformed cache file is treated as a cold cache. The
184
- // cache is a pure optimisation, so discarding it is always safe — the
180
+ // cache is a pure optimisation, so discarding it is always safe. The
185
181
  // alternative is failing lint over a corrupt sidecar.
186
182
  return createEmptyPerPatchLintCache();
187
183
  }
@@ -203,7 +199,7 @@ function normalizeLintIgnoreSet(lintIgnore) {
203
199
  }
204
200
  /**
205
201
  * Returns the cached lint payload for a patch when the stored key still
206
- * matches AND the entry was computed under the same lint-ignore waiver set.
202
+ * matches and the entry was computed under the same lint-ignore waiver set.
207
203
  * A waiver change makes a replayed verdict actively wrong, so the waiver set
208
204
  * is compared explicitly rather than trusted to the key.
209
205
  */
@@ -223,7 +219,8 @@ export function getCachedPerPatchLintIssues(cache, patchFilename, key, lintIgnor
223
219
  };
224
220
  }
225
221
  /** Stores the per-patch lint payload after a successful lint calculation. */
226
- export function setCachedPerPatchLintIssues(cache, patchFilename, key, issues, suppressed, lineCount, lintIgnore) {
222
+ export function setCachedPerPatchLintIssues(input) {
223
+ const { cache, patchFilename, key, issues, suppressed, lineCount, lintIgnore } = input;
227
224
  cache.entries[patchFilename] = {
228
225
  key,
229
226
  patchFilename,