@hominis/fireforge 0.43.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +10 -1
  3. package/dist/bin/fireforge.d.ts +4 -9
  4. package/dist/bin/fireforge.js +42 -40
  5. package/dist/build-info.json +4 -4
  6. package/dist/src/cli.js +74 -8
  7. package/dist/src/commands/bootstrap.js +17 -20
  8. package/dist/src/commands/build.js +25 -32
  9. package/dist/src/commands/config.js +34 -41
  10. package/dist/src/commands/discard.js +8 -9
  11. package/dist/src/commands/doctor-check-core.d.ts +4 -18
  12. package/dist/src/commands/doctor-check-core.js +8 -35
  13. package/dist/src/commands/doctor-external-toolchains.js +2 -2
  14. package/dist/src/commands/doctor-furnace-config-sync.d.ts +18 -0
  15. package/dist/src/commands/{doctor-furnace-manifest-sync.js → doctor-furnace-config-sync.js} +27 -26
  16. package/dist/src/commands/doctor-furnace-jar.d.ts +7 -9
  17. package/dist/src/commands/doctor-furnace-jar.js +7 -9
  18. package/dist/src/commands/doctor-furnace.js +21 -24
  19. package/dist/src/commands/doctor-orphaned-harness.d.ts +16 -20
  20. package/dist/src/commands/doctor-orphaned-harness.js +18 -44
  21. package/dist/src/commands/doctor-post-rebase-audit.d.ts +2 -0
  22. package/dist/src/commands/{doctor/post-rebase-audit.js → doctor-post-rebase-audit.js} +3 -3
  23. package/dist/src/commands/doctor-working-tree.d.ts +10 -12
  24. package/dist/src/commands/doctor-working-tree.js +11 -18
  25. package/dist/src/commands/doctor.js +35 -53
  26. package/dist/src/commands/download.js +32 -48
  27. package/dist/src/commands/export-all.js +29 -33
  28. package/dist/src/commands/export-flow.js +6 -6
  29. package/dist/src/commands/export-placement-conflicts.js +10 -9
  30. package/dist/src/commands/export-placement-gate.js +5 -5
  31. package/dist/src/commands/export-shared.d.ts +30 -33
  32. package/dist/src/commands/export-shared.js +45 -43
  33. package/dist/src/commands/export.js +21 -27
  34. package/dist/src/commands/furnace/apply.js +14 -23
  35. package/dist/src/commands/furnace/chrome-doc-remove.js +14 -21
  36. package/dist/src/commands/furnace/chrome-doc-templates.d.ts +23 -23
  37. package/dist/src/commands/furnace/chrome-doc-templates.js +23 -23
  38. package/dist/src/commands/furnace/chrome-doc-tests.js +26 -29
  39. package/dist/src/commands/furnace/chrome-doc.d.ts +16 -17
  40. package/dist/src/commands/furnace/chrome-doc.js +31 -41
  41. package/dist/src/commands/furnace/create-browser-test.d.ts +4 -4
  42. package/dist/src/commands/furnace/create-browser-test.js +8 -8
  43. package/dist/src/commands/furnace/create-mochikit.d.ts +6 -7
  44. package/dist/src/commands/furnace/create-mochikit.js +8 -9
  45. package/dist/src/commands/furnace/create-readback.d.ts +12 -13
  46. package/dist/src/commands/furnace/create-readback.js +12 -13
  47. package/dist/src/commands/furnace/create-templates.d.ts +22 -28
  48. package/dist/src/commands/furnace/create-templates.js +35 -30
  49. package/dist/src/commands/furnace/create-xpcshell.js +2 -2
  50. package/dist/src/commands/furnace/create.js +33 -23
  51. package/dist/src/commands/furnace/deploy.js +16 -24
  52. package/dist/src/commands/furnace/diff.js +9 -9
  53. package/dist/src/commands/furnace/init.js +33 -36
  54. package/dist/src/commands/furnace/override.js +23 -25
  55. package/dist/src/commands/furnace/preview.js +47 -67
  56. package/dist/src/commands/furnace/refresh.js +12 -16
  57. package/dist/src/commands/furnace/remove-mutations.d.ts +3 -6
  58. package/dist/src/commands/furnace/remove-mutations.js +9 -16
  59. package/dist/src/commands/furnace/remove-state.js +1 -1
  60. package/dist/src/commands/furnace/remove.js +33 -38
  61. package/dist/src/commands/furnace/rename-xpcshell.d.ts +8 -11
  62. package/dist/src/commands/furnace/rename-xpcshell.js +8 -11
  63. package/dist/src/commands/furnace/rename.js +59 -69
  64. package/dist/src/commands/furnace/scan.js +19 -33
  65. package/dist/src/commands/furnace/status.js +12 -9
  66. package/dist/src/commands/furnace/sync.js +9 -16
  67. package/dist/src/commands/furnace/validate.js +20 -20
  68. package/dist/src/commands/import.js +42 -35
  69. package/dist/src/commands/lint-per-patch.js +15 -10
  70. package/dist/src/commands/lint-per-run-checkjs.d.ts +13 -13
  71. package/dist/src/commands/lint-per-run-checkjs.js +13 -13
  72. package/dist/src/commands/lint-report.js +6 -7
  73. package/dist/src/commands/lint.d.ts +15 -16
  74. package/dist/src/commands/lint.js +86 -102
  75. package/dist/src/commands/package.js +6 -11
  76. package/dist/src/commands/patch/compact.js +1 -1
  77. package/dist/src/commands/patch/delete.js +24 -33
  78. package/dist/src/commands/patch/index.d.ts +5 -6
  79. package/dist/src/commands/patch/index.js +10 -12
  80. package/dist/src/commands/patch/lint-ignore.js +14 -13
  81. package/dist/src/commands/patch/move-files-create.d.ts +6 -6
  82. package/dist/src/commands/patch/move-files-create.js +8 -8
  83. package/dist/src/commands/patch/move-files-into.d.ts +6 -6
  84. package/dist/src/commands/patch/move-files-into.js +8 -8
  85. package/dist/src/commands/patch/patch-context.d.ts +2 -3
  86. package/dist/src/commands/patch/patch-context.js +2 -3
  87. package/dist/src/commands/patch/rename.d.ts +10 -11
  88. package/dist/src/commands/patch/rename.js +11 -12
  89. package/dist/src/commands/patch/reorder.js +8 -9
  90. package/dist/src/commands/patch/split-plan.js +1 -1
  91. package/dist/src/commands/patch/split.d.ts +8 -10
  92. package/dist/src/commands/patch/split.js +9 -11
  93. package/dist/src/commands/patch/staged-dependency-validate.js +8 -8
  94. package/dist/src/commands/patch/staged-dependency.js +7 -3
  95. package/dist/src/commands/patch/tier.d.ts +9 -9
  96. package/dist/src/commands/patch/tier.js +18 -15
  97. package/dist/src/commands/re-export-adjacent.js +9 -8
  98. package/dist/src/commands/re-export-bulk-scan.d.ts +9 -9
  99. package/dist/src/commands/re-export-bulk-scan.js +22 -21
  100. package/dist/src/commands/re-export-drift.js +10 -10
  101. package/dist/src/commands/re-export-files.d.ts +6 -7
  102. package/dist/src/commands/re-export-files.js +34 -44
  103. package/dist/src/commands/re-export-lint.d.ts +10 -13
  104. package/dist/src/commands/re-export-lint.js +16 -14
  105. package/dist/src/commands/re-export-options.d.ts +6 -6
  106. package/dist/src/commands/re-export-options.js +6 -6
  107. package/dist/src/commands/re-export-register.d.ts +4 -10
  108. package/dist/src/commands/re-export-register.js +5 -11
  109. package/dist/src/commands/re-export-scan.js +1 -1
  110. package/dist/src/commands/re-export-single.d.ts +3 -3
  111. package/dist/src/commands/re-export-single.js +33 -25
  112. package/dist/src/commands/re-export.js +13 -21
  113. package/dist/src/commands/rebase/abort.js +3 -3
  114. package/dist/src/commands/rebase/confirm.js +2 -1
  115. package/dist/src/commands/rebase/continue.d.ts +1 -1
  116. package/dist/src/commands/rebase/continue.js +14 -9
  117. package/dist/src/commands/rebase/index.js +11 -11
  118. package/dist/src/commands/rebase/patch-loop.d.ts +7 -1
  119. package/dist/src/commands/rebase/patch-loop.js +60 -39
  120. package/dist/src/commands/rebase/summary.js +1 -1
  121. package/dist/src/commands/register.js +5 -7
  122. package/dist/src/commands/reset.js +2 -1
  123. package/dist/src/commands/resolve.d.ts +16 -13
  124. package/dist/src/commands/resolve.js +30 -33
  125. package/dist/src/commands/run.js +33 -35
  126. package/dist/src/commands/setup-support.js +15 -19
  127. package/dist/src/commands/setup.js +13 -9
  128. package/dist/src/commands/status-check.d.ts +6 -6
  129. package/dist/src/commands/status-json.d.ts +6 -6
  130. package/dist/src/commands/status-json.js +5 -0
  131. package/dist/src/commands/status-output.d.ts +5 -5
  132. package/dist/src/commands/status-output.js +6 -6
  133. package/dist/src/commands/status-ownership.d.ts +16 -14
  134. package/dist/src/commands/status-ownership.js +16 -14
  135. package/dist/src/commands/status.js +42 -34
  136. package/dist/src/commands/test-build-phase.js +26 -13
  137. package/dist/src/commands/test-diagnose.js +44 -44
  138. package/dist/src/commands/test-register.js +1 -0
  139. package/dist/src/commands/test-run.d.ts +14 -16
  140. package/dist/src/commands/test-run.js +21 -13
  141. package/dist/src/commands/test-stale-gate.d.ts +15 -16
  142. package/dist/src/commands/test-stale-gate.js +15 -16
  143. package/dist/src/commands/test-verdict.d.ts +20 -3
  144. package/dist/src/commands/test-verdict.js +30 -0
  145. package/dist/src/commands/test.js +83 -76
  146. package/dist/src/commands/token-coverage.js +3 -4
  147. package/dist/src/commands/token.js +16 -18
  148. package/dist/src/commands/tree.js +47 -31
  149. package/dist/src/commands/typecheck.d.ts +10 -12
  150. package/dist/src/commands/typecheck.js +24 -27
  151. package/dist/src/commands/verify.js +13 -15
  152. package/dist/src/commands/watch.js +21 -23
  153. package/dist/src/commands/wire.js +52 -62
  154. package/dist/src/core/ast-utils.d.ts +8 -7
  155. package/dist/src/core/ast-utils.js +8 -7
  156. package/dist/src/core/branding.d.ts +9 -14
  157. package/dist/src/core/branding.js +7 -11
  158. package/dist/src/core/browser-wire.d.ts +1 -1
  159. package/dist/src/core/browser-wire.js +14 -19
  160. package/dist/src/core/build-audit-platform.js +25 -33
  161. package/dist/src/core/build-audit-registration.js +17 -25
  162. package/dist/src/core/build-audit-resolve.d.ts +15 -17
  163. package/dist/src/core/build-audit-resolve.js +27 -33
  164. package/dist/src/core/build-audit-transforms.js +18 -19
  165. package/dist/src/core/build-audit.js +28 -42
  166. package/dist/src/core/build-baseline-types.d.ts +29 -35
  167. package/dist/src/core/build-baseline.d.ts +5 -4
  168. package/dist/src/core/build-baseline.js +14 -14
  169. package/dist/src/core/build-overwrite-guard.d.ts +7 -14
  170. package/dist/src/core/build-overwrite-guard.js +62 -19
  171. package/dist/src/core/build-prepare.d.ts +2 -2
  172. package/dist/src/core/build-prepare.js +8 -9
  173. package/dist/src/core/config-state.js +12 -4
  174. package/dist/src/core/config-validate.js +8 -5
  175. package/dist/src/core/config.d.ts +5 -8
  176. package/dist/src/core/config.js +7 -16
  177. package/dist/src/core/coverage-extend.d.ts +15 -13
  178. package/dist/src/core/coverage-extend.js +15 -13
  179. package/dist/src/core/destructive.d.ts +31 -9
  180. package/dist/src/core/destructive.js +29 -26
  181. package/dist/src/core/diff-hunks.js +10 -12
  182. package/dist/src/core/discard-baseline.d.ts +8 -8
  183. package/dist/src/core/discard-baseline.js +16 -15
  184. package/dist/src/core/display-state.d.ts +12 -14
  185. package/dist/src/core/display-state.js +12 -14
  186. package/dist/src/core/engine-changes.d.ts +2 -4
  187. package/dist/src/core/engine-changes.js +2 -4
  188. package/dist/src/core/engine-precondition.d.ts +28 -13
  189. package/dist/src/core/engine-precondition.js +25 -10
  190. package/dist/src/core/engine-session-lock.d.ts +47 -21
  191. package/dist/src/core/engine-session-lock.js +168 -33
  192. package/dist/src/core/export-moved-code-shape.d.ts +10 -10
  193. package/dist/src/core/export-moved-code-shape.js +10 -10
  194. package/dist/src/core/file-lock.d.ts +62 -5
  195. package/dist/src/core/file-lock.js +196 -59
  196. package/dist/src/core/firefox-cache.js +1 -3
  197. package/dist/src/core/firefox-extract.js +10 -14
  198. package/dist/src/core/firefox.d.ts +7 -5
  199. package/dist/src/core/firefox.js +4 -5
  200. package/dist/src/core/furnace-apply-dry-run.d.ts +2 -2
  201. package/dist/src/core/furnace-apply-dry-run.js +3 -2
  202. package/dist/src/core/furnace-apply-ftl.d.ts +7 -9
  203. package/dist/src/core/furnace-apply-ftl.js +12 -12
  204. package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
  205. package/dist/src/core/furnace-apply-helpers.js +19 -16
  206. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +8 -9
  207. package/dist/src/core/furnace-apply-overwrite-warn.js +8 -9
  208. package/dist/src/core/furnace-apply-undeploy-actions.d.ts +3 -4
  209. package/dist/src/core/furnace-apply-undeploy-actions.js +3 -4
  210. package/dist/src/core/furnace-apply.d.ts +5 -8
  211. package/dist/src/core/furnace-apply.js +19 -24
  212. package/dist/src/core/furnace-checksum-utils.d.ts +14 -0
  213. package/dist/src/core/furnace-checksum-utils.js +16 -0
  214. package/dist/src/core/furnace-config.d.ts +21 -30
  215. package/dist/src/core/furnace-config.js +32 -54
  216. package/dist/src/core/furnace-constants.d.ts +8 -0
  217. package/dist/src/core/furnace-constants.js +10 -2
  218. package/dist/src/core/furnace-css-fragments.d.ts +5 -5
  219. package/dist/src/core/furnace-css-fragments.js +5 -5
  220. package/dist/src/core/furnace-jsconfig.d.ts +11 -12
  221. package/dist/src/core/furnace-jsconfig.js +11 -12
  222. package/dist/src/core/furnace-marker.d.ts +7 -8
  223. package/dist/src/core/furnace-marker.js +7 -8
  224. package/dist/src/core/furnace-operation.d.ts +31 -0
  225. package/dist/src/core/furnace-operation.js +54 -17
  226. package/dist/src/core/furnace-precondition.d.ts +61 -0
  227. package/dist/src/core/furnace-precondition.js +67 -0
  228. package/dist/src/core/furnace-registration-remove.d.ts +5 -6
  229. package/dist/src/core/furnace-registration-remove.js +6 -7
  230. package/dist/src/core/furnace-registration-validate.d.ts +13 -0
  231. package/dist/src/core/furnace-registration-validate.js +20 -1
  232. package/dist/src/core/furnace-registration.d.ts +5 -6
  233. package/dist/src/core/furnace-registration.js +10 -12
  234. package/dist/src/core/furnace-rollback.js +7 -7
  235. package/dist/src/core/furnace-scanner.d.ts +1 -0
  236. package/dist/src/core/furnace-scanner.js +1 -2
  237. package/dist/src/core/furnace-stale-export.d.ts +10 -10
  238. package/dist/src/core/furnace-stale-export.js +10 -10
  239. package/dist/src/core/furnace-state-persist.d.ts +6 -8
  240. package/dist/src/core/furnace-state-persist.js +6 -8
  241. package/dist/src/core/furnace-validate-accessibility.d.ts +22 -0
  242. package/dist/src/core/furnace-validate-accessibility.js +310 -1
  243. package/dist/src/core/furnace-validate-compatibility.js +141 -1
  244. package/dist/src/core/furnace-validate-helpers.d.ts +5 -116
  245. package/dist/src/core/furnace-validate-helpers.js +0 -491
  246. package/dist/src/core/furnace-validate-registration.d.ts +7 -0
  247. package/dist/src/core/furnace-validate-registration.js +115 -41
  248. package/dist/src/core/furnace-validate.d.ts +16 -0
  249. package/dist/src/core/furnace-validate.js +188 -145
  250. package/dist/src/core/furnace-version-drift.d.ts +10 -11
  251. package/dist/src/core/furnace-version-drift.js +10 -11
  252. package/dist/src/core/git-base.d.ts +7 -9
  253. package/dist/src/core/git-base.js +7 -9
  254. package/dist/src/core/git-diff.d.ts +20 -9
  255. package/dist/src/core/git-diff.js +148 -63
  256. package/dist/src/core/git-file-ops.d.ts +19 -19
  257. package/dist/src/core/git-file-ops.js +19 -19
  258. package/dist/src/core/git-readonly-index.d.ts +53 -19
  259. package/dist/src/core/git-readonly-index.js +75 -31
  260. package/dist/src/core/git-status.d.ts +5 -6
  261. package/dist/src/core/git-status.js +5 -6
  262. package/dist/src/core/git.d.ts +9 -10
  263. package/dist/src/core/git.js +54 -70
  264. package/dist/src/core/license-headers.d.ts +17 -23
  265. package/dist/src/core/license-headers.js +17 -23
  266. package/dist/src/core/mach-build-artifacts.d.ts +9 -9
  267. package/dist/src/core/mach-build-artifacts.js +57 -19
  268. package/dist/src/core/mach-error-hints.js +42 -29
  269. package/dist/src/core/mach-known-noise-filter.d.ts +15 -16
  270. package/dist/src/core/mach-known-noise-filter.js +18 -20
  271. package/dist/src/core/mach-mozconfig.d.ts +14 -0
  272. package/dist/src/core/mach-mozconfig.js +30 -0
  273. package/dist/src/core/mach-resource-shim.d.ts +43 -58
  274. package/dist/src/core/mach-resource-shim.js +50 -67
  275. package/dist/src/core/mach.d.ts +37 -41
  276. package/dist/src/core/mach.js +50 -51
  277. package/dist/src/core/marionette-port.d.ts +36 -1
  278. package/dist/src/core/marionette-port.js +96 -31
  279. package/dist/src/core/marionette-preflight.d.ts +8 -12
  280. package/dist/src/core/marionette-preflight.js +86 -52
  281. package/dist/src/core/mochitest-server-port.d.ts +42 -0
  282. package/dist/src/core/mochitest-server-port.js +119 -0
  283. package/dist/src/core/module-resolution-preflight.d.ts +9 -11
  284. package/dist/src/core/module-resolution-preflight.js +9 -11
  285. package/dist/src/core/moz-manifest-helpers.d.ts +79 -0
  286. package/dist/src/core/moz-manifest-helpers.js +163 -0
  287. package/dist/src/core/{manifest-register.d.ts → moz-manifest-register.d.ts} +1 -1
  288. package/dist/src/core/{manifest-register.js → moz-manifest-register.js} +13 -28
  289. package/dist/src/core/{manifest-rules.d.ts → moz-manifest-rules.d.ts} +10 -1
  290. package/dist/src/core/{manifest-rules.js → moz-manifest-rules.js} +31 -24
  291. package/dist/src/core/{manifest-tokenizers.d.ts → moz-manifest-tokenizers.d.ts} +3 -5
  292. package/dist/src/core/{manifest-tokenizers.js → moz-manifest-tokenizers.js} +9 -12
  293. package/dist/src/core/ownership-table.d.ts +14 -16
  294. package/dist/src/core/ownership-table.js +14 -16
  295. package/dist/src/core/parser-fallback.d.ts +15 -1
  296. package/dist/src/core/parser-fallback.js +22 -3
  297. package/dist/src/core/patch-apply-fuzz.d.ts +10 -12
  298. package/dist/src/core/patch-apply-fuzz.js +15 -18
  299. package/dist/src/core/patch-apply.d.ts +13 -34
  300. package/dist/src/core/patch-apply.js +16 -76
  301. package/dist/src/core/patch-artifact-normalize.d.ts +13 -15
  302. package/dist/src/core/patch-artifact-normalize.js +13 -15
  303. package/dist/src/core/patch-export-metadata.d.ts +12 -2
  304. package/dist/src/core/patch-export-metadata.js +13 -4
  305. package/dist/src/core/patch-export-update.d.ts +13 -1
  306. package/dist/src/core/patch-export-update.js +25 -8
  307. package/dist/src/core/patch-export.d.ts +15 -8
  308. package/dist/src/core/patch-export.js +10 -11
  309. package/dist/src/core/patch-files.d.ts +5 -6
  310. package/dist/src/core/patch-files.js +5 -6
  311. package/dist/src/core/patch-identifier-suggest.d.ts +7 -12
  312. package/dist/src/core/patch-identifier-suggest.js +14 -19
  313. package/dist/src/core/patch-lint-binary.d.ts +51 -0
  314. package/dist/src/core/patch-lint-binary.js +39 -0
  315. package/dist/src/core/{lint-cache.d.ts → patch-lint-cache.d.ts} +5 -5
  316. package/dist/src/core/{lint-cache.js → patch-lint-cache.js} +21 -23
  317. package/dist/src/core/patch-lint-checkjs.d.ts +16 -16
  318. package/dist/src/core/patch-lint-checkjs.js +16 -16
  319. package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +6 -9
  320. package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -14
  321. package/dist/src/core/patch-lint-creators.d.ts +8 -8
  322. package/dist/src/core/patch-lint-creators.js +8 -8
  323. package/dist/src/core/patch-lint-cross.d.ts +17 -20
  324. package/dist/src/core/patch-lint-cross.js +16 -16
  325. package/dist/src/core/patch-lint-css.d.ts +3 -5
  326. package/dist/src/core/patch-lint-css.js +17 -22
  327. package/dist/src/core/patch-lint-diff-tag.d.ts +14 -16
  328. package/dist/src/core/patch-lint-diff-tag.js +14 -16
  329. package/dist/src/core/patch-lint-jsdoc.d.ts +7 -8
  330. package/dist/src/core/patch-lint-jsdoc.js +26 -19
  331. package/dist/src/core/patch-lint-mozbuild.js +20 -20
  332. package/dist/src/core/patch-lint-observer.d.ts +7 -7
  333. package/dist/src/core/patch-lint-observer.js +7 -7
  334. package/dist/src/core/patch-lint.d.ts +38 -29
  335. package/dist/src/core/patch-lint.js +89 -121
  336. package/dist/src/core/patch-lock.d.ts +1 -1
  337. package/dist/src/core/patch-lock.js +45 -9
  338. package/dist/src/core/patch-manifest-consistency.d.ts +2 -1
  339. package/dist/src/core/patch-manifest-consistency.js +25 -27
  340. package/dist/src/core/patch-manifest-io.js +14 -18
  341. package/dist/src/core/patch-manifest-resolve.d.ts +9 -12
  342. package/dist/src/core/patch-manifest-resolve.js +9 -12
  343. package/dist/src/core/patch-manifest-validate.d.ts +6 -1
  344. package/dist/src/core/patch-manifest-validate.js +25 -13
  345. package/dist/src/core/patch-parse.d.ts +24 -13
  346. package/dist/src/core/patch-parse.js +19 -14
  347. package/dist/src/core/patch-policy.d.ts +2 -2
  348. package/dist/src/core/patch-policy.js +2 -2
  349. package/dist/src/core/patch-registration-refs.d.ts +7 -8
  350. package/dist/src/core/patch-registration-refs.js +9 -9
  351. package/dist/src/core/process-cpu-time.d.ts +12 -0
  352. package/dist/src/core/process-cpu-time.js +52 -0
  353. package/dist/src/core/rebase-session.d.ts +38 -26
  354. package/dist/src/core/rebase-session.js +55 -28
  355. package/dist/src/core/register-browser-content.js +9 -74
  356. package/dist/src/core/{register-test-manifest.js → register-browser-test.js} +7 -42
  357. package/dist/src/core/register-module.js +10 -43
  358. package/dist/src/core/register-scaffold.d.ts +8 -8
  359. package/dist/src/core/register-scaffold.js +10 -10
  360. package/dist/src/core/register-shared-css.d.ts +9 -12
  361. package/dist/src/core/register-shared-css.js +17 -87
  362. package/dist/src/core/register-xpcshell-test.d.ts +6 -7
  363. package/dist/src/core/register-xpcshell-test.js +7 -8
  364. package/dist/src/core/shared-ftl.js +12 -4
  365. package/dist/src/core/state-file.d.ts +45 -0
  366. package/dist/src/core/state-file.js +34 -0
  367. package/dist/src/core/status-binary.d.ts +18 -11
  368. package/dist/src/core/status-binary.js +19 -12
  369. package/dist/src/core/status-classify.d.ts +30 -36
  370. package/dist/src/core/status-classify.js +21 -26
  371. package/dist/src/core/test-changed-prefs.d.ts +30 -0
  372. package/dist/src/core/test-changed-prefs.js +78 -0
  373. package/dist/src/core/test-harness-crash.d.ts +25 -63
  374. package/dist/src/core/test-harness-crash.js +121 -142
  375. package/dist/src/core/test-harness-signature.d.ts +18 -0
  376. package/dist/src/core/test-harness-signature.js +13 -0
  377. package/dist/src/core/test-path-scope.d.ts +12 -15
  378. package/dist/src/core/test-path-scope.js +15 -18
  379. package/dist/src/core/test-stale-check.d.ts +17 -17
  380. package/dist/src/core/test-stale-check.js +50 -43
  381. package/dist/src/core/test-stall-triage.d.ts +51 -0
  382. package/dist/src/core/test-stall-triage.js +126 -0
  383. package/dist/src/core/token-category.js +5 -7
  384. package/dist/src/core/token-coverage.js +9 -9
  385. package/dist/src/core/token-dark-mode.d.ts +9 -11
  386. package/dist/src/core/token-dark-mode.js +9 -11
  387. package/dist/src/core/token-docs.d.ts +2 -0
  388. package/dist/src/core/token-docs.js +2 -0
  389. package/dist/src/core/token-manager.d.ts +10 -2
  390. package/dist/src/core/token-manager.js +17 -8
  391. package/dist/src/core/token-scaffold.d.ts +7 -7
  392. package/dist/src/core/token-scaffold.js +7 -7
  393. package/dist/src/core/token-variant.d.ts +4 -4
  394. package/dist/src/core/token-variant.js +4 -4
  395. package/dist/src/core/toolchain-preflight.d.ts +20 -21
  396. package/dist/src/core/toolchain-preflight.js +28 -31
  397. package/dist/src/core/tree-guard.js +12 -2
  398. package/dist/src/core/tree-store.d.ts +41 -27
  399. package/dist/src/core/tree-store.js +63 -42
  400. package/dist/src/core/typecheck-shim.d.ts +23 -24
  401. package/dist/src/core/typecheck-shim.js +23 -24
  402. package/dist/src/core/typecheck.js +8 -8
  403. package/dist/src/core/wire-destroy.d.ts +3 -3
  404. package/dist/src/core/wire-destroy.js +7 -15
  405. package/dist/src/core/wire-dom-fragment.d.ts +9 -17
  406. package/dist/src/core/wire-dom-fragment.js +11 -44
  407. package/dist/src/core/wire-init.d.ts +2 -3
  408. package/dist/src/core/wire-init.js +8 -19
  409. package/dist/src/core/wire-subscript.d.ts +2 -3
  410. package/dist/src/core/wire-subscript.js +4 -13
  411. package/dist/src/core/wire-utils.d.ts +7 -8
  412. package/dist/src/core/wire-utils.js +7 -8
  413. package/dist/src/core/xpcshell-appdir.d.ts +38 -45
  414. package/dist/src/core/xpcshell-appdir.js +38 -45
  415. package/dist/src/errors/base.d.ts +37 -16
  416. package/dist/src/errors/base.js +37 -16
  417. package/dist/src/errors/build.d.ts +13 -1
  418. package/dist/src/errors/build.js +14 -2
  419. package/dist/src/errors/codes.d.ts +16 -0
  420. package/dist/src/errors/codes.js +16 -0
  421. package/dist/src/errors/furnace.d.ts +4 -4
  422. package/dist/src/errors/git.d.ts +6 -10
  423. package/dist/src/errors/git.js +6 -10
  424. package/dist/src/errors/patch.d.ts +7 -7
  425. package/dist/src/errors/patch.js +7 -7
  426. package/dist/src/errors/rebase.d.ts +4 -4
  427. package/dist/src/errors/rebase.js +4 -4
  428. package/dist/src/index.d.ts +7 -1
  429. package/dist/src/index.js +5 -0
  430. package/dist/src/types/commands/index.d.ts +2 -2
  431. package/dist/src/types/commands/options.d.ts +88 -70
  432. package/dist/src/types/commands/patches.d.ts +24 -34
  433. package/dist/src/types/commands/project.d.ts +5 -34
  434. package/dist/src/types/config.d.ts +25 -23
  435. package/dist/src/types/config.js +6 -1
  436. package/dist/src/types/furnace.d.ts +37 -13
  437. package/dist/src/types/furnace.js +19 -1
  438. package/dist/src/types/index.d.ts +3 -3
  439. package/dist/src/utils/build-info.d.ts +7 -8
  440. package/dist/src/utils/build-info.js +12 -11
  441. package/dist/src/utils/errors.d.ts +6 -8
  442. package/dist/src/utils/errors.js +6 -8
  443. package/dist/src/utils/logger.d.ts +27 -10
  444. package/dist/src/utils/logger.js +28 -16
  445. package/dist/src/utils/machine-output.d.ts +12 -0
  446. package/dist/src/utils/machine-output.js +33 -0
  447. package/dist/src/utils/options.d.ts +31 -14
  448. package/dist/src/utils/options.js +86 -30
  449. package/dist/src/utils/paths.d.ts +10 -8
  450. package/dist/src/utils/paths.js +10 -8
  451. package/dist/src/utils/platform.d.ts +0 -25
  452. package/dist/src/utils/platform.js +1 -42
  453. package/dist/src/utils/process-group.d.ts +9 -4
  454. package/dist/src/utils/process-group.js +19 -5
  455. package/dist/src/utils/process.d.ts +42 -7
  456. package/dist/src/utils/process.js +44 -17
  457. package/dist/src/utils/ps-duration.d.ts +31 -0
  458. package/dist/src/utils/ps-duration.js +70 -0
  459. package/dist/src/utils/regex.d.ts +9 -10
  460. package/dist/src/utils/regex.js +9 -10
  461. package/dist/src/utils/validation.d.ts +58 -28
  462. package/dist/src/utils/validation.js +60 -33
  463. package/package.json +2 -2
  464. package/dist/src/commands/doctor/post-rebase-audit.d.ts +0 -2
  465. package/dist/src/commands/doctor-furnace-manifest-sync.d.ts +0 -18
  466. package/dist/src/core/manifest-helpers.d.ts +0 -38
  467. package/dist/src/core/manifest-helpers.js +0 -120
  468. /package/dist/src/core/{lint-projection.d.ts → patch-lint-projection.d.ts} +0 -0
  469. /package/dist/src/core/{lint-projection.js → patch-lint-projection.js} +0 -0
  470. /package/dist/src/core/{register-test-manifest.d.ts → register-browser-test.d.ts} +0 -0
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * `fireforge patch move-files <from> <to> --create --order <n>` — creates
3
- * the target patch at the requested sparse order and moves the files into
4
- * it as one transaction. This is the transactional bootstrap of a split:
5
- * without it, moving files into a not-yet-existing patch required a manual
3
+ * the target patch at the requested sparse order and moves the files into it
4
+ * as one transaction. This is the transactional bootstrap of a split:
5
+ * without it, moving files into a not-yet-existing patch requires a manual
6
6
  * shrink-then-export dance with hand-repointed staged-dependency owners.
