@hominis/fireforge 0.34.2 → 0.36.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 (360) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +43 -5
  3. package/dist/bin/fireforge.d.ts +4 -0
  4. package/dist/bin/fireforge.js +25 -6
  5. package/dist/src/cli.js +22 -5
  6. package/dist/src/commands/bootstrap-checks.js +0 -1
  7. package/dist/src/commands/bootstrap.d.ts +2 -1
  8. package/dist/src/commands/bootstrap.js +16 -7
  9. package/dist/src/commands/build.js +17 -3
  10. package/dist/src/commands/config.js +30 -10
  11. package/dist/src/commands/discard.js +24 -5
  12. package/dist/src/commands/doctor/post-rebase-audit.js +0 -1
  13. package/dist/src/commands/doctor-check-core.js +0 -1
  14. package/dist/src/commands/doctor-external-toolchains.d.ts +3 -0
  15. package/dist/src/commands/doctor-external-toolchains.js +54 -0
  16. package/dist/src/commands/doctor-furnace-jar.js +0 -1
  17. package/dist/src/commands/doctor-furnace-manifest-sync.js +0 -1
  18. package/dist/src/commands/doctor-furnace.js +2 -2
  19. package/dist/src/commands/doctor-working-tree.js +0 -1
  20. package/dist/src/commands/doctor.js +4 -1
  21. package/dist/src/commands/download.js +51 -15
  22. package/dist/src/commands/export-all.js +5 -3
  23. package/dist/src/commands/export-flow.js +12 -7
  24. package/dist/src/commands/export-placement-gate.js +0 -1
  25. package/dist/src/commands/export-placement-policy.js +0 -1
  26. package/dist/src/commands/export-shared.d.ts +5 -1
  27. package/dist/src/commands/export-shared.js +18 -6
  28. package/dist/src/commands/export.js +15 -10
  29. package/dist/src/commands/furnace/apply.js +22 -6
  30. package/dist/src/commands/furnace/chrome-doc-remove.js +0 -1
  31. package/dist/src/commands/furnace/chrome-doc-templates.js +0 -1
  32. package/dist/src/commands/furnace/chrome-doc-tests.js +0 -1
  33. package/dist/src/commands/furnace/chrome-doc.js +0 -1
  34. package/dist/src/commands/furnace/create-browser-test.js +0 -1
  35. package/dist/src/commands/furnace/create-dry-run.js +0 -1
  36. package/dist/src/commands/furnace/create-features.js +0 -1
  37. package/dist/src/commands/furnace/create-mochikit.js +0 -1
  38. package/dist/src/commands/furnace/create-readback.js +0 -1
  39. package/dist/src/commands/furnace/create-templates.js +0 -1
  40. package/dist/src/commands/furnace/create-validation.js +0 -1
  41. package/dist/src/commands/furnace/create-xpcshell.js +0 -1
  42. package/dist/src/commands/furnace/create.js +0 -1
  43. package/dist/src/commands/furnace/deploy.js +7 -83
  44. package/dist/src/commands/furnace/diff.js +0 -1
  45. package/dist/src/commands/furnace/index.js +59 -25
  46. package/dist/src/commands/furnace/init.js +0 -1
  47. package/dist/src/commands/furnace/list.js +0 -1
  48. package/dist/src/commands/furnace/override.js +0 -1
  49. package/dist/src/commands/furnace/preview.js +3 -3
  50. package/dist/src/commands/furnace/refresh.js +0 -1
  51. package/dist/src/commands/furnace/remove-state.d.ts +15 -0
  52. package/dist/src/commands/furnace/remove-state.js +47 -1
  53. package/dist/src/commands/furnace/remove.js +3 -9
  54. package/dist/src/commands/furnace/rename-browser-test.js +1 -5
  55. package/dist/src/commands/furnace/rename-helpers.d.ts +6 -0
  56. package/dist/src/commands/furnace/rename-helpers.js +30 -1
  57. package/dist/src/commands/furnace/rename-xpcshell.js +7 -6
  58. package/dist/src/commands/furnace/rename.js +15 -36
  59. package/dist/src/commands/furnace/scan.js +0 -1
  60. package/dist/src/commands/furnace/status.js +0 -1
  61. package/dist/src/commands/furnace/sync.js +76 -4
  62. package/dist/src/commands/furnace/validate.js +0 -1
  63. package/dist/src/commands/furnace/validation-output.js +0 -1
  64. package/dist/src/commands/import.js +35 -9
  65. package/dist/src/commands/lint-per-patch.js +19 -7
  66. package/dist/src/commands/lint.js +13 -3
  67. package/dist/src/commands/manifest.js +1 -2
  68. package/dist/src/commands/package.js +2 -1
  69. package/dist/src/commands/patch/compact.js +1 -1
  70. package/dist/src/commands/patch/delete.js +1 -1
  71. package/dist/src/commands/patch/index.js +1 -1
  72. package/dist/src/commands/patch/lint-ignore.js +21 -6
  73. package/dist/src/commands/patch/move-files.js +1 -1
  74. package/dist/src/commands/patch/patch-context.js +0 -1
  75. package/dist/src/commands/patch/rename.js +4 -4
  76. package/dist/src/commands/patch/reorder.js +3 -4
  77. package/dist/src/commands/patch/split-plan.js +2 -1
  78. package/dist/src/commands/patch/split.js +4 -4
  79. package/dist/src/commands/patch/staged-dependency.js +1 -1
  80. package/dist/src/commands/patch/tier.js +18 -5
  81. package/dist/src/commands/re-export-bulk-scan.js +0 -1
  82. package/dist/src/commands/re-export-files.js +1 -1
  83. package/dist/src/commands/re-export-options.js +0 -1
  84. package/dist/src/commands/re-export-scan.js +0 -1
  85. package/dist/src/commands/re-export.js +6 -4
  86. package/dist/src/commands/rebase/abort.js +2 -9
  87. package/dist/src/commands/rebase/confirm.js +0 -1
  88. package/dist/src/commands/rebase/conflict-summary.js +0 -1
  89. package/dist/src/commands/rebase/continue.js +0 -1
  90. package/dist/src/commands/rebase/index.d.ts +1 -1
  91. package/dist/src/commands/rebase/index.js +10 -15
  92. package/dist/src/commands/rebase/patch-loop.js +38 -7
  93. package/dist/src/commands/rebase/summary.js +2 -3
  94. package/dist/src/commands/rebase.js +0 -1
  95. package/dist/src/commands/register.js +1 -1
  96. package/dist/src/commands/reset.js +16 -9
  97. package/dist/src/commands/resolve.js +2 -2
  98. package/dist/src/commands/run.js +18 -6
  99. package/dist/src/commands/setup-support.js +0 -1
  100. package/dist/src/commands/setup.js +1 -2
  101. package/dist/src/commands/source.js +1 -2
  102. package/dist/src/commands/status-output.js +1 -12
  103. package/dist/src/commands/status.js +147 -133
  104. package/dist/src/commands/test-appdir.js +0 -1
  105. package/dist/src/commands/test-diagnose.js +18 -2
  106. package/dist/src/commands/test-modes.d.ts +15 -0
  107. package/dist/src/commands/test-modes.js +61 -0
  108. package/dist/src/commands/test-register.d.ts +4 -0
  109. package/dist/src/commands/test-register.js +64 -0
  110. package/dist/src/commands/test-run.d.ts +23 -7
  111. package/dist/src/commands/test-run.js +15 -14
  112. package/dist/src/commands/test.d.ts +0 -4
  113. package/dist/src/commands/test.js +95 -56
  114. package/dist/src/commands/token-coverage.js +0 -1
  115. package/dist/src/commands/token.js +1 -2
  116. package/dist/src/commands/typecheck.js +1 -1
  117. package/dist/src/commands/verify.js +3 -9
  118. package/dist/src/commands/watch.js +5 -1
  119. package/dist/src/commands/wire.js +1 -1
  120. package/dist/src/core/ast-utils.js +0 -1
  121. package/dist/src/core/brand-validation.js +0 -1
  122. package/dist/src/core/branding.js +0 -1
  123. package/dist/src/core/browser-wire.js +0 -1
  124. package/dist/src/core/build-audit-platform.js +0 -1
  125. package/dist/src/core/build-audit-registration.js +0 -1
  126. package/dist/src/core/build-audit-resolve.js +0 -1
  127. package/dist/src/core/build-audit-transforms.js +0 -1
  128. package/dist/src/core/build-audit.js +0 -1
  129. package/dist/src/core/build-baseline-types.js +0 -1
  130. package/dist/src/core/build-baseline.js +0 -1
  131. package/dist/src/core/build-prepare.js +21 -7
  132. package/dist/src/core/config-mutate.js +0 -1
  133. package/dist/src/core/config-paths.d.ts +2 -2
  134. package/dist/src/core/config-paths.js +6 -1
  135. package/dist/src/core/config-state.js +0 -1
  136. package/dist/src/core/config-validate-patch-policy.js +0 -1
  137. package/dist/src/core/config-validate-test-toolchains.d.ts +8 -0
  138. package/dist/src/core/config-validate-test-toolchains.js +105 -0
  139. package/dist/src/core/config-validate.js +3 -1
  140. package/dist/src/core/config.js +0 -1
  141. package/dist/src/core/destructive.js +0 -1
  142. package/dist/src/core/diff-hunks.js +13 -7
  143. package/dist/src/core/engine-changes.js +0 -1
  144. package/dist/src/core/engine-session-lock.d.ts +12 -0
  145. package/dist/src/core/engine-session-lock.js +45 -0
  146. package/dist/src/core/file-lock.d.ts +8 -0
  147. package/dist/src/core/file-lock.js +157 -48
  148. package/dist/src/core/firefox-archive.d.ts +4 -0
  149. package/dist/src/core/firefox-archive.js +6 -1
  150. package/dist/src/core/firefox-cache.js +67 -8
  151. package/dist/src/core/firefox-download.js +0 -1
  152. package/dist/src/core/firefox-extract.d.ts +21 -1
  153. package/dist/src/core/firefox-extract.js +178 -9
  154. package/dist/src/core/firefox-ignorefile.js +0 -1
  155. package/dist/src/core/firefox.d.ts +12 -0
  156. package/dist/src/core/firefox.js +64 -2
  157. package/dist/src/core/furnace-apply-dry-run.js +0 -1
  158. package/dist/src/core/furnace-apply-ftl.d.ts +7 -3
  159. package/dist/src/core/furnace-apply-ftl.js +10 -5
  160. package/dist/src/core/furnace-apply-helpers.js +0 -1
  161. package/dist/src/core/furnace-apply-output.js +2 -2
  162. package/dist/src/core/furnace-apply.d.ts +7 -1
  163. package/dist/src/core/furnace-apply.js +47 -13
  164. package/dist/src/core/furnace-checksum-utils.js +0 -1
  165. package/dist/src/core/furnace-config-array-utils.js +0 -1
  166. package/dist/src/core/furnace-config-custom.js +0 -1
  167. package/dist/src/core/furnace-config-order.js +0 -1
  168. package/dist/src/core/furnace-config-tokens.js +0 -1
  169. package/dist/src/core/furnace-config-validate.js +0 -1
  170. package/dist/src/core/furnace-config.d.ts +11 -0
  171. package/dist/src/core/furnace-config.js +37 -1
  172. package/dist/src/core/furnace-constants.js +0 -1
  173. package/dist/src/core/furnace-css-fragments.js +0 -1
  174. package/dist/src/core/furnace-graph-utils.js +0 -1
  175. package/dist/src/core/furnace-jsconfig.d.ts +2 -3
  176. package/dist/src/core/furnace-jsconfig.js +25 -18
  177. package/dist/src/core/furnace-marker.js +0 -1
  178. package/dist/src/core/furnace-operation.js +0 -1
  179. package/dist/src/core/furnace-refresh.js +0 -1
  180. package/dist/src/core/furnace-registration-ast.d.ts +14 -0
  181. package/dist/src/core/furnace-registration-ast.js +1 -2
  182. package/dist/src/core/furnace-registration-remove.js +0 -1
  183. package/dist/src/core/furnace-registration-validate.js +1 -5
  184. package/dist/src/core/furnace-registration.js +0 -1
  185. package/dist/src/core/furnace-rollback.js +0 -1
  186. package/dist/src/core/furnace-scanner.js +0 -1
  187. package/dist/src/core/furnace-staleness.js +0 -1
  188. package/dist/src/core/furnace-state-persist.d.ts +72 -0
  189. package/dist/src/core/furnace-state-persist.js +118 -0
  190. package/dist/src/core/furnace-step-errors.d.ts +23 -0
  191. package/dist/src/core/furnace-step-errors.js +25 -0
  192. package/dist/src/core/furnace-stories.js +0 -1
  193. package/dist/src/core/furnace-validate-accessibility.js +0 -1
  194. package/dist/src/core/furnace-validate-checks.js +0 -1
  195. package/dist/src/core/furnace-validate-compatibility.js +0 -1
  196. package/dist/src/core/furnace-validate-helpers.js +0 -1
  197. package/dist/src/core/furnace-validate-registration.js +7 -7
  198. package/dist/src/core/furnace-validate-structure.d.ts +8 -0
  199. package/dist/src/core/furnace-validate-structure.js +11 -2
  200. package/dist/src/core/furnace-validate.js +0 -1
  201. package/dist/src/core/furnace-version-drift.d.ts +6 -3
  202. package/dist/src/core/furnace-version-drift.js +6 -4
  203. package/dist/src/core/git-base.js +0 -1
  204. package/dist/src/core/git-diff.js +0 -1
  205. package/dist/src/core/git-file-ops.js +0 -1
  206. package/dist/src/core/git-status.d.ts +13 -0
  207. package/dist/src/core/git-status.js +32 -2
  208. package/dist/src/core/git.d.ts +10 -1
  209. package/dist/src/core/git.js +65 -8
  210. package/dist/src/core/license-headers.d.ts +16 -0
  211. package/dist/src/core/license-headers.js +19 -1
  212. package/dist/src/core/lint-cache.js +0 -1
  213. package/dist/src/core/lint-projection.js +0 -1
  214. package/dist/src/core/mach-build-artifacts.js +0 -1
  215. package/dist/src/core/mach-error-hints.js +27 -1
  216. package/dist/src/core/mach-mozconfig.js +0 -1
  217. package/dist/src/core/mach-python.js +0 -1
  218. package/dist/src/core/mach-resource-shim.js +0 -1
  219. package/dist/src/core/mach.js +0 -1
  220. package/dist/src/core/manifest-helpers.js +0 -1
  221. package/dist/src/core/manifest-register.js +0 -1
  222. package/dist/src/core/manifest-rules.js +0 -1
  223. package/dist/src/core/manifest-tokenizers.js +0 -1
  224. package/dist/src/core/marionette-port.d.ts +8 -0
  225. package/dist/src/core/marionette-port.js +34 -3
  226. package/dist/src/core/marionette-preflight.js +0 -1
  227. package/dist/src/core/markdown-table.js +0 -1
  228. package/dist/src/core/ownership-table.js +2 -9
  229. package/dist/src/core/parser-fallback.js +0 -1
  230. package/dist/src/core/patch-apply-fuzz.d.ts +27 -9
  231. package/dist/src/core/patch-apply-fuzz.js +71 -34
  232. package/dist/src/core/patch-apply.d.ts +30 -0
  233. package/dist/src/core/patch-apply.js +152 -39
  234. package/dist/src/core/patch-artifact-normalize.d.ts +18 -5
  235. package/dist/src/core/patch-artifact-normalize.js +19 -15
  236. package/dist/src/core/patch-export-coverage.js +0 -1
  237. package/dist/src/core/patch-export-metadata.js +0 -1
  238. package/dist/src/core/patch-export-update.js +2 -3
  239. package/dist/src/core/patch-export.d.ts +2 -6
  240. package/dist/src/core/patch-export.js +24 -48
  241. package/dist/src/core/patch-files.js +0 -1
  242. package/dist/src/core/patch-identifier-suggest.js +0 -1
  243. package/dist/src/core/patch-lint-checkjs.js +0 -1
  244. package/dist/src/core/patch-lint-chrome-jsdoc.js +0 -1
  245. package/dist/src/core/patch-lint-cross.js +0 -1
  246. package/dist/src/core/patch-lint-css.js +0 -1
  247. package/dist/src/core/patch-lint-diff-tag.js +0 -1
  248. package/dist/src/core/patch-lint-diff.d.ts +2 -1
  249. package/dist/src/core/patch-lint-diff.js +17 -32
  250. package/dist/src/core/patch-lint-imports.js +0 -1
  251. package/dist/src/core/patch-lint-jsdoc.js +0 -1
  252. package/dist/src/core/patch-lint-observer.js +0 -1
  253. package/dist/src/core/patch-lint-ownership.js +0 -1
  254. package/dist/src/core/patch-lint-reexports.js +0 -1
  255. package/dist/src/core/patch-lint.d.ts +37 -2
  256. package/dist/src/core/patch-lint.js +48 -24
  257. package/dist/src/core/patch-lock.js +0 -1
  258. package/dist/src/core/patch-manifest-consistency.js +9 -1
  259. package/dist/src/core/patch-manifest-io.d.ts +16 -0
  260. package/dist/src/core/patch-manifest-io.js +37 -12
  261. package/dist/src/core/patch-manifest-query.d.ts +6 -0
  262. package/dist/src/core/patch-manifest-query.js +27 -12
  263. package/dist/src/core/patch-manifest-resolve.js +0 -1
  264. package/dist/src/core/patch-manifest-validate.js +0 -1
  265. package/dist/src/core/patch-manifest.d.ts +1 -1
  266. package/dist/src/core/patch-manifest.js +1 -2
  267. package/dist/src/core/patch-parse.d.ts +59 -0
  268. package/dist/src/core/patch-parse.js +209 -92
  269. package/dist/src/core/patch-policy.js +0 -1
  270. package/dist/src/core/patch-registration-refs.js +16 -26
  271. package/dist/src/core/patch-source-metadata.js +0 -1
  272. package/dist/src/core/patch-transform.d.ts +4 -0
  273. package/dist/src/core/patch-transform.js +30 -38
  274. package/dist/src/core/rebase-session.js +0 -1
  275. package/dist/src/core/register-browser-content.js +0 -1
  276. package/dist/src/core/register-module.js +0 -1
  277. package/dist/src/core/register-result.js +0 -1
  278. package/dist/src/core/register-scaffold.js +0 -1
  279. package/dist/src/core/register-shared-css.js +0 -1
  280. package/dist/src/core/register-test-manifest.js +0 -1
  281. package/dist/src/core/register-xpcshell-test.js +0 -1
  282. package/dist/src/core/shared-ftl.js +0 -1
  283. package/dist/src/core/signal-critical.js +0 -1
  284. package/dist/src/core/smoke-patterns.js +0 -1
  285. package/dist/src/core/state-file.js +0 -1
  286. package/dist/src/core/status-classify.d.ts +16 -0
  287. package/dist/src/core/status-classify.js +24 -16
  288. package/dist/src/core/test-harness-crash.d.ts +64 -7
  289. package/dist/src/core/test-harness-crash.js +196 -15
  290. package/dist/src/core/test-harness-output.js +0 -1
  291. package/dist/src/core/test-path-scope.d.ts +62 -0
  292. package/dist/src/core/test-path-scope.js +148 -0
  293. package/dist/src/core/test-stale-check.js +0 -1
  294. package/dist/src/core/test-stale-symlink.js +0 -1
  295. package/dist/src/core/test-xpcshell-retry.js +0 -1
  296. package/dist/src/core/token-coverage.js +0 -1
  297. package/dist/src/core/token-dark-mode.js +0 -1
  298. package/dist/src/core/token-docs.js +0 -1
  299. package/dist/src/core/token-manager.js +0 -1
  300. package/dist/src/core/token-scaffold.js +0 -1
  301. package/dist/src/core/token-variant.js +0 -1
  302. package/dist/src/core/toolchain-preflight.d.ts +85 -0
  303. package/dist/src/core/toolchain-preflight.js +256 -0
  304. package/dist/src/core/typecheck-shim.d.ts +4 -1
  305. package/dist/src/core/typecheck-shim.js +61 -18
  306. package/dist/src/core/typecheck.js +0 -1
  307. package/dist/src/core/wire-destroy.js +0 -1
  308. package/dist/src/core/wire-dom-fragment.js +0 -1
  309. package/dist/src/core/wire-init.js +0 -1
  310. package/dist/src/core/wire-subscript.js +0 -1
  311. package/dist/src/core/wire-targets.js +0 -1
  312. package/dist/src/core/wire-utils.js +0 -1
  313. package/dist/src/core/xpcshell-appdir.js +1 -4
  314. package/dist/src/errors/base.d.ts +29 -0
  315. package/dist/src/errors/base.js +35 -1
  316. package/dist/src/errors/build.js +0 -1
  317. package/dist/src/errors/codes.d.ts +6 -0
  318. package/dist/src/errors/codes.js +6 -1
  319. package/dist/src/errors/config.js +0 -1
  320. package/dist/src/errors/download.js +2 -1
  321. package/dist/src/errors/furnace.d.ts +11 -1
  322. package/dist/src/errors/furnace.js +6 -5
  323. package/dist/src/errors/git.js +0 -1
  324. package/dist/src/errors/patch.d.ts +17 -0
  325. package/dist/src/errors/patch.js +29 -1
  326. package/dist/src/errors/rebase.js +0 -1
  327. package/dist/src/errors/run.js +1 -1
  328. package/dist/src/index.js +0 -1
  329. package/dist/src/types/cli.js +0 -1
  330. package/dist/src/types/commands/index.js +0 -1
  331. package/dist/src/types/commands/options.d.ts +20 -5
  332. package/dist/src/types/commands/options.js +0 -1
  333. package/dist/src/types/commands/patches.d.ts +8 -0
  334. package/dist/src/types/commands/patches.js +0 -1
  335. package/dist/src/types/commands/project.d.ts +11 -2
  336. package/dist/src/types/commands/project.js +0 -1
  337. package/dist/src/types/config.d.ts +32 -0
  338. package/dist/src/types/config.js +0 -1
  339. package/dist/src/types/furnace.d.ts +10 -0
  340. package/dist/src/types/furnace.js +0 -1
  341. package/dist/src/types/index.js +0 -1
  342. package/dist/src/types/typecheck.js +0 -1
  343. package/dist/src/utils/elapsed.js +0 -1
  344. package/dist/src/utils/errors.js +0 -1
  345. package/dist/src/utils/fs.js +37 -5
  346. package/dist/src/utils/logger.d.ts +7 -0
  347. package/dist/src/utils/logger.js +85 -3
  348. package/dist/src/utils/options.d.ts +15 -0
  349. package/dist/src/utils/options.js +25 -1
  350. package/dist/src/utils/package-root.js +11 -4
  351. package/dist/src/utils/parse.js +0 -1
  352. package/dist/src/utils/paths.js +0 -1
  353. package/dist/src/utils/platform.js +0 -1
  354. package/dist/src/utils/process.d.ts +33 -4
  355. package/dist/src/utils/process.js +183 -28
  356. package/dist/src/utils/regex.d.ts +13 -3
  357. package/dist/src/utils/regex.js +53 -4
  358. package/dist/src/utils/validation.d.ts +0 -12
  359. package/dist/src/utils/validation.js +13 -26
  360. package/package.json +8 -7
