@hominis/fireforge 0.51.0 → 0.53.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 (254) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/build-info.json +4 -4
  3. package/dist/src/commands/bootstrap.js +2 -3
  4. package/dist/src/commands/build-prelock.d.ts +3 -3
  5. package/dist/src/commands/build-prelock.js +3 -3
  6. package/dist/src/commands/build.js +4 -0
  7. package/dist/src/commands/declarations-report.d.ts +9 -3
  8. package/dist/src/commands/declarations-report.js +18 -11
  9. package/dist/src/commands/discard.js +3 -3
  10. package/dist/src/commands/doctor-furnace-config-sync.js +4 -4
  11. package/dist/src/commands/doctor-furnace.js +5 -5
  12. package/dist/src/commands/export-adopt-check.d.ts +5 -6
  13. package/dist/src/commands/export-adopt-check.js +5 -6
  14. package/dist/src/commands/export-flow.js +6 -9
  15. package/dist/src/commands/export-staged-registration.d.ts +4 -4
  16. package/dist/src/commands/export-staged-registration.js +4 -4
  17. package/dist/src/commands/forward-import-remedy.d.ts +2 -3
  18. package/dist/src/commands/forward-import-remedy.js +2 -3
  19. package/dist/src/commands/furnace/create-dry-run.d.ts +2 -2
  20. package/dist/src/commands/furnace/deploy-fragment-includers.d.ts +2 -2
  21. package/dist/src/commands/furnace/deploy-fragment-includers.js +2 -2
  22. package/dist/src/commands/furnace/index.js +2 -2
  23. package/dist/src/commands/lint.js +4 -4
  24. package/dist/src/commands/patch/compact.js +1 -1
  25. package/dist/src/commands/patch/lint-ignore-from.d.ts +3 -4
  26. package/dist/src/commands/patch/lint-ignore-from.js +3 -4
  27. package/dist/src/commands/patch/move-files-adopt.d.ts +33 -0
  28. package/dist/src/commands/patch/move-files-adopt.js +65 -0
  29. package/dist/src/commands/patch/move-files-create.js +41 -20
  30. package/dist/src/commands/patch/move-files-into.d.ts +18 -0
  31. package/dist/src/commands/patch/move-files-into.js +125 -60
  32. package/dist/src/commands/patch/move-files-retire.d.ts +39 -0
  33. package/dist/src/commands/patch/move-files-retire.js +91 -0
  34. package/dist/src/commands/patch/move-files.d.ts +3 -0
  35. package/dist/src/commands/patch/move-files.js +42 -12
  36. package/dist/src/commands/patch/move-size-tier.d.ts +27 -0
  37. package/dist/src/commands/patch/move-size-tier.js +66 -0
  38. package/dist/src/commands/patch/rename.js +1 -1
  39. package/dist/src/commands/patch/reorder-projection.d.ts +17 -0
  40. package/dist/src/commands/patch/reorder-projection.js +49 -0
  41. package/dist/src/commands/patch/reorder-shift.d.ts +30 -0
  42. package/dist/src/commands/patch/reorder-shift.js +307 -0
  43. package/dist/src/commands/patch/reorder.d.ts +9 -15
  44. package/dist/src/commands/patch/reorder.js +52 -50
  45. package/dist/src/commands/patch/split-plan.d.ts +31 -3
  46. package/dist/src/commands/patch/split-plan.js +36 -12
  47. package/dist/src/commands/patch/split-staged.d.ts +2 -2
  48. package/dist/src/commands/patch/split-staged.js +2 -2
  49. package/dist/src/commands/patch/split.js +18 -5
  50. package/dist/src/commands/patch/staged-dependency-entries.d.ts +9 -1
  51. package/dist/src/commands/patch/staged-dependency-entries.js +32 -4
  52. package/dist/src/commands/patch/staged-dependency-from.js +15 -9
  53. package/dist/src/commands/patch/staged-dependency.js +13 -9
  54. package/dist/src/commands/patch/tier.js +2 -2
  55. package/dist/src/commands/patch-rename-map.d.ts +14 -3
  56. package/dist/src/commands/patch-rename-map.js +21 -3
  57. package/dist/src/commands/re-export-adjacent.d.ts +4 -5
  58. package/dist/src/commands/re-export-lint.d.ts +4 -3
  59. package/dist/src/commands/re-export-lint.js +4 -3
  60. package/dist/src/commands/re-export-preflight.js +1 -2
  61. package/dist/src/commands/re-export-purity-scope.d.ts +1 -1
  62. package/dist/src/commands/re-export-purity-scope.js +13 -7
  63. package/dist/src/commands/re-export-retired-declarations.d.ts +22 -0
  64. package/dist/src/commands/re-export-retired-declarations.js +113 -0
  65. package/dist/src/commands/re-export-single.js +2 -2
  66. package/dist/src/commands/re-export-stale-registrations.d.ts +27 -6
  67. package/dist/src/commands/re-export-stale-registrations.js +65 -21
  68. package/dist/src/commands/re-export.js +4 -0
  69. package/dist/src/commands/rebase/continue.js +3 -3
  70. package/dist/src/commands/register.js +5 -4
  71. package/dist/src/commands/status-output.js +5 -1
  72. package/dist/src/commands/status.js +1 -1
  73. package/dist/src/commands/test-build-furnace.d.ts +1 -2
  74. package/dist/src/commands/test-build-furnace.js +1 -2
  75. package/dist/src/commands/test-build-phase.d.ts +10 -0
  76. package/dist/src/commands/test-build-phase.js +51 -16
  77. package/dist/src/commands/test-control-restore.d.ts +40 -0
  78. package/dist/src/commands/test-control-restore.js +86 -0
  79. package/dist/src/commands/test-dispatch.js +83 -13
  80. package/dist/src/commands/test-multi-verdict.js +1 -0
  81. package/dist/src/commands/test-orchestrate.d.ts +11 -0
  82. package/dist/src/commands/test-orchestrate.js +33 -2
  83. package/dist/src/commands/test-perf-scope.d.ts +1 -1
  84. package/dist/src/commands/test-perf-scope.js +1 -1
  85. package/dist/src/commands/test-prelock.d.ts +7 -8
  86. package/dist/src/commands/test-prelock.js +15 -12
  87. package/dist/src/commands/test-register.js +2 -2
  88. package/dist/src/commands/test-results.d.ts +10 -1
  89. package/dist/src/commands/test-results.js +20 -3
  90. package/dist/src/commands/test-run.d.ts +6 -0
  91. package/dist/src/commands/test-run.js +23 -4
  92. package/dist/src/commands/test-shards.d.ts +7 -3
  93. package/dist/src/commands/test-shards.js +24 -7
  94. package/dist/src/commands/test-stale-gate.d.ts +6 -1
  95. package/dist/src/commands/test-stale-gate.js +47 -2
  96. package/dist/src/commands/test-verdict.d.ts +5 -3
  97. package/dist/src/commands/test.js +14 -1
  98. package/dist/src/commands/token.js +2 -2
  99. package/dist/src/commands/verify.js +1 -1
  100. package/dist/src/commands/watch.js +1 -1
  101. package/dist/src/commands/wire.js +1 -1
  102. package/dist/src/core/build-audit-resolve.d.ts +4 -5
  103. package/dist/src/core/build-audit-resolve.js +4 -5
  104. package/dist/src/core/build-audit-skip.d.ts +2 -2
  105. package/dist/src/core/build-audit.d.ts +3 -4
  106. package/dist/src/core/build-baseline-types.d.ts +37 -3
  107. package/dist/src/core/build-baseline-validate.d.ts +30 -1
  108. package/dist/src/core/build-baseline-validate.js +134 -33
  109. package/dist/src/core/build-baseline.d.ts +8 -2
  110. package/dist/src/core/build-baseline.js +32 -16
  111. package/dist/src/core/build-jar-escalation.d.ts +4 -4
  112. package/dist/src/core/build-jar-escalation.js +4 -4
  113. package/dist/src/core/build-prepare.js +4 -4
  114. package/dist/src/core/config-validate.js +4 -4
  115. package/dist/src/core/coverage-extend.d.ts +5 -3
  116. package/dist/src/core/coverage-extend.js +8 -3
  117. package/dist/src/core/coverage-records.d.ts +4 -5
  118. package/dist/src/core/coverage-records.js +4 -5
  119. package/dist/src/core/destructive.d.ts +2 -2
  120. package/dist/src/core/destructive.js +2 -2
  121. package/dist/src/core/discard-baseline.d.ts +2 -2
  122. package/dist/src/core/discard-baseline.js +3 -3
  123. package/dist/src/core/engine-session-lock.d.ts +1 -1
  124. package/dist/src/core/engine-session-lock.js +1 -1
  125. package/dist/src/core/file-lock-owner.d.ts +5 -5
  126. package/dist/src/core/file-lock-owner.js +5 -5
  127. package/dist/src/core/file-lock-queue.js +6 -8
  128. package/dist/src/core/file-lock-shared.d.ts +4 -4
  129. package/dist/src/core/file-lock-shared.js +4 -4
  130. package/dist/src/core/file-lock.js +7 -10
  131. package/dist/src/core/firefox.js +2 -2
  132. package/dist/src/core/furnace-apply-overwrite-warn.d.ts +1 -1
  133. package/dist/src/core/furnace-apply-overwrite-warn.js +1 -1
  134. package/dist/src/core/furnace-apply.js +3 -3
  135. package/dist/src/core/furnace-config-validate-exceptions.d.ts +4 -3
  136. package/dist/src/core/furnace-config-validate-exceptions.js +26 -6
  137. package/dist/src/core/furnace-operation.js +5 -5
  138. package/dist/src/core/furnace-registration-jar-inplace.js +5 -6
  139. package/dist/src/core/furnace-registration-rename.d.ts +5 -5
  140. package/dist/src/core/furnace-registration-rename.js +5 -5
  141. package/dist/src/core/furnace-registration-validate.d.ts +2 -1
  142. package/dist/src/core/furnace-registration-validate.js +2 -1
  143. package/dist/src/core/furnace-registration.js +2 -2
  144. package/dist/src/core/furnace-validate-accessibility.d.ts +1 -1
  145. package/dist/src/core/furnace-validate-accessibility.js +22 -11
  146. package/dist/src/core/furnace-validate-exceptions.d.ts +2 -1
  147. package/dist/src/core/furnace-validate-exceptions.js +31 -13
  148. package/dist/src/core/git-base.js +4 -3
  149. package/dist/src/core/git-diff.js +1 -1
  150. package/dist/src/core/git.js +1 -1
  151. package/dist/src/core/harness-orphans.d.ts +6 -6
  152. package/dist/src/core/harness-orphans.js +6 -6
  153. package/dist/src/core/harness-port-reservation.d.ts +60 -0
  154. package/dist/src/core/harness-port-reservation.js +122 -0
  155. package/dist/src/core/history-log-file.d.ts +9 -9
  156. package/dist/src/core/history-log-file.js +15 -15
  157. package/dist/src/core/history-log.d.ts +3 -3
  158. package/dist/src/core/history-log.js +3 -3
  159. package/dist/src/core/launchable-build.d.ts +39 -0
  160. package/dist/src/core/launchable-build.js +85 -0
  161. package/dist/src/core/marionette-port.js +1 -3
  162. package/dist/src/core/moz-manifest-rules.js +3 -2
  163. package/dist/src/core/negative-control-compiled.d.ts +22 -3
  164. package/dist/src/core/negative-control-compiled.js +41 -5
  165. package/dist/src/core/parser-fallback.d.ts +5 -5
  166. package/dist/src/core/parser-fallback.js +5 -5
  167. package/dist/src/core/patch-identifier-suggest.d.ts +6 -0
  168. package/dist/src/core/patch-identifier-suggest.js +11 -4
  169. package/dist/src/core/patch-lint-checkjs.d.ts +1 -1
  170. package/dist/src/core/patch-lint-checkjs.js +1 -1
  171. package/dist/src/core/patch-lint-css.js +2 -2
  172. package/dist/src/core/patch-lint-file-size.d.ts +5 -7
  173. package/dist/src/core/patch-lint-file-size.js +5 -7
  174. package/dist/src/core/patch-lint-ignore.d.ts +3 -3
  175. package/dist/src/core/patch-lint-ignore.js +3 -3
  176. package/dist/src/core/patch-lint-prettier.d.ts +4 -6
  177. package/dist/src/core/patch-lint-prettier.js +4 -6
  178. package/dist/src/core/patch-lint-projection.d.ts +1 -1
  179. package/dist/src/core/patch-lint-projection.js +1 -1
  180. package/dist/src/core/patch-lint-queue-types.d.ts +2 -2
  181. package/dist/src/core/patch-lint-queue-types.js +2 -2
  182. package/dist/src/core/patch-manifest-consistency.d.ts +2 -2
  183. package/dist/src/core/patch-manifest-consistency.js +2 -2
  184. package/dist/src/core/patch-manifest-io.d.ts +5 -1
  185. package/dist/src/core/patch-manifest-io.js +12 -10
  186. package/dist/src/core/patch-manifest-key-order.d.ts +3 -4
  187. package/dist/src/core/patch-manifest-key-order.js +3 -4
  188. package/dist/src/core/patch-parse.d.ts +3 -3
  189. package/dist/src/core/patch-parse.js +3 -3
  190. package/dist/src/core/patch-policy.d.ts +1 -1
  191. package/dist/src/core/patch-policy.js +1 -1
  192. package/dist/src/core/patch-source-metadata.d.ts +1 -1
  193. package/dist/src/core/patch-source-metadata.js +1 -1
  194. package/dist/src/core/patch-subset.d.ts +5 -3
  195. package/dist/src/core/patch-subset.js +8 -7
  196. package/dist/src/core/patch-transform.d.ts +2 -2
  197. package/dist/src/core/patch-transform.js +2 -2
  198. package/dist/src/core/rebase-session.js +4 -6
  199. package/dist/src/core/register-xpcshell-test.d.ts +28 -7
  200. package/dist/src/core/register-xpcshell-test.js +76 -27
  201. package/dist/src/core/run-log.d.ts +8 -8
  202. package/dist/src/core/run-log.js +8 -8
  203. package/dist/src/core/status-classify.d.ts +1 -2
  204. package/dist/src/core/status-classify.js +1 -2
  205. package/dist/src/core/test-harness-crash.d.ts +5 -3
  206. package/dist/src/core/test-harness-crash.js +13 -14
  207. package/dist/src/core/test-harness-infra.d.ts +32 -0
  208. package/dist/src/core/test-harness-infra.js +69 -0
  209. package/dist/src/core/test-harness-signature.d.ts +6 -0
  210. package/dist/src/core/test-run-completeness.d.ts +12 -5
  211. package/dist/src/core/test-run-completeness.js +15 -8
  212. package/dist/src/core/test-stale-check.d.ts +48 -1
  213. package/dist/src/core/test-stale-check.js +97 -2
  214. package/dist/src/core/test-stall-triage.js +5 -7
  215. package/dist/src/core/token-category.js +2 -2
  216. package/dist/src/core/token-inventory.js +3 -3
  217. package/dist/src/core/token-manager.d.ts +2 -2
  218. package/dist/src/core/token-manager.js +5 -7
  219. package/dist/src/core/token-variant.d.ts +6 -6
  220. package/dist/src/core/token-variant.js +7 -7
  221. package/dist/src/core/typecheck-shim.d.ts +2 -1
  222. package/dist/src/core/typecheck-shim.js +29 -5
  223. package/dist/src/core/wire-destroy.d.ts +1 -1
  224. package/dist/src/core/wire-destroy.js +1 -1
  225. package/dist/src/core/wire-dom-fragment.js +1 -1
  226. package/dist/src/core/wire-init.d.ts +1 -1
  227. package/dist/src/core/wire-init.js +1 -1
  228. package/dist/src/core/wire-subscript.d.ts +1 -1
  229. package/dist/src/core/wire-subscript.js +1 -1
  230. package/dist/src/core/wire-utils.d.ts +2 -2
  231. package/dist/src/core/wire-utils.js +3 -3
  232. package/dist/src/errors/base.d.ts +1 -1
  233. package/dist/src/errors/base.js +1 -1
  234. package/dist/src/errors/rebase.d.ts +1 -1
  235. package/dist/src/errors/rebase.js +1 -1
  236. package/dist/src/types/commands/options.d.ts +26 -3
  237. package/dist/src/types/config.d.ts +5 -7
  238. package/dist/src/types/furnace.d.ts +9 -0
  239. package/dist/src/utils/options.js +2 -2
  240. package/dist/src/utils/process.js +2 -2
  241. package/dist/src/utils/regex.d.ts +2 -2
  242. package/dist/src/utils/regex.js +3 -3
  243. package/dist/src/utils/sleep.d.ts +5 -6
  244. package/dist/src/utils/sleep.js +5 -6
  245. package/dist/src/utils/validation.js +2 -2
  246. package/docs/configuration.md +40 -26
  247. package/docs/exit-codes.md +8 -11
  248. package/docs/furnace.md +21 -3
  249. package/docs/lifecycle-invariants.md +36 -45
  250. package/docs/machine-output.md +43 -22
  251. package/docs/patch-workflow.md +129 -24
  252. package/docs/run-logs.md +8 -9
  253. package/docs/testing.md +118 -44
  254. package/package.json +1 -1
