@hominis/fireforge 0.48.0 → 0.49.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 (101) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/build-info.json +4 -4
  3. package/dist/src/cli.js +16 -28
  4. package/dist/src/commands/build.js +30 -4
  5. package/dist/src/commands/doctor-engine-eslint.d.ts +3 -0
  6. package/dist/src/commands/doctor-engine-eslint.js +12 -0
  7. package/dist/src/commands/doctor-macos-sdk.js +7 -5
  8. package/dist/src/commands/doctor-source-pin.js +9 -2
  9. package/dist/src/commands/doctor.js +2 -0
  10. package/dist/src/commands/furnace/apply.js +10 -4
  11. package/dist/src/commands/furnace/create-templates.js +0 -3
  12. package/dist/src/commands/lint.js +4 -0
  13. package/dist/src/commands/manifest.d.ts +1 -2
  14. package/dist/src/commands/patch/delete.js +18 -4
  15. package/dist/src/commands/re-export-options.js +7 -0
  16. package/dist/src/commands/re-export-register.js +1 -0
  17. package/dist/src/commands/re-export-removed.d.ts +4 -0
  18. package/dist/src/commands/re-export-removed.js +49 -0
  19. package/dist/src/commands/re-export-single.js +4 -1
  20. package/dist/src/commands/re-export.js +4 -0
  21. package/dist/src/commands/test-browser-preflight.d.ts +28 -0
  22. package/dist/src/commands/test-browser-preflight.js +181 -0
  23. package/dist/src/commands/test-build-phase.js +30 -7
  24. package/dist/src/commands/test-checkjs.d.ts +3 -0
  25. package/dist/src/commands/test-checkjs.js +27 -0
  26. package/dist/src/commands/test-diagnose.js +3 -0
  27. package/dist/src/commands/test-harness-env.d.ts +5 -6
  28. package/dist/src/commands/test-harness-env.js +27 -7
  29. package/dist/src/commands/test-modes.d.ts +2 -4
  30. package/dist/src/commands/test-register.js +11 -5
  31. package/dist/src/commands/test-run.d.ts +2 -0
  32. package/dist/src/commands/test-run.js +21 -1
  33. package/dist/src/commands/test-verdict.d.ts +2 -2
  34. package/dist/src/commands/test.js +83 -211
  35. package/dist/src/core/build-baseline-types.d.ts +12 -14
  36. package/dist/src/core/build-baseline-validate.d.ts +3 -0
  37. package/dist/src/core/build-baseline-validate.js +53 -0
  38. package/dist/src/core/build-baseline.d.ts +4 -3
  39. package/dist/src/core/build-baseline.js +23 -11
  40. package/dist/src/core/component-source-guard.d.ts +20 -0
  41. package/dist/src/core/component-source-guard.js +68 -0
  42. package/dist/src/core/coverage-extend.d.ts +5 -34
  43. package/dist/src/core/coverage-extend.js +26 -37
  44. package/dist/src/core/engine-write-boundary.d.ts +5 -0
  45. package/dist/src/core/engine-write-boundary.js +41 -0
  46. package/dist/src/core/furnace-apply-helpers.js +8 -2
  47. package/dist/src/core/furnace-apply.js +7 -0
  48. package/dist/src/core/furnace-validate-accessibility.js +9 -12
  49. package/dist/src/core/furnace-validate.js +0 -43
  50. package/dist/src/core/gecko-dom-types.d.ts +2 -0
  51. package/dist/src/core/gecko-dom-types.js +17 -0
  52. package/dist/src/core/lit-template-regions.d.ts +4 -0
  53. package/dist/src/core/lit-template-regions.js +50 -0
  54. package/dist/src/core/mach-build-artifacts.d.ts +6 -6
  55. package/dist/src/core/mach-build-artifacts.js +13 -7
  56. package/dist/src/core/mach-resource-shim.d.ts +1 -1
  57. package/dist/src/core/mach-resource-shim.js +2 -0
  58. package/dist/src/core/marionette-port.d.ts +2 -0
  59. package/dist/src/core/marionette-port.js +38 -53
  60. package/dist/src/core/mochitest-server-port.d.ts +1 -1
  61. package/dist/src/core/mochitest-server-port.js +20 -17
  62. package/dist/src/core/objdir-maintenance.d.ts +10 -0
  63. package/dist/src/core/objdir-maintenance.js +151 -0
  64. package/dist/src/core/patch-lint-checkjs.js +2 -1
  65. package/dist/src/core/preflight-wait.d.ts +2 -0
  66. package/dist/src/core/preflight-wait.js +24 -0
  67. package/dist/src/core/process-owner.d.ts +9 -0
  68. package/dist/src/core/process-owner.js +43 -0
  69. package/dist/src/core/test-harness-crash.d.ts +1 -1
  70. package/dist/src/core/test-harness-crash.js +5 -5
  71. package/dist/src/core/test-host-state.d.ts +14 -0
  72. package/dist/src/core/test-host-state.js +80 -0
  73. package/dist/src/core/test-profile-files.d.ts +17 -0
  74. package/dist/src/core/test-profile-files.js +75 -0
  75. package/dist/src/core/test-stale-check.d.ts +6 -7
  76. package/dist/src/core/test-stale-check.js +9 -32
  77. package/dist/src/core/token-category.d.ts +7 -26
  78. package/dist/src/core/token-category.js +68 -121
  79. package/dist/src/core/token-inventory.js +12 -7
  80. package/dist/src/core/typecheck.js +6 -6
  81. package/dist/src/types/commands/options.d.ts +14 -3
  82. package/dist/src/utils/assert.js +2 -7
  83. package/dist/src/utils/child-env.d.ts +0 -3
  84. package/dist/src/utils/child-env.js +0 -3
  85. package/dist/src/utils/concurrency.d.ts +2 -2
  86. package/dist/src/utils/concurrency.js +15 -4
  87. package/dist/src/utils/fs.js +11 -1
  88. package/dist/src/utils/options.d.ts +16 -1
  89. package/dist/src/utils/options.js +5 -3
  90. package/dist/src/utils/paths.js +3 -2
  91. package/dist/src/utils/process-group.d.ts +1 -2
  92. package/dist/src/utils/process-group.js +1 -2
  93. package/dist/src/utils/process-input.js +0 -3
  94. package/dist/src/utils/process.d.ts +3 -2
  95. package/dist/src/utils/process.js +19 -7
  96. package/docs/configuration.md +12 -11
  97. package/docs/lifecycle-invariants.md +9 -5
  98. package/docs/machine-output.md +36 -19
  99. package/docs/patch-workflow.md +15 -0
  100. package/docs/testing.md +77 -12
  101. package/package.json +4 -3