@@ -95,4 +95,3 @@ export async function measureTokenCoverage(repoDir, cssFiles, projectRoot) {
95
95
  files: entries,
96
96
  };
97
97
  }
98
- //# sourceMappingURL=token-coverage.js.map
@@ -167,4 +167,3 @@ export function findDarkMediaCloseIndex(lines) {
167
167
  return -1;
168
168
  return findBlockCloseIndex(stripped, darkMediaLine);
169
169
  }
170
- //# sourceMappingURL=token-dark-mode.js.map
@@ -98,4 +98,3 @@ export async function addTokenToDocs(engineDir, options, annotation) {
98
98
  await writeText(filePath, lines.join('\n'));
99
99
  return { docsAdded, unmappedAdded, countUpdated };
100
100
  }
101
- //# sourceMappingURL=token-docs.js.map
@@ -455,4 +455,3 @@ async function addTokenToCSS(engineDir, options, tokensCssPath) {
455
455
  await writeText(filePath, content);
456
456
  return { added: true, categoryCreated };
457
457
  }
458
- //# sourceMappingURL=token-manager.js.map
@@ -71,4 +71,3 @@ ${categoryBlocks}
71
71
  }
72
72
  `;
73
73
  }
74
- //# sourceMappingURL=token-scaffold.js.map
@@ -138,4 +138,3 @@ export function insertVariantDeclaration(lines, variant, declLine) {
138
138
  }
139
139
  lines.splice(findVariantBlockInsertionPoint(lines), 0, '', `:root${variant} {`, declLine, '}');
140
140
  }
141
- //# sourceMappingURL=token-variant.js.map
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Toolchain-minimum awareness for Firefox source hops.
3
+ *
4
+ * When `fireforge download --force` moves the engine to a new Firefox
5
+ * MAJOR version, the tree's declared toolchain minimums (cbindgen, Rust)
6
+ * frequently move with it — and the first `fireforge build` then dies a
7
+ * few seconds into `mach configure` with a message whose remediation
8
+ * text names `./mach bootstrap`, the wrong tool for a FireForge-managed
9
+ * repo (152.0b7 → 153.0b8 source-refresh drill: `ERROR: cbindgen version
10
+ * 0.29.1 is too old. At least version 0.29.4 is required.`).
11
+ *
12
+ * Two layers:
13
+ * 1. {@link formatMajorVersionHopNotice} — a post-download nudge when
14
+ * the downloaded major differs from the previously downloaded one.
15
+ * 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing
16
+ * the minimums the tree itself declares against the host binaries
17
+ * `mach configure` will resolve, probing configure's own candidate
18
+ * order: env override first, then the `~/.mozbuild` state-directory
19
+ * copy bootstrap installs, then PATH (0.35.0 probed env-or-PATH
20
+ * only, blocking builds whose current tool lived in the state dir
21
+ * behind a stale PATH copy). Deliberately FAIL-SOFT: it reports a
22
+ * mismatch only when a minimum was positively parsed AND at least
23
+ * one candidate resolved AND every resolved candidate is
24
+ * definitively lower. Any uncertainty (file moved upstream,
25
+ * unparseable output, no candidate found) skips silently — the
26
+ * mach-error-hints translator still catches the real configure
27
+ * failure downstream.
28
+ */
29
+ /** Tools the preflight knows how to probe. */
30
+ export type ToolchainTool = 'cbindgen' | 'rustc';
31
+ /** One probed candidate binary for a tool. */
32
+ export interface ToolchainCandidate {
33
+ /** Binary path (or bare name for the PATH candidate). */
34
+ binary: string;
35
+ /** Parsed version of the candidate. */
36
+ version: string;
37
+ }
38
+ /** One definitive host-vs-tree mismatch found by the preflight. */
39
+ export interface ToolchainMismatch {
40
+ tool: ToolchainTool;
41
+ minimumVersion: string;
42
+ /** Engine-relative file the minimum was parsed from. */
43
+ declaredIn: string;
44
+ /**
45
+ * Every candidate that resolved — all of them below the minimum
46
+ * (mach-resolution order: env override, mozbuild state dir, PATH).
47
+ */
48
+ candidates: ToolchainCandidate[];
49
+ }
50
+ /**
51
+ * Returns the one-line notice to print after a download that hopped the
52
+ * Firefox MAJOR version, or undefined when no notice is warranted (first
53
+ * download, same major, or unparseable versions — an unparseable version
54
+ * must not spam every download with a false hint).
55
+ *
56
+ * @param previousVersion - `downloadedVersion` recorded in state before this download
57
+ * @param newVersion - Version that was just downloaded
58
+ */
59
+ export declare function formatMajorVersionHopNotice(previousVersion: string | undefined, newVersion: string): string | undefined;
60
+ /**
61
+ * Reads the toolchain minimums the engine tree itself declares. Any file
62
+ * that is missing or no longer matches the expected declaration shape
63
+ * yields undefined for that tool — never an error.
64
+ */
65
+ export declare function readDeclaredToolchainMinimums(engineDir: string): Promise<Partial<Record<ToolchainTool, string>>>;
66
+ /**
67
+ * Compares the tree-declared toolchain minimums against the host binaries
68
+ * `mach configure` will resolve, in configure's own candidate order (env
69
+ * override, mozbuild state dir, PATH). A tool fails ONLY when at least
70
+ * one candidate resolved and none of them meets the minimum; any single
71
+ * passing candidate passes the tool (configure will find it), and a tool
72
+ * with no resolvable candidate skips silently (see module header for the
73
+ * fail-soft rationale).
74
+ *
75
+ * @param engineDir - Path to the engine directory
76
+ */
77
+ export declare function runToolchainPreflight(engineDir: string): Promise<ToolchainMismatch[]>;
78
+ /**
79
+ * Formats the fail-fast message for definitive preflight mismatches,
80
+ * listing every candidate probed (in mach's resolution order) and naming
81
+ * `fireforge bootstrap` as the remedy (mach's own configure error
82
+ * suggests `./mach bootstrap`, which is the wrong entry point for a
83
+ * FireForge-managed repo).
84
+ */
85
+ export declare function formatToolchainMismatchMessage(mismatches: ToolchainMismatch[]): string;
@@ -0,0 +1,256 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * Toolchain-minimum awareness for Firefox source hops.
4
+ *
5
+ * When `fireforge download --force` moves the engine to a new Firefox
6
+ * MAJOR version, the tree's declared toolchain minimums (cbindgen, Rust)
7
+ * frequently move with it — and the first `fireforge build` then dies a
8
+ * few seconds into `mach configure` with a message whose remediation
9
+ * text names `./mach bootstrap`, the wrong tool for a FireForge-managed
10
+ * repo (152.0b7 → 153.0b8 source-refresh drill: `ERROR: cbindgen version
11
+ * 0.29.1 is too old. At least version 0.29.4 is required.`).
12
+ *
13
+ * Two layers:
14
+ * 1. {@link formatMajorVersionHopNotice} — a post-download nudge when
15
+ * the downloaded major differs from the previously downloaded one.
16
+ * 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing
17
+ * the minimums the tree itself declares against the host binaries
18
+ * `mach configure` will resolve, probing configure's own candidate
19
+ * order: env override first, then the `~/.mozbuild` state-directory
20
+ * copy bootstrap installs, then PATH (0.35.0 probed env-or-PATH
21
+ * only, blocking builds whose current tool lived in the state dir
22
+ * behind a stale PATH copy). Deliberately FAIL-SOFT: it reports a
23
+ * mismatch only when a minimum was positively parsed AND at least
24
+ * one candidate resolved AND every resolved candidate is
25
+ * definitively lower. Any uncertainty (file moved upstream,
26
+ * unparseable output, no candidate found) skips silently — the
27
+ * mach-error-hints translator still catches the real configure
28
+ * failure downstream.
29
+ */
30
+ import { execFile } from 'node:child_process';
31
+ import { homedir } from 'node:os';
32
+ import { join } from 'node:path';
33
+ import { pathExists, readText } from '../utils/fs.js';
34
+ import { verbose } from '../utils/logger.js';
35
+ /**
36
+ * Resolves the mach state directory the same way mach itself does:
37
+ * `$MOZBUILD_STATE_PATH`, else `~/.mozbuild` (same resolution as
38
+ * `mach-resource-shim.ts`).
39
+ */
40
+ function mozbuildStateDir() {
41
+ return process.env['MOZBUILD_STATE_PATH'] ?? join(homedir(), '.mozbuild');
42
+ }
43
+ /** Where each tool's minimum is declared inside the Firefox tree. */
44
+ const MINIMUM_DECLARATIONS = {
45
+ // build/moz.configure/bindgen.configure:
46
+ // cbindgen_min_version = Version("0.27.0")
47
+ cbindgen: {
48
+ relPath: 'build/moz.configure/bindgen.configure',
49
+ pattern: /cbindgen_min_version\s*=\s*Version\(\s*["']([\d.]+)["']\s*\)/,
50
+ },
51
+ // python/mozboot/mozboot/util.py:
52
+ // MINIMUM_RUST_VERSION = "1.82.0"
53
+ // (build/moz.configure/rust.configure imports this constant, so the
54
+ // mozboot file is the single authority in the tree.)
55
+ rustc: {
56
+ relPath: 'python/mozboot/mozboot/util.py',
57
+ pattern: /MINIMUM_RUST_VERSION\s*=\s*["']([\d.]+)["']/,
58
+ },
59
+ };
60
+ /**
61
+ * How each tool's host binary is resolved and its version parsed.
62
+ *
63
+ * `stateDirRelPaths` are the mach-state-directory locations `fireforge
64
+ * bootstrap` (via mozboot) installs the tool to. mach's configure tries
65
+ * the state directory BEFORE the PATH candidates (bindgen.configure's
66
+ * toolchain search path lists `~/.mozbuild/cbindgen/cbindgen` first — a
67
+ * configure log shows `trying cbindgen: ~/.mozbuild/cbindgen/cbindgen`
68
+ * ahead of PATH), so the probe must too. 0.35.0 probed only env-or-PATH,
69
+ * which failed a build configure would have accepted whenever an old
70
+ * `~/.cargo/bin/cbindgen` shadowed a current bootstrap-installed copy
71
+ * (field report: PATH 0.29.1 vs mozbuild 0.29.4, minimum 0.29.4). Rust
72
+ * has no state-dir install — rustup owns it — so its list is empty.
73
+ */
74
+ const HOST_PROBES = {
75
+ // `mach configure` honours the CBINDGEN env option (bindgen.configure's
76
+ // `option(env="CBINDGEN", ...)`), so the probe must too — otherwise the
77
+ // preflight could veto a build configure would have accepted.
78
+ cbindgen: {
79
+ envVar: 'CBINDGEN',
80
+ versionPattern: /cbindgen\s+(\d+(?:\.\d+)*)/,
81
+ stateDirRelPaths: ['cbindgen/cbindgen'],
82
+ },
83
+ rustc: { envVar: 'RUSTC', versionPattern: /rustc\s+(\d+(?:\.\d+)*)/, stateDirRelPaths: [] },
84
+ };
85
+ /**
86
+ * Parses a dotted version string into numeric components. Trailing
87
+ * non-numeric suffixes are ignored; returns undefined when the string
88
+ * does not start with a number. (Same posture as the furnace version
89
+ * drift classifier, kept local so the two modules stay decoupled.)
90
+ */
91
+ function parseVersionComponents(version) {
92
+ const match = /^(\d+(?:\.\d+)*)/.exec(version.trim());
93
+ if (!match?.[1])
94
+ return undefined;
95
+ return match[1].split('.').map(Number);
96
+ }
97
+ /** Component-wise comparison; missing components count as 0. */
98
+ function isVersionLower(candidate, minimum) {
99
+ const length = Math.max(candidate.length, minimum.length);
100
+ for (let i = 0; i < length; i += 1) {
101
+ const a = candidate[i] ?? 0;
102
+ const b = minimum[i] ?? 0;
103
+ if (a !== b)
104
+ return a < b;
105
+ }
106
+ return false;
107
+ }
108
+ /**
109
+ * Returns the one-line notice to print after a download that hopped the
110
+ * Firefox MAJOR version, or undefined when no notice is warranted (first
111
+ * download, same major, or unparseable versions — an unparseable version
112
+ * must not spam every download with a false hint).
113
+ *
114
+ * @param previousVersion - `downloadedVersion` recorded in state before this download
115
+ * @param newVersion - Version that was just downloaded
116
+ */
117
+ export function formatMajorVersionHopNotice(previousVersion, newVersion) {
118
+ if (!previousVersion)
119
+ return undefined;
120
+ const previousMajor = parseVersionComponents(previousVersion)?.[0];
121
+ const newMajor = parseVersionComponents(newVersion)?.[0];
122
+ if (previousMajor === undefined || newMajor === undefined)
123
+ return undefined;
124
+ if (previousMajor === newMajor)
125
+ return undefined;
126
+ return (`Firefox major version changed (${String(previousMajor)} → ${String(newMajor)}): ` +
127
+ 'upstream toolchain minimums (cbindgen, Rust, …) may have moved with it. ' +
128
+ 'Consider running "fireforge bootstrap" before the next build.');
129
+ }
130
+ /**
131
+ * Reads the toolchain minimums the engine tree itself declares. Any file
132
+ * that is missing or no longer matches the expected declaration shape
133
+ * yields undefined for that tool — never an error.
134
+ */
135
+ export async function readDeclaredToolchainMinimums(engineDir) {
136
+ const minimums = {};
137
+ for (const [tool, declaration] of Object.entries(MINIMUM_DECLARATIONS)) {
138
+ const filePath = join(engineDir, declaration.relPath);
139
+ if (!(await pathExists(filePath))) {
140
+ verbose(`Toolchain preflight: ${declaration.relPath} not found; skipping ${tool}.`);
141
+ continue;
142
+ }
143
+ try {
144
+ const content = await readText(filePath);
145
+ const match = declaration.pattern.exec(content);
146
+ if (match?.[1]) {
147
+ minimums[tool] = match[1];
148
+ }
149
+ else {
150
+ verbose(`Toolchain preflight: no ${tool} minimum declaration recognized in ${declaration.relPath}; skipping.`);
151
+ }
152
+ }
153
+ catch (error) {
154
+ verbose(`Toolchain preflight: could not read ${declaration.relPath} (${error instanceof Error ? error.message : String(error)}); skipping ${tool}.`);
155
+ }
156
+ }
157
+ return minimums;
158
+ }
159
+ /** Runs `<binary> --version` and parses the leading version number. */
160
+ async function probeBinaryVersion(binary, versionPattern) {
161
+ const output = await new Promise((resolvePromise) => {
162
+ execFile(binary, ['--version'], { timeout: 10_000 }, (err, stdout) => {
163
+ resolvePromise(err ? undefined : stdout);
164
+ });
165
+ });
166
+ if (output === undefined)
167
+ return undefined;
168
+ const match = versionPattern.exec(output);
169
+ if (!match?.[1]) {
170
+ verbose(`Toolchain preflight: could not parse a version from "${output.trim()}" (${binary}).`);
171
+ return undefined;
172
+ }
173
+ return match[1];
174
+ }
175
+ /**
176
+ * Probes every candidate binary for a tool in mach's resolution order:
177
+ * the env override (which, when set, is the ONLY candidate — configure
178
+ * uses it even when a better binary exists elsewhere), then the mozbuild
179
+ * state-directory copy bootstrap installs, then PATH. Candidates that
180
+ * fail to run or to parse are dropped silently.
181
+ */
182
+ async function probeHostToolCandidates(tool) {
183
+ const probe = HOST_PROBES[tool];
184
+ const envOverride = process.env[probe.envVar];
185
+ const binaries = envOverride
186
+ ? [envOverride]
187
+ : [...probe.stateDirRelPaths.map((rel) => join(mozbuildStateDir(), rel)), tool];
188
+ const candidates = [];
189
+ for (const binary of binaries) {
190
+ const version = await probeBinaryVersion(binary, probe.versionPattern);
191
+ if (version !== undefined) {
192
+ candidates.push({ binary, version });
193
+ }
194
+ else {
195
+ verbose(`Toolchain preflight: "${binary} --version" failed or not found; skipping.`);
196
+ }
197
+ }
198
+ return candidates;
199
+ }
200
+ /**
201
+ * Compares the tree-declared toolchain minimums against the host binaries
202
+ * `mach configure` will resolve, in configure's own candidate order (env
203
+ * override, mozbuild state dir, PATH). A tool fails ONLY when at least
204
+ * one candidate resolved and none of them meets the minimum; any single
205
+ * passing candidate passes the tool (configure will find it), and a tool
206
+ * with no resolvable candidate skips silently (see module header for the
207
+ * fail-soft rationale).
208
+ *
209
+ * @param engineDir - Path to the engine directory
210
+ */
211
+ export async function runToolchainPreflight(engineDir) {
212
+ const minimums = await readDeclaredToolchainMinimums(engineDir);
213
+ const mismatches = [];
214
+ for (const [tool, minimumVersion] of Object.entries(minimums)) {
215
+ const minimum = parseVersionComponents(minimumVersion);
216
+ if (!minimum)
217
+ continue;
218
+ const candidates = await probeHostToolCandidates(tool);
219
+ const parsed = candidates.filter((c) => parseVersionComponents(c.version) !== undefined);
220
+ if (parsed.length === 0)
221
+ continue;
222
+ const satisfying = parsed.find((c) => {
223
+ const components = parseVersionComponents(c.version);
224
+ return components !== undefined && !isVersionLower(components, minimum);
225
+ });
226
+ if (satisfying) {
227
+ verbose(`Toolchain preflight: ${tool} ${satisfying.version} (${satisfying.binary}) satisfies minimum ${minimumVersion}.`);
228
+ continue;
229
+ }
230
+ mismatches.push({
231
+ tool,
232
+ minimumVersion,
233
+ declaredIn: MINIMUM_DECLARATIONS[tool].relPath,
234
+ candidates: parsed,
235
+ });
236
+ }
237
+ return mismatches;
238
+ }
239
+ /**
240
+ * Formats the fail-fast message for definitive preflight mismatches,
241
+ * listing every candidate probed (in mach's resolution order) and naming
242
+ * `fireforge bootstrap` as the remedy (mach's own configure error
243
+ * suggests `./mach bootstrap`, which is the wrong entry point for a
244
+ * FireForge-managed repo).
245
+ */
246
+ export function formatToolchainMismatchMessage(mismatches) {
247
+ const lines = mismatches.map((m) => {
248
+ const probed = m.candidates.map((c) => `${c.version} (${c.binary})`).join(', ');
249
+ return (` - ${m.tool}: no resolvable candidate meets the minimum ${m.minimumVersion} declared by ` +
250
+ `this Firefox source (engine/${m.declaredIn}); probed in mach's resolution order: ${probed}`);
251
+ });
252
+ return ('Toolchain preflight found host tools older than what this Firefox source requires:\n' +
253
+ `${lines.join('\n')}\n\n` +
254
+ 'This typically happens after "fireforge download --force" moved the engine to a new ' +
255
+ 'Firefox major version. Run "fireforge bootstrap" to update the toolchain, then retry the build.');
256
+ }
@@ -40,7 +40,10 @@ export interface ComposedShim {
40
40
  * direction is intentional (declarations later in concat order
41
41
  * augment earlier ones), so a project that wants to refine `Services`
42
42
  * with a more specific type can do so by declaring it in the extra
43
- * shim. Any triple-slash `/// <reference path="…">` directives inside the
43
+ * shim, and members can be ADDED to the structured globals by merging
44
+ * their interfaces (`interface ChromeUtilsShim { newMember(): any }` —
45
+ * see the module doc comment). Any triple-slash
46
+ * `/// <reference path="…">` directives inside the
44
47
  * extra shim are inlined (resolved against the extra shim's own directory)
45
48
  * so they are not silently dropped at the synthetic shim path.
46
49
  *
@@ -22,6 +22,23 @@ export const SHIM_FILENAME = '__fireforge_firefox_globals.d.ts';
22
22
  * for the most common Mozilla APIs. Types are intentionally loose
23
23
  * (`any`) because full Firefox type coverage is out of scope.
24
24
  *
25
+ * Structured globals (`ChromeUtils`, `Localization`) are declared via
26
+ * named global interfaces (`ChromeUtilsShim`, `LocalizationShim`, …)
27
+ * rather than closed object-literal types, so a project's extra shim
28
+ * (`patchLint.checkJsExtraShim` / `typecheck.extraShim`) can ADD members
29
+ * through TypeScript interface merging:
30
+ *
31
+ * // my-extra-shim.d.ts
32
+ * interface ChromeUtilsShim {
33
+ * someNewApi(arg: string): unknown;
34
+ * }
35
+ *
36
+ * (A second `declare var ChromeUtils` in the extra shim remains a
37
+ * duplicate-identifier error by design — merge the interface instead.)
38
+ * The member lists track upstream WebIDL additions per Firefox release
39
+ * (`dom/chrome-webidl/ChromeUtils.webidl` for ChromeUtils); when a new
40
+ * release adds a commonly-patched member, add a loose signature here.
41
+ *
25
42
  * Notable patterns that require shimming:
26
43
  * - `const lazy = {};` + `ChromeUtils.defineESModuleGetters(lazy, { ... })`
27
44
  * populates `lazy` at runtime; we declare it as `Record<string, any>`.
@@ -37,16 +54,24 @@ export const SHIM_FILENAME = '__fireforge_firefox_globals.d.ts';
37
54
  */
38
55
  const FIREFOX_GLOBALS_SHIM = `
39
56
  declare var Services: any;
40
- declare var ChromeUtils: {
57
+ // Extensible via interface merging from a project extra shim — see the
58
+ // module doc comment in typecheck-shim.ts.
59
+ interface ChromeUtilsShim {
41
60
  defineESModuleGetters(target: any, modules: Record<string, string>): void;
42
61
  importESModule(specifier: string): any;
43
62
  import(specifier: string): any;
63
+ registerWindowActor(name: string, options: Record<string, any>): void;
44
64
  defineModuleGetter(target: any, name: string, specifier: string): void;
45
65
  defineLazyGetter(target: any, name: string, getter: () => any): void;
46
66
  generateQI(interfaces: any[]): Function;
47
67
  getClassName(obj: any, unwrap?: boolean): string;
48
68
  isClassInfo(obj: any): boolean;
49
- };
69
+ // Firefox 153, dom/chrome-webidl/ChromeUtils.webidl: two overloads
70
+ // (URI string / nsIURI) with a PredictRemoteTypeOptions dictionary —
71
+ // collapsed into one loose signature per the shim's pragmatic posture.
72
+ predictRemoteTypeForURI(uri: string | object | null, options?: object): string | null;
73
+ }
74
+ declare var ChromeUtils: ChromeUtilsShim;
50
75
  declare var Cu: any;
51
76
  declare var Ci: any;
52
77
  declare var Cc: any;
@@ -61,25 +86,41 @@ declare var gBrowser: any;
61
86
  declare var gURLBar: any;
62
87
  declare var gNavigatorBundle: any;
63
88
  declare var AppConstants: any;
89
+ declare class JSWindowActorChild {
90
+ readonly browsingContext: any;
91
+ readonly contentWindow: any;
92
+ readonly document: any;
93
+ sendAsyncMessage(name: string, data?: any, transfers?: any[]): void;
94
+ sendQuery(name: string, data?: any, transfers?: any[]): Promise<any>;
95
+ }
96
+ declare class JSWindowActorParent {
97
+ readonly browsingContext: any;
98
+ sendAsyncMessage(name: string, data?: any, transfers?: any[]): void;
99
+ sendQuery(name: string, data?: any, transfers?: any[]): Promise<any>;
100
+ }
64
101
  // Fluent localization — a stable chrome global. Members stay loose (any),
65
102
  // but the constructor shape is declared so "new Localization([...])" and
66
- // "new Localization([...], true)" typecheck without a local cast.
67
- declare var Localization: {
103
+ // "new Localization([...], true)" typecheck without a local cast. Both
104
+ // interfaces are extensible via interface merging from a project extra
105
+ // shim, same as ChromeUtilsShim.
106
+ interface LocalizationInstanceShim {
107
+ formatValue(id: string, args?: Record<string, unknown>): any;
108
+ formatValues(keys: any[]): any;
109
+ formatMessages(keys: any[]): any;
110
+ formatValueSync(id: string, args?: Record<string, unknown>): any;
111
+ formatValuesSync(keys: any[]): any;
112
+ formatMessagesSync(keys: any[]): any;
113
+ addResourceIds(ids: Array<string | { path: string; optional?: boolean }>): void;
114
+ removeResourceIds(ids: string[]): number;
115
+ setAsync(): void;
116
+ }
117
+ interface LocalizationShim {
68
118
  new (
69
119
  resourceIds: Array<string | { path: string; optional?: boolean }>,
70
120
  sync?: boolean
71
- ): {
72
- formatValue(id: string, args?: Record<string, unknown>): any;
73
- formatValues(keys: any[]): any;
74
- formatMessages(keys: any[]): any;
75
- formatValueSync(id: string, args?: Record<string, unknown>): any;
76
- formatValuesSync(keys: any[]): any;
77
- formatMessagesSync(keys: any[]): any;
78
- addResourceIds(ids: Array<string | { path: string; optional?: boolean }>): void;
79
- removeResourceIds(ids: string[]): number;
80
- setAsync(): void;
81
- };
82
- };
121
+ ): LocalizationInstanceShim;
122
+ }
123
+ declare var Localization: LocalizationShim;
83
124
 
84
125
  // Shorthand ambient modules — exports from matching URL imports are loosely typed,
85
126
  // avoiding noResolve empty-graph namespaces. (Named member access broke when we tried
@@ -154,7 +195,10 @@ async function inlineTripleSlashReferences(source, baseDir, seen) {
154
195
  * direction is intentional (declarations later in concat order
155
196
  * augment earlier ones), so a project that wants to refine `Services`
156
197
  * with a more specific type can do so by declaring it in the extra
157
- * shim. Any triple-slash `/// <reference path="…">` directives inside the
198
+ * shim, and members can be ADDED to the structured globals by merging
199
+ * their interfaces (`interface ChromeUtilsShim { newMember(): any }` —
200
+ * see the module doc comment). Any triple-slash
201
+ * `/// <reference path="…">` directives inside the
158
202
  * extra shim are inlined (resolved against the extra shim's own directory)
159
203
  * so they are not silently dropped at the synthetic shim path.
160
204
  *
@@ -182,4 +226,3 @@ export async function composeShimSource(projectRoot, extraShimPath) {
182
226
  extraShimAppended: true,
183
227
  };
184
228
  }
185
- //# sourceMappingURL=typecheck-shim.js.map
@@ -327,4 +327,3 @@ export function relativeForDisplay(projectRoot, absoluteFile) {
327
327
  return absoluteFile;
328
328
  return rel;
329
329
  }
330
- //# sourceMappingURL=typecheck.js.map
@@ -121,4 +121,3 @@ export async function addDestroyToBrowserInit(engineDir, expression, marker = DE
121
121
  await writeText(filePath, value);
122
122
  return true;
123
123
  }
124
- //# sourceMappingURL=wire-destroy.js.map
@@ -181,4 +181,3 @@ export async function addDomFragment(engineDir, domFilePath, targetPath = DEFAUL
181
181
  await writeText(targetAbsPath, value);
182
182
  return true;
183
183
  }
184
- //# sourceMappingURL=wire-dom-fragment.js.map
@@ -231,4 +231,3 @@ export async function addInitToBrowserInit(engineDir, expression, after, marker
231
231
  await writeText(filePath, value);
232
232
  return true;
233
233
  }
234
- //# sourceMappingURL=wire-init.js.map
@@ -144,4 +144,3 @@ export async function addSubscriptToBrowserMain(engineDir, name, marker = DEFAUL
144
144
  await writeText(filePath, value);
145
145
  return true;
146
146
  }
147
- //# sourceMappingURL=wire-subscript.js.map
@@ -6,4 +6,3 @@ export { addDestroyToBrowserInit } from './wire-destroy.js';
6
6
  export { addDomFragment } from './wire-dom-fragment.js';
7
7
  export { addInitToBrowserInit } from './wire-init.js';
8
8
  export { addSubscriptToBrowserMain } from './wire-subscript.js';
9
- //# sourceMappingURL=wire-targets.js.map
@@ -349,4 +349,3 @@ export function findMethodBody(ast, methodName) {
349
349
  });
350
350
  return found;
351
351
  }