7
7
  *
8
- * Mirrors `patch split` end-to-end (same planning, projection lint,
9
- * policy enforcement, and locked commit); the `<to>` argument becomes the
10
- * new patch's name/slug the way `split --name` does.
8
+ * Mirrors `patch split` end-to-end (same planning, projection lint, policy
9
+ * enforcement, and locked commit); the `<to>` argument becomes the new
10
+ * patch's name/slug the way `split --name` does.
11
11
  */
12
12
  import type { PatchMoveFilesOptions } from '../../types/commands/index.js';
13
13
  /**
@@ -1,14 +1,14 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
3
  * `fireforge patch move-files <from> <to> --create --order <n>` — creates
4
- * the target patch at the requested sparse order and moves the files into
5
- * it as one transaction. This is the transactional bootstrap of a split:
6
- * without it, moving files into a not-yet-existing patch required a manual
4
+ * the target patch at the requested sparse order and moves the files into it
5
+ * as one transaction. This is the transactional bootstrap of a split:
6
+ * without it, moving files into a not-yet-existing patch requires a manual
7
7
  * shrink-then-export dance with hand-repointed staged-dependency owners.
8
8
  *
9
- * Mirrors `patch split` end-to-end (same planning, projection lint,
10
- * policy enforcement, and locked commit); the `<to>` argument becomes the
11
- * new patch's name/slug the way `split --name` does.
9
+ * Mirrors `patch split` end-to-end (same planning, projection lint, policy
10
+ * enforcement, and locked commit); the `<to>` argument becomes the new
11
+ * patch's name/slug the way `split --name` does.
12
12
  */