@@ -17,7 +17,7 @@ import { findVariantBlockDeclaration, insertVariantDeclaration, validateVariantS
17
17
  *
18
18
  * Derived from {@link TOKEN_MODES} so the runtime allowlist and the type
19
19
  * cannot drift: adding a member here without updating the list (or the
20
- * reverse) is no longer possible, because there is only one list.
20
+ * reverse) is impossible, because there is only one list.
21
21
  */
22
22
  export const TOKEN_MODES = ['auto', 'static', 'override'];
23
23
  /** Narrows an arbitrary string to a {@link TokenMode}. */
@@ -109,12 +109,10 @@ function normalizeVariantOption(options) {
109
109
  * Narrows {@link AddTokenOptions.category} for the base-declaration path,
110
110
  * which cannot proceed without one.
111
111
  *
112
- * `--category` used to be unconditionally required, including under
113
- * `--variant`, where the declaration is routed into a `:root<selector>`
114
- * block and the category names nothing about where the token lands. The
115
- * requirement existed so the argument would not be silently discarded,
116
- * a fair goal that produced a mandatory argument describing nothing. Under
117
- * a variant it is now optional. Everywhere else this states the reason
112
+ * `--category` is optional under `--variant`, where the declaration is
113
+ * routed into a `:root<selector>` block and the category names nothing
114
+ * about where the token lands, so requiring it there would make a
115
+ * mandatory argument describing nothing. Everywhere else this states the reason
118
116
  * rather than leaving commander to print a bare "required option not
119
117
  * specified".
120
118
  *
@@ -28,12 +28,12 @@ export type VariantValidation = {
28
28
  * Boolean-attribute fragments are returned unchanged.
29
29
  *
30
30
  * Structure is decided by {@link rootAttributeSelector}, the matcher's own
31
- * parse, rather than by a second regex. 0.44.2 widened
32
- * the matcher to consume consecutive `[…]` groups and stop at a pseudo-class
33
- * tail, and the validator did not move with it, so
34
- * `:root[data-skin="humanist"]:not([data-private])` was a block the tool
35
- * could find but would not let you name. Running both halves off one parse
36
- * is what stops them drifting apart again. Character-level safety stays a
31
+ * parse, rather than by a second regex. The matcher consumes consecutive
32
+ * `[…]` groups and stops at a pseudo-class tail, and a separate validator
33
+ * that does not follow it leaves blocks such as
34
+ * `:root[data-skin="humanist"]:not([data-private])` findable but
35
+ * unnameable. Running both halves off one parse keeps them from drifting
36
+ * apart. Character-level safety stays a
37
37
  * separate, per-group check, because the matcher finds bracket boundaries
38
38
  * and validates no characters at all.
39
39
  *
@@ -68,12 +68,12 @@ function normalizeAttributeFragment(group) {
68
68
  * Boolean-attribute fragments are returned unchanged.
69
69
  *
70
70
  * Structure is decided by {@link rootAttributeSelector}, the matcher's own
71
- * parse, rather than by a second regex. 0.44.2 widened
72
- * the matcher to consume consecutive `[…]` groups and stop at a pseudo-class
73
- * tail, and the validator did not move with it, so
74
- * `:root[data-skin="humanist"]:not([data-private])` was a block the tool
75
- * could find but would not let you name. Running both halves off one parse
76
- * is what stops them drifting apart again. Character-level safety stays a
71
+ * parse, rather than by a second regex. The matcher consumes consecutive
72
+ * `[…]` groups and stops at a pseudo-class tail, and a separate validator
73
+ * that does not follow it leaves blocks such as
74
+ * `:root[data-skin="humanist"]:not([data-private])` findable but
75
+ * unnameable. Running both halves off one parse keeps them from drifting
76
+ * apart. Character-level safety stays a
77
77
  * separate, per-group check, because the matcher finds bracket boundaries
78
78
  * and validates no characters at all.
79
79
  *
@@ -194,7 +194,7 @@ function findVariantBlock(lines, variant) {
194
194
  if (selector === undefined || canonicalSelector(selector.attributes) !== want)
195
195
  continue;
196
196
  // An unqualified request still matches a qualified block: that is the
197
- // 0.44.2 behaviour `variantBlockQualifier` exists to report, since
197
+ // behaviour `variantBlockQualifier` exists to report, since
198
198
  // silently skipping the block is the worse failure. A request that names
199
199
  // a qualifier, though, means it, so it must match.
200
200
  if (wantQualifier !== '' && canonicalSelector(selector.qualifier) !== wantQualifier)
@@ -82,7 +82,8 @@ export interface ComposedShim {
82
82
  * shim path
83
83
  * @param extraShimPath - Optional project-relative path to an extra `.d.ts`
84
84
  * @param options - `litTypes` appends {@link LIT_TYPES_SHIM} after the
85
- * built-in shim (before the extra shim, which can still merge into it)
85
+ * built-in shim (before the extra shim, which can still merge into it),
86
+ * and {@link LOOSE_LIT_SHIM} otherwise
86
87
  */
87
88
  export declare function composeShimSource(projectRoot: string, extraShimPath: string | undefined, options?: {
88
89
  litTypes?: boolean | undefined;
@@ -291,12 +291,17 @@ export const UNDEFINED_IDENTIFIER_CODES = new Set([
291
291
  ]);
292
292
  /**
293
293
  * Typed Lit, opt-in through `typecheck.litTypes`. Declares the two chrome
294
- * modules widgets import Lit from, so they no longer fall to the
294
+ * modules widgets import Lit from, so they do not fall to the
295
295
  * `chrome:*` wildcard as `any`: `LitElement` (with `ReactiveElement`'s
296
296
  * lifecycle) and `MozLitElement` carry closed member lists, so a misspelt
297
297
  * member of a widget host is TS2339, as `Cu` is in the built-in shim.
298
- * Template helpers and directives stay loose. A project shim can merge
299
- * members into `LitElementShimMembers`; a project whose jsconfig `paths`
298
+ * Template helpers and directives stay loose. The global
299
+ * `MozLitElementWith<Extra>` types a widget's query getters and
300
+ * `static properties` members: the widget casts its `MozLitElement` import
301
+ * to it before extending ({@link LOOSE_LIT_SHIM} keeps it `any` without
302
+ * typed Lit). A project
303
+ * shim can merge members into `LitElementShimMembers`; a project whose
304
+ * jsconfig `paths`
300
305
  * maps these URLs to the real sources gets those instead, since a resolved
301
306
  * file wins over an ambient module.
302
307
  */
@@ -399,6 +404,24 @@ declare module 'chrome://global/content/lit-utils.mjs' {
399
404
  export const SelectControlBaseElement: any;
400
405
  export const SelectControlItemMixin: any;
401
406
  }
407
+ // MozLitElement with instance members Extra: what a widget casts its base
408
+ // to for the getters static queries installs (and properties it declares
409
+ // only in static properties). A class field would redefine a query getter
410
+ // and throw, and a constructor declaration reads it before renderRoot.
411
+ type MozLitElementWith<Extra> = Pick<
412
+ typeof import('chrome://global/content/lit-utils.mjs').MozLitElement,
413
+ keyof typeof import('chrome://global/content/lit-utils.mjs').MozLitElement
414
+ > &
415
+ (new () => import('chrome://global/content/lit-utils.mjs').MozLitElement & Extra);
416
+ `;
417
+ /**
418
+ * Without typed Lit, `MozLitElementWith<Extra>` is `any`, as the base it
419
+ * casts is: the same widget source checks under per-patch checkJs and a
420
+ * project typecheck that leaves `litTypes` off.
421
+ */
422
+ const LOOSE_LIT_SHIM = `
423
+ // FireForge loose Lit (typecheck.litTypes off): see typecheck-shim.ts.
424
+ type MozLitElementWith<Extra> = any;
402
425
  `;
403
426
  /** Hint appended to reported undefined-identifier diagnostics. */
404
427
  export const UNDEFINED_IDENTIFIER_HINT = '(undefined identifier — import or declare it, add the global to the extra shim, ' +
@@ -462,10 +485,11 @@ async function inlineTripleSlashReferences(source, baseDir, seen) {
462
485
  * shim path
463
486
  * @param extraShimPath - Optional project-relative path to an extra `.d.ts`
464
487
  * @param options - `litTypes` appends {@link LIT_TYPES_SHIM} after the
465
- * built-in shim (before the extra shim, which can still merge into it)
488
+ * built-in shim (before the extra shim, which can still merge into it),
489
+ * and {@link LOOSE_LIT_SHIM} otherwise
466
490
  */
467
491
  export async function composeShimSource(projectRoot, extraShimPath, options = {}) {
468
- const base = options.litTypes === true ? `${FIREFOX_GLOBALS_SHIM}\n${LIT_TYPES_SHIM}` : FIREFOX_GLOBALS_SHIM;
492
+ const base = `${FIREFOX_GLOBALS_SHIM}\n${options.litTypes === true ? LIT_TYPES_SHIM : LOOSE_LIT_SHIM}`;
469
493
  if (!extraShimPath) {
470
494
  return { source: base, extraShimAppended: false };
471
495
  }
@@ -11,7 +11,7 @@
11
11
  */
12
12
  export declare function addDestroyAST(content: string, expression: string, marker?: string): string;
13
13
  /**
14
- * Legacy regex/line-based implementation preserved as fallback.
14
+ * Regex/line-based fallback implementation.
15
15
  */
16
16
  export declare function legacyAddDestroy(content: string, expression: string, marker?: string): string;
17
17
  /**
@@ -65,7 +65,7 @@ export function addDestroyAST(content, expression, marker = DEFAULT_MARKER) {
65
65
  return ms.toString();
66
66
  }
67
67
  /**
68
- * Legacy regex/line-based implementation preserved as fallback.
68
+ * Regex/line-based fallback implementation.
69
69
  */
70
70
  export function legacyAddDestroy(content, expression, marker = DEFAULT_MARKER) {
71
71
  const name = extractNameFromExpression(expression);
@@ -66,7 +66,7 @@ export async function probeDomFragmentInsertionPoint(engineDir, domFilePath, tar
66
66
  // dry-run is allowed to proceed too.
67
67
  return;
68
68
  }
69
- // Check the tokenised and legacy insertion paths symmetrically with
69
+ // Check the tokenised and line-based insertion paths symmetrically with
70
70
  // the real run. Either helper returning without throwing is sufficient
71
71
  // evidence that the real run can land the directive.
72
72
  addDomFragmentTokenized(content, includeDirective);
@@ -13,7 +13,7 @@
13
13
  */
14
14
  export declare function addInitAST(content: string, expression: string, after?: string, marker?: string): string;
15
15
  /**
16
- * Legacy regex/line-based implementation preserved as fallback.
16
+ * Regex/line-based fallback implementation.
17
17
  */
18
18
  export declare function legacyAddInit(content: string, expression: string, after?: string, marker?: string): string;
19
19
  /**
@@ -112,7 +112,7 @@ export function addInitAST(content, expression, after, marker = DEFAULT_MARKER)
112
112
  return ms.toString();
113
113
  }
114
114
  /**
115
- * Legacy regex/line-based implementation preserved as fallback.
115
+ * Regex/line-based fallback implementation.
116
116
  */
117
117
  export function legacyAddInit(content, expression, after, marker = DEFAULT_MARKER) {
118
118
  const name = extractNameFromExpression(expression);
@@ -10,7 +10,7 @@
10
10
  */
11
11
  export declare function addSubscriptAST(content: string, name: string, marker?: string): string;
12
12
  /**
13
- * Legacy regex/line-based implementation preserved as fallback.
13
+ * Regex/line-based fallback implementation.
14
14
  */
15
15
  export declare function legacyAddSubscript(content: string, name: string, marker?: string): string;
16
16
  /**
@@ -73,7 +73,7 @@ export function addSubscriptAST(content, name, marker = DEFAULT_MARKER) {
73
73
  return ms.toString();
74
74
  }
75
75
  /**
76
- * Legacy regex/line-based implementation preserved as fallback.
76
+ * Regex/line-based fallback implementation.
77
77
  */
78
78
  export function legacyAddSubscript(content, name, marker = DEFAULT_MARKER) {
79
79
  const lines = content.split('\n');
@@ -104,7 +104,7 @@ export declare function walkToTryBlockEnd(lines: string[], startLine: number, op
104
104
  }): number;
105
105
  /**
106
106
  * Scans the entire file and returns the net brace balance so callers can
107
- * assert that a legacy fallback mutation did not silently introduce or
107
+ * assert that a line-based fallback mutation did not silently introduce or
108
108
  * drop a `{` / `}`. The helper reuses {@link countBraceDepth} so strings,
109
109
  * comments, and regex literals are handled consistently with the walker.
110
110
  *
@@ -117,7 +117,7 @@ export declare function computeFileBraceBalance(content: string): {
117
117
  balanced: boolean;
118
118
  };
119
119
  /**
120
- * Round-trip guard used after a legacy fallback mutation: if the file's
120
+ * Round-trip guard used after a line-based fallback mutation: if the file's
121
121
  * net brace balance drifts between `before` and `after`, something went
122
122
  * wrong and the fallback is refusing to write a corrupted file. Expects
123
123
  * the delta to be exactly zero, since wire fallbacks only insert whole
@@ -159,7 +159,7 @@ export function tokenizeXhtml(lines) {
159
159
  });
160
160
  }
161
161
  // ---------------------------------------------------------------------------
162
- // Legacy (line-based) helpers, shared by fallback implementations in
162
+ // Line-based helpers, shared by fallback implementations in
163
163
  // the wire target modules. Extracted to reduce duplication and make the brace-
164
164
  // walking logic independently testable.
165
165
  // ---------------------------------------------------------------------------
@@ -224,7 +224,7 @@ export function walkToTryBlockEnd(lines, startLine, options) {
224
224
  }
225
225
  /**
226
226
  * Scans the entire file and returns the net brace balance so callers can
227
- * assert that a legacy fallback mutation did not silently introduce or
227
+ * assert that a line-based fallback mutation did not silently introduce or
228
228
  * drop a `{` / `}`. The helper reuses {@link countBraceDepth} so strings,
229
229
  * comments, and regex literals are handled consistently with the walker.
230
230
  *
@@ -244,7 +244,7 @@ export function computeFileBraceBalance(content) {
244
244
  return { depth, balanced: depth === 0 };
245
245
  }
246
246
  /**
247
- * Round-trip guard used after a legacy fallback mutation: if the file's
247
+ * Round-trip guard used after a line-based fallback mutation: if the file's
248
248
  * net brace balance drifts between `before` and `after`, something went
249
249
  * wrong and the fallback is refusing to write a corrupted file. Expects
250
250
  * the delta to be exactly zero, since wire fallbacks only insert whole
@@ -80,7 +80,7 @@ export declare class InternalInvariantError extends FireForgeError {
80
80
  get userMessage(): string;
81
81
  }
82
82
  /**
83
- * Raised when a legacy regex/brace-depth fallback parser decides it
83
+ * Raised when a regex/brace-depth fallback parser decides it
84
84
  * cannot safely perform its mutation, e.g. because a block it expected
85
85
  * to walk never closes, because the inserted result fails a round-trip
86
86
  * brace balance check, or because an expected pattern is missing.
@@ -106,7 +106,7 @@ export class InternalInvariantError extends FireForgeError {
106
106
  }
107
107
  }
108
108
  /**
109
- * Raised when a legacy regex/brace-depth fallback parser decides it
109
+ * Raised when a regex/brace-depth fallback parser decides it
110
110
  * cannot safely perform its mutation, e.g. because a block it expected
111
111
  * to walk never closes, because the inserted result fails a round-trip
112
112
  * brace balance check, or because an expected pattern is missing.
@@ -33,7 +33,7 @@ export declare class CorruptRebaseSessionError extends RebaseError {
33
33
  }
34
34
  /**
35
35
  * Thrown by `rebase --dry-run` when the replay rejects at least one patch.
36
- * A dry run that exited 0 regardless used to read as "the rebase is ready".
36
+ * A dry run that exited 0 regardless would read as "the rebase is ready".
37
37
  */
38
38
  export declare class RebaseDryRunRejectError extends RebaseError {
39
39
  readonly rejected: readonly string[];
@@ -51,7 +51,7 @@ export class CorruptRebaseSessionError extends RebaseError {
51
51
  }
52
52
  /**
53
53
  * Thrown by `rebase --dry-run` when the replay rejects at least one patch.
54
- * A dry run that exited 0 regardless used to read as "the rebase is ready".
54
+ * A dry run that exited 0 regardless would read as "the rebase is ready".
55
55
  */
56
56
  export class RebaseDryRunRejectError extends RebaseError {
57
57
  rejected;
@@ -516,6 +516,8 @@ export interface PatchSplitOptions extends Confirmable, PatchLockWaitable, Unsaf
516
516
  skipLint?: boolean;
517
517
  /** Where a refusal writes its one `--from`-ready declaration report. */
518
518
  declarationsOut?: string;
519
+ /** Write the committed old-to-new filename map of renumbered patches here as JSON. */
520
+ mapOut?: string;
519
521
  }
520
522
  /**
521
523
  * Options for the `fireforge patch move-files` subcommand. Without
@@ -541,6 +543,16 @@ export interface PatchMoveFilesOptions extends Confirmable, PatchLockWaitable, U
541
543
  skipLint?: boolean;
542
544
  /** Where a refusal writes its one `--from`-ready declaration report. */
543
545
  declarationsOut?: string;
546
+ /**
547
+ * New engine files no patch owns, adopted into the destination in the
548
+ * same transaction (engine-relative, repeatable).
549
+ */
550
+ scanFile?: string[];
551
+ /**
552
+ * Allow the move to empty the source: re-point the declarations it owns
553
+ * to the destination and retire its slot. Not valid with `create`.
554
+ */
555
+ retireEmpty?: boolean;
544
556
  }
545
557
  /**
546
558
  * Options for the rebase command.
@@ -673,8 +685,8 @@ export interface TestOptions extends EngineLockWaitable {
673
685
  * build would overwrite engine content recorded in neither a patch body
674
686
  * nor the pristine baseline. Same meaning as `fireforge build`'s flag of
675
687
  * the same name. A scripted `test --build` is exactly the shape the
676
- * multi-session hazard shows up in, and until now it was the one shape
677
- * that could not arm the refusal. Valid only with `--build`/`--build-only`.
688
+ * multi-session hazard shows up in, so it must be able to arm the
689
+ * refusal too. Valid only with `--build`/`--build-only`.
678
690
  */
679
691
  refuseUnexportedDrift?: boolean;
680
692
  /**
@@ -1073,7 +1085,7 @@ export interface PatchRenameOptions extends Confirmable, DryRunnable, PatchLockW
1073
1085
  /**
1074
1086
  * New category (validated against configured categories). Rewrites
1075
1087
  * the filename prefix and the manifest row in one transaction, so
1076
- * recategorising no longer requires `patch delete` + fresh export.
1088
+ * recategorising does not require `patch delete` + fresh export.
1077
1089
  */
1078
1090
  category?: string;
1079
1091
  /**
@@ -1096,6 +1108,17 @@ export interface PatchReorderOptions extends PatchLockWaitable {
1096
1108
  to?: number;
1097
1109
  before?: string;
1098
1110
  after?: string;
1111
+ /**
1112
+ * Shift a run of patches up by this many orders (`--shift <n> --from
1113
+ * <order> [--through <order>]`) instead of moving one patch.
1114
+ */
1115
+ shift?: number;
1116
+ /** First order of the run `shift` moves. */
1117
+ from?: number;
1118
+ /** Last order of the run `shift` moves (default: the end of the run). */
1119
+ through?: number;
1120
+ /** Write the committed old-to-new filename map here as JSON. */
1121
+ mapOut?: string;
1099
1122
  yes?: boolean;
1100
1123
  dryRun?: boolean;
1101
1124
  forceUnsafe?: boolean;
@@ -433,11 +433,10 @@ export interface PatchLintFileSizeTier {
433
433
  /**
434
434
  * Overrides for the `file-too-large` thresholds, per file class.
435
435
  *
436
- * These were module constants until 0.45.0, and nothing in `fireforge.json`
437
- * could move them. That is a problem specifically because the recommended
438
- * gate posture is `--max-warnings 0`: under it the `warning` band is not a
439
- * soft limit at all, so a project whose controllers legitimately sit a few
440
- * lines over 750 has a hard failure with no dial, at exactly the moment
436
+ * Configurable because the recommended gate posture is `--max-warnings 0`:
437
+ * under it the `warning` band is not a soft limit at all, so with fixed
438
+ * thresholds a project whose controllers legitimately sit a few lines over
439
+ * 750 would have a hard failure with no dial, at exactly the moment
441
440
  * someone is deciding whether to restructure a file.
442
441
  */
443
442
  export interface PatchLintFileSizeThresholds {
@@ -466,8 +465,7 @@ export interface PatchLintPatchSizeTier {
466
465
  /**
467
466
  * Overrides for the patch-size thresholds, per tier.
468
467
  *
469
- * Module constants until 0.50.0. The defaults are the old constants: lines
470
- * general 800/1500/3000, test 1500/3000/6000, branding 8000/18000/30000;
468
+ * Defaults: lines general 800/1500/3000, test 1500/3000/6000, branding 8000/18000/30000;
471
469
  * files warn above 5 (general, test) or 60 (branding). The files triple has
472
470
  * no notice or error band by default: an unset `files.notice` follows the
473
471
  * effective `files.warning`, and an unset `files.error` never fires.
@@ -115,6 +115,13 @@ export interface FurnaceValidationException {
115
115
  * check for every other element of the component.
116
116
  */
117
117
  tag?: string;
118
+ /**
119
+ * Narrows the exception to the findings in this module file of the
120
+ * component (a finding's `files`), by file name: a vendored bundle whose
121
+ * bytes are pinned can be accepted without muting the check for the
122
+ * authored modules beside it.
123
+ */
124
+ file?: string;
118
125
  /** Why the finding is accepted. Required: the entry is the review record. */
119
126
  reason: string;
120
127
  }
@@ -379,6 +386,8 @@ export interface ValidationIssue {
379
386
  message: string;
380
387
  /** Element tags the finding is about, when it is about particular elements. */
381
388
  tags?: string[];
389
+ /** Component module files the finding is in (`hardcoded-text`), by file name. */
390
+ files?: string[];
382
391
  }
383
392
  /** Resolved test-harness selection for a `furnace create` run. */
384
393
  export type ResolvedTestStyle = 'mochikit' | 'browser-chrome' | 'xpcshell' | 'none';
@@ -71,8 +71,8 @@ export const WAIT_LOCK_ENV_VAR = 'FIREFORGE_WAIT_LOCK';
71
71
  /**
72
72
  * Bounds shared by the flag and the environment variable. The ceiling is a
73
73
  * day: on a shared engine a re-export or `test --build` queued behind a
74
- * peer's long series can need more than the hour the cap used to be, and a
75
- * longer wait then had to be a requeue after exit 15.
74
+ * peer's long series can need more than an hour, and a cap below that turns
75
+ * a longer wait into a requeue after exit 15.
76
76
  */
77
77
  const MIN_WAIT_LOCK_SECONDS = 1;
78
78
  export const MAX_WAIT_LOCK_SECONDS = 86_400;
@@ -173,7 +173,7 @@ async function spawnTracked(spec) {
173
173
  let rejection;
174
174
  child.on('error', (error) => {
175
175
  // Abort/startup failure: make sure a partially-started tree does not
176
- // outlive the dispatch (a mach dying at startup used to strand
176
+ // outlive the dispatch (a mach dying at startup would otherwise strand
177
177
  // multiprocessing workers).
178
178
  if (options.processGroup === true) {
179
179
  killProcessTree(child, 'SIGKILL', usesProcessGroup);
@@ -229,7 +229,7 @@ export async function execStream(command, args, options = {}) {
229
229
  args,
230
230
  options,
231
231
  graceMs: 1500,
232
- // A detached group leader no longer receives the terminal's Ctrl+C, so
232
+ // A detached group leader does not receive the terminal's Ctrl+C, so
233
233
  // the forwarder is mandatory (not just graceful-UX) when processGroup
234
234
  // is set. A plain streamed child does not get one.
235
235
  forwardWithoutProcessGroup: false,
@@ -18,7 +18,7 @@ export declare function hasRawCssColors(content: string): boolean;
18
18
  * the line is blanked, corrupting whatever lint pass consumes the stripped
19
19
  * text. The source is tokenized as a module, then as a script. Firefox
20
20
  * chrome sources can contain constructs acorn tokenizes under neither goal.
21
- * Those fall back to the legacy regex strip, which handles strings but not
21
+ * Those fall back to the regex-only strip, which handles strings but not
22
22
  * regex literals.
23
23
  */
24
24
  export declare function stripJsComments(source: string): string;
@@ -30,7 +30,7 @@ export declare function stripJsComments(source: string): string;
30
30
  * legacy octal escape is a tokenizer error only under the module goal.
31
31
  * Callers that must not under-count when tokenizing fails (the code-line
32
32
  * size metric) read the `null` and pick their own fallback rather than the
33
- * legacy regex strip, which can blank code.
33
+ * regex-only strip, which can blank code.
34
34
  */
35
35
  export declare function stripJsCommentsParsed(source: string): string | null;
36
36
  /**
@@ -34,7 +34,7 @@ export function hasRawCssColors(content) {
34
34
  * the line is blanked, corrupting whatever lint pass consumes the stripped
35
35
  * text. The source is tokenized as a module, then as a script. Firefox
36
36
  * chrome sources can contain constructs acorn tokenizes under neither goal.
37
- * Those fall back to the legacy regex strip, which handles strings but not
37
+ * Those fall back to the regex-only strip, which handles strings but not
38
38
  * regex literals.
39
39
  */
40
40
  export function stripJsComments(source) {
@@ -48,7 +48,7 @@ export function stripJsComments(source) {
48
48
  * legacy octal escape is a tokenizer error only under the module goal.
49
49
  * Callers that must not under-count when tokenizing fails (the code-line
50
50
  * size metric) read the `null` and pick their own fallback rather than the
51
- * legacy regex strip, which can blank code.
51
+ * regex-only strip, which can blank code.
52
52
  */
53
53
  export function stripJsCommentsParsed(source) {
54
54
  const comments = collectJsComments(source, 'module') ?? collectJsComments(source, 'script');
@@ -91,7 +91,7 @@ function collectJsComments(source, sourceType) {
91
91
  return comments;
92
92
  }
93
93
  /**
94
- * Legacy pure-regex comment strip, used only when acorn cannot tokenize
94
+ * Pure-regex comment strip, used only when acorn cannot tokenize
95
95
  * the source (preprocessor directives, syntax errors). Strings survive.
96
96
  * Regex literals are not modeled, so `//` inside a regex blanks the rest
97
97
  * of the line.
@@ -1,12 +1,11 @@
1
1
  /**
2
2
  * The single awaitable delay used across FireForge.
3
3
  *
4
- * Five modules had grown a private copy of this (`sleep`, `delay`,
5
- * `sweepDelay`) and four more sites inlined
6
- * `new Promise((resolve) => setTimeout(resolve, ms))`. The copies disagreed on
7
- * the one property that actually matters (whether the pending timer holds
8
- * the event loop open) and the disagreement was invisible at each call site.
9
- * Both behaviours now live here, and callers state which one they need.
4
+ * Callers use this rather than a private `sleep`/`delay` or an inline
5
+ * `new Promise((resolve) => setTimeout(resolve, ms))`, because such copies
6
+ * disagree on the one property that actually matters (whether the pending
7
+ * timer holds the event loop open) and the disagreement is invisible at each
8
+ * call site. Both behaviours live here, and callers state which one they need.
10
9
  *
11
10
  * The default is a ref'd timer, because the dangerous mistake is the other
12
11
  * one: an unref'd delay awaited between a SIGTERM and its escalation lets Node
@@ -2,12 +2,11 @@
2
2
  /**
3
3
  * The single awaitable delay used across FireForge.
4
4
  *
5
- * Five modules had grown a private copy of this (`sleep`, `delay`,
6
- * `sweepDelay`) and four more sites inlined
7
- * `new Promise((resolve) => setTimeout(resolve, ms))`. The copies disagreed on
8
- * the one property that actually matters (whether the pending timer holds
9
- * the event loop open) and the disagreement was invisible at each call site.
10
- * Both behaviours now live here, and callers state which one they need.
5
+ * Callers use this rather than a private `sleep`/`delay` or an inline
6
+ * `new Promise((resolve) => setTimeout(resolve, ms))`, because such copies
7
+ * disagree on the one property that actually matters (whether the pending
8
+ * timer holds the event loop open) and the disagreement is invisible at each
9
+ * call site. Both behaviours live here, and callers state which one they need.
11
10
  *
12
11
  * The default is a ref'd timer, because the dangerous mistake is the other
13
12
  * one: an unref'd delay awaited between a SIGTERM and its escalation lets Node
@@ -20,8 +20,8 @@ export function isString(value) {
20
20
  */
21
21
  export function isNumber(value) {
22
22
  // Number.isFinite matches the documented contract: NaN and ±Infinity are
23
- // excluded (a JSON config field of 1e999 parses to Infinity and used to
24
- // validate as a legal number).
23
+ // excluded (a JSON config field of 1e999 parses to Infinity, which must
24
+ // not validate as a legal number).
25
25
  return typeof value === 'number' && Number.isFinite(value);
26
26
  }
27
27
  /**