352
- //# sourceMappingURL=wire-utils.js.map
@@ -41,6 +41,7 @@
41
41
  import { readdir, stat } from 'node:fs/promises';
42
42
  import { dirname, join, resolve, sep } from 'node:path';
43
43
  import { pathExists, readJson, readText } from '../utils/fs.js';
44
+ import { escapeRegex } from '../utils/regex.js';
44
45
  import { isObject, isString } from '../utils/validation.js';
45
46
  /**
46
47
  * `[DEFAULT]` section parser shaped to the narrow case we need: pull a
@@ -88,9 +89,6 @@ export function parseAppdirFromToml(tomlText, key) {
88
89
  }
89
90
  return undefined;
90
91
  }
91
- function escapeRegex(input) {
92
- return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
93
- }
94
92
  function stripQuotes(raw) {
95
93
  if (raw.length === 0)
96
94
  return undefined;
@@ -305,4 +303,3 @@ export function operatorAlreadySetAppPath(extraArgs) {
305
303
  }
306
304
  return false;
307
305
  }
308
- //# sourceMappingURL=xpcshell-appdir.js.map
@@ -54,6 +54,35 @@ export declare class InvalidArgumentError extends FireForgeError {
54
54
  constructor(message: string, argument?: string | undefined, cause?: Error);
55
55
  get userMessage(): string;
56
56
  }
57
+ /**
58
+ * Error thrown when a spawned command exceeds its `timeout` option.
59
+ *
60
+ * Every `exec*` helper in `src/utils/process.ts` rejects with this type
61
+ * (instead of Node's bare `AbortError: The operation was aborted`) when the
62
+ * caller-supplied timeout fires. The bare AbortError bit an operator during
63
+ * the 2026-04-24 eval (see {@link GitIndexingTimeoutError} in errors/git.ts):
64
+ * an 854 s git indexing pass died with no command name, no elapsed time, and
65
+ * no hint that a timeout — not git — was responsible. The git path gained a
66
+ * site-local typed error then; this class extends the same courtesy to every
67
+ * other `timeout` caller.
68
+ */
69
+ export declare class ExecTimeoutError extends FireForgeError {
70
+ /** Executable that was spawned (argv[0]). */
71
+ readonly command: string;
72
+ /** Arguments the executable was spawned with. */
73
+ readonly args: readonly string[];
74
+ /** Timeout that elapsed, in milliseconds. */
75
+ readonly timeoutMs: number;
76
+ readonly code: 1;
77
+ constructor(
78
+ /** Executable that was spawned (argv[0]). */
79
+ command: string,
80
+ /** Arguments the executable was spawned with. */
81
+ args: readonly string[],
82
+ /** Timeout that elapsed, in milliseconds. */
83
+ timeoutMs: number, cause?: unknown);
84
+ get userMessage(): string;
85
+ }
57
86
  /**
58
87
  * Error thrown when the user cancels an interactive prompt.
59
88
  */
