@hominis/fireforge 0.43.1 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +126 -0
- package/README.md +10 -1
- 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 +4 -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-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.js +35 -53
- 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 +9 -9
- 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 +9 -16
- 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 +42 -35
- 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 +27 -33
- 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-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 +12 -12
- package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
- package/dist/src/core/furnace-apply-helpers.js +19 -16
- 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 +7 -9
- package/dist/src/core/git-base.js +7 -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 +54 -70
- 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 +16 -16
- 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 +2 -1
- package/dist/src/core/patch-manifest-consistency.js +25 -27
- 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-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 +5 -7
- 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 +9 -11
- package/dist/src/core/token-docs.d.ts +2 -0
- package/dist/src/core/token-docs.js +2 -0
- 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 +4 -4
- 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 +63 -42
- 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 +8 -8
- 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 +88 -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 +2 -2
- 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,6 +3,7 @@ import { stat } from 'node:fs/promises';
|
|
|
3
3
|
import { basename, dirname, isAbsolute, join, normalize } from 'node:path';
|
|
4
4
|
import { text } from '@clack/prompts';
|
|
5
5
|
import { getProjectPaths, loadConfig, mutateConfig, writeConfig } from '../../core/config.js';
|
|
6
|
+
import { stdioIsInteractive } from '../../core/destructive.js';
|
|
6
7
|
import { createDefaultFurnaceConfig, furnaceConfigExists, writeFurnaceConfig, } from '../../core/furnace-config.js';
|
|
7
8
|
import { DEFAULT_LICENSE } from '../../core/license-headers.js';
|
|
8
9
|
import { registerSharedCSS } from '../../core/register-shared-css.js';
|
|
@@ -15,17 +16,15 @@ import { cancel, info, intro, isCancel, note, outro, success, warn } from '../..
|
|
|
15
16
|
/**
|
|
16
17
|
* File extensions that are definitely FTL resources (not locale
|
|
17
18
|
* directories). A value ending in one of these is almost certainly the
|
|
18
|
-
* result of the operator pointing at a single FTL file instead of the
|
|
19
|
-
*
|
|
19
|
+
* result of the operator pointing at a single FTL file instead of the locale
|
|
20
|
+
* directory that contains it.
|
|
20
21
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* Rejecting file-shaped values up-front keeps the operator on the
|
|
28
|
-
* correct path before any partial state is written.
|
|
22
|
+
* `furnace init --ftl-base-path browser/<name>.ftl` otherwise produces a
|
|
23
|
+
* misleading success path: the subsequent `furnace create --localized`
|
|
24
|
+
* scaffolds an `.mjs` referencing `insertFTLIfNeeded("<name>.ftl")` while
|
|
25
|
+
* furnace.json has no component entry, leaving the scaffold orphaned.
|
|
26
|
+
* Rejecting file-shaped values up-front keeps the operator on the correct
|
|
27
|
+
* path before any partial state is written.
|
|
29
28
|
*/
|
|
30
29
|
const FTL_FILE_EXTENSIONS = new Set(['.ftl', '.properties', '.dtd']);
|
|
31
30
|
function hasFtlFileExtension(value) {
|
|
@@ -112,13 +111,13 @@ export async function furnaceInitCommand(projectRoot, options = {}) {
|
|
|
112
111
|
}
|
|
113
112
|
const paths = getProjectPaths(projectRoot);
|
|
114
113
|
// Seed the default furnace config with a tokenPrefix derived from
|
|
115
|
-
// fireforge.json's binaryName so `token coverage` sees real tokens on
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
114
|
+
// fireforge.json's binaryName so `token coverage` sees real tokens on the
|
|
115
|
+
// very first run — without the prefix default, a fresh init → token add →
|
|
116
|
+
// coverage sequence reports `0 tokens / N unknown` because the scan has
|
|
117
|
+
// nothing to key off. Loading fireforge.json here is best-effort: a
|
|
118
|
+
// project without one (mid-setup) falls through to the prefix-less
|
|
119
|
+
// default, and `token coverage` emits its existing "no tokenPrefix"
|
|
120
|
+
// warning.
|
|
122
121
|
let derivedBinaryName;
|
|
123
122
|
try {
|
|
124
123
|
const fireForgeConfig = await loadConfig(projectRoot);
|
|
@@ -129,7 +128,7 @@ export async function furnaceInitCommand(projectRoot, options = {}) {
|
|
|
129
128
|
// rare but not forbidden. Skip the prefix default in that case.
|
|
130
129
|
}
|
|
131
130
|
const config = createDefaultFurnaceConfig(derivedBinaryName ? { binaryName: derivedBinaryName } : {});
|
|
132
|
-
const isInteractive =
|
|
131
|
+
const isInteractive = stdioIsInteractive();
|
|
133
132
|
const engineForValidation = (await pathExists(paths.engine)) ? paths.engine : undefined;
|
|
134
133
|
// Resolve componentPrefix
|
|
135
134
|
if (options.prefix !== undefined) {
|
|
@@ -231,12 +230,11 @@ async function scaffoldTokensCss(projectRoot) {
|
|
|
231
230
|
info(`Tokens CSS already present at engine/${tokensCssPath}; leaving it untouched.`);
|
|
232
231
|
}
|
|
233
232
|
// Registering the tokens file in `patchLint.rawColorAllowlist` is the
|
|
234
|
-
// complement to the scaffold itself: the file exists specifically to
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
//
|
|
239
|
-
// does not duplicate the entry.
|
|
233
|
+
// complement to the scaffold itself: the file exists specifically to carry
|
|
234
|
+
// raw color literals, and without the allowlist entry the first
|
|
235
|
+
// `fireforge lint` after a `token add` fails on raw-color-value issues for
|
|
236
|
+
// tokens the operator just created. The add is idempotent, so re-running
|
|
237
|
+
// `furnace init --force` does not duplicate the entry.
|
|
240
238
|
try {
|
|
241
239
|
const existingAllowlist = forgeConfig.patchLint?.rawColorAllowlist ?? [];
|
|
242
240
|
if (!existingAllowlist.includes(tokensCssPath)) {
|
|
@@ -252,18 +250,17 @@ async function scaffoldTokensCss(projectRoot) {
|
|
|
252
250
|
warn(`Could not register tokens CSS in patchLint.rawColorAllowlist: ${toError(error).message}. ` +
|
|
253
251
|
`Add "${tokensCssPath}" manually under patchLint.rawColorAllowlist in fireforge.json if lint flags its contents.`);
|
|
254
252
|
}
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
// shared
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
// `furnace init --force` against a registered tree is a no-op.
|
|
253
|
+
// Register the tokens CSS in browser/themes/shared/jar.inc.mn so the file
|
|
254
|
+
// is owned end-to-end by tooling. Scaffolding and allowlisting it without
|
|
255
|
+
// registering leaves the very next `fireforge status` correctly flagging
|
|
256
|
+
// it as unmanaged + unregistered while `furnace deploy --dry-run` reports
|
|
257
|
+
// nothing to deploy — a documented init command turning a clean project
|
|
258
|
+
// unclean. The CSS lives at the canonical
|
|
259
|
+
// `browser/themes/shared/<binaryName>-tokens.css` path the shared-CSS rule
|
|
260
|
+
// already targets, so it gets the same
|
|
261
|
+
// `skin/classic/browser/<name>.css (../shared/<name>.css)` entry as any
|
|
262
|
+
// other shared CSS. Idempotent — `furnace init --force` against a
|
|
263
|
+
// registered tree is a no-op.
|
|
267
264
|
try {
|
|
268
265
|
const fileBase = `${forgeConfig.binaryName}-tokens.css`;
|
|
269
266
|
const result = await registerSharedCSS(paths.engine, fileBase, undefined, false);
|
|
@@ -3,11 +3,13 @@ import { readdir } from 'node:fs/promises';
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { select, text } from '@clack/prompts';
|
|
5
5
|
import { getProjectPaths, loadConfig, loadState } from '../../core/config.js';
|
|
6
|
+
import { stdioIsInteractive } from '../../core/destructive.js';
|
|
6
7
|
import { createDefaultFurnaceConfig, furnaceConfigExists, getFurnacePaths, loadFurnaceConfig, writeFurnaceConfig, } from '../../core/furnace-config.js';
|
|
7
8
|
import { resolveFtlDir } from '../../core/furnace-constants.js';
|
|
8
|
-
import {
|
|
9
|
+
import { completeJournalRollback, runFurnaceMutation } from '../../core/furnace-operation.js';
|
|
10
|
+
import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
|
|
9
11
|
import { CUSTOM_ELEMENT_TAG_PATTERN, CUSTOM_ELEMENT_TAG_RULES, } from '../../core/furnace-registration-validate.js';
|
|
10
|
-
import { createRollbackJournal, recordCreatedDir,
|
|
12
|
+
import { createRollbackJournal, recordCreatedDir, snapshotFile, } from '../../core/furnace-rollback.js';
|
|
11
13
|
import { getComponentDetails, scanWidgetsDirectory } from '../../core/furnace-scanner.js';
|
|
12
14
|
import { InvalidArgumentError } from '../../errors/base.js';
|
|
13
15
|
import { FurnaceError } from '../../errors/furnace.js';
|
|
@@ -22,9 +24,14 @@ async function loadAuthoringFurnaceConfig(projectRoot) {
|
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* Copies the source files needed for a new override into the workspace.
|
|
27
|
+
* @param engineDir - Absolute path to the engine checkout
|
|
25
28
|
* @param srcDir - Original component directory in the engine checkout
|
|
26
29
|
* @param destDir - Destination override directory in the workspace
|
|
30
|
+
* @param componentName - Custom element tag name being overridden
|
|
31
|
+
* @param hasFTL - Whether the component ships a localized `.ftl` file
|
|
27
32
|
* @param overrideType - Requested override mode
|
|
33
|
+
* @param ftlDir - Engine-relative directory the shared `.ftl` deploys into
|
|
34
|
+
* @param journal - Rollback journal every write is recorded in
|
|
28
35
|
* @returns Filenames copied into the override directory
|
|
29
36
|
*/
|
|
30
37
|
async function copyOverrideFiles(engineDir, srcDir, destDir, componentName, hasFTL, overrideType, ftlDir, journal) {
|
|
@@ -81,10 +88,10 @@ async function copyOverrideFiles(engineDir, srcDir, destDir, componentName, hasF
|
|
|
81
88
|
/**
|
|
82
89
|
* Writes override metadata to disk and updates furnace.json with the new
|
|
83
90
|
* override entry. Re-reads the current on-disk furnace.json inside the
|
|
84
|
-
* operation lock and splices the new entry onto the fresh state so two
|
|
85
|
-
* concurrent `furnace override` commands cannot race their read-modify
|
|
86
|
-
*
|
|
87
|
-
*
|
|
91
|
+
* operation lock and splices the new entry onto the fresh state, so two
|
|
92
|
+
* concurrent `furnace override` commands cannot race their read-modify-write
|
|
93
|
+
* cycles into a single surviving entry — otherwise both report success and
|
|
94
|
+
* furnace.json keeps only the second writer's.
|
|
88
95
|
*/
|
|
89
96
|
async function saveOverrideConfig(projectRoot, destDir, componentName, overrideType, description, details, firefoxVersion, journal, baseCommit) {
|
|
90
97
|
const overrideJson = {
|
|
@@ -137,17 +144,12 @@ async function performOverrideMutations(args) {
|
|
|
137
144
|
return filesCopied;
|
|
138
145
|
}
|
|
139
146
|
catch (error) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
catch (rollbackError) {
|
|
147
|
-
await recordFurnaceRollbackFailure(args.projectRoot, 'override-rollback', `component "${args.componentName}": ${toError(rollbackError).message}`);
|
|
148
|
-
throw rollbackError;
|
|
149
|
-
}
|
|
150
|
-
throw error;
|
|
147
|
+
return await completeJournalRollback(ctx, journal, error, {
|
|
148
|
+
projectRoot: args.projectRoot,
|
|
149
|
+
operation: 'override-rollback',
|
|
150
|
+
failureMessage: `Failed to override component "${args.componentName}"`,
|
|
151
|
+
subject: `component "${args.componentName}"`,
|
|
152
|
+
});
|
|
151
153
|
}
|
|
152
154
|
});
|
|
153
155
|
}
|
|
@@ -190,7 +192,7 @@ function promoteStockToOverrideIfNeeded(config, componentName) {
|
|
|
190
192
|
* @param options - CLI options for non-interactive mode
|
|
191
193
|
*/
|
|
192
194
|
export async function furnaceOverrideCommand(projectRoot, name, options = {}) {
|
|
193
|
-
const isInteractive =
|
|
195
|
+
const isInteractive = stdioIsInteractive();
|
|
194
196
|
intro('Furnace Override');
|
|
195
197
|
// --- Validate config-independent inputs BEFORE auto-creating furnace.json
|
|
196
198
|
// so a failed authoring command never strands a fresh config in the
|
|
@@ -205,9 +207,7 @@ export async function furnaceOverrideCommand(projectRoot, name, options = {}) {
|
|
|
205
207
|
'Usage: fireforge furnace override <name> -t <type> -d "description"', 'name');
|
|
206
208
|
}
|
|
207
209
|
// Verify engine/ exists (config-independent precondition)
|
|
208
|
-
|
|
209
|
-
throw new FurnaceError('Engine directory not found. Run "fireforge download" first.');
|
|
210
|
-
}
|
|
210
|
+
await assertFurnaceEngineReady(projectRoot);
|
|
211
211
|
// Load the current config without auto-creating a new furnace.json. A user
|
|
212
212
|
// cancelling out of the interactive prompts should not leave a fresh config
|
|
213
213
|
// behind in an otherwise untouched project.
|
|
@@ -334,14 +334,12 @@ export async function furnaceOverrideCommand(projectRoot, name, options = {}) {
|
|
|
334
334
|
*/
|
|
335
335
|
export async function furnaceBatchOverrideCommand(projectRoot, names, options = {}) {
|
|
336
336
|
intro(`Furnace Override (batch: ${names.length} components)`);
|
|
337
|
-
const isInteractive =
|
|
337
|
+
const isInteractive = stdioIsInteractive();
|
|
338
338
|
if (!options.type && !isInteractive) {
|
|
339
339
|
throw new InvalidArgumentError('Override type is required for batch override in non-interactive mode. Use -t css-only or -t full.', 'type');
|
|
340
340
|
}
|
|
341
341
|
const paths = getProjectPaths(projectRoot);
|
|
342
|
-
|
|
343
|
-
throw new FurnaceError('Engine directory not found. Run "fireforge download" first.');
|
|
344
|
-
}
|
|
342
|
+
await assertFurnaceEngineReady(projectRoot);
|
|
345
343
|
// Validate all names upfront before any mutations
|
|
346
344
|
for (const name of names) {
|
|
347
345
|
if (!CUSTOM_ELEMENT_TAG_PATTERN.test(name)) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { getProjectPaths } from '../../core/config.js';
|
|
4
3
|
import { applyAllComponents } from '../../core/furnace-apply.js';
|
|
5
|
-
import {
|
|
4
|
+
import { updateFurnaceState } from '../../core/furnace-config.js';
|
|
6
5
|
import { runFurnaceMutation } from '../../core/furnace-operation.js';
|
|
6
|
+
import { assertFurnaceReady } from '../../core/furnace-precondition.js';
|
|
7
7
|
import { restoreRollbackJournal } from '../../core/furnace-rollback.js';
|
|
8
8
|
import { countEntriesWithBlockingStepErrors } from '../../core/furnace-step-errors.js';
|
|
9
9
|
import { cleanStories, syncStories } from '../../core/furnace-stories.js';
|
|
@@ -49,14 +49,11 @@ async function runPreviewTeardown(engineDir, storiesCleanupRequired, journal) {
|
|
|
49
49
|
return errors;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
|
-
* Reports staging failures (component-level errors and per-step errors) to
|
|
53
|
-
* user and throws a single FurnaceError summarising the failure count.
|
|
54
|
-
* Extracted from `furnacePreviewCommand` to keep that function under the
|
|
55
|
-
* `max-lines-per-function` threshold and to colocate the failure-reporting
|
|
56
|
-
* contract in one place.
|
|
52
|
+
* Reports staging failures (component-level errors and per-step errors) to
|
|
53
|
+
* the user and throws a single FurnaceError summarising the failure count.
|
|
57
54
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
55
|
+
* Never returns: it always throws after logging, which is what the `never`
|
|
56
|
+
* return type states.
|
|
60
57
|
*/
|
|
61
58
|
function reportPreviewStagingFailures(stageResult) {
|
|
62
59
|
for (const err of stageResult.errors) {
|
|
@@ -76,13 +73,12 @@ function reportPreviewStagingFailures(stageResult) {
|
|
|
76
73
|
/**
|
|
77
74
|
* Filenames emitted by the Firefox build backend (not by Storybook's npm
|
|
78
75
|
* package set) — their absence means `mach build` has not produced its
|
|
79
|
-
* post-configure artifacts, which is a different failure mode from a
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* backend-rebuild hint when we are confident.
|
|
76
|
+
* post-configure artifacts, which is a different failure mode from a missing
|
|
77
|
+
* Storybook workspace dependency tree. A
|
|
78
|
+
* `FileNotFoundError: [...] chrome-map.json` AFTER a successful Storybook
|
|
79
|
+
* `npm install` is the case a dep-focused heuristic misdiagnoses, sending
|
|
80
|
+
* the operator back to `--install`. The pattern list is narrow on purpose so
|
|
81
|
+
* the backend-rebuild hint only fires when it is confident.
|
|
86
82
|
*/
|
|
87
83
|
const BACKEND_ARTIFACT_PATTERNS = [
|
|
88
84
|
/chrome-map\.json/i,
|
|
@@ -124,17 +120,14 @@ export function buildStorybookFailureMessage(output, installRequested) {
|
|
|
124
120
|
}
|
|
125
121
|
/**
|
|
126
122
|
* Preflights the Firefox build + toolchain prerequisites `mach storybook`
|
|
127
|
-
* quietly assumes.
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* Extracted from `furnacePreviewCommand` so the main function stays
|
|
133
|
-
* under the per-function LOC budget as the preflight list grows.
|
|
123
|
+
* quietly assumes. Without it, preview stages components and launches a
|
|
124
|
+
* ~1000-package `mach storybook upgrade` npm install before the backend
|
|
125
|
+
* surfaces a "missing chrome-map.json" / Cargo-config failure; this refuses
|
|
126
|
+
* fast and leaves the workspace untouched.
|
|
134
127
|
*
|
|
135
128
|
* @param engineDir - Resolved engine directory
|
|
136
|
-
* @throws FurnaceError when the Firefox build
|
|
137
|
-
*
|
|
129
|
+
* @throws FurnaceError when the Firefox build has not produced dist/, or
|
|
130
|
+
* when `.cargo/config.toml` is absent
|
|
138
131
|
*/
|
|
139
132
|
async function assertPreviewPrerequisites(engineDir) {
|
|
140
133
|
const buildCheck = await hasBuildArtifacts(engineDir);
|
|
@@ -146,14 +139,12 @@ async function assertPreviewPrerequisites(engineDir) {
|
|
|
146
139
|
}
|
|
147
140
|
// Accept either `.cargo/config.toml` (post-configure) or
|
|
148
141
|
// `.cargo/config.toml.in` (post-bootstrap template, consumed at
|
|
149
|
-
// `mach configure` time).
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
// un-configured tree, so relaxing this to an OR-check does not weaken
|
|
156
|
-
// the signal we care about.
|
|
142
|
+
// `mach configure` time). Insisting on the plain file makes operators who
|
|
143
|
+
// follow the remediation instruction ("run bootstrap then rerun preview")
|
|
144
|
+
// hit the same refusal on the retry, because `fireforge bootstrap` alone
|
|
145
|
+
// produces only `.in`. Either name is sufficient to prove the Rust
|
|
146
|
+
// toolchain is registered; the stronger `hasBuildArtifacts` check above
|
|
147
|
+
// already guards against a completely un-configured tree.
|
|
157
148
|
const cargoConfigPath = join(engineDir, '.cargo', 'config.toml');
|
|
158
149
|
const cargoConfigInPath = join(engineDir, '.cargo', 'config.toml.in');
|
|
159
150
|
const cargoConfigPresent = (await pathExists(cargoConfigPath)) || (await pathExists(cargoConfigInPath));
|
|
@@ -165,15 +156,14 @@ async function assertPreviewPrerequisites(engineDir) {
|
|
|
165
156
|
}
|
|
166
157
|
}
|
|
167
158
|
/**
|
|
168
|
-
* Emits a framing banner when the Storybook workspace has not yet had
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* as a failure (2026-04-24 eval Finding 13).
|
|
159
|
+
* Emits a framing banner when the Storybook workspace has not yet had its npm
|
|
160
|
+
* dependencies installed. `mach storybook` drives the install internally and
|
|
161
|
+
* prints ELSPROBLEMS / UNMET DEPENDENCY lines verbatim; without this banner
|
|
162
|
+
* operators reliably read the npm output as a failure.
|
|
173
163
|
*
|
|
174
|
-
* Skipped when `--install` was explicitly requested — that path already
|
|
175
|
-
*
|
|
176
|
-
*
|
|
164
|
+
* Skipped when `--install` was explicitly requested — that path already runs
|
|
165
|
+
* `mach storybook upgrade` before the preview launches, so the npm output
|
|
166
|
+
* for the subsequent `mach storybook` invocation is a no-op.
|
|
177
167
|
*/
|
|
178
168
|
async function announceStorybookFirstRunIfNeeded(engineDir, installRequested) {
|
|
179
169
|
if (installRequested)
|
|
@@ -203,16 +193,7 @@ function announceStorybookCleanExitIfApplicable(exitCode) {
|
|
|
203
193
|
*/
|
|
204
194
|
export async function furnacePreviewCommand(projectRoot, options = {}) {
|
|
205
195
|
intro('Furnace Preview (Storybook)');
|
|
206
|
-
|
|
207
|
-
const paths = getProjectPaths(projectRoot);
|
|
208
|
-
if (!(await pathExists(paths.engine))) {
|
|
209
|
-
throw new FurnaceError('Engine directory not found. Run "fireforge download" first.');
|
|
210
|
-
}
|
|
211
|
-
// Load furnace config
|
|
212
|
-
if (!(await furnaceConfigExists(projectRoot))) {
|
|
213
|
-
throw new FurnaceError('No furnace.json found. Run "fireforge furnace create" or "fireforge furnace override" to get started.');
|
|
214
|
-
}
|
|
215
|
-
const config = await loadFurnaceConfig(projectRoot);
|
|
196
|
+
const { paths, config } = await assertFurnaceReady(projectRoot);
|
|
216
197
|
const stockCount = config.stock.length;
|
|
217
198
|
const overrideCount = Object.keys(config.overrides).length;
|
|
218
199
|
const customCount = Object.keys(config.custom).length;
|
|
@@ -226,8 +207,8 @@ export async function furnacePreviewCommand(projectRoot, options = {}) {
|
|
|
226
207
|
if (!(await pathExists(storybookRoot))) {
|
|
227
208
|
throw new FurnaceError('This Firefox checkout does not contain browser/components/storybook. Furnace preview requires the upstream Storybook workspace to exist before stories can be synced.');
|
|
228
209
|
}
|
|
229
|
-
// Build + toolchain preflight
|
|
230
|
-
//
|
|
210
|
+
// Build + toolchain preflight, extracted into a helper so the function
|
|
211
|
+
// below stays under the per-function LOC budget.
|
|
231
212
|
await assertPreviewPrerequisites(paths.engine);
|
|
232
213
|
let previewResult;
|
|
233
214
|
// True once we are about to (or have) written to engine/.../stories/furnace.
|
|
@@ -302,10 +283,8 @@ export async function furnacePreviewCommand(projectRoot, options = {}) {
|
|
|
302
283
|
}
|
|
303
284
|
installSpinner.stop('Storybook dependencies reinstalled');
|
|
304
285
|
}
|
|
305
|
-
//
|
|
306
|
-
//
|
|
307
|
-
// failure. The banner-before / banner-after helpers are extracted
|
|
308
|
-
// so the command body stays under the per-function LOC budget.
|
|
286
|
+
// Frame the npm noise `mach storybook` emits on first run as expected
|
|
287
|
+
// progress rather than a failure.
|
|
309
288
|
await announceStorybookFirstRunIfNeeded(paths.engine, options.install ?? false);
|
|
310
289
|
// Start Storybook
|
|
311
290
|
info('Starting Storybook...');
|
|
@@ -317,16 +296,17 @@ export async function furnacePreviewCommand(projectRoot, options = {}) {
|
|
|
317
296
|
primaryError = error;
|
|
318
297
|
}
|
|
319
298
|
// Teardown runs unconditionally and never short-circuits: a failure in
|
|
320
|
-
// cleanStories must not prevent the journal restore, and vice versa.
|
|
321
|
-
//
|
|
322
|
-
// `restoreRollbackJournalOrThrow
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
//
|
|
328
|
-
//
|
|
329
|
-
//
|
|
299
|
+
// cleanStories must not prevent the journal restore, and vice versa.
|
|
300
|
+
// Running teardown in a `finally` that calls
|
|
301
|
+
// `restoreRollbackJournalOrThrow` throws synchronously, bypassing the
|
|
302
|
+
// primary error and skipping downstream handling — the engine is left
|
|
303
|
+
// with staged files and the user gets a teardown message with no
|
|
304
|
+
// guidance. Both failures are collected instead and, if anything went
|
|
305
|
+
// wrong, a `pendingRepair` marker is persisted for `fireforge doctor` to
|
|
306
|
+
// finish the reconciliation.
|
|
307
|
+
//
|
|
308
|
+
// Teardown restores the journal itself, so the lifecycle wrapper must
|
|
309
|
+
// not restore it again when the throw below propagates out of this body.
|
|
330
310
|
ctx.markRolledBack();
|
|
331
311
|
const teardownErrors = await runPreviewTeardown(paths.engine, storiesCleanupRequired, previewJournal);
|
|
332
312
|
if (teardownErrors.length > 0) {
|
|
@@ -6,9 +6,10 @@ import { getOverrideEngineTargetPath } from '../../core/furnace-apply-helpers.js
|
|
|
6
6
|
import { getFurnacePaths, loadFurnaceConfig, writeFurnaceConfig, } from '../../core/furnace-config.js';
|
|
7
7
|
import { resolveFtlDir } from '../../core/furnace-constants.js';
|
|
8
8
|
import { isComponentSourceFile } from '../../core/furnace-constants.js';
|
|
9
|
-
import {
|
|
9
|
+
import { completeJournalRollback, runFurnaceMutation } from '../../core/furnace-operation.js';
|
|
10
|
+
import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
|
|
10
11
|
import { refreshOverrideFile } from '../../core/furnace-refresh.js';
|
|
11
|
-
import { createRollbackJournal, restoreRollbackJournal,
|
|
12
|
+
import { createRollbackJournal, restoreRollbackJournal, snapshotDir, snapshotFile, } from '../../core/furnace-rollback.js';
|
|
12
13
|
import { getHead } from '../../core/git.js';
|
|
13
14
|
import { FurnaceError } from '../../errors/furnace.js';
|
|
14
15
|
import { toError } from '../../utils/errors.js';
|
|
@@ -144,17 +145,15 @@ async function refreshSingleOverride(projectRoot, name, options = {}) {
|
|
|
144
145
|
return fileResults;
|
|
145
146
|
}
|
|
146
147
|
catch (error) {
|
|
148
|
+
// A dry run wrote nothing, so there is no journal to restore — it
|
|
149
|
+
// rethrows without touching the lifecycle wrapper.
|
|
147
150
|
if (!dryRun) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
catch (rollbackError) {
|
|
155
|
-
await recordFurnaceRollbackFailure(projectRoot, 'refresh-rollback', `override "${name}": ${toError(rollbackError).message}`);
|
|
156
|
-
throw rollbackError;
|
|
157
|
-
}
|
|
151
|
+
return await completeJournalRollback(ctx, journal, error, {
|
|
152
|
+
projectRoot,
|
|
153
|
+
operation: 'refresh-rollback',
|
|
154
|
+
failureMessage: `Failed to refresh override "${name}"`,
|
|
155
|
+
subject: `override "${name}"`,
|
|
156
|
+
});
|
|
158
157
|
}
|
|
159
158
|
throw error;
|
|
160
159
|
}
|
|
@@ -228,10 +227,7 @@ export async function furnaceRefreshCommand(projectRoot, name, options = {}) {
|
|
|
228
227
|
// Verify engine exists — refresh reads engine files for three-way merge
|
|
229
228
|
// and --reset-base reads engine HEAD. Without this check, the user gets
|
|
230
229
|
// an obscure git error instead of a clear precondition message.
|
|
231
|
-
|
|
232
|
-
if (!(await pathExists(paths.engine))) {
|
|
233
|
-
throw new FurnaceError('Engine directory not found. Run "fireforge download" first.');
|
|
234
|
-
}
|
|
230
|
+
await assertFurnaceEngineReady(projectRoot);
|
|
235
231
|
const dryRun = options.dryRun ?? false;
|
|
236
232
|
if (name) {
|
|
237
233
|
intro('Furnace Refresh');
|
|
@@ -5,12 +5,9 @@ import type { FurnaceState } from '../../types/furnace.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Engine-side and workspace-side removal for an OVERRIDE component.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* file lines with `furnaceRemoveCommand` at 149/150 — one line from a build
|
|
12
|
-
* failure. Both run inside the caller's rollback journal rather than opening
|
|
13
|
-
* their own, so a failure anywhere still restores the whole operation.
|
|
8
|
+
* Runs inside the caller's rollback journal rather than opening its own, so
|
|
9
|
+
* a failure anywhere in the remove still restores the whole operation as a
|
|
10
|
+
* single unit.
|
|
14
11
|
*/
|
|
15
12
|
export declare function performOverrideRemovalMutations(args: {
|
|
16
13
|
name: string;
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Engine-side and workspace-side mutation bodies for `furnace remove`.
|
|
4
4
|
*
|
|
5
|
-
* Split out of `remove.ts
|
|
6
|
-
* functions
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* failure. Extracting them inside the same file traded a function-length
|
|
10
|
-
* problem for a file-length one, so they live here instead.
|
|
5
|
+
* Split out of `remove.ts`, where the two `perform*RemovalMutations`
|
|
6
|
+
* functions held the file at the per-file line cap with
|
|
7
|
+
* `furnaceRemoveCommand` at the per-function cap. Extracting them inside the
|
|
8
|
+
* same file would trade a function-length problem for a file-length one.
|
|
11
9
|
*
|
|
12
10
|
* Both run inside the CALLER's rollback journal rather than opening their
|
|
13
11
|
* own, so a failure anywhere in the remove still restores the whole
|
|
@@ -84,12 +82,9 @@ async function restoreOverrideEngineFiles(engineDir, overrideDir, overrideConfig
|
|
|
84
82
|
/**
|
|
85
83
|
* Engine-side and workspace-side removal for an OVERRIDE component.
|
|
86
84
|
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* file lines with `furnaceRemoveCommand` at 149/150 — one line from a build
|
|
91
|
-
* failure. Both run inside the caller's rollback journal rather than opening
|
|
92
|
-
* their own, so a failure anywhere still restores the whole operation.
|
|
85
|
+
* Runs inside the caller's rollback journal rather than opening its own, so
|
|
86
|
+
* a failure anywhere in the remove still restores the whole operation as a
|
|
87
|
+
* single unit.
|
|
93
88
|
*/
|
|
94
89
|
export async function performOverrideRemovalMutations(args) {
|
|
95
90
|
const { name, paths, furnacePaths, freshConfig, freshState, ftlDir, journal } = args;
|
|
@@ -162,10 +157,8 @@ export async function performCustomRemovalMutations(args) {
|
|
|
162
157
|
}
|
|
163
158
|
// Drop the locale jar.mn chrome registration that `applyCustomFtlFile`
|
|
164
159
|
// wrote during deploy — otherwise the engine is left with a
|
|
165
|
-
// `locale/.../${name}.ftl` entry pointing at a file
|
|
166
|
-
//
|
|
167
|
-
// `browser/locales/jar.mn` referencing the missing FTL, which
|
|
168
|
-
// would break the next package-manifest validation.
|
|
160
|
+
// `locale/.../${name}.ftl` entry pointing at a file just deleted, which
|
|
161
|
+
// breaks the next package-manifest validation.
|
|
169
162
|
await removeCustomFtlJarMnEntry(paths.engine, `${name}.ftl`, ftlDir, customConfig, journal);
|
|
170
163
|
}
|
|
171
164
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { readdir } from 'node:fs/promises';
|
|
2
3
|
import { join } from 'node:path';
|
|
3
4
|
import { loadFurnaceState } from '../../core/furnace-config.js';
|
|
4
5
|
import { snapshotFile } from '../../core/furnace-rollback.js';
|
|
@@ -52,7 +53,6 @@ export async function removeDeployedCustomFiles(projectRoot, engineDir, name, ta
|
|
|
52
53
|
if (deletedCount > 0) {
|
|
53
54
|
info(`Deleted ${deletedCount} deployed file(s) from engine/${targetPath}/`);
|
|
54
55
|
}
|
|
55
|
-
const { readdir } = await import('node:fs/promises');
|
|
56
56
|
if ((await readdir(engineTargetDir)).length === 0) {
|
|
57
57
|
await removeDir(engineTargetDir);
|
|
58
58
|
info(`Removed now-empty engine/${targetPath}/`);
|