@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
@@ -6,12 +6,12 @@
6
6
  * brand-new file an author just created beside a patch's owned files is
7
7
  * silently left out of the refreshed body. This module detects such adjacent
8
8
  * files, filters out tool-managed paths (branding, furnace) so the notice
9
- * names only genuinely unmanaged candidates, and — under
10
- * `--refuse-adjacent-unmanaged` — lets the caller turn the notice into a
9
+ * names only genuinely unmanaged candidates, and, under
10
+ * `--refuse-adjacent-unmanaged`, lets the caller turn the notice into a
11
11
  * non-zero refusal.
12
12
  *
13
- * Split out of re-export.ts to keep that file inside the max-lines budget;
14
- * exports helpers consumed by re-export.ts, no registrar.
13
+ * Split out of re-export.ts to keep that file inside the max-lines budget.
14
+ * Exports helpers consumed by re-export.ts, no registrar.
15
15
  */
16
16
  import { dirname, join } from 'node:path';
17
17
  import { isBrandingManagedPath } from '../core/branding.js';
@@ -30,7 +30,7 @@ export async function findMissingFiles(engineDir, files) {
30
30
  }
31
31
  function isToolManagedPath(file, isNewFile, ctx) {
32
32
  // Mirrors status-classify: a generated branding path is tool-managed
33
- // outright; a brand-new unowned file under the branding root is still a
33
+ // outright. A brand-new unowned file under the branding root is still a
34
34
  // patch candidate (the Assets.car precedent) and must stay listed.
35
35
  if (isBrandingManagedPath(file, ctx.binaryName) &&
36
36
  (!isNewFile || isGeneratedBrandingPath(file, ctx.binaryName))) {
@@ -47,7 +47,9 @@ async function findAdjacentUnmanagedFiles(args) {
47
47
  const parentDirs = [...new Set(currentFilesAffected.map((file) => dirname(file)))];
48
48
  const currentSet = new Set(currentFilesAffected);
49
49
  const claimedByOthers = getClaimedFiles(manifest, patchFilename);
50
- const candidates = new Set();
50
+ // First anchor wins: the dirs are scanned in ownership order and a file
51
+ // lives in exactly one of them, so the map is a dedupe, not a choice.
52
+ const candidates = new Map();
51
53
  for (const dir of parentDirs) {
52
54
  const [modifiedFiles, untrackedFiles] = await Promise.all([
53
55
  getModifiedFilesInDir(engineDir, dir),
@@ -59,36 +61,43 @@ async function findAdjacentUnmanagedFiles(args) {
59
61
  continue;
60
62
  if (isToolManagedPath(file, untrackedSet.has(file), ctx))
61
63
  continue;
62
- candidates.add(file);
64
+ if (!candidates.has(file))
65
+ candidates.set(file, dir);
63
66
  }
64
67
  }
65
- return [...candidates].sort();
68
+ return [...candidates.entries()]
69
+ .map(([file, anchorDir]) => ({ file, anchorDir }))
70
+ .sort((a, b) => a.file.localeCompare(b.file));
66
71
  }
67
72
  /**
68
73
  * Splits the candidates into the ones that refuse and the ones a
69
74
  * `--expect-unmanaged` carve-out admits. Approved paths are recorded as seen
70
- * so an unused carve-out can be reported, and are RETURNED rather than
71
- * dropped: an exception nobody can see is how a carve-out quietly widens.
75
+ * so an unused carve-out can be reported, and are returned rather than
76
+ * dropped, so the exception stays visible instead of quietly widening.
72
77
  */
73
78
  function partitionApproved(files, ctx) {
74
79
  const refusing = [];
75
80
  const approved = [];
76
- for (const file of files) {
77
- if (ctx.approvedUnmanaged.has(file)) {
78
- ctx.approvedSeen.add(file);
79
- approved.push(file);
81
+ for (const entry of files) {
82
+ if (ctx.approvedUnmanaged.has(entry.file)) {
83
+ ctx.approvedSeen.add(entry.file);
84
+ approved.push(entry);
80
85
  }
81
86
  else {
82
- refusing.push(file);
87
+ refusing.push(entry);
83
88
  }
84
89
  }
85
90
  return { refusing, approved };
86
91
  }
92
+ /** Renders `<file> (beside engine/<dir>)` for a notice line. */
93
+ function describeAnchored(entry) {
94
+ return `${entry.file} (beside engine/${entry.anchorDir})`;
95
+ }
87
96
  /**
88
97
  * Emits the scan-less advisory for one patch: missing manifest files and
89
98
  * unmanaged files adjacent to the patch's ownership. When
90
99
  * `--refuse-adjacent-unmanaged` is set and any unmanaged adjacent file
91
- * exists, records the patch into `ctx.refusals` and returns true — the
100
+ * exists, records the patch into `ctx.refusals` and returns true. The
92
101
  * caller then skips the write for this patch and converts the collection
93
102
  * into one run-level non-zero refusal after the loop.
94
103
  */
@@ -112,19 +121,26 @@ export async function reportAdjacentUnmanagedFiles(args) {
112
121
  });
113
122
  const { refusing: unmanagedFiles, approved } = partitionApproved(allUnmanaged, ctx);
114
123
  if (approved.length > 0) {
115
- info(`${patch.filename}: ${String(approved.length)} adjacent unmanaged file(s) admitted by ` +
116
- `--expect-unmanaged (${approved.join(', ')}) — reported, not refused.`);
124
+ info(`${patch.filename}: ${approved.length} adjacent unmanaged file(s) admitted by ` +
125
+ `--expect-unmanaged (${approved.map(describeAnchored).join(', ')}) — reported, not refused.`);
117
126
  }
118
127
  if (unmanagedFiles.length === 0)
119
128
  return false;
120
- const firstFew = unmanagedFiles.slice(0, 3).join(', ');
121
- const more = unmanagedFiles.length > 3 ? `, +${String(unmanagedFiles.length - 3)} more` : '';
122
- warn(`${patch.filename}: found ${String(unmanagedFiles.length)} unmanaged file(s) adjacent to this patch's ownership (${firstFew}${more}); plain re-export keeps filesAffected unchanged — use --scan-file to include reviewed files.`);
123
- for (const file of unmanagedFiles) {
124
- info(` ${file} — fireforge re-export ${patch.filename} --scan --scan-file ${file}`);
129
+ const firstFew = unmanagedFiles.slice(0, 3).map(describeAnchored).join(', ');
130
+ const more = unmanagedFiles.length > 3 ? `, +${unmanagedFiles.length - 3} more` : '';
131
+ warn(`${patch.filename}: found ${unmanagedFiles.length} unmanaged file(s) adjacent to this patch's ownership (${firstFew}${more}); ` +
132
+ `adjacent means the file sits in a directory this patch already owns a file in. ` +
133
+ `Plain re-export keeps filesAffected unchanged — use --scan-file to include reviewed files.`);
134
+ for (const entry of unmanagedFiles) {
135
+ info(` ${entry.file} — beside engine/${entry.anchorDir} — ` +
136
+ `fireforge re-export ${patch.filename} --scan --scan-file ${entry.file}`);
125
137
  }
126
138
  if (ctx.refuseAdjacentUnmanaged) {
127
- ctx.refusals.push({ patchFilename: patch.filename, files: unmanagedFiles });
139
+ ctx.refusals.push({
140
+ patchFilename: patch.filename,
141
+ files: unmanagedFiles.map((entry) => entry.file),
142
+ anchored: unmanagedFiles.map(describeAnchored),
143
+ });
128
144
  return true;
129
145
  }
130
146
  return false;
@@ -7,9 +7,9 @@ export declare function loadScanFilesAssignments(manifestPath: string, manifest:
7
7
  * a dry-run changed anything it promised only to inspect. That turns a
8
8
  * "dry-run reverted a just-written export" incident into a hard, named
9
9
  * failure instead of silent data loss discovered only when a later gate
10
- * fails. The post-fingerprint runs whether `operation` resolves or rejects —
11
- * a dry-run that mutates state and THEN fails is exactly the case where a
12
- * rollback defect must not go unreported; a rejection with a purity
10
+ * fails. The post-fingerprint runs whether `operation` resolves or rejects,
11
+ * because a dry-run that mutates state and then fails is exactly the case
12
+ * where a rollback defect must not go unreported. A rejection with a purity
13
13
  * violation surfaces the violation with the original error as `cause`.
14
14
  * No-op outside dry-run.
15
15
  */
@@ -1,5 +1,4 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
- import { createHash } from 'node:crypto';
3
2
  import { readdir, readFile } from 'node:fs/promises';
4
3
  import { join } from 'node:path';
5
4
  import { isUnavailableGenerationToken, snapshotEngineGeneration, unavailableGenerationReason, } from '../core/engine-session-lock.js';
@@ -10,12 +9,11 @@ import { GeneralError, InvalidArgumentError } from '../errors/base.js';
10
9
  import { mapWithConcurrency } from '../utils/concurrency.js';
11
10
  import { getNodeErrorCode, toError } from '../utils/errors.js';
12
11
  import { readText } from '../utils/fs.js';
12
+ import { sha256Hex } from '../utils/hash.js';
13
+ import { isObject } from '../utils/validation.js';
13
14
  import { normalizeEngineRelativeInput } from './re-export-scan.js';
14
15
  /** Concurrency bound for patch-body hashing (matches the classify/lint pools). */
15
16
  const PATCH_HASH_CONCURRENCY = 8;
16
- function isRecord(value) {
17
- return typeof value === 'object' && value !== null && !Array.isArray(value);
18
- }
19
17
  function parseScanFilesManifest(raw, manifestPath) {
20
18
  let parsed;
21
19
  try {
@@ -24,12 +22,12 @@ function parseScanFilesManifest(raw, manifestPath) {
24
22
  catch (error) {
25
23
  throw new InvalidArgumentError(`--scan-files manifest is not valid JSON (${manifestPath}): ${toError(error).message}`, '--scan-files');
26
24
  }
27
- if (!isRecord(parsed) || !Array.isArray(parsed['assignments'])) {
25
+ if (!isObject(parsed) || !Array.isArray(parsed['assignments'])) {
28
26
  throw new InvalidArgumentError('--scan-files manifest must contain an assignments array.', '--scan-files');
29
27
  }
30
28
  const assignments = [];
31
29
  for (const [index, assignment] of parsed['assignments'].entries()) {
32
- if (!isRecord(assignment)) {
30
+ if (!isObject(assignment)) {
33
31
  throw new InvalidArgumentError(`--scan-files assignments[${index}] must be an object.`, '--scan-files');
34
32
  }
35
33
  const { patch, files } = assignment;
@@ -56,7 +54,7 @@ export async function loadScanFilesAssignments(manifestPath, manifest) {
56
54
  for (const assignment of parsed.assignments) {
57
55
  const patch = resolvePatchIdentifier(assignment.patch, manifest.patches);
58
56
  if (!patch) {
59
- // Suggest, never dump.
57
+ // Suggest close matches instead of dumping the whole queue.
60
58
  throw new InvalidArgumentError(`--scan-files: ${formatPatchNotFoundError(assignment.patch, manifest.patches)}`, '--scan-files');
61
59
  }
62
60
  const patchFiles = filesByPatch.get(patch.filename) ?? new Set();
@@ -77,29 +75,29 @@ export async function loadScanFilesAssignments(manifestPath, manifest) {
77
75
  * Fingerprints every piece of state a `re-export --dry-run` promises not to
78
76
  * disturb: the engine's commit + working-tree status (via the same
79
77
  * generation token `fireforge test` uses) and the byte content of every
80
- * regular file under `patches/` — ALL of them, not just the selected
81
- * patches, because a dry-run of patch B can revert a just-written export of
82
- * patch A.
78
+ * regular file under `patches/`. That covers all of them, not just the
79
+ * selected patches, because a dry-run of patch B can revert a just-written
80
+ * export of patch A.
83
81
  *
84
- * A missing patches directory (ENOENT/ENOTDIR) fingerprints as empty — there
85
- * is nothing there to protect — but any other listing failure (EACCES, EIO,
82
+ * A missing patches directory (ENOENT/ENOTDIR) fingerprints as empty, since
83
+ * there is nothing there to protect. Any other listing failure (EACCES, EIO,
86
84
  * …) throws: an unreadable directory is not evidence it is empty, and
87
85
  * treating it as such lets the guard silently vouch for state it never saw.
88
86
  * The same rule covers an unmeasurable engine generation and an unreadable
89
- * individual patch file; a before-pass failure aborts the dry run before it
87
+ * individual patch file. A before-pass failure aborts the dry run before it
90
88
  * starts, since a guard that measured nothing cannot vouch for anything.
91
89
  */
92
90
  async function fingerprintDryRunState(engineDir, patchesDir) {
93
91
  const fingerprint = new Map();
94
92
  const generation = await snapshotEngineGeneration(engineDir);
95
93
  if (isUnavailableGenerationToken(generation)) {
96
- // A failed probe measured nothing — hashing the failure token would let
94
+ // A failed probe measured nothing. Hashing the failure token would let
97
95
  // two identical failures compare "unchanged" (vouching for unmeasured
98
96
  // state) and two differing messages report a spurious violation.
99
97
  throw new GeneralError(`[dry-run] cannot fingerprint the engine working tree for the purity guard: ` +
100
98
  unavailableGenerationReason(generation));
101
99
  }
102
- fingerprint.set('the engine working tree', createHash('sha256').update(generation).digest('hex'));
100
+ fingerprint.set('the engine working tree', sha256Hex(generation));
103
101
  let names = [];
104
102
  try {
105
103
  const entries = await readdir(patchesDir, { withFileTypes: true });
@@ -109,9 +107,9 @@ async function fingerprintDryRunState(engineDir, patchesDir) {
109
107
  .sort();
110
108
  }
111
109
  catch (error) {
112
- // No patches directory — nothing there to protect; the same condition on
113
- // the post-run pass produces the same empty set, and a directory that
114
- // appears mid-dry-run correctly reports as a violation. Any OTHER failure
110
+ // No patches directory, so nothing there to protect. The same condition
111
+ // on the post-run pass produces the same empty set, and a directory that
112
+ // appears mid-dry-run correctly reports as a violation. Any other failure
115
113
  // must not read as "empty": the guard would be vouching for state it
116
114
  // never saw.
117
115
  const code = getNodeErrorCode(error);
@@ -122,14 +120,12 @@ async function fingerprintDryRunState(engineDir, patchesDir) {
122
120
  const results = await mapWithConcurrency(names, PATCH_HASH_CONCURRENCY, async (name) => {
123
121
  try {
124
122
  return {
125
- hash: createHash('sha256')
126
- .update(await readFile(join(patchesDir, name)))
127
- .digest('hex'),
123
+ hash: sha256Hex(await readFile(join(patchesDir, name))),
128
124
  };
129
125
  }
130
126
  catch (error) {
131
127
  // A file that vanished between the listing and the read is omitted, so
132
- // a dry run that DELETED a patch artifact reports as the violation it
128
+ // a dry run that deleted a patch artifact reports as the violation it
133
129
  // is (key present before, absent after) instead of hiding behind a
134
130
  // fingerprinting error. Every other failure fails closed: a constant
135
131
  // placeholder would make unreadable-before equal unreadable-after even
@@ -159,9 +155,9 @@ async function fingerprintDryRunState(engineDir, patchesDir) {
159
155
  * a dry-run changed anything it promised only to inspect. That turns a
160
156
  * "dry-run reverted a just-written export" incident into a hard, named
161
157
  * failure instead of silent data loss discovered only when a later gate
162
- * fails. The post-fingerprint runs whether `operation` resolves or rejects —
163
- * a dry-run that mutates state and THEN fails is exactly the case where a
164
- * rollback defect must not go unreported; a rejection with a purity
158
+ * fails. The post-fingerprint runs whether `operation` resolves or rejects,
159
+ * because a dry-run that mutates state and then fails is exactly the case
160
+ * where a rollback defect must not go unreported. A rejection with a purity
165
161
  * violation surfaces the violation with the original error as `cause`.
166
162
  * No-op outside dry-run.
167
163
  */
@@ -185,9 +181,9 @@ export async function withDryRunPurityGuard(engineDir, patchesDir, isDryRun, ope
185
181
  }
186
182
  catch (fingerprintError) {
187
183
  // The post-run fingerprint failing must not swallow the dry run's own
188
- // failure — an operation that mutated state, broke it, AND made it
184
+ // failure: an operation that mutated state, broke it, and made it
189
185
  // unreadable is exactly the case where both facts matter. The combined
190
- // message carries both; the operation error stays the `cause`.
186
+ // message carries both. The operation error stays the `cause`.
191
187
  if (failed) {
192
188
  throw new GeneralError(`[dry-run] this dry run failed (${toError(operationError).message}), and its purity could ` +
193
189
  `not be verified afterwards: ${toError(fingerprintError).message}. Inspect engine/ and ` +
@@ -2,21 +2,21 @@
2
2
  * Foreign-drift preview + `--refuse-foreign-drift` gate for `re-export`.
3
3
  *
4
4
  * A scan-less re-export rebuilds each patch body as a whole-file
5
- * `git diff HEAD` over the owned files — so a CONCURRENT session's
5
+ * `git diff HEAD` over the owned files, so a concurrent session's
6
6
  * uncommitted lines inside a file the patch already owns are silently
7
7
  * absorbed into the refreshed body. The adjacency advisory
8
- * (`re-export-adjacent.ts`) warns about unmanaged NEIGHBOUR files but is
8
+ * (`re-export-adjacent.ts`) warns about unmanaged neighbour files but is
9
9
  * structurally blind to drift inside owned files. This module compares
10
10
  * the old body against the refreshed body per file and reports the
11
- * payload lines that are about to ENTER the body; under
11
+ * payload lines that are about to enter the body. Under
12
12
  * `--refuse-foreign-drift` the patch is skipped and the run exits
13
13
  * non-zero, mirroring `--refuse-adjacent-unmanaged`.
14
14
  *
15
15
  * "Foreign" is decided by content, not authorship: re-export's legitimate
16
16
  * job is capturing intentional engine edits, so the preview always prints
17
17
  * and the hard stop is an explicit opt-in for multi-session checkouts.
18
- * The comparison is offset-insensitive — per-file MULTISETS of `+`/`-`
19
- * payload lines — because a refresh legitimately shifts hunk offsets and
18
+ * The comparison is offset-insensitive, using per-file multisets of `+`/`-`
19
+ * payload lines, because a refresh legitimately shifts hunk offsets and
20
20
  * context without changing what the patch does.
21
21
  */
22
22
  import type { PatchMetadata } from '../types/commands/index.js';
@@ -55,14 +55,14 @@ export interface FileForeignDrift {
55
55
  }
56
56
  /**
57
57
  * Pure comparison: per owned file, which `+`/`-` payload lines the
58
- * refreshed body carries that the old body did not. Files NOT in
59
- * `previousFilesAffected` are skipped — those are intentional adoptions
60
- * (`--scan`), not drift.
58
+ * refreshed body carries that the old body did not. Files not in
59
+ * `previousFilesAffected` are skipped, since those are intentional
60
+ * adoptions (`--scan`) rather than drift.
61
61
  */
62
62
  export declare function computeForeignDrift(oldBody: string, newBody: string, previousFilesAffected: readonly string[]): FileForeignDrift[];
63
63
  /**
64
64
  * Reads the old body, prints the always-on drift preview (including under
65
- * dry-run and `--scan`), and — when `ctx.refuseForeignDrift` is set —
65
+ * dry-run and `--scan`), and, when `ctx.refuseForeignDrift` is set,
66
66
  * records a refusal and returns `true` so the caller skips the write.
67
67
  */
68
68
  export declare function reportForeignDrift(args: {
@@ -75,7 +75,7 @@ export declare function reportForeignDrift(args: {
75
75
  /**
76
76
  * Names `--expect` paths that never drifted this run. A typo'd
77
77
  * `--expect` path silently degrades the flag back to refusing the slice it
78
- * was meant to admit, so surface the mismatch — but only as a warning: an
78
+ * was meant to admit, so surface the mismatch, but only as a warning: an
79
79
  * expected file legitimately shows no drift in several shapes, all named
80
80
  * below.
81
81
  */
@@ -3,21 +3,21 @@
3
3
  * Foreign-drift preview + `--refuse-foreign-drift` gate for `re-export`.
4
4
  *
5
5
  * A scan-less re-export rebuilds each patch body as a whole-file
6
- * `git diff HEAD` over the owned files — so a CONCURRENT session's
6
+ * `git diff HEAD` over the owned files, so a concurrent session's
7
7
  * uncommitted lines inside a file the patch already owns are silently
8
8
  * absorbed into the refreshed body. The adjacency advisory
9
- * (`re-export-adjacent.ts`) warns about unmanaged NEIGHBOUR files but is
9
+ * (`re-export-adjacent.ts`) warns about unmanaged neighbour files but is
10
10
  * structurally blind to drift inside owned files. This module compares
11
11
  * the old body against the refreshed body per file and reports the
12
- * payload lines that are about to ENTER the body; under
12
+ * payload lines that are about to enter the body. Under
13
13
  * `--refuse-foreign-drift` the patch is skipped and the run exits
14
14
  * non-zero, mirroring `--refuse-adjacent-unmanaged`.
15
15
  *
16
16
  * "Foreign" is decided by content, not authorship: re-export's legitimate
17
17
  * job is capturing intentional engine edits, so the preview always prints
18
18
  * and the hard stop is an explicit opt-in for multi-session checkouts.
19
- * The comparison is offset-insensitive — per-file MULTISETS of `+`/`-`
20
- * payload lines — because a refresh legitimately shifts hunk offsets and
19
+ * The comparison is offset-insensitive, using per-file multisets of `+`/`-`
20
+ * payload lines, because a refresh legitimately shifts hunk offsets and
21
21
  * context without changing what the patch does.
22
22
  */
23
23
  import { stat } from 'node:fs/promises';
@@ -101,7 +101,7 @@ function summarizeForeignHunks(payload, foreignAdded, foreignRemoved) {
101
101
  }
102
102
  }
103
103
  if (added > 0 || removed > 0) {
104
- summaries.push(`@@ -${String(hunk.oldStart)},${String(hunk.oldCount)} +${String(hunk.newStart)},${String(hunk.newCount)} @@ (+${String(added)}/-${String(removed)})`);
104
+ summaries.push(`@@ -${hunk.oldStart},${hunk.oldCount} +${hunk.newStart},${hunk.newCount} @@ (+${added}/-${removed})`);
105
105
  }
106
106
  }
107
107
  }
@@ -115,9 +115,9 @@ function countExcess(excess) {
115
115
  }
116
116
  /**
117
117
  * Pure comparison: per owned file, which `+`/`-` payload lines the
118
- * refreshed body carries that the old body did not. Files NOT in
119
- * `previousFilesAffected` are skipped — those are intentional adoptions
120
- * (`--scan`), not drift.
118
+ * refreshed body carries that the old body did not. Files not in
119
+ * `previousFilesAffected` are skipped, since those are intentional
120
+ * adoptions (`--scan`) rather than drift.
121
121
  */
122
122
  export function computeForeignDrift(oldBody, newBody, previousFilesAffected) {
123
123
  const owned = new Set(previousFilesAffected);
@@ -156,7 +156,7 @@ export function computeForeignDrift(oldBody, newBody, previousFilesAffected) {
156
156
  }
157
157
  /**
158
158
  * Reads the old body, prints the always-on drift preview (including under
159
- * dry-run and `--scan`), and — when `ctx.refuseForeignDrift` is set —
159
+ * dry-run and `--scan`), and, when `ctx.refuseForeignDrift` is set,
160
160
  * records a refusal and returns `true` so the caller skips the write.
161
161
  */
162
162
  export async function reportForeignDrift(args) {
@@ -184,7 +184,7 @@ export async function reportForeignDrift(args) {
184
184
  const recentlyEdited = await findFilesEditedSinceLastExport(engineDir, oldPath, drift.map((d) => d.file));
185
185
  const totalLines = drift.reduce((sum, d) => sum + d.addedLines + d.removedLines, 0);
186
186
  const lineNoun = totalLines === 1 ? 'line' : 'lines';
187
- warn(`${patch.filename}: refreshed body absorbs ${String(totalLines)} ${lineNoun} not present in the old patch body (${String(drift.length)} file(s)):`);
187
+ warn(`${patch.filename}: refreshed body absorbs ${totalLines} ${lineNoun} not present in the old patch body (${drift.length} file(s)):`);
188
188
  for (const entry of drift.slice(0, MAX_FILES_REPORTED)) {
189
189
  const expectedTag = ctx.expectedDriftFiles.has(entry.file) ? ' (expected via --expect)' : '';
190
190
  const authorshipTag = recentlyEdited.has(entry.file)
@@ -194,13 +194,13 @@ export async function reportForeignDrift(args) {
194
194
  info(` ${entry.file}: binary content changed${expectedTag}${authorshipTag}`);
195
195
  continue;
196
196
  }
197
- info(` ${entry.file}: +${String(entry.addedLines)}/-${String(entry.removedLines)} newly captured line(s)${expectedTag}${authorshipTag}`);
197
+ info(` ${entry.file}: +${entry.addedLines}/-${entry.removedLines} newly captured line(s)${expectedTag}${authorshipTag}`);
198
198
  for (const summary of entry.hunkSummaries) {
199
199
  info(` ${summary}`);
200
200
  }
201
201
  }
202
202
  if (drift.length > MAX_FILES_REPORTED) {
203
- info(` +${String(drift.length - MAX_FILES_REPORTED)} more file(s)`);
203
+ info(` +${drift.length - MAX_FILES_REPORTED} more file(s)`);
204
204
  }
205
205
  if (ctx.refuseForeignDrift) {
206
206
  if (unexpected.length === 0) {
@@ -225,13 +225,13 @@ export async function reportForeignDrift(args) {
225
225
  /**
226
226
  * Splits the drifting files into "you probably wrote this" and "this predates
227
227
  * your last export". `--refuse-foreign-drift` calls every absorbed line
228
- * "foreign" — including the operator's OWN additions from the same session —
229
- * and "foreign" reads as "another session's", which is precisely the case
230
- * where proceeding would be wrong. Authorship is unknowable, but RECENCY is
231
- * not: a file whose mtime is newer than the patch body this run is refreshing
228
+ * "foreign", including the operator's own additions from the same session,
229
+ * and "foreign" reads as "another session's", which is the case where
230
+ * proceeding would be wrong. Authorship is unknowable, but recency is not:
231
+ * a file whose mtime is newer than the patch body this run is refreshing
232
232
  * changed after the last export, which on a single-operator slice is the
233
- * operator's own edit. Returns the subset of `files` that qualifies; an
234
- * unstattable path is reported as NOT recently edited, so the cautious
233
+ * operator's own edit. Returns the subset of `files` that qualifies. An
234
+ * unstattable path is reported as not recently edited, so the cautious
235
235
  * wording is the fallback.
236
236
  */
237
237
  async function findFilesEditedSinceLastExport(engineDir, patchBodyPath, files) {
@@ -257,7 +257,7 @@ async function findFilesEditedSinceLastExport(engineDir, patchBodyPath, files) {
257
257
  }
258
258
  /**
259
259
  * Fail-closed baseline handling: a missing or unreadable old
260
- * patch body means the drift comparison CANNOT run, so under
260
+ * patch body means the drift comparison cannot run, so under
261
261
  * `--refuse-foreign-drift` the patch is refused rather than written on the
262
262
  * strength of a check that never happened. Without the flag this stays the
263
263
  * historical advisory skip (the preview is best-effort there).
@@ -272,28 +272,28 @@ function refuseUnreadableBaseline(ctx, patchFilename, detail) {
272
272
  return true;
273
273
  }
274
274
  /**
275
- * States, verbatim in the notice, WHAT the `--expect` whitelist is compared
276
- * against and WHEN. This notice is the only feedback an operator gets that
275
+ * States, verbatim in the notice, what the `--expect` whitelist is compared
276
+ * against and when. This notice is the only feedback an operator gets that
277
277
  * the drift belt looked at the files they named, and a downstream report
278
278
  * showed the previous copy actively misleading: it warned "showed no drift"
279
- * over an edit that WAS captured correctly, and none of the causes it named
279
+ * over an edit that was captured correctly, and none of the causes it named
280
280
  * held, so the operator's only recourse was `grep -c` on the written body.
281
281
  *
282
282
  * The measurement, stated exactly:
283
283
  *
284
- * - COMPARED: for each file already in the patch's `filesAffected`, the
285
- * `+`/`-` payload lines the REFRESHED body carries that the OLD patch
284
+ * - Compared: for each file already in the patch's `filesAffected`, the
285
+ * `+`/`-` payload lines the refreshed body carries that the old patch
286
286
  * body did not (`computeForeignDrift`). It is a content comparison, and
287
- * it is ONE-DIRECTIONAL: excess in the new body only.
288
- * - WHEN: per patch, on the body about to be written, BEFORE the write —
289
- * never against post-write state.
287
+ * it is one-directional: excess in the new body only.
288
+ * - When: per patch, on the body about to be written, before the write.
289
+ * Never against post-write state.
290
290
  *
291
291
  * The one-directional half is what the earlier copy hid, and it is the
292
292
  * cause the report's first shape actually hit: deleting a line from an
293
- * engine file makes the refreshed body DROP that file's `+` line. Nothing
294
- * is absorbed, so by design there is no drift to see — the belt exists to
295
- * catch a concurrent session's edits being silently swallowed INTO a body,
296
- * not every difference between two bodies. Naming it is the fix; widening
293
+ * engine file makes the refreshed body drop that file's `+` line. Nothing
294
+ * is absorbed, so there is no drift to see. The belt exists to catch a
295
+ * concurrent session's edits being silently swallowed into a body, not
296
+ * every difference between two bodies. Stating that is the fix. Widening
297
297
  * the comparison would turn every ordinary line removal into a refusal.
298
298
  */
299
299
  const EXPECT_MEASUREMENT_NOTE = '--expect is evaluated against CONTENT, before the write: for each file already in the ' +
@@ -302,7 +302,7 @@ const EXPECT_MEASUREMENT_NOTE = '--expect is evaluated against CONTENT, before t
302
302
  /**
303
303
  * Names `--expect` paths that never drifted this run. A typo'd
304
304
  * `--expect` path silently degrades the flag back to refusing the slice it
305
- * was meant to admit, so surface the mismatch — but only as a warning: an
305
+ * was meant to admit, so surface the mismatch, but only as a warning: an
306
306
  * expected file legitimately shows no drift in several shapes, all named
307
307
  * below.
308
308
  */
@@ -1,6 +1,5 @@
1
- import { getProjectPaths } from '../core/config.js';
2
1
  import type { PatchMetadata, ReExportOptions } from '../types/commands/index.js';
3
- import type { FireForgeConfig } from '../types/config.js';
2
+ import type { FireForgeConfig, ProjectPaths } from '../types/config.js';
4
3
  /**
5
4
  * Handles `re-export --files` end-to-end: computes the projected diff, runs
6
5
  * the per-patch and cross-patch lint against a context in which the target
@@ -13,4 +12,4 @@ import type { FireForgeConfig } from '../types/config.js';
13
12
  * generic single-patch helper is what makes the projection lint run against
14
13
  * the current (unchanged) queue instead of the projected state.
15
14
  */
16
- export declare function reExportFilesInPlace(paths: ReturnType<typeof getProjectPaths>, selectedPatches: PatchMetadata[], options: ReExportOptions, config: FireForgeConfig): Promise<void>;
15
+ export declare function reExportFilesInPlace(paths: ProjectPaths, selectedPatches: PatchMetadata[], options: ReExportOptions, config: FireForgeConfig): Promise<void>;