13
13
  import { getProjectPaths, loadConfig } from '../../core/config.js';
14
14
  import { assertConfirmationAvailable, confirmDestructive } from '../../core/destructive.js';
@@ -92,7 +92,7 @@ export async function patchMoveFilesCreateCommand(projectRoot, fromIdentifier, n
92
92
  // same patch-policy shape as the committed `lint --per-patch` gate) makes
93
93
  // cross-patch `resource:///` imports and sibling head.js harness roots
94
94
  // resolve exactly as they will after the move lands — without it the
95
- // projection lint was blind.
95
+ // projection lint is blind.
96
96
  const patchQueueCtx = await buildPatchQueueContext(paths.patches, config);
97
97
  const ignoreChecks = source.lintIgnore ? new Set(source.lintIgnore) : undefined;
98
98
  await runPatchLint(paths.engine, remainingFiles, remainingDiff, config, options.skipLint, patchQueueCtx, ignoreChecks, source.tier);
@@ -122,7 +122,7 @@ export async function patchMoveFilesCreateCommand(projectRoot, fromIdentifier, n
122
122
  outro('Dry run complete — no changes made');
123
123
  return;
124
124
  }
125
- if (decision === 'cancelled') {
125
+ if (decision === 'declined') {
126
126
  outro('Move cancelled');
127
127
  return;
128
128
  }
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Transactional file-ownership move into an EXISTING patch.
3
3
  *
4
- * Before 0.39.0, `patch move-files <from> <to>` with an existing target was
5
- * preview-only: it printed two `re-export --files` commands whose real
6
- * execution cost three further refusals (`--allow-shrink`, `--yes`, and a
7
- * projected `duplicate-new-file-creation` unless the SHRINK landed first —
8
- * while the printed plan listed the grow first). This module performs the
9
- * same shrink→grow as one transaction under the patch-directory lock with
4
+ * A preview-only `patch move-files <from> <to>` prints two
5
+ * `re-export --files` commands whose real execution costs three further
6
+ * refusals (`--allow-shrink`, `--yes`, and a projected
7
+ * `duplicate-new-file-creation` unless the SHRINK lands first — while the
8
+ * printed plan lists the grow first). This module performs the same
9
+ * shrink→grow as one transaction under the patch-directory lock with
10
10
  * rollback, mirroring `patch split` / `move-files --create`.
11
11
  *
12
12
  * Preconditions match `re-export`: the engine worktree must currently
@@ -2,12 +2,12 @@
2
2
  /**
3
3
  * Transactional file-ownership move into an EXISTING patch.
4
4
  *
5
- * Before 0.39.0, `patch move-files <from> <to>` with an existing target was
6
- * preview-only: it printed two `re-export --files` commands whose real
7
- * execution cost three further refusals (`--allow-shrink`, `--yes`, and a
8
- * projected `duplicate-new-file-creation` unless the SHRINK landed first —
9
- * while the printed plan listed the grow first). This module performs the
10
- * same shrink→grow as one transaction under the patch-directory lock with
5
+ * A preview-only `patch move-files <from> <to>` prints two
6
+ * `re-export --files` commands whose real execution costs three further
7
+ * refusals (`--allow-shrink`, `--yes`, and a projected
8
+ * `duplicate-new-file-creation` unless the SHRINK lands first — while the
9
+ * printed plan lists the grow first). This module performs the same
10
+ * shrink→grow as one transaction under the patch-directory lock with
11
11
  * rollback, mirroring `patch split` / `move-files --create`.
12
12
  *
13
13
  * Preconditions match `re-export`: the engine worktree must currently
@@ -16,9 +16,9 @@
16
16
  */
17
17
  import { join } from 'node:path';
18
18
  import { appendHistory, assertConfirmationAvailable, confirmDestructive, } from '../../core/destructive.js';
19
- import { computeProjectedLintRegressions } from '../../core/lint-projection.js';
20
19
  import { normalizePatchArtifact } from '../../core/patch-artifact-normalize.js';
21
20
  import { buildModifiedFileAdditionsFromDiff, buildPatchQueueContext, collectForwardImportEdges, detectNewFilesInDiff, formatPatchLintIssue, lintPatchQueue, } from '../../core/patch-lint.js';
21
+ import { computeProjectedLintRegressions } from '../../core/patch-lint-projection.js';
22
22
  import { withPatchDirectoryLock } from '../../core/patch-lock.js';
23
23
  import { loadPatchesManifest, savePatchesManifest, validatePatchesManifest, } from '../../core/patch-manifest.js';
24
24
  import { extractNewFileContentFromDiff } from '../../core/patch-transform.js';
@@ -238,7 +238,7 @@ export async function runMoveFilesInto(args) {
238
238
  outro('Dry run complete — no changes made');
239
239
  return;
240
240
  }
241
- if (decision === 'cancelled') {
241
+ if (decision === 'declined') {
242
242
  outro('Move cancelled');
243
243
  return;
244
244
  }
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * Shared preamble for the patch subcommands: every mutation command starts
3
3
  * by loading the project paths and the patches manifest and (for the
4
- * single-patch commands) resolving the operator-supplied identifier. The
5
- * sequence and its error wording were previously copied into each command;
6
- * this module is the single source for both.
4
+ * single-patch commands) resolving the operator-supplied identifier. This
5
+ * module is the single source for that sequence and its error wording.
7
6
  */
8
7
  import type { PatchesManifest, PatchMetadata } from '../../types/commands/index.js';
9
8
  import type { ProjectPaths } from '../../types/config.js';
@@ -2,9 +2,8 @@
2
2
  /**
3
3
  * Shared preamble for the patch subcommands: every mutation command starts
4
4
  * by loading the project paths and the patches manifest and (for the
5
- * single-patch commands) resolving the operator-supplied identifier. The
6
- * sequence and its error wording were previously copied into each command;
7
- * this module is the single source for both.
5
+ * single-patch commands) resolving the operator-supplied identifier. This
6
+ * module is the single source for that sequence and its error wording.
8
7
  */
9
8
  import { getProjectPaths } from '../../core/config.js';
10
9
  import { formatPatchNotFoundError } from '../../core/patch-identifier-suggest.js';
@@ -1,19 +1,18 @@
1
1
  /**
2
2
  * `fireforge patch rename <name>` — relabels a patch's filename, manifest
3
- * `name`, and (optionally) `description` without rewriting the `.patch`
4
- * file body.
3
+ * `name`, and (optionally) `description` without rewriting the `.patch` file
4
+ * body.
5
5
  *
6
- * Companion to `re-export --files <subset>`. Re-export shrinks the body
7
- * + `filesAffected`, but leaves the patch's identity describing the
8
- * pre-shrink scope. Before this verb existed, the only workaround for
9
- * that drift was `delete` + re-export, which briefly removed the patch
10
- * from the queue (any forward-import dependent would refuse the
11
- * re-export until the deleted patch's siblings were rewritten).
6
+ * Companion to `re-export --files <subset>`. Re-export shrinks the body and
7
+ * `filesAffected` but leaves the patch's identity describing the pre-shrink
8
+ * scope. The only alternative for that drift is `delete` + re-export, which
9
+ * briefly removes the patch from the queue — any forward-import dependent
10
+ * then refuses the re-export until the deleted patch's siblings are
11
+ * rewritten.
12
12
  *
13
13
  * The filename rename and the manifest mutation happen under the patch
14
- * directory lock so concurrent exports cannot allocate the new
15
- * filename, and a filesystem rename failure rolls back before the
16
- * manifest is touched.
14
+ * directory lock so concurrent exports cannot allocate the new filename, and
15
+ * a filesystem rename failure rolls back before the manifest is touched.
17
16
  */
18
17
  import { Command } from 'commander';
19
18
  import type { CommandContext } from '../../types/cli.js';
@@ -1,20 +1,19 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
3
  * `fireforge patch rename <name>` — relabels a patch's filename, manifest
4
- * `name`, and (optionally) `description` without rewriting the `.patch`
5
- * file body.
4
+ * `name`, and (optionally) `description` without rewriting the `.patch` file
5
+ * body.
6
6
  *
7
- * Companion to `re-export --files <subset>`. Re-export shrinks the body
8
- * + `filesAffected`, but leaves the patch's identity describing the
9
- * pre-shrink scope. Before this verb existed, the only workaround for
10
- * that drift was `delete` + re-export, which briefly removed the patch
11
- * from the queue (any forward-import dependent would refuse the
12
- * re-export until the deleted patch's siblings were rewritten).
7
+ * Companion to `re-export --files <subset>`. Re-export shrinks the body and
8
+ * `filesAffected` but leaves the patch's identity describing the pre-shrink
9
+ * scope. The only alternative for that drift is `delete` + re-export, which
10
+ * briefly removes the patch from the queue — any forward-import dependent
11
+ * then refuses the re-export until the deleted patch's siblings are
12
+ * rewritten.
13
13
  *
14
14
  * The filename rename and the manifest mutation happen under the patch
15
- * directory lock so concurrent exports cannot allocate the new
16
- * filename, and a filesystem rename failure rolls back before the
17
- * manifest is touched.
15
+ * directory lock so concurrent exports cannot allocate the new filename, and
16
+ * a filesystem rename failure rolls back before the manifest is touched.
18
17
  */
19
18
  import { rename as fsRename } from 'node:fs/promises';
20
19
  import { join } from 'node:path';
@@ -314,7 +313,7 @@ export async function patchRenameCommand(projectRoot, identifier, options = {})
314
313
  outro('Dry run complete — no changes made');
315
314
  return;
316
315
  }
317
- if (decision === 'cancelled') {
316
+ if (decision === 'declined') {
318
317
  outro('Rename cancelled');
319
318
  return;
320
319
  }
@@ -241,14 +241,13 @@ async function commitReorderPlan(patchesDir, target, renameMap, anchorFilename,
241
241
  .join('\n ')}\nPass --force-unsafe to override.`, '--force-unsafe');
242
242
  }
243
243
  await renumberPatchesInManifest(patchesDir, currentRenameMap);
244
- // Append the history record inside the lock so two concurrent
245
- // reorders cannot interleave mutation and history writes, and so a
246
- // crash between the rename and the history write cannot orphan a
247
- // committed reorder with no audit trail. If the append itself
248
- // fails (disk full, permissions), we warn but do not re-throw:
249
- // the mutation has already succeeded and is not reversible, so
250
- // surfacing the history failure as a command failure would
251
- // mislead the caller.
244
+ // Append the history record inside the lock so two concurrent reorders
245
+ // cannot interleave mutation and history writes, and so a crash
246
+ // between the rename and the history write cannot orphan a committed
247
+ // reorder with no audit trail. An append failure (disk full,
248
+ // permissions) is warned but not re-thrown: the mutation has already
249
+ // succeeded and is not reversible, so surfacing it as a command
250
+ // failure would mislead.
252
251
  try {
253
252
  await appendHistory(patchesDir, buildHistoryEntry(currentRenameMap));
254
253
  }
@@ -334,7 +333,7 @@ export async function patchReorderCommand(projectRoot, identifier, options = {})
334
333
  outro('Dry run complete — no changes made');
335
334
  return;
336
335
  }
337
- if (decision === 'cancelled') {
336
+ if (decision === 'declined') {
338
337
  outro('Reorder cancelled');
339
338
  return;
340
339
  }
@@ -9,9 +9,9 @@
9
9
  import { join } from 'node:path';
10
10
  import {} from '../../core/destructive.js';
11
11
  import { getDiffForFilesAgainstHead } from '../../core/git-diff.js';
12
- import { computeProjectedLintRegressions } from '../../core/lint-projection.js';
13
12
  import { extractAffectedFiles } from '../../core/patch-apply.js';
14
13
  import { buildModifiedFileAdditionsFromDiff, buildPatchQueueContext, collectForwardImportEdges, detectNewFilesInDiff, formatPatchLintIssue, lintPatchQueue, } from '../../core/patch-lint.js';
14
+ import { computeProjectedLintRegressions } from '../../core/patch-lint-projection.js';
15
15
  import { rewriteStagedDependencyOwners } from '../../core/patch-manifest.js';
16
16
  import { applyRenameMapToManifest, buildProjectedManifest } from '../../core/patch-policy.js';
17
17
  import { buildPatchSourceMetadata } from '../../core/patch-source-metadata.js';
@@ -1,16 +1,14 @@
1
1
  /**
2
2
  * `fireforge patch split <source> --files <p...> --name <n>` — moves files
3
- * out of an existing patch into a brand-new patch as one transaction
4
- * (field report A4).
3
+ * out of an existing patch into a brand-new patch as one transaction.
5
4
  *
6
- * Before this command, splitting a patch whose files have inbound
7
- * forward-imports required a precise manual order: re-point each
8
- * staged-dependency owner at a not-yet-created patch, shrink the source
9
- * via `re-export --files --allow-shrink`, then `export --order` — any
10
- * other order refused or needed `--force-unsafe`. Split performs the
11
- * shrink, the new-patch creation, and the dependent owner rewrites under
12
- * one patch-directory lock with rollback, validating only the final
13
- * projection.
5
+ * Splitting a patch whose files have inbound forward-imports otherwise
6
+ * requires a precise manual order: re-point each staged-dependency owner at
7
+ * a not-yet-created patch, shrink the source via
8
+ * `re-export --files --allow-shrink`, then `export --order` — any other
9
+ * order refuses or needs `--force-unsafe`. Split performs the shrink, the
10
+ * new-patch creation, and the dependent owner rewrites under one
11
+ * patch-directory lock with rollback, validating only the final projection.
14
12
  *
15
13
  * Preconditions match `re-export`: the engine worktree must currently
16
14
  * reflect both patches' content, because both bodies are regenerated from
@@ -1,17 +1,15 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
3
  * `fireforge patch split <source> --files <p...> --name <n>` — moves files
4
- * out of an existing patch into a brand-new patch as one transaction
5
- * (field report A4).
4
+ * out of an existing patch into a brand-new patch as one transaction.
6
5
  *
7
- * Before this command, splitting a patch whose files have inbound
8
- * forward-imports required a precise manual order: re-point each
9
- * staged-dependency owner at a not-yet-created patch, shrink the source
10
- * via `re-export --files --allow-shrink`, then `export --order` — any
11
- * other order refused or needed `--force-unsafe`. Split performs the
12
- * shrink, the new-patch creation, and the dependent owner rewrites under
13
- * one patch-directory lock with rollback, validating only the final
14
- * projection.
6
+ * Splitting a patch whose files have inbound forward-imports otherwise
7
+ * requires a precise manual order: re-point each staged-dependency owner at
8
+ * a not-yet-created patch, shrink the source via
9
+ * `re-export --files --allow-shrink`, then `export --order` — any other
10
+ * order refuses or needs `--force-unsafe`. Split performs the shrink, the
11
+ * new-patch creation, and the dependent owner rewrites under one
12
+ * patch-directory lock with rollback, validating only the final projection.
15
13
  *
16
14
  * Preconditions match `re-export`: the engine worktree must currently
17
15
  * reflect both patches' content, because both bodies are regenerated from
@@ -252,7 +250,7 @@ export async function patchSplitCommand(projectRoot, sourceId, options) {
252
250
  outro('Dry run complete — no changes made');
253
251
  return;
254
252
  }
255
- if (decision === 'cancelled') {
253
+ if (decision === 'declined') {
256
254
  outro('Split cancelled');
257
255
  return;
258
256
  }
@@ -2,14 +2,14 @@
2
2
  /**
3
3
  * Shape validation for `patch staged-dependency --add`.
4
4
  *
5
- * `--creates`/`--file` take engine-relative FILE paths and `--owner`
6
- * takes a patch FILENAME, but all three were accepted as arbitrary
7
- * strings — a `--creates <patch-name>` mixup produced a declaration
8
- * nothing could ever discharge, surfacing only later as a
9
- * `staged-dependency-unused` warning. Refusals here fire only on a clear
10
- * patch-name shape (slash-free values that end in `.patch` or match a
11
- * queue patch filename/stem): legitimate engine paths always contain a
12
- * `/`, so deep paths can never false-positive.
5
+ * `--creates`/`--file` take engine-relative FILE paths and `--owner` takes a
6
+ * patch FILENAME. Accepting all three as arbitrary strings lets a
7
+ * `--creates <patch-name>` mixup produce a declaration nothing can ever
8
+ * discharge, surfacing only later as a `staged-dependency-unused` warning.
9
+ * Refusals here fire only on a clear patch-name shape (slash-free values
10
+ * that end in `.patch` or match a queue patch filename/stem): legitimate
11
+ * engine paths always contain a `/`, so deep paths can never
12
+ * false-positive.
13
13
  */
14
14
  import { InvalidArgumentError } from '../../errors/base.js';
15
15
  import { warn } from '../../utils/logger.js';
@@ -9,6 +9,7 @@ import { mutatePatchMetadata } from '../../core/patch-export.js';
9
9
  import { GeneralError, InvalidArgumentError } from '../../errors/base.js';
10
10
  import { toError } from '../../utils/errors.js';
11
11
  import { info, intro, outro, warn } from '../../utils/logger.js';
12
+ import { addWaitLockOption, resolveWaitLockSeconds } from '../../utils/options.js';
12
13
  import { requirePatchQueue, requirePatchTarget } from './patch-context.js';
13
14
  import { validateStagedDependencyAdd } from './staged-dependency-validate.js';
14
15
  /** Joins the names of the missing flags for error attribution. */
@@ -269,6 +270,9 @@ export async function patchStagedDependencyCommand(projectRoot, identifier, opti
269
270
  if (countStagedEntries(after) === 0)
270
271
  return { unset: ['stagedDependencies'] };
271
272
  return { set: { stagedDependencies: after } };
273
+ }, {
274
+ waitLockSeconds: resolveWaitLockSeconds(options.waitLock),
275
+ command: 'patch staged-dependency',
272
276
  });
273
277
  if (!result) {
274
278
  throw new GeneralError(`Patch ${targetPatch.filename} disappeared from the manifest during the update. Re-run after investigating.`);
@@ -303,7 +307,7 @@ export async function patchStagedDependencyCommand(projectRoot, identifier, opti
303
307
  */
304
308
  export function registerPatchStagedDependency(parent, context) {
305
309
  const { getProjectRoot, withErrorHandling } = context;
306
- parent
310
+ const command = parent
307
311
  .command('staged-dependency <name>')
308
312
  .description('Edit PatchMetadata.stagedDependencies on a single patch (no .patch body rewrite).')
309
313
  .option('--add', 'Add a staged dependency declaration')
@@ -317,8 +321,8 @@ export function registerPatchStagedDependency(parent, context) {
317
321
  .option('--owner <patch>', 'Exact later patch filename expected to create --creates')
318
322
  .option('--reason <text>', 'Human-readable rationale stored with the declaration')
319
323
  .option('--dry-run', 'Show what would change without writing')
320
- .option('-y, --yes', 'Record scripted consent in the destructive-operation history log. This command never prompts; the flag exists for workflow uniformity with commands that do.')
321
- .action(withErrorHandling(async (name, options) => {
324
+ .option('-y, --yes', 'Record scripted consent in the destructive-operation history log. This command never prompts; the flag exists for workflow uniformity with commands that do.');
325
+ addWaitLockOption(command).action(withErrorHandling(async (name, options) => {
322
326
  await patchStagedDependencyCommand(getProjectRoot(), name, options);
323
327
  }));
324
328
  }
@@ -1,14 +1,14 @@
1
1
  /**
2
- * `fireforge patch tier <name>` — sets or clears `PatchMetadata.tier` on
3
- * a single patch without rewriting the `.patch` file body.
2
+ * `fireforge patch tier <name>` — sets or clears `PatchMetadata.tier` on a
3
+ * single patch without rewriting the `.patch` file body.
4
4
  *
5
- * Companion to `fireforge re-export <name> --tier <tier>`. Re-export is
6
- * the right tool when the patch body itself needs to be regenerated; this
7
- * subcommand exists for the metadata-only adjustment, where the operator
8
- * has discovered (e.g. from a `lint --per-patch` warning) that the
9
- * threshold-tier override should be set but the patch body is already
10
- * correct. Avoiding the re-export saves the engine read + diff
11
- * regeneration roundtrip and leaves the `.patch` file's mtime alone.
5
+ * Companion to `fireforge re-export <name> --tier <tier>`. Re-export is the
6
+ * right tool when the patch body itself needs regenerating; this subcommand
7
+ * covers the metadata-only adjustment, where the operator has discovered
8
+ * (from a `lint --per-patch` warning, say) that the threshold-tier override
9
+ * should be set but the patch body is already correct. Avoiding the
10
+ * re-export saves the engine read + diff regeneration roundtrip and leaves
11
+ * the `.patch` file's mtime alone.
12
12
  *
13
13
  * Modes are mutually exclusive: exactly one of `--tier <branding>` or
14
14
  * `--clear` must be supplied per invocation.
@@ -1,15 +1,15 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
- * `fireforge patch tier <name>` — sets or clears `PatchMetadata.tier` on
4
- * a single patch without rewriting the `.patch` file body.
3
+ * `fireforge patch tier <name>` — sets or clears `PatchMetadata.tier` on a
4
+ * single patch without rewriting the `.patch` file body.
5
5
  *
6
- * Companion to `fireforge re-export <name> --tier <tier>`. Re-export is
7
- * the right tool when the patch body itself needs to be regenerated; this
8
- * subcommand exists for the metadata-only adjustment, where the operator
9
- * has discovered (e.g. from a `lint --per-patch` warning) that the
10
- * threshold-tier override should be set but the patch body is already
11
- * correct. Avoiding the re-export saves the engine read + diff
12
- * regeneration roundtrip and leaves the `.patch` file's mtime alone.
6
+ * Companion to `fireforge re-export <name> --tier <tier>`. Re-export is the
7
+ * right tool when the patch body itself needs regenerating; this subcommand
8
+ * covers the metadata-only adjustment, where the operator has discovered
9
+ * (from a `lint --per-patch` warning, say) that the threshold-tier override
10
+ * should be set but the patch body is already correct. Avoiding the
11
+ * re-export saves the engine read + diff regeneration roundtrip and leaves
12
+ * the `.patch` file's mtime alone.
13
13
  *
14
14
  * Modes are mutually exclusive: exactly one of `--tier <branding>` or
15
15
  * `--clear` must be supplied per invocation.
@@ -20,7 +20,7 @@ import { updatePatchMetadata } from '../../core/patch-export.js';
20
20
  import { InvalidArgumentError } from '../../errors/base.js';
21
21
  import { toError } from '../../utils/errors.js';
22
22
  import { info, intro, outro, warn } from '../../utils/logger.js';
23
- import { pickDefined } from '../../utils/options.js';
23
+ import { addWaitLockOption, pickDefined, resolveWaitLockSeconds } from '../../utils/options.js';
24
24
  import { requirePatchQueue, requirePatchTarget } from './patch-context.js';
25
25
  /**
26
26
  * Runs the `patch tier` command: updates `PatchMetadata.tier` on the
@@ -75,7 +75,7 @@ export async function patchTierCommand(projectRoot, identifier, options = {}) {
75
75
  outro('Dry run complete — no changes made');
76
76
  return;
77
77
  }
78
- if (decision === 'cancelled') {
78
+ if (decision === 'declined') {
79
79
  outro('Cancelled — no changes made');
80
80
  return;
81
81
  }
@@ -84,7 +84,10 @@ export async function patchTierCommand(projectRoot, identifier, options = {}) {
84
84
  // routes through `unsetFields` so TypeScript's exact optional types
85
85
  // do not have to carry an explicit `undefined` on the `tier` field.
86
86
  if (after !== undefined) {
87
- await updatePatchMetadata(paths.patches, target.filename, { tier: after });
87
+ await updatePatchMetadata(paths.patches, target.filename, { tier: after }, [], {
88
+ waitLockSeconds: resolveWaitLockSeconds(options.waitLock),
89
+ command: 'patch tier',
90
+ });
88
91
  }
89
92
  else {
90
93
  await updatePatchMetadata(paths.patches, target.filename, {}, ['tier']);
@@ -115,14 +118,14 @@ export async function patchTierCommand(projectRoot, identifier, options = {}) {
115
118
  */
116
119
  export function registerPatchTier(parent, context) {
117
120
  const { getProjectRoot, withErrorHandling } = context;
118
- parent
121
+ const command = parent
119
122
  .command('tier <name>')
120
123
  .description('Set or clear PatchMetadata.tier on a single patch (no .patch body rewrite). Use --tier <branding> to set, --clear to remove.')
121
124
  .addOption(new Option('--tier <tier>', 'Force the tier override on the patch (only "branding" recognised)').choices(['branding']))
122
125
  .option('--clear', 'Remove the tier override (restores tier auto-detection)')
123
126
  .option('--dry-run', 'Show what would change without writing')
124
- .option('-y, --yes', 'Skip confirmation prompt (required for non-TTY)')
125
- .action(withErrorHandling(async (name, options) => {
127
+ .option('-y, --yes', 'Skip confirmation prompt (required for non-TTY)');
128
+ addWaitLockOption(command).action(withErrorHandling(async (name, options) => {
126
129
  const { tier, ...rest } = options;
127
130
  await patchTierCommand(getProjectRoot(), name, {
128
131
  ...pickDefined(rest),
@@ -1,16 +1,17 @@
1
1
  // SPDX-License-Identifier: EUPL-1.2
2
2
  /**
3
- * Scan-less re-export adjacency advisory. A plain `re-export`
4
- * keeps the manifest's filesAffected unchanged, so a brand-new file an
5
- * author just created beside a patch's owned files is silently left out
6
- * of the refreshed body. This module detects such adjacent files, filters
7
- * out tool-managed paths (branding, furnace) so the notice names only
8
- * genuinely unmanaged candidates, and — under
3
+ * Scan-less re-export adjacency advisory.
4
+ *
5
+ * A plain `re-export` keeps the manifest's filesAffected unchanged, so a
6
+ * brand-new file an author just created beside a patch's owned files is
7
+ * silently left out of the refreshed body. This module detects such adjacent
8
+ * files, filters out tool-managed paths (branding, furnace) so the notice
9
+ * names only genuinely unmanaged candidates, and — under
9
10
  * `--refuse-adjacent-unmanaged` — lets the caller turn the notice into a
10
11
  * non-zero refusal.
11
12
  *
12
- * Split out of re-export.ts to keep that file inside the max-lines
13
- * budget; 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.
14
15
  */
15
16
  import { dirname, join } from 'node:path';
16
17
  import { isBrandingManagedPath } from '../core/branding.js';
@@ -2,15 +2,15 @@ import type { PatchesManifest } from '../types/commands/index.js';
2
2
  /** Loads and validates a `re-export --scan-files` assignment manifest. */
3
3
  export declare function loadScanFilesAssignments(manifestPath: string, manifest: PatchesManifest): Promise<Map<string, string[]>>;
4
4
  /**
5
- * Runtime enforcement of the dry-run purity contract: fingerprints
6
- * the engine tree and every patch artifact before and after `operation`, and
7
- * throws when a dry-run changed anything it promised only to inspect. This
8
- * turns any recurrence of the 0.40.0 "dry-run reverted a just-written export"
9
- * incident into a hard, named failure instead of silent data loss discovered
10
- * only when a later gate fails. The post-fingerprint runs whether `operation`
11
- * resolves or rejects — a dry-run that mutates state and THEN fails is exactly
12
- * the case where a rollback defect must not go unreported; a rejection with a
13
- * purity violation surfaces the violation with the original error as `cause`.
5
+ * Runtime enforcement of the dry-run purity contract: fingerprints the engine
6
+ * tree and every patch artifact before and after `operation`, and throws when
7
+ * a dry-run changed anything it promised only to inspect. That turns a
8
+ * "dry-run reverted a just-written export" incident into a hard, named
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
13
+ * violation surfaces the violation with the original error as `cause`.
14
14
  * No-op outside dry-run.
15
15
  */
16
16
  export declare function withDryRunPurityGuard<T>(engineDir: string, patchesDir: string, isDryRun: boolean, operation: () => Promise<T>): Promise<T>;
@@ -75,18 +75,19 @@ export async function loadScanFilesAssignments(manifestPath, manifest) {
75
75
  }
76
76
  /**
77
77
  * Fingerprints every piece of state a `re-export --dry-run` promises not to
78
- * disturb: the engine's commit + working-tree status (via the same generation
79
- * token `fireforge test` uses) and the byte content of every regular file
80
- * under `patches/` — ALL of them, not just the selected patches, because the
81
- * field incident was a dry-run of patch B reverting a just-written
82
- * export of patch A. A missing patches directory (ENOENT/ENOTDIR) fingerprints
83
- * as empty — there is nothing there to protect — but any other listing failure
84
- * (EACCES, EIO, …) throws: an unreadable directory is not evidence it is
85
- * empty, and treating it as such would let the guard silently vouch for state
86
- * it never saw (fail closed). The same rule covers an unmeasurable engine
87
- * generation and an unreadable individual patch file; a before-pass failure
88
- * aborts the dry run before it starts, since a guard that measured nothing
89
- * cannot vouch for anything.
78
+ * disturb: the engine's commit + working-tree status (via the same
79
+ * 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.
83
+ *
84
+ * A missing patches directory (ENOENT/ENOTDIR) fingerprints as empty — there
85
+ * is nothing there to protect — but any other listing failure (EACCES, EIO,
86
+ * …) throws: an unreadable directory is not evidence it is empty, and
87
+ * treating it as such lets the guard silently vouch for state it never saw.
88
+ * 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
90
+ * starts, since a guard that measured nothing cannot vouch for anything.
90
91
  */
91
92
  async function fingerprintDryRunState(engineDir, patchesDir) {
92
93
  const fingerprint = new Map();
@@ -153,15 +154,15 @@ async function fingerprintDryRunState(engineDir, patchesDir) {
153
154
  return fingerprint;
154
155
  }
155
156
  /**
156
- * Runtime enforcement of the dry-run purity contract: fingerprints
157
- * the engine tree and every patch artifact before and after `operation`, and
158
- * throws when a dry-run changed anything it promised only to inspect. This
159
- * turns any recurrence of the 0.40.0 "dry-run reverted a just-written export"
160
- * incident into a hard, named failure instead of silent data loss discovered
161
- * only when a later gate fails. The post-fingerprint runs whether `operation`
162
- * resolves or rejects — a dry-run that mutates state and THEN fails is exactly
163
- * the case where a rollback defect must not go unreported; a rejection with a
164
- * purity violation surfaces the violation with the original error as `cause`.
157
+ * Runtime enforcement of the dry-run purity contract: fingerprints the engine
158
+ * tree and every patch artifact before and after `operation`, and throws when
159
+ * a dry-run changed anything it promised only to inspect. That turns a
160
+ * "dry-run reverted a just-written export" incident into a hard, named
161
+ * 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
165
+ * violation surfaces the violation with the original error as `cause`.
165
166
  * No-op outside dry-run.
166
167
  */
167
168
  export async function withDryRunPurityGuard(engineDir, patchesDir, isDryRun, operation) {