@hominis/fireforge 0.43.1 → 0.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +153 -0
- package/README.md +3 -3
- package/dist/bin/fireforge.d.ts +4 -9
- package/dist/bin/fireforge.js +42 -40
- package/dist/build-info.json +4 -4
- package/dist/src/cli.js +74 -8
- package/dist/src/commands/bootstrap.js +17 -20
- package/dist/src/commands/build.js +25 -32
- package/dist/src/commands/config.js +34 -41
- package/dist/src/commands/discard.js +8 -9
- package/dist/src/commands/doctor-check-core.d.ts +13 -18
- package/dist/src/commands/doctor-check-core.js +8 -35
- package/dist/src/commands/doctor-external-toolchains.js +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.d.ts +18 -0
- package/dist/src/commands/{doctor-furnace-manifest-sync.js → doctor-furnace-config-sync.js} +27 -26
- package/dist/src/commands/doctor-furnace-jar.d.ts +7 -9
- package/dist/src/commands/doctor-furnace-jar.js +7 -9
- package/dist/src/commands/doctor-furnace.js +21 -24
- package/dist/src/commands/doctor-orphaned-harness.d.ts +16 -20
- package/dist/src/commands/doctor-orphaned-harness.js +18 -44
- package/dist/src/commands/doctor-patch-manifest.d.ts +8 -0
- package/dist/src/commands/doctor-patch-manifest.js +155 -0
- package/dist/src/commands/doctor-post-rebase-audit.d.ts +2 -0
- package/dist/src/commands/{doctor/post-rebase-audit.js → doctor-post-rebase-audit.js} +3 -3
- package/dist/src/commands/doctor-working-tree.d.ts +10 -12
- package/dist/src/commands/doctor-working-tree.js +11 -18
- package/dist/src/commands/doctor.d.ts +1 -1
- package/dist/src/commands/doctor.js +64 -96
- package/dist/src/commands/download.js +32 -48
- package/dist/src/commands/export-all.js +29 -33
- package/dist/src/commands/export-flow.js +6 -6
- package/dist/src/commands/export-placement-conflicts.js +10 -9
- package/dist/src/commands/export-placement-gate.js +5 -5
- package/dist/src/commands/export-shared.d.ts +30 -33
- package/dist/src/commands/export-shared.js +45 -43
- package/dist/src/commands/export.js +21 -27
- package/dist/src/commands/furnace/apply.js +14 -23
- package/dist/src/commands/furnace/chrome-doc-remove.js +14 -21
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +23 -23
- package/dist/src/commands/furnace/chrome-doc-templates.js +23 -23
- package/dist/src/commands/furnace/chrome-doc-tests.js +26 -29
- package/dist/src/commands/furnace/chrome-doc.d.ts +16 -17
- package/dist/src/commands/furnace/chrome-doc.js +31 -41
- package/dist/src/commands/furnace/create-browser-test.d.ts +4 -4
- package/dist/src/commands/furnace/create-browser-test.js +8 -8
- package/dist/src/commands/furnace/create-mochikit.d.ts +6 -7
- package/dist/src/commands/furnace/create-mochikit.js +8 -9
- package/dist/src/commands/furnace/create-readback.d.ts +12 -13
- package/dist/src/commands/furnace/create-readback.js +12 -13
- package/dist/src/commands/furnace/create-templates.d.ts +22 -28
- package/dist/src/commands/furnace/create-templates.js +35 -30
- package/dist/src/commands/furnace/create-xpcshell.js +2 -2
- package/dist/src/commands/furnace/create.js +33 -23
- package/dist/src/commands/furnace/deploy.js +16 -24
- package/dist/src/commands/furnace/diff.js +15 -10
- package/dist/src/commands/furnace/init.js +33 -36
- package/dist/src/commands/furnace/override.js +23 -25
- package/dist/src/commands/furnace/preview.js +47 -67
- package/dist/src/commands/furnace/refresh.js +12 -16
- package/dist/src/commands/furnace/remove-mutations.d.ts +3 -6
- package/dist/src/commands/furnace/remove-mutations.js +14 -17
- package/dist/src/commands/furnace/remove-state.js +1 -1
- package/dist/src/commands/furnace/remove.js +33 -38
- package/dist/src/commands/furnace/rename-xpcshell.d.ts +8 -11
- package/dist/src/commands/furnace/rename-xpcshell.js +8 -11
- package/dist/src/commands/furnace/rename.js +59 -69
- package/dist/src/commands/furnace/scan.js +19 -33
- package/dist/src/commands/furnace/status.js +12 -9
- package/dist/src/commands/furnace/sync.js +9 -16
- package/dist/src/commands/furnace/validate.js +20 -20
- package/dist/src/commands/import.js +48 -37
- package/dist/src/commands/lint-per-patch.js +15 -10
- package/dist/src/commands/lint-per-run-checkjs.d.ts +13 -13
- package/dist/src/commands/lint-per-run-checkjs.js +13 -13
- package/dist/src/commands/lint-report.js +6 -7
- package/dist/src/commands/lint.d.ts +15 -16
- package/dist/src/commands/lint.js +86 -102
- package/dist/src/commands/package.js +6 -11
- package/dist/src/commands/patch/compact.js +1 -1
- package/dist/src/commands/patch/delete.js +24 -33
- package/dist/src/commands/patch/index.d.ts +5 -6
- package/dist/src/commands/patch/index.js +10 -12
- package/dist/src/commands/patch/lint-ignore.js +14 -13
- package/dist/src/commands/patch/move-files-create.d.ts +6 -6
- package/dist/src/commands/patch/move-files-create.js +8 -8
- package/dist/src/commands/patch/move-files-into.d.ts +6 -6
- package/dist/src/commands/patch/move-files-into.js +8 -8
- package/dist/src/commands/patch/patch-context.d.ts +2 -3
- package/dist/src/commands/patch/patch-context.js +2 -3
- package/dist/src/commands/patch/rename.d.ts +10 -11
- package/dist/src/commands/patch/rename.js +11 -12
- package/dist/src/commands/patch/reorder.js +8 -9
- package/dist/src/commands/patch/split-plan.js +1 -1
- package/dist/src/commands/patch/split.d.ts +8 -10
- package/dist/src/commands/patch/split.js +9 -11
- package/dist/src/commands/patch/staged-dependency-validate.js +8 -8
- package/dist/src/commands/patch/staged-dependency.js +7 -3
- package/dist/src/commands/patch/tier.d.ts +9 -9
- package/dist/src/commands/patch/tier.js +18 -15
- package/dist/src/commands/re-export-adjacent.js +9 -8
- package/dist/src/commands/re-export-bulk-scan.d.ts +9 -9
- package/dist/src/commands/re-export-bulk-scan.js +22 -21
- package/dist/src/commands/re-export-drift.js +10 -10
- package/dist/src/commands/re-export-files.d.ts +6 -7
- package/dist/src/commands/re-export-files.js +34 -44
- package/dist/src/commands/re-export-lint.d.ts +10 -13
- package/dist/src/commands/re-export-lint.js +16 -14
- package/dist/src/commands/re-export-options.d.ts +6 -6
- package/dist/src/commands/re-export-options.js +6 -6
- package/dist/src/commands/re-export-register.d.ts +4 -10
- package/dist/src/commands/re-export-register.js +5 -11
- package/dist/src/commands/re-export-scan.js +1 -1
- package/dist/src/commands/re-export-single.d.ts +3 -3
- package/dist/src/commands/re-export-single.js +33 -25
- package/dist/src/commands/re-export.js +13 -21
- package/dist/src/commands/rebase/abort.js +3 -3
- package/dist/src/commands/rebase/confirm.js +2 -1
- package/dist/src/commands/rebase/continue.d.ts +1 -1
- package/dist/src/commands/rebase/continue.js +14 -9
- package/dist/src/commands/rebase/index.js +11 -11
- package/dist/src/commands/rebase/patch-loop.d.ts +7 -1
- package/dist/src/commands/rebase/patch-loop.js +60 -39
- package/dist/src/commands/rebase/summary.js +1 -1
- package/dist/src/commands/register.js +5 -7
- package/dist/src/commands/reset.js +2 -1
- package/dist/src/commands/resolve.d.ts +16 -13
- package/dist/src/commands/resolve.js +30 -33
- package/dist/src/commands/run.js +33 -35
- package/dist/src/commands/setup-support.js +15 -19
- package/dist/src/commands/setup.js +13 -9
- package/dist/src/commands/status-check.d.ts +6 -6
- package/dist/src/commands/status-json.d.ts +6 -6
- package/dist/src/commands/status-json.js +5 -0
- package/dist/src/commands/status-output.d.ts +5 -5
- package/dist/src/commands/status-output.js +6 -6
- package/dist/src/commands/status-ownership.d.ts +16 -14
- package/dist/src/commands/status-ownership.js +16 -14
- package/dist/src/commands/status.js +42 -34
- package/dist/src/commands/test-build-phase.js +26 -13
- package/dist/src/commands/test-diagnose.js +44 -44
- package/dist/src/commands/test-register.js +1 -0
- package/dist/src/commands/test-run.d.ts +14 -16
- package/dist/src/commands/test-run.js +21 -13
- package/dist/src/commands/test-stale-gate.d.ts +15 -16
- package/dist/src/commands/test-stale-gate.js +15 -16
- package/dist/src/commands/test-verdict.d.ts +20 -3
- package/dist/src/commands/test-verdict.js +30 -0
- package/dist/src/commands/test.js +83 -76
- package/dist/src/commands/token-coverage.js +3 -4
- package/dist/src/commands/token.js +16 -18
- package/dist/src/commands/tree.js +47 -31
- package/dist/src/commands/typecheck.d.ts +10 -12
- package/dist/src/commands/typecheck.js +24 -27
- package/dist/src/commands/verify.js +13 -15
- package/dist/src/commands/watch.js +21 -23
- package/dist/src/commands/wire.js +52 -62
- package/dist/src/core/ast-utils.d.ts +8 -7
- package/dist/src/core/ast-utils.js +8 -7
- package/dist/src/core/branding.d.ts +9 -14
- package/dist/src/core/branding.js +7 -11
- package/dist/src/core/browser-wire.d.ts +1 -1
- package/dist/src/core/browser-wire.js +14 -19
- package/dist/src/core/build-audit-platform.js +25 -33
- package/dist/src/core/build-audit-registration.js +17 -25
- package/dist/src/core/build-audit-resolve.d.ts +15 -17
- package/dist/src/core/build-audit-resolve.js +39 -36
- package/dist/src/core/build-audit-transforms.js +18 -19
- package/dist/src/core/build-audit.js +28 -42
- package/dist/src/core/build-baseline-types.d.ts +29 -35
- package/dist/src/core/build-baseline.d.ts +5 -4
- package/dist/src/core/build-baseline.js +14 -14
- package/dist/src/core/build-overwrite-guard.d.ts +7 -14
- package/dist/src/core/build-overwrite-guard.js +17 -27
- package/dist/src/core/build-prepare.d.ts +2 -2
- package/dist/src/core/build-prepare.js +8 -9
- package/dist/src/core/config-mutate.js +20 -19
- package/dist/src/core/config-state.js +12 -4
- package/dist/src/core/config-validate.js +8 -5
- package/dist/src/core/config.d.ts +5 -8
- package/dist/src/core/config.js +7 -16
- package/dist/src/core/coverage-extend.d.ts +15 -13
- package/dist/src/core/coverage-extend.js +15 -13
- package/dist/src/core/destructive.d.ts +31 -9
- package/dist/src/core/destructive.js +29 -26
- package/dist/src/core/diff-hunks.js +10 -12
- package/dist/src/core/discard-baseline.d.ts +8 -8
- package/dist/src/core/discard-baseline.js +16 -15
- package/dist/src/core/display-state.d.ts +12 -14
- package/dist/src/core/display-state.js +12 -14
- package/dist/src/core/engine-changes.d.ts +2 -4
- package/dist/src/core/engine-changes.js +2 -4
- package/dist/src/core/engine-precondition.d.ts +28 -13
- package/dist/src/core/engine-precondition.js +25 -10
- package/dist/src/core/engine-session-lock.d.ts +47 -21
- package/dist/src/core/engine-session-lock.js +168 -33
- package/dist/src/core/export-moved-code-shape.d.ts +10 -10
- package/dist/src/core/export-moved-code-shape.js +10 -10
- package/dist/src/core/file-lock.d.ts +62 -5
- package/dist/src/core/file-lock.js +196 -59
- package/dist/src/core/firefox-cache.js +1 -3
- package/dist/src/core/firefox-extract.js +10 -14
- package/dist/src/core/firefox.d.ts +7 -5
- package/dist/src/core/firefox.js +4 -5
- package/dist/src/core/furnace-apply-dry-run.d.ts +2 -2
- package/dist/src/core/furnace-apply-dry-run.js +3 -2
- package/dist/src/core/furnace-apply-ftl.d.ts +7 -9
- package/dist/src/core/furnace-apply-ftl.js +16 -13
- package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
- package/dist/src/core/furnace-apply-helpers.js +30 -21
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +8 -9
- package/dist/src/core/furnace-apply-overwrite-warn.js +8 -9
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +3 -4
- package/dist/src/core/furnace-apply-undeploy-actions.js +3 -4
- package/dist/src/core/furnace-apply.d.ts +5 -8
- package/dist/src/core/furnace-apply.js +19 -24
- package/dist/src/core/furnace-checksum-utils.d.ts +14 -0
- package/dist/src/core/furnace-checksum-utils.js +16 -0
- package/dist/src/core/furnace-config.d.ts +21 -30
- package/dist/src/core/furnace-config.js +32 -54
- package/dist/src/core/furnace-constants.d.ts +8 -0
- package/dist/src/core/furnace-constants.js +10 -2
- package/dist/src/core/furnace-css-fragments.d.ts +5 -5
- package/dist/src/core/furnace-css-fragments.js +5 -5
- package/dist/src/core/furnace-jsconfig.d.ts +11 -12
- package/dist/src/core/furnace-jsconfig.js +11 -12
- package/dist/src/core/furnace-marker.d.ts +7 -8
- package/dist/src/core/furnace-marker.js +7 -8
- package/dist/src/core/furnace-operation.d.ts +31 -0
- package/dist/src/core/furnace-operation.js +54 -17
- package/dist/src/core/furnace-precondition.d.ts +61 -0
- package/dist/src/core/furnace-precondition.js +67 -0
- package/dist/src/core/furnace-registration-remove.d.ts +5 -6
- package/dist/src/core/furnace-registration-remove.js +6 -7
- package/dist/src/core/furnace-registration-validate.d.ts +13 -0
- package/dist/src/core/furnace-registration-validate.js +20 -1
- package/dist/src/core/furnace-registration.d.ts +5 -6
- package/dist/src/core/furnace-registration.js +10 -12
- package/dist/src/core/furnace-rollback.js +7 -7
- package/dist/src/core/furnace-scanner.d.ts +1 -0
- package/dist/src/core/furnace-scanner.js +1 -2
- package/dist/src/core/furnace-stale-export.d.ts +10 -10
- package/dist/src/core/furnace-stale-export.js +10 -10
- package/dist/src/core/furnace-state-persist.d.ts +6 -8
- package/dist/src/core/furnace-state-persist.js +6 -8
- package/dist/src/core/furnace-validate-accessibility.d.ts +22 -0
- package/dist/src/core/furnace-validate-accessibility.js +310 -1
- package/dist/src/core/furnace-validate-compatibility.js +141 -1
- package/dist/src/core/furnace-validate-helpers.d.ts +5 -116
- package/dist/src/core/furnace-validate-helpers.js +0 -491
- package/dist/src/core/furnace-validate-registration.d.ts +7 -0
- package/dist/src/core/furnace-validate-registration.js +115 -41
- package/dist/src/core/furnace-validate.d.ts +16 -0
- package/dist/src/core/furnace-validate.js +188 -145
- package/dist/src/core/furnace-version-drift.d.ts +10 -11
- package/dist/src/core/furnace-version-drift.js +10 -11
- package/dist/src/core/git-base.d.ts +21 -9
- package/dist/src/core/git-base.js +24 -9
- package/dist/src/core/git-diff.d.ts +20 -9
- package/dist/src/core/git-diff.js +148 -63
- package/dist/src/core/git-file-ops.d.ts +19 -19
- package/dist/src/core/git-file-ops.js +19 -19
- package/dist/src/core/git-readonly-index.d.ts +53 -19
- package/dist/src/core/git-readonly-index.js +75 -31
- package/dist/src/core/git-status.d.ts +5 -6
- package/dist/src/core/git-status.js +5 -6
- package/dist/src/core/git.d.ts +9 -10
- package/dist/src/core/git.js +57 -71
- package/dist/src/core/license-headers.d.ts +17 -23
- package/dist/src/core/license-headers.js +17 -23
- package/dist/src/core/mach-build-artifacts.d.ts +9 -9
- package/dist/src/core/mach-build-artifacts.js +57 -19
- package/dist/src/core/mach-error-hints.js +42 -29
- package/dist/src/core/mach-known-noise-filter.d.ts +15 -16
- package/dist/src/core/mach-known-noise-filter.js +18 -20
- package/dist/src/core/mach-mozconfig.d.ts +14 -0
- package/dist/src/core/mach-mozconfig.js +30 -0
- package/dist/src/core/mach-resource-shim.d.ts +43 -58
- package/dist/src/core/mach-resource-shim.js +50 -67
- package/dist/src/core/mach.d.ts +37 -41
- package/dist/src/core/mach.js +50 -51
- package/dist/src/core/marionette-port.d.ts +36 -1
- package/dist/src/core/marionette-port.js +96 -31
- package/dist/src/core/marionette-preflight.d.ts +8 -12
- package/dist/src/core/marionette-preflight.js +86 -52
- package/dist/src/core/mochitest-server-port.d.ts +42 -0
- package/dist/src/core/mochitest-server-port.js +119 -0
- package/dist/src/core/module-resolution-preflight.d.ts +9 -11
- package/dist/src/core/module-resolution-preflight.js +9 -11
- package/dist/src/core/moz-manifest-helpers.d.ts +79 -0
- package/dist/src/core/moz-manifest-helpers.js +163 -0
- package/dist/src/core/{manifest-register.d.ts → moz-manifest-register.d.ts} +1 -1
- package/dist/src/core/{manifest-register.js → moz-manifest-register.js} +13 -28
- package/dist/src/core/{manifest-rules.d.ts → moz-manifest-rules.d.ts} +10 -1
- package/dist/src/core/{manifest-rules.js → moz-manifest-rules.js} +31 -24
- package/dist/src/core/{manifest-tokenizers.d.ts → moz-manifest-tokenizers.d.ts} +3 -5
- package/dist/src/core/{manifest-tokenizers.js → moz-manifest-tokenizers.js} +9 -12
- package/dist/src/core/ownership-table.d.ts +14 -16
- package/dist/src/core/ownership-table.js +14 -16
- package/dist/src/core/parser-fallback.d.ts +15 -1
- package/dist/src/core/parser-fallback.js +22 -3
- package/dist/src/core/patch-apply-fuzz.d.ts +10 -12
- package/dist/src/core/patch-apply-fuzz.js +15 -18
- package/dist/src/core/patch-apply.d.ts +13 -34
- package/dist/src/core/patch-apply.js +16 -76
- package/dist/src/core/patch-artifact-normalize.d.ts +13 -15
- package/dist/src/core/patch-artifact-normalize.js +13 -15
- package/dist/src/core/patch-export-metadata.d.ts +12 -2
- package/dist/src/core/patch-export-metadata.js +13 -4
- package/dist/src/core/patch-export-update.d.ts +13 -1
- package/dist/src/core/patch-export-update.js +25 -8
- package/dist/src/core/patch-export.d.ts +15 -8
- package/dist/src/core/patch-export.js +10 -11
- package/dist/src/core/patch-files.d.ts +5 -6
- package/dist/src/core/patch-files.js +5 -6
- package/dist/src/core/patch-identifier-suggest.d.ts +7 -12
- package/dist/src/core/patch-identifier-suggest.js +14 -19
- package/dist/src/core/patch-lint-binary.d.ts +51 -0
- package/dist/src/core/patch-lint-binary.js +39 -0
- package/dist/src/core/{lint-cache.d.ts → patch-lint-cache.d.ts} +5 -5
- package/dist/src/core/{lint-cache.js → patch-lint-cache.js} +21 -23
- package/dist/src/core/patch-lint-checkjs.d.ts +16 -16
- package/dist/src/core/patch-lint-checkjs.js +41 -20
- package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +6 -9
- package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -14
- package/dist/src/core/patch-lint-creators.d.ts +8 -8
- package/dist/src/core/patch-lint-creators.js +8 -8
- package/dist/src/core/patch-lint-cross.d.ts +17 -20
- package/dist/src/core/patch-lint-cross.js +16 -16
- package/dist/src/core/patch-lint-css.d.ts +3 -5
- package/dist/src/core/patch-lint-css.js +17 -22
- package/dist/src/core/patch-lint-diff-tag.d.ts +14 -16
- package/dist/src/core/patch-lint-diff-tag.js +14 -16
- package/dist/src/core/patch-lint-jsdoc.d.ts +7 -8
- package/dist/src/core/patch-lint-jsdoc.js +26 -19
- package/dist/src/core/patch-lint-mozbuild.js +20 -20
- package/dist/src/core/patch-lint-observer.d.ts +7 -7
- package/dist/src/core/patch-lint-observer.js +7 -7
- package/dist/src/core/patch-lint.d.ts +38 -29
- package/dist/src/core/patch-lint.js +89 -121
- package/dist/src/core/patch-lock.d.ts +1 -1
- package/dist/src/core/patch-lock.js +45 -9
- package/dist/src/core/patch-manifest-consistency.d.ts +57 -6
- package/dist/src/core/patch-manifest-consistency.js +111 -40
- package/dist/src/core/patch-manifest-files-affected.d.ts +43 -0
- package/dist/src/core/patch-manifest-files-affected.js +77 -0
- package/dist/src/core/patch-manifest-io.js +14 -18
- package/dist/src/core/patch-manifest-resolve.d.ts +9 -12
- package/dist/src/core/patch-manifest-resolve.js +9 -12
- package/dist/src/core/patch-manifest-validate.d.ts +6 -1
- package/dist/src/core/patch-manifest-validate.js +25 -13
- package/dist/src/core/patch-manifest.d.ts +2 -1
- package/dist/src/core/patch-manifest.js +2 -1
- package/dist/src/core/patch-parse.d.ts +24 -13
- package/dist/src/core/patch-parse.js +19 -14
- package/dist/src/core/patch-policy.d.ts +2 -2
- package/dist/src/core/patch-policy.js +2 -2
- package/dist/src/core/patch-registration-refs.d.ts +7 -8
- package/dist/src/core/patch-registration-refs.js +9 -9
- package/dist/src/core/process-cpu-time.d.ts +12 -0
- package/dist/src/core/process-cpu-time.js +52 -0
- package/dist/src/core/rebase-session.d.ts +38 -26
- package/dist/src/core/rebase-session.js +55 -28
- package/dist/src/core/register-browser-content.js +9 -74
- package/dist/src/core/{register-test-manifest.js → register-browser-test.js} +7 -42
- package/dist/src/core/register-module.js +10 -43
- package/dist/src/core/register-scaffold.d.ts +8 -8
- package/dist/src/core/register-scaffold.js +10 -10
- package/dist/src/core/register-shared-css.d.ts +9 -12
- package/dist/src/core/register-shared-css.js +17 -87
- package/dist/src/core/register-xpcshell-test.d.ts +6 -7
- package/dist/src/core/register-xpcshell-test.js +7 -8
- package/dist/src/core/shared-ftl.js +12 -4
- package/dist/src/core/state-file.d.ts +45 -0
- package/dist/src/core/state-file.js +34 -0
- package/dist/src/core/status-binary.d.ts +18 -11
- package/dist/src/core/status-binary.js +19 -12
- package/dist/src/core/status-classify.d.ts +30 -36
- package/dist/src/core/status-classify.js +21 -26
- package/dist/src/core/test-changed-prefs.d.ts +30 -0
- package/dist/src/core/test-changed-prefs.js +78 -0
- package/dist/src/core/test-harness-crash.d.ts +25 -63
- package/dist/src/core/test-harness-crash.js +121 -142
- package/dist/src/core/test-harness-signature.d.ts +18 -0
- package/dist/src/core/test-harness-signature.js +13 -0
- package/dist/src/core/test-path-scope.d.ts +12 -15
- package/dist/src/core/test-path-scope.js +15 -18
- package/dist/src/core/test-stale-check.d.ts +17 -17
- package/dist/src/core/test-stale-check.js +50 -43
- package/dist/src/core/test-stall-triage.d.ts +51 -0
- package/dist/src/core/test-stall-triage.js +126 -0
- package/dist/src/core/token-category.js +66 -14
- package/dist/src/core/token-coverage.js +9 -9
- package/dist/src/core/token-dark-mode.d.ts +9 -11
- package/dist/src/core/token-dark-mode.js +29 -13
- package/dist/src/core/token-docs.d.ts +2 -0
- package/dist/src/core/token-docs.js +3 -1
- package/dist/src/core/token-manager.d.ts +10 -2
- package/dist/src/core/token-manager.js +17 -8
- package/dist/src/core/token-scaffold.d.ts +7 -7
- package/dist/src/core/token-scaffold.js +7 -7
- package/dist/src/core/token-variant.d.ts +4 -4
- package/dist/src/core/token-variant.js +28 -6
- package/dist/src/core/toolchain-preflight.d.ts +20 -21
- package/dist/src/core/toolchain-preflight.js +28 -31
- package/dist/src/core/tree-guard.js +12 -2
- package/dist/src/core/tree-store.d.ts +41 -27
- package/dist/src/core/tree-store.js +68 -43
- package/dist/src/core/typecheck-shim.d.ts +23 -24
- package/dist/src/core/typecheck-shim.js +23 -24
- package/dist/src/core/typecheck.js +15 -9
- package/dist/src/core/wire-destroy.d.ts +3 -3
- package/dist/src/core/wire-destroy.js +7 -15
- package/dist/src/core/wire-dom-fragment.d.ts +9 -17
- package/dist/src/core/wire-dom-fragment.js +11 -44
- package/dist/src/core/wire-init.d.ts +2 -3
- package/dist/src/core/wire-init.js +8 -19
- package/dist/src/core/wire-subscript.d.ts +2 -3
- package/dist/src/core/wire-subscript.js +4 -13
- package/dist/src/core/wire-utils.d.ts +7 -8
- package/dist/src/core/wire-utils.js +7 -8
- package/dist/src/core/xpcshell-appdir.d.ts +38 -45
- package/dist/src/core/xpcshell-appdir.js +38 -45
- package/dist/src/errors/base.d.ts +37 -16
- package/dist/src/errors/base.js +37 -16
- package/dist/src/errors/build.d.ts +13 -1
- package/dist/src/errors/build.js +14 -2
- package/dist/src/errors/codes.d.ts +16 -0
- package/dist/src/errors/codes.js +16 -0
- package/dist/src/errors/furnace.d.ts +4 -4
- package/dist/src/errors/git.d.ts +6 -10
- package/dist/src/errors/git.js +6 -10
- package/dist/src/errors/patch.d.ts +7 -7
- package/dist/src/errors/patch.js +7 -7
- package/dist/src/errors/rebase.d.ts +4 -4
- package/dist/src/errors/rebase.js +4 -4
- package/dist/src/index.d.ts +7 -1
- package/dist/src/index.js +5 -0
- package/dist/src/types/commands/index.d.ts +2 -2
- package/dist/src/types/commands/options.d.ts +111 -70
- package/dist/src/types/commands/patches.d.ts +24 -34
- package/dist/src/types/commands/project.d.ts +5 -34
- package/dist/src/types/config.d.ts +25 -23
- package/dist/src/types/config.js +6 -1
- package/dist/src/types/furnace.d.ts +37 -13
- package/dist/src/types/furnace.js +19 -1
- package/dist/src/types/index.d.ts +3 -3
- package/dist/src/utils/build-info.d.ts +7 -8
- package/dist/src/utils/build-info.js +12 -11
- package/dist/src/utils/errors.d.ts +6 -8
- package/dist/src/utils/errors.js +6 -8
- package/dist/src/utils/logger.d.ts +27 -10
- package/dist/src/utils/logger.js +28 -16
- package/dist/src/utils/machine-output.d.ts +12 -0
- package/dist/src/utils/machine-output.js +33 -0
- package/dist/src/utils/options.d.ts +31 -14
- package/dist/src/utils/options.js +86 -30
- package/dist/src/utils/paths.d.ts +10 -8
- package/dist/src/utils/paths.js +10 -8
- package/dist/src/utils/platform.d.ts +0 -25
- package/dist/src/utils/platform.js +1 -42
- package/dist/src/utils/process-group.d.ts +9 -4
- package/dist/src/utils/process-group.js +19 -5
- package/dist/src/utils/process.d.ts +42 -7
- package/dist/src/utils/process.js +44 -17
- package/dist/src/utils/ps-duration.d.ts +31 -0
- package/dist/src/utils/ps-duration.js +70 -0
- package/dist/src/utils/regex.d.ts +9 -10
- package/dist/src/utils/regex.js +9 -10
- package/dist/src/utils/validation.d.ts +58 -28
- package/dist/src/utils/validation.js +60 -33
- package/package.json +3 -3
- package/dist/src/commands/doctor/post-rebase-audit.d.ts +0 -2
- package/dist/src/commands/doctor-furnace-manifest-sync.d.ts +0 -18
- package/dist/src/core/manifest-helpers.d.ts +0 -38
- package/dist/src/core/manifest-helpers.js +0 -120
- /package/dist/src/core/{lint-projection.d.ts → patch-lint-projection.d.ts} +0 -0
- /package/dist/src/core/{lint-projection.js → patch-lint-projection.js} +0 -0
- /package/dist/src/core/{register-test-manifest.d.ts → register-browser-test.d.ts} +0 -0
|
@@ -3,26 +3,26 @@ import type { ExportOptions, PatchCategory } from '../types/commands/index.js';
|
|
|
3
3
|
import type { FireForgeConfig } from '../types/config.js';
|
|
4
4
|
import type { SpinnerHandle } from '../utils/logger.js';
|
|
5
5
|
/**
|
|
6
|
-
* Runs the full patch lint pipeline and reports results.
|
|
7
|
-
*
|
|
6
|
+
* Runs the full patch lint pipeline and reports results. Warnings are always
|
|
7
|
+
* displayed. Errors block the export unless skipLint is true.
|
|
8
8
|
*
|
|
9
9
|
* @param engineDir - Engine root directory
|
|
10
10
|
* @param filesAffected - Files touched by the patch
|
|
11
11
|
* @param diffContent - Raw unified diff string
|
|
12
12
|
* @param config - Project configuration
|
|
13
13
|
* @param skipLint - If true, downgrade errors to warnings
|
|
14
|
-
* @param patchQueueCtx - Optional cross-patch context for ownership
|
|
14
|
+
* @param patchQueueCtx - Optional cross-patch context for ownership
|
|
15
|
+
* resolution
|
|
15
16
|
* @param ignoreChecks - Optional per-patch set of `check` IDs to suppress
|
|
16
17
|
* (threaded from `PatchMetadata.lintIgnore`). Surgical alternative to
|
|
17
18
|
* `--skip-lint` when exactly one advisory rule does not apply to a
|
|
18
|
-
* specific patch — e.g. `large-patch-lines` on a cohesive branding
|
|
19
|
-
*
|
|
19
|
+
* specific patch — e.g. `large-patch-lines` on a cohesive branding bundle
|
|
20
|
+
* that genuinely cannot be split.
|
|
20
21
|
* @param patchTier - Optional explicit tier override (threaded from
|
|
21
|
-
* `PatchMetadata.tier`). Forces the branding-tier thresholds when
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* visible rather than silent.
|
|
22
|
+
* `PatchMetadata.tier`). Forces the branding-tier thresholds when set,
|
|
23
|
+
* independent of the auto-detect allowlist. When the branding tier is
|
|
24
|
+
* applied, a single `info()` line surfaces the choice so the tier decision
|
|
25
|
+
* is visible rather than silent.
|
|
26
26
|
*/
|
|
27
27
|
export declare function runPatchLint(engineDir: string, filesAffected: string[], diffContent: string, config: FireForgeConfig, skipLint?: boolean, patchQueueCtx?: import('../core/patch-lint-cross.js').PatchQueueContext, ignoreChecks?: ReadonlySet<string>, patchTier?: 'branding'): Promise<void>;
|
|
28
28
|
/**
|
|
@@ -55,18 +55,18 @@ export declare function confirmSupersedePatches(patchesDir: string, filesAffecte
|
|
|
55
55
|
/**
|
|
56
56
|
* Detects new files missing license headers and offers to add them.
|
|
57
57
|
*
|
|
58
|
-
* In interactive mode the user is prompted before any files are modified.
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* In interactive mode the user is prompted before any files are modified. In
|
|
59
|
+
* non-interactive mode the function is a no-op — the existing lint error
|
|
60
|
+
* blocks the export instead.
|
|
61
61
|
*
|
|
62
62
|
* @param engineDir - Absolute path to engine directory
|
|
63
63
|
* @param diffContent - Current unified diff
|
|
64
64
|
* @param config - Project configuration
|
|
65
65
|
* @param isInteractive - Whether interactive prompts are available
|
|
66
66
|
* @param dryRun - When true, only REPORT missing headers, never prompt or
|
|
67
|
-
* write. Dry-run must stay read-only:
|
|
68
|
-
*
|
|
69
|
-
*
|
|
67
|
+
* write. Dry-run must stay read-only: without this flag an interactive
|
|
68
|
+
* `export --dry-run` prompts (default Yes), writes license headers into
|
|
69
|
+
* engine/ files, and then closes with "no changes made".
|
|
70
70
|
* @returns true if files were modified on disk (caller must regenerate diff)
|
|
71
71
|
*/
|
|
72
72
|
export declare function autoFixLicenseHeaders(engineDir: string, diffContent: string, config: FireForgeConfig, isInteractive: boolean, dryRun?: boolean): Promise<boolean>;
|
|
@@ -83,19 +83,17 @@ export declare function autoFixLicenseHeaders(engineDir: string, diffContent: st
|
|
|
83
83
|
export declare function findPartialOwnershipOverlap(manifest: PatchesManifest, filesAffected: string[], excludeFilenames: ReadonlySet<string>): Map<string, string[]>;
|
|
84
84
|
/**
|
|
85
85
|
* Gate that refuses the default export path when the new patch would
|
|
86
|
-
* silently claim files
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* `browser/themes/shared/jar.inc.mn` after a second export with
|
|
91
|
-
* `--before`).
|
|
86
|
+
* silently claim files already tracked by other non-superseded patches.
|
|
87
|
+
* `findAllPatchesForFiles` catches the full-coverage supersede case; this
|
|
88
|
+
* fills the gap for PARTIAL overlap — two patches both claiming e.g.
|
|
89
|
+
* `browser/themes/shared/jar.inc.mn` after a second export with `--before`.
|
|
92
90
|
*
|
|
93
91
|
* Proceeds silently when there is no overlap, or when the caller passed
|
|
94
92
|
* `--allow-overlap`. In interactive mode the caller is prompted to
|
|
95
93
|
* acknowledge the overlap (the proper fix path is `re-export --files` to
|
|
96
94
|
* repartition ownership, so the prompt surfaces that pointer). In
|
|
97
|
-
* non-interactive mode
|
|
98
|
-
*
|
|
95
|
+
* non-interactive mode it throws — better to fail fast than let the queue
|
|
96
|
+
* fall out of sync with verify.
|
|
99
97
|
*/
|
|
100
98
|
export declare function guardOwnershipOverlap(args: {
|
|
101
99
|
patchesDir: string;
|
|
@@ -107,13 +105,12 @@ export declare function guardOwnershipOverlap(args: {
|
|
|
107
105
|
}): Promise<boolean>;
|
|
108
106
|
/**
|
|
109
107
|
* Runs the two pre-commit gates shared by `export` and `export-all` in
|
|
110
|
-
* order: the supersede confirmation, then the cross-patch ownership
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* patches both claimed the file and `verify` failed immediately).
|
|
108
|
+
* order: the supersede confirmation, then the cross-patch ownership overlap
|
|
109
|
+
* guard. The overlap guard receives the filenames of the patches the export
|
|
110
|
+
* would fully supersede so it does not flag a file claimed by a patch that
|
|
111
|
+
* is about to be removed. Catching only FULL-coverage supersedes leaves a
|
|
112
|
+
* second export targeting a shared file creating a queue where two patches
|
|
113
|
+
* both claim it and `verify` fails immediately.
|
|
117
114
|
*
|
|
118
115
|
* @param args - Gate inputs shared by both export commands
|
|
119
116
|
* @param args.patchesDir - Absolute path of the patches directory
|
|
@@ -122,8 +119,8 @@ export declare function guardOwnershipOverlap(args: {
|
|
|
122
119
|
* @param args.allowOverlap - The command's `--allow-overlap` flag
|
|
123
120
|
* @param args.isInteractive - Whether prompting the operator is possible
|
|
124
121
|
* @param args.s - Active spinner, stopped before any prompt
|
|
125
|
-
* @returns `true` when both gates passed; `false` when the operator
|
|
126
|
-
*
|
|
122
|
+
* @returns `true` when both gates passed; `false` when the operator declined
|
|
123
|
+
* (the caller returns without committing)
|
|
127
124
|
*/
|
|
128
125
|
export declare function runSupersedeAndOverlapGates(args: {
|
|
129
126
|
patchesDir: string;
|
|
@@ -10,36 +10,36 @@ import { getPatchPolicyCategories, isCategoryAllowedByConfig } from '../core/pat
|
|
|
10
10
|
import { GeneralError, InvalidArgumentError } from '../errors/base.js';
|
|
11
11
|
import { pathExists, readText } from '../utils/fs.js';
|
|
12
12
|
import { cancel, info, isCancel, warn } from '../utils/logger.js';
|
|
13
|
-
import { normalizePatchDisplayName, PATCH_CATEGORIES,
|
|
13
|
+
import { describePatchNameProblem, normalizePatchDisplayName, PATCH_CATEGORIES, } from '../utils/validation.js';
|
|
14
14
|
/**
|
|
15
|
-
* Runs the full patch lint pipeline and reports results.
|
|
16
|
-
*
|
|
15
|
+
* Runs the full patch lint pipeline and reports results. Warnings are always
|
|
16
|
+
* displayed. Errors block the export unless skipLint is true.
|
|
17
17
|
*
|
|
18
18
|
* @param engineDir - Engine root directory
|
|
19
19
|
* @param filesAffected - Files touched by the patch
|
|
20
20
|
* @param diffContent - Raw unified diff string
|
|
21
21
|
* @param config - Project configuration
|
|
22
22
|
* @param skipLint - If true, downgrade errors to warnings
|
|
23
|
-
* @param patchQueueCtx - Optional cross-patch context for ownership
|
|
23
|
+
* @param patchQueueCtx - Optional cross-patch context for ownership
|
|
24
|
+
* resolution
|
|
24
25
|
* @param ignoreChecks - Optional per-patch set of `check` IDs to suppress
|
|
25
26
|
* (threaded from `PatchMetadata.lintIgnore`). Surgical alternative to
|
|
26
27
|
* `--skip-lint` when exactly one advisory rule does not apply to a
|
|
27
|
-
* specific patch — e.g. `large-patch-lines` on a cohesive branding
|
|
28
|
-
*
|
|
28
|
+
* specific patch — e.g. `large-patch-lines` on a cohesive branding bundle
|
|
29
|
+
* that genuinely cannot be split.
|
|
29
30
|
* @param patchTier - Optional explicit tier override (threaded from
|
|
30
|
-
* `PatchMetadata.tier`). Forces the branding-tier thresholds when
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* visible rather than silent.
|
|
31
|
+
* `PatchMetadata.tier`). Forces the branding-tier thresholds when set,
|
|
32
|
+
* independent of the auto-detect allowlist. When the branding tier is
|
|
33
|
+
* applied, a single `info()` line surfaces the choice so the tier decision
|
|
34
|
+
* is visible rather than silent.
|
|
35
35
|
*/
|
|
36
36
|
export async function runPatchLint(engineDir, filesAffected, diffContent, config, skipLint, patchQueueCtx, ignoreChecks, patchTier) {
|
|
37
|
-
// Compute the tier decision independently of the lint pipeline so
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
37
|
+
// Compute the tier decision independently of the lint pipeline so it can
|
|
38
|
+
// be surfaced even when the rule body emitted no issues — a branding patch
|
|
39
|
+
// under the soft threshold still benefits from operators knowing which
|
|
40
|
+
// tier governed the run. The same helper is reused inside `lintPatchSize`,
|
|
41
|
+
// so the surfaced tier and the tier that actually drove the thresholds
|
|
42
|
+
// never drift.
|
|
43
43
|
const tierDecision = resolvePatchSizeTier(filesAffected, patchTier);
|
|
44
44
|
if (tierDecision.tier === 'branding') {
|
|
45
45
|
info(tierDecision.source === 'explicit'
|
|
@@ -54,7 +54,12 @@ export async function runPatchLint(engineDir, filesAffected, diffContent, config
|
|
|
54
54
|
const checkJsReportScope = patchQueueCtx
|
|
55
55
|
? resolvePatchOwnedSysMjs(detectNewFilesInDiff(diffContent))
|
|
56
56
|
: undefined;
|
|
57
|
-
const issues = await lintExportedPatch(engineDir, filesAffected, diffContent, config,
|
|
57
|
+
const issues = await lintExportedPatch(engineDir, filesAffected, diffContent, config, {
|
|
58
|
+
...(patchQueueCtx ? { patchQueueCtx } : {}),
|
|
59
|
+
...(ignoreChecks ? { ignoreChecks } : {}),
|
|
60
|
+
...(patchTier ? { patchTier } : {}),
|
|
61
|
+
...(checkJsReportScope ? { checkJsReportScope } : {}),
|
|
62
|
+
});
|
|
58
63
|
reportPatchLintOutcome(issues, skipLint);
|
|
59
64
|
}
|
|
60
65
|
/**
|
|
@@ -115,7 +120,7 @@ export async function promptExportPatchMetadata(options, isInteractive, commandN
|
|
|
115
120
|
// both name shapes.
|
|
116
121
|
let patchName = options.name?.trim().replace(/\.patch$/i, '');
|
|
117
122
|
if (patchName) {
|
|
118
|
-
const validationError =
|
|
123
|
+
const validationError = describePatchNameProblem(patchName);
|
|
119
124
|
if (validationError) {
|
|
120
125
|
throw new InvalidArgumentError(validationError, '--name');
|
|
121
126
|
}
|
|
@@ -127,7 +132,7 @@ export async function promptExportPatchMetadata(options, isInteractive, commandN
|
|
|
127
132
|
const nameResult = await text({
|
|
128
133
|
message: 'Enter a name for this patch:',
|
|
129
134
|
placeholder: commandName === 'export' ? 'my-change' : 'my-changes',
|
|
130
|
-
validate: (value) =>
|
|
135
|
+
validate: (value) => describePatchNameProblem((value ?? '').trim()),
|
|
131
136
|
});
|
|
132
137
|
if (isCancel(nameResult)) {
|
|
133
138
|
cancel('Export cancelled');
|
|
@@ -217,18 +222,18 @@ export async function confirmSupersedePatches(patchesDir, filesAffected, superse
|
|
|
217
222
|
/**
|
|
218
223
|
* Detects new files missing license headers and offers to add them.
|
|
219
224
|
*
|
|
220
|
-
* In interactive mode the user is prompted before any files are modified.
|
|
221
|
-
*
|
|
222
|
-
*
|
|
225
|
+
* In interactive mode the user is prompted before any files are modified. In
|
|
226
|
+
* non-interactive mode the function is a no-op — the existing lint error
|
|
227
|
+
* blocks the export instead.
|
|
223
228
|
*
|
|
224
229
|
* @param engineDir - Absolute path to engine directory
|
|
225
230
|
* @param diffContent - Current unified diff
|
|
226
231
|
* @param config - Project configuration
|
|
227
232
|
* @param isInteractive - Whether interactive prompts are available
|
|
228
233
|
* @param dryRun - When true, only REPORT missing headers, never prompt or
|
|
229
|
-
* write. Dry-run must stay read-only:
|
|
230
|
-
*
|
|
231
|
-
*
|
|
234
|
+
* write. Dry-run must stay read-only: without this flag an interactive
|
|
235
|
+
* `export --dry-run` prompts (default Yes), writes license headers into
|
|
236
|
+
* engine/ files, and then closes with "no changes made".
|
|
232
237
|
* @returns true if files were modified on disk (caller must regenerate diff)
|
|
233
238
|
*/
|
|
234
239
|
export async function autoFixLicenseHeaders(engineDir, diffContent, config, isInteractive, dryRun = false) {
|
|
@@ -324,19 +329,17 @@ export function findPartialOwnershipOverlap(manifest, filesAffected, excludeFile
|
|
|
324
329
|
}
|
|
325
330
|
/**
|
|
326
331
|
* Gate that refuses the default export path when the new patch would
|
|
327
|
-
* silently claim files
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
* `browser/themes/shared/jar.inc.mn` after a second export with
|
|
332
|
-
* `--before`).
|
|
332
|
+
* silently claim files already tracked by other non-superseded patches.
|
|
333
|
+
* `findAllPatchesForFiles` catches the full-coverage supersede case; this
|
|
334
|
+
* fills the gap for PARTIAL overlap — two patches both claiming e.g.
|
|
335
|
+
* `browser/themes/shared/jar.inc.mn` after a second export with `--before`.
|
|
333
336
|
*
|
|
334
337
|
* Proceeds silently when there is no overlap, or when the caller passed
|
|
335
338
|
* `--allow-overlap`. In interactive mode the caller is prompted to
|
|
336
339
|
* acknowledge the overlap (the proper fix path is `re-export --files` to
|
|
337
340
|
* repartition ownership, so the prompt surfaces that pointer). In
|
|
338
|
-
* non-interactive mode
|
|
339
|
-
*
|
|
341
|
+
* non-interactive mode it throws — better to fail fast than let the queue
|
|
342
|
+
* fall out of sync with verify.
|
|
340
343
|
*/
|
|
341
344
|
export async function guardOwnershipOverlap(args) {
|
|
342
345
|
const { patchesDir, filesAffected, supersedingFilenames, allowOverlap, isInteractive, s } = args;
|
|
@@ -373,13 +376,12 @@ export async function guardOwnershipOverlap(args) {
|
|
|
373
376
|
}
|
|
374
377
|
/**
|
|
375
378
|
* Runs the two pre-commit gates shared by `export` and `export-all` in
|
|
376
|
-
* order: the supersede confirmation, then the cross-patch ownership
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
* patches both claimed the file and `verify` failed immediately).
|
|
379
|
+
* order: the supersede confirmation, then the cross-patch ownership overlap
|
|
380
|
+
* guard. The overlap guard receives the filenames of the patches the export
|
|
381
|
+
* would fully supersede so it does not flag a file claimed by a patch that
|
|
382
|
+
* is about to be removed. Catching only FULL-coverage supersedes leaves a
|
|
383
|
+
* second export targeting a shared file creating a queue where two patches
|
|
384
|
+
* both claim it and `verify` fails immediately.
|
|
383
385
|
*
|
|
384
386
|
* @param args - Gate inputs shared by both export commands
|
|
385
387
|
* @param args.patchesDir - Absolute path of the patches directory
|
|
@@ -388,8 +390,8 @@ export async function guardOwnershipOverlap(args) {
|
|
|
388
390
|
* @param args.allowOverlap - The command's `--allow-overlap` flag
|
|
389
391
|
* @param args.isInteractive - Whether prompting the operator is possible
|
|
390
392
|
* @param args.s - Active spinner, stopped before any prompt
|
|
391
|
-
* @returns `true` when both gates passed; `false` when the operator
|
|
392
|
-
*
|
|
393
|
+
* @returns `true` when both gates passed; `false` when the operator declined
|
|
394
|
+
* (the caller returns without committing)
|
|
393
395
|
*/
|
|
394
396
|
export async function runSupersedeAndOverlapGates(args) {
|
|
395
397
|
const { patchesDir, filesAffected, supersede, allowOverlap, isInteractive, s } = args;
|
|
@@ -3,11 +3,12 @@ import { stat } from 'node:fs/promises';
|
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { Command, Option } from 'commander';
|
|
5
5
|
import { getProjectPaths, loadConfig } from '../core/config.js';
|
|
6
|
-
import { appendHistory } from '../core/destructive.js';
|
|
6
|
+
import { appendHistory, stdioIsInteractive } from '../core/destructive.js';
|
|
7
|
+
import { assertEngineGitReady } from '../core/engine-precondition.js';
|
|
7
8
|
import { withEngineSessionLock } from '../core/engine-session-lock.js';
|
|
8
9
|
import { collectFurnaceManagedPrefixes } from '../core/furnace-config.js';
|
|
9
10
|
import { enforceFreshFurnaceSources } from '../core/furnace-stale-export.js';
|
|
10
|
-
import { getStatusWithCodes
|
|
11
|
+
import { getStatusWithCodes } from '../core/git.js';
|
|
11
12
|
import { generateBinaryFilePatch, generateFullFilePatch } from '../core/git-diff.js';
|
|
12
13
|
import { isBinaryFile } from '../core/git-file-ops.js';
|
|
13
14
|
import { getModifiedFilesInDir, getUntrackedFiles, getUntrackedFilesInDir, } from '../core/git-status.js';
|
|
@@ -33,11 +34,10 @@ async function collectExportFiles(paths, files) {
|
|
|
33
34
|
let untrackedFiles;
|
|
34
35
|
// Accept both repo-root-relative (`engine/browser/...`) and engine-relative
|
|
35
36
|
// (`browser/...`) paths for every input, matching `register`/`test`/`lint`.
|
|
36
|
-
//
|
|
37
|
-
// `File "engine/..." has no changes to export
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
// a no-op for the lookup pipeline.
|
|
37
|
+
// Without the strip, an `engine/`-prefixed path falls through to
|
|
38
|
+
// `File "engine/..." has no changes to export.`: the status lookup sees
|
|
39
|
+
// paths relative to `paths.engine`, so the explicit prefix double-roots the
|
|
40
|
+
// candidate.
|
|
41
41
|
for (const rawInputPath of files) {
|
|
42
42
|
const inputPath = stripEnginePrefix(rawInputPath);
|
|
43
43
|
const fullInputPath = join(paths.engine, inputPath);
|
|
@@ -88,13 +88,14 @@ async function collectExportFiles(paths, files) {
|
|
|
88
88
|
return { files: [...collectedFiles].sort(), fromDirectory };
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
|
-
* Auto-excludes directory-derived files already owned by OTHER patches
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* the wrong tool for "leave
|
|
96
|
-
* files are never excluded (the
|
|
97
|
-
* with those). Prints one notice
|
|
91
|
+
* Auto-excludes directory-derived files already owned by OTHER patches.
|
|
92
|
+
*
|
|
93
|
+
* A directory export otherwise plans files owned by earlier patches into the
|
|
94
|
+
* new patch, and the duplicate-new-file-creation refusal surfaces only at
|
|
95
|
+
* placement lint, suggesting `--force-unsafe` — the wrong tool for "leave
|
|
96
|
+
* that file with its owner". Explicitly named files are never excluded (the
|
|
97
|
+
* overlap gates still confront the operator with those). Prints one notice
|
|
98
|
+
* per exclusion.
|
|
98
99
|
*/
|
|
99
100
|
async function excludeFilesOwnedByOtherPatches(patchesDir, collected) {
|
|
100
101
|
if (collected.fromDirectory.size === 0)
|
|
@@ -169,14 +170,7 @@ async function prepareExport(projectRoot, files, options) {
|
|
|
169
170
|
throw new InvalidArgumentError('--order, --before, and --after are mutually exclusive.', 'export placement');
|
|
170
171
|
}
|
|
171
172
|
const paths = getProjectPaths(projectRoot);
|
|
172
|
-
|
|
173
|
-
if (!(await pathExists(paths.engine))) {
|
|
174
|
-
throw new GeneralError('Firefox source not found. Run "fireforge download" first.');
|
|
175
|
-
}
|
|
176
|
-
// Check if it's a git repository
|
|
177
|
-
if (!(await isGitRepository(paths.engine))) {
|
|
178
|
-
throw new GeneralError('Engine directory is not a git repository. Run "fireforge download" to initialize.');
|
|
179
|
-
}
|
|
173
|
+
await assertEngineGitReady(paths.engine);
|
|
180
174
|
const collected = await collectExportFiles(paths, files);
|
|
181
175
|
let allFiles = await excludeFilesOwnedByOtherPatches(paths.patches, collected);
|
|
182
176
|
const ownershipExclusions = collected.files.length - allFiles.length;
|
|
@@ -202,10 +196,10 @@ async function prepareExport(projectRoot, files, options) {
|
|
|
202
196
|
throw new GeneralError(`Paths "${pathList}" have no changes to export.\n\n` +
|
|
203
197
|
'Run "fireforge status" to see modified files.');
|
|
204
198
|
}
|
|
205
|
-
// Stale-furnace-source gate
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
//
|
|
199
|
+
// Stale-furnace-source gate: the export captures deployed engine copies,
|
|
200
|
+
// so refuse (or warn under --allow-stale-furnace) when a covered
|
|
201
|
+
// component's source changed since the last furnace apply. Runs after
|
|
202
|
+
// --exclude-furnace so excluded furnace files never trigger it.
|
|
209
203
|
await enforceFreshFurnaceSources(projectRoot, allFiles, options.allowStaleFurnace === true, 'export');
|
|
210
204
|
let diff = await generatePatchDiff(paths.engine, allFiles);
|
|
211
205
|
if (!diff.trim()) {
|
|
@@ -222,7 +216,7 @@ async function prepareExport(projectRoot, files, options) {
|
|
|
222
216
|
await ensureDir(paths.patches);
|
|
223
217
|
}
|
|
224
218
|
const config = await loadConfig(projectRoot);
|
|
225
|
-
const isInteractive =
|
|
219
|
+
const isInteractive = stdioIsInteractive();
|
|
226
220
|
// Auto-fix missing license headers on new files (interactive only;
|
|
227
221
|
// report-only under --dry-run so the preview never mutates engine/)
|
|
228
222
|
const headersAdded = await autoFixLicenseHeaders(paths.engine, diff, config, isInteractive, options.dryRun ?? false);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { watch as fsWatch } from 'node:fs';
|
|
3
|
-
import {
|
|
3
|
+
import { loadConfig } from '../../core/config.js';
|
|
4
4
|
import { applyAllComponents, computeComponentChecksums } from '../../core/furnace-apply.js';
|
|
5
5
|
import { logApplyResult } from '../../core/furnace-apply-output.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getFurnacePaths } from '../../core/furnace-config.js';
|
|
7
7
|
import { isComponentSourceFile } from '../../core/furnace-constants.js';
|
|
8
8
|
import { runFurnaceMutation } from '../../core/furnace-operation.js';
|
|
9
|
+
import { assertFurnaceReady } from '../../core/furnace-precondition.js';
|
|
9
10
|
import { getPersistableAppliedEntry, persistSingleComponentState, shouldPersistSingleComponentState, } from '../../core/furnace-state-persist.js';
|
|
10
11
|
import { countEntriesWithBlockingStepErrors } from '../../core/furnace-step-errors.js';
|
|
11
12
|
import { findOverrideBaseVersionDrift, formatOverrideBaseVersionDriftError, formatOverrideBaseVersionDriftWarning, } from '../../core/furnace-version-drift.js';
|
|
@@ -74,11 +75,10 @@ function classifyWatchApplyError(err) {
|
|
|
74
75
|
async function runWatchLoop(projectRoot) {
|
|
75
76
|
const furnacePaths = getFurnacePaths(projectRoot);
|
|
76
77
|
// Both categories are eligible targets. The set is fixed; only existence
|
|
77
|
-
// varies over time — a component dir created AFTER watch started (
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
// creation invisible.
|
|
78
|
+
// varies over time — a component dir created AFTER watch started (the user
|
|
79
|
+
// running `furnace create` in another terminal) must be picked up without
|
|
80
|
+
// restarting watch. A one-shot `pathExists` check at startup captures only
|
|
81
|
+
// the dirs that existed then, leaving any later creation invisible.
|
|
82
82
|
const candidateDirs = [furnacePaths.overridesDir, furnacePaths.customDir];
|
|
83
83
|
const watchDirs = [];
|
|
84
84
|
const watchers = new Map();
|
|
@@ -253,16 +253,7 @@ async function runWatchLoop(projectRoot) {
|
|
|
253
253
|
*/
|
|
254
254
|
export async function furnaceApplyCommand(projectRoot, name, options = {}) {
|
|
255
255
|
intro(name ? `Furnace Apply (${name})` : 'Furnace Apply');
|
|
256
|
-
|
|
257
|
-
const paths = getProjectPaths(projectRoot);
|
|
258
|
-
if (!(await pathExists(paths.engine))) {
|
|
259
|
-
throw new FurnaceError('Engine directory not found. Run "fireforge download" first.');
|
|
260
|
-
}
|
|
261
|
-
// Load furnace config
|
|
262
|
-
if (!(await furnaceConfigExists(projectRoot))) {
|
|
263
|
-
throw new FurnaceError('No furnace.json found. Run "fireforge furnace create" or "fireforge furnace override" to get started.');
|
|
264
|
-
}
|
|
265
|
-
const config = await loadFurnaceConfig(projectRoot);
|
|
256
|
+
const { config } = await assertFurnaceReady(projectRoot);
|
|
266
257
|
const overrideCount = Object.keys(config.overrides).length;
|
|
267
258
|
const customCount = Object.keys(config.custom).length;
|
|
268
259
|
if (overrideCount === 0 && customCount === 0) {
|
|
@@ -289,12 +280,12 @@ export async function furnaceApplyCommand(projectRoot, name, options = {}) {
|
|
|
289
280
|
// `persistState: false` for a NAMED apply is load-bearing: the batch
|
|
290
281
|
// persist path replaces `appliedChecksums` wholesale with only this
|
|
291
282
|
// run's entries, and the batch loops filter to the named component —
|
|
292
|
-
// so routing a named apply through it
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
//
|
|
283
|
+
// so routing a named apply through it persists a state file containing
|
|
284
|
+
// ONLY that component, wiping every other component's checksums.
|
|
285
|
+
// Orphan detection and deleted-file undeploy both key on that state,
|
|
286
|
+
// so the wiped components' stale engine files become invisible to
|
|
287
|
+
// apply AND to `furnace validate`. Named apply merges per-component
|
|
288
|
+
// state below, exactly like `furnace deploy <name>`.
|
|
298
289
|
const applyResult = await applyAllComponents(projectRoot, dryRun, {
|
|
299
290
|
operationContext: ctx,
|
|
300
291
|
...(name !== undefined ? { componentName: name, persistState: false } : {}),
|
|
@@ -7,10 +7,11 @@ import { readdir } from 'node:fs/promises';
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { confirm } from '@clack/prompts';
|
|
9
9
|
import { loadConfig } from '../../core/config.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { stdioIsInteractive } from '../../core/destructive.js';
|
|
11
|
+
import { completeJournalRollback, runFurnaceMutation, } from '../../core/furnace-operation.js';
|
|
12
|
+
import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
|
|
13
|
+
import { createRollbackJournal, snapshotDir, snapshotFile } from '../../core/furnace-rollback.js';
|
|
12
14
|
import { FurnaceError } from '../../errors/furnace.js';
|
|
13
|
-
import { toError } from '../../utils/errors.js';
|
|
14
15
|
import { pathExists, readText, removeDir, removeFile, writeText } from '../../utils/fs.js';
|
|
15
16
|
import { cancel, info, intro, isCancel, note, outro } from '../../utils/logger.js';
|
|
16
17
|
import { buildChromeDocPlan, validateChromeDocName } from './chrome-doc.js';
|
|
@@ -87,20 +88,12 @@ async function performChromeDocRemoveMutations(args) {
|
|
|
87
88
|
await removeEmptyDirIfPresent(join(args.engineDir, 'browser/base/content/test', `${args.binaryName}-xpcshell`), journal);
|
|
88
89
|
}
|
|
89
90
|
catch (error) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
catch (rollbackError) {
|
|
97
|
-
// Matches the seven sibling mutation sites: a failed rollback leaves the
|
|
98
|
-
// engine in an unknown state, so record the repair breadcrumb and let
|
|
99
|
-
// the rollback error win rather than discarding it.
|
|
100
|
-
await recordFurnaceRollbackFailure(args.projectRoot, 'chrome-doc-rollback', `chrome-doc "${args.name}": ${toError(rollbackError).message}`);
|
|
101
|
-
throw rollbackError;
|
|
102
|
-
}
|
|
103
|
-
throw error;
|
|
91
|
+
return await completeJournalRollback(args.operationContext, journal, error, {
|
|
92
|
+
projectRoot: args.projectRoot,
|
|
93
|
+
operation: 'chrome-doc-rollback',
|
|
94
|
+
failureMessage: `Failed to remove chrome-doc "${args.name}"`,
|
|
95
|
+
subject: `chrome-doc "${args.name}"`,
|
|
96
|
+
});
|
|
104
97
|
}
|
|
105
98
|
return { removedFiles, removedJarEntries, removedTestDir };
|
|
106
99
|
}
|
|
@@ -110,9 +103,9 @@ export async function furnaceChromeDocRemoveCommand(projectRoot, name, options =
|
|
|
110
103
|
validateChromeDocName(name);
|
|
111
104
|
const forgeConfig = await loadConfig(projectRoot);
|
|
112
105
|
const engineDir = join(projectRoot, 'engine');
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
106
|
+
await assertFurnaceEngineReady(projectRoot, {
|
|
107
|
+
engineMissingSuffix: ' before removing a chrome-doc.',
|
|
108
|
+
});
|
|
116
109
|
const plan = await buildChromeDocPlan({
|
|
117
110
|
engineDir,
|
|
118
111
|
name,
|
|
@@ -125,7 +118,7 @@ export async function furnaceChromeDocRemoveCommand(projectRoot, name, options =
|
|
|
125
118
|
outro('Dry run complete');
|
|
126
119
|
return;
|
|
127
120
|
}
|
|
128
|
-
const isInteractive =
|
|
121
|
+
const isInteractive = stdioIsInteractive();
|
|
129
122
|
if (!options.yes && !isInteractive) {
|
|
130
123
|
throw new FurnaceError(`Cannot remove chrome-doc "${name}" in non-interactive mode without --yes flag.`, name);
|
|
131
124
|
}
|
|
@@ -41,23 +41,25 @@
|
|
|
41
41
|
*/
|
|
42
42
|
export declare function generateChromeDocXhtml(name: string, withTitlebar: boolean, license: string): string;
|
|
43
43
|
/**
|
|
44
|
-
* browser.xhtml-like scaffold for the document that ships as the fork's
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* browser.xhtml-like scaffold for the document that ships as the fork's MAIN
|
|
45
|
+
* BROWSER WINDOW.
|
|
46
|
+
*
|
|
47
|
+
* The generic dialog-shaped `<window>` scaffold is wrong for the
|
|
48
|
+
* `tokenHostDocuments[0]` / BROWSER_CHROME_URL target: platform C++ reads
|
|
49
|
+
* the root element BEFORE any script runs, and expects the `browser.xhtml`
|
|
50
|
+
* shape:
|
|
49
51
|
*
|
|
50
52
|
* - `<html id="main-window">` root (not `<window id="<name>-window">`) —
|
|
51
53
|
* upstream code from nsXULWindow sizing to session restore looks up
|
|
52
54
|
* `main-window` by id;
|
|
53
55
|
* - `windowtype="navigator:browser"`, `chromehidden=""` and the geometry
|
|
54
56
|
* `persist` allowlist declared as ROOT ATTRIBUTES so the platform's
|
|
55
|
-
* pre-script pass (window tracking, XULStore geometry, chrome flags)
|
|
56
|
-
*
|
|
57
|
+
* pre-script pass (window tracking, XULStore geometry, chrome flags) sees
|
|
58
|
+
* them;
|
|
57
59
|
* - the same head/bootstrap wiring (customElements.js, per-doc subscript,
|
|
58
60
|
* CSS + Fluent links) and `data-furnace-chrome-doc` sentinel as the
|
|
59
|
-
* generic scaffold, so jar.mn registration and the platform-module
|
|
60
|
-
*
|
|
61
|
+
* generic scaffold, so jar.mn registration and the platform-module guard
|
|
62
|
+
* pattern are unchanged.
|
|
61
63
|
*/
|
|
62
64
|
export declare function generateBrowserWindowXhtml(name: string, license: string): string;
|
|
63
65
|
/**
|
|
@@ -105,25 +107,23 @@ export declare function jarMnEntriesForChromeDoc(name: string): string[];
|
|
|
105
107
|
/**
|
|
106
108
|
* jar.inc.mn entry that registers the scoped CSS under `content/browser/`.
|
|
107
109
|
*
|
|
108
|
-
* The source path is `../shared/<name>-chrome.css` because `jar.inc.mn`
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* `obj-.../browser/themes/osx/shared/<name>-chrome.css
|
|
114
|
-
*
|
|
115
|
-
* `browser/themes/shared/`.
|
|
110
|
+
* The source path is `../shared/<name>-chrome.css` because `jar.inc.mn` is
|
|
111
|
+
* included from each theme-specific manifest (`browser/themes/osx/jar.mn`,
|
|
112
|
+
* `.../linux/`, `.../windows/`), and every existing entry in those manifests
|
|
113
|
+
* resolves paths relative to the INCLUDING manifest's directory. A bare
|
|
114
|
+
* `(shared/…)` path resolves to
|
|
115
|
+
* `obj-.../browser/themes/osx/shared/<name>-chrome.css`, which does not
|
|
116
|
+
* exist.
|
|
116
117
|
*/
|
|
117
118
|
export declare function jarIncMnEntryForChromeDoc(name: string): string;
|
|
118
119
|
/**
|
|
119
120
|
* locales/jar.mn entry that registers the `.ftl` under the browser locale
|
|
120
121
|
* bundle. The source path is resolved by mach-locale-jar relative to the
|
|
121
|
-
* per-locale root (e.g. `engine/browser/locales/en-US/`), and the FTL
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* and broke the first post-scaffold `fireforge build` with
|
|
122
|
+
* per-locale root (e.g. `engine/browser/locales/en-US/`), and the FTL file
|
|
123
|
+
* is scaffolded at `browser/${name}.ftl` under that root — the `%` prefix
|
|
124
|
+
* means "per-locale content" and the `browser/` subdirectory matches where
|
|
125
|
+
* the scaffolder writes. A bare `(%${name}.ftl)` points at
|
|
126
|
+
* `en-US/${name}.ftl` and breaks the first post-scaffold build with
|
|
127
127
|
* "jar.mn: Cannot find ${name}.ftl".
|
|
128
128
|
*/
|
|
129
129
|
export declare function localeJarMnEntryForChromeDoc(name: string): string;
|