package/docs/testing.md CHANGED
@@ -34,9 +34,59 @@ build, `test` fails before launching stale artifacts. Use `--build` to
34
34
  refresh, or `--allow-stale-build` only for intentional out-of-band rebuilds.
35
35
 
36
36
  `--build-only` packages mixed-harness paths once, and then each harness half
37
- can run without `--build`. `--extend-coverage` retains prior scoped coverage
38
- instead of replacing it. It is refused when the build anchor moved (engine
39
- HEAD, `engine/mozconfig`, or a previously fingerprinted packageable file).
37
+ can run without `--build`. Scoped builds retain prior coverage automatically
38
+ when engine HEAD, `engine/mozconfig` and recorded staging inputs outside the
39
+ rebuilt scope are unchanged. Changed files explicitly included in this
40
+ build are allowed. The fingerprints include test scripts and support files,
41
+ not only packageable chrome sources. A failed anchor narrows the claim and
42
+ prints the dropped paths; `--extend-coverage` instead refuses. Baselines
43
+ without complete staging-input fingerprints require a new build before they
44
+ can retain prior coverage.
45
+ New dirty inputs outside the rebuilt scope invalidate retention conservatively,
46
+ including shared fixtures outside test directories.
47
+
48
+ When `patchLint.checkJs` and `patchLint.checkJsTestFiles` are enabled, named
49
+ pre-test builds check the selected test scripts before deployment or mach.
50
+ This includes new scripts not yet owned by an exported patch.
51
+
52
+ ### Shared browsers, ports and host state
53
+
54
+ Browser ownership is checked before a pre-test deployment and before full
55
+ or UI builds. A live or unreadable parent means busy, with its owner named
56
+ when available. `--kill-stale-marionette` requires a dead parent plus harness
57
+ arguments; a profile argument alone does not prove abandonment. A plain
58
+ launchd-parented app remains unattributed and is not automatically killed.
59
+
60
+ `test --wait-browser [seconds]` waits for this objdir's browser to exit;
61
+ `test --wait-port [seconds]` waits for mochitest and Marionette listeners.
62
+ `build --wait-browser [seconds]` queues a full or UI build behind the browser.
63
+ Bare flags wait 60 seconds; explicit values accept 1–3600 seconds. They are
64
+ independent of the FireForge lock budget. On expiry the normal preflight
65
+ refusal and its remedy are preserved.
66
+
67
+ Every suite samples host load and the highest CPU process before and after
68
+ dispatch. Load at least 4 or a process at least 90% CPU produces a warning;
69
+ verdicts include `host-load` and, when needed, `host-cpu-warning=true`.
70
+ Perf runs include `power-source=ac|battery|unknown`; on macOS this comes from
71
+ `pmset -g ps`, including charging on AC. Sample JSON gains a `fireforgeHost`
72
+ object with start/end states and `powerSourceChanged`. A known power-source
73
+ transition produces `FAIL reason=inconclusive power-changed=true`.
74
+ Unknown power state is reported without inventing a transition.
75
+
76
+ ### Profile overlays
77
+
78
+ Use repeatable `--profile-file source=relative/destination` to add files to
79
+ the test profile, for example:
80
+
81
+ ```sh
82
+ fireforge test --perf-samples sample.json --profile-file arm.css=chrome/userChrome.css browser/base/content/test/perf/browser_perf.js
83
+ ```
84
+
85
+ The source resolves from the project root. Destinations must stay relative
86
+ with no traversal. FireForge stages copies and merges only those staged
87
+ directories into the harness profile, preserving existing chrome files.
88
+ A raw `--extra-profile-file` directory collision is classified as
89
+ `reason=harness-arguments` and names this remedy rather than a rebuild.
40
90
 
41
91
  ### What a pre-test build costs
42
92
 
@@ -183,15 +233,16 @@ redirected run keeps the reason as well as the verdict. See
183
233
 
184
234
  ## Seeded shuffle
185
235
 
186
- `fireforge test --shuffle` runs a mochitest selection in a seeded random file
187
- order and prints the seed; `--shuffle=<seed>` replays it. FireForge forwards
188
- mach's own `--shuffle`, exports `FIREFORGE_SHUFFLE_SEED=<seed>` to the harness
189
- so in-file task reordering (harness `head.js` code, not FireForge) can key off
190
- the same number, and stamps `shuffle=<seed>` on the verdict line. It is
191
- mochitest-only: the xpcshell harness has no shuffle, and generic `mach test`
192
- dispatch would hand the flag to every suite. Write the flag as
193
- `--shuffle=<seed>` or after the paths, because a bare `--shuffle <path>` reads
194
- the path as the seed.
236
+ `fireforge test --shuffle` deterministically permutes isolated mochitest path
237
+ arguments and prints the seed; `--shuffle=<seed>` replays that shard order for
238
+ the same input selection. A directory remains one invocation. `--no-shard`
239
+ disables this argument permutation. FireForge also forwards native mach
240
+ `--shuffle` within each invocation, whose file order remains unseeded and is
241
+ not replayed by the FireForge seed. `FIREFORGE_SHUFFLE_SEED=<seed>` is available
242
+ to custom harness `head.js` code for in-file task ordering, and `shuffle=<seed>`
243
+ is recorded on the verdict. The option is mochitest-only. Write
244
+ `--shuffle=<seed>` or place it after the paths because a bare
245
+ `--shuffle <path>` consumes the path as its optional seed.
195
246
 
196
247
  Exit code 14 (`INCONCLUSIVE`) is not red: it means `engine/` moved while the
197
248
  harness ran and the result was thrown away. Exit 15 (`LOCK_TIMEOUT`) means
@@ -256,3 +307,17 @@ instead, use a [verification tree](verification-trees.md).
256
307
  In dev builds, files under `obj-*/dist/bin` may be symlinks back into the
257
308
  source tree (prefs especially), so edit source prefs directly and keep a
258
309
  backup before bisection experiments.
310
+
311
+ ## Repository release gate
312
+
313
+ Run `npm run release:check` with the exact Node version in `.nvmrc` and npm
314
+ version in `package.json`'s `packageManager`. The gate verifies these pins
315
+ before formatting, whitespace, zero-warning lint, strict typecheck, development
316
+ and production dead-code checks, import cycles, coverage floors, and installed
317
+ package smoke tests. `prepublishOnly` and the CI quality job run the same gate.
318
+ Supported Node-version and OS matrices continue to run ordinary tests separately.
319
+
320
+ The full-Firefox integration runner is opt-in. It snapshots project files,
321
+ engine changes and the index before arming recovery; a refusal cannot erase an
322
+ existing workspace. Failed recovery fails the run, preserves affected paths and
323
+ writes recovery evidence for manual repair.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hominis/fireforge",
3
- "version": "0.48.0",
3
+ "version": "0.49.0",
4
4
  "description": "FireForge — a build tool for customizing Firefox",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -39,8 +39,9 @@
39
39
  "format:check": "prettier --check --ignore-unknown \"src/**/*.ts\" \"bin/**/*.ts\" \"scripts/**/*.mjs\" \"eslint-rules/**/*.js\" \"package.json\" \"eslint.config.js\" \"vitest.config.ts\" \"vitest.pack.config.ts\" \"tsconfig.json\" \"tsconfig.build.json\" \".lintstagedrc.json\" \".prettierignore\" \".prettierrc\" \".gitignore\" \"README.md\" \"CHANGELOG.md\" \"docs/**/*.md\" \"knip.json\" \"knip.production.json\"",
40
40
  "prepare": "node -e \"import('./scripts/prepare.mjs').catch((error) => { if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_MODULE_NOT_FOUND') process.exit(0); throw error; })\"",
41
41
  "prepack": "npm run build && node ./scripts/generate-build-info.mjs --loud",
42
- "release:check": "npm run format:check && npm run whitespace:check && npm run lint:ci && npm run typecheck && npm run deadcode:check && npm run deadcode:check:production && npm run cycles:check && npm run test:coverage && npm run pack:verify",
43
- "prepublishOnly": "npm run release:check"
42
+ "release:check": "npm run toolchain:check && npm run format:check && npm run whitespace:check && npm run lint:ci && npm run typecheck && npm run deadcode:check && npm run deadcode:check:production && npm run cycles:check && npm run test:coverage && npm run pack:verify",
43
+ "prepublishOnly": "npm run release:check",
44
+ "toolchain:check": "node ./scripts/check-release-toolchain.mjs"
44
45
  },
45
46
  "files": [
46
47
  "dist/",