@@ -78,6 +78,41 @@ export class InvalidArgumentError extends FireForgeError {
78
78
  return msg;
79
79
  }
80
80
  }
81
+ /**
82
+ * Error thrown when a spawned command exceeds its `timeout` option.
83
+ *
84
+ * Every `exec*` helper in `src/utils/process.ts` rejects with this type
85
+ * (instead of Node's bare `AbortError: The operation was aborted`) when the
86
+ * caller-supplied timeout fires. The bare AbortError bit an operator during
87
+ * the 2026-04-24 eval (see {@link GitIndexingTimeoutError} in errors/git.ts):
88
+ * an 854 s git indexing pass died with no command name, no elapsed time, and
89
+ * no hint that a timeout — not git — was responsible. The git path gained a
90
+ * site-local typed error then; this class extends the same courtesy to every
91
+ * other `timeout` caller.
92
+ */
93
+ export class ExecTimeoutError extends FireForgeError {
94
+ command;
95
+ args;
96
+ timeoutMs;
97
+ code = ExitCode.GENERAL_ERROR;
98
+ constructor(
99
+ /** Executable that was spawned (argv[0]). */
100
+ command,
101
+ /** Arguments the executable was spawned with. */
102
+ args,
103
+ /** Timeout that elapsed, in milliseconds. */
104
+ timeoutMs, cause) {
105
+ super(`Command timed out after ${Math.round(timeoutMs / 1000)}s: ${[command, ...args].join(' ')}`, cause);
106
+ this.command = command;
107
+ this.args = args;
108
+ this.timeoutMs = timeoutMs;
109
+ }
110
+ get userMessage() {
111
+ return (`${this.message}\n\n` +
112
+ 'The command was killed because it exceeded its time budget, not because it failed on its own. ' +
113
+ 'If the host is just slow or loaded, re-running may succeed.');
114
+ }
115
+ }
81
116
  /**
82
117
  * Error thrown when the user cancels an interactive prompt.
83
118
  */
@@ -108,4 +143,3 @@ export class CommandError extends Error {
108
143
  this.name = 'CommandError';
109
144
  }
110
145
  }
111
- //# sourceMappingURL=base.js.map