@hominis/fireforge 0.43.0 → 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 +127 -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 +62 -19
- 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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { FurnaceError } from '../errors/furnace.js';
|
|
4
|
+
import { FURNACE_PENDING_REPAIR_OPERATIONS } from '../types/furnace.js';
|
|
4
5
|
import { toError } from '../utils/errors.js';
|
|
5
6
|
import { pathExists, readJson, writeJson } from '../utils/fs.js';
|
|
6
7
|
import { warn } from '../utils/logger.js';
|
|
@@ -128,9 +129,8 @@ export function validateFurnaceConfig(data) {
|
|
|
128
129
|
// Warn when two custom components share a targetPath. Nothing technically
|
|
129
130
|
// prevents co-location, but per-component removal and orphan detection
|
|
130
131
|
// both reason about "files this component deployed into its directory" —
|
|
131
|
-
// shared directories make those judgements ambiguous, and
|
|
132
|
-
//
|
|
133
|
-
// other's deployed files.
|
|
132
|
+
// shared directories make those judgements ambiguous, and can lead to
|
|
133
|
+
// `furnace remove` of one component deleting the other's deployed files.
|
|
134
134
|
const targetPathOwners = new Map();
|
|
135
135
|
for (const [name, custom_] of Object.entries(custom)) {
|
|
136
136
|
const owners = targetPathOwners.get(custom_.targetPath) ?? [];
|
|
@@ -166,18 +166,11 @@ function validateFurnaceState(data) {
|
|
|
166
166
|
}
|
|
167
167
|
return result.state;
|
|
168
168
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
'create-rollback',
|
|
175
|
-
'chrome-doc-rollback',
|
|
176
|
-
'override-rollback',
|
|
177
|
-
'scan-rollback',
|
|
178
|
-
'rename-rollback',
|
|
179
|
-
'refresh-rollback',
|
|
180
|
-
];
|
|
169
|
+
// Single source of truth: the list the union is derived from. The copy
|
|
170
|
+
// this replaced was annotated, not linked — it caught a member REMOVED
|
|
171
|
+
// from the union but never one ADDED to it, and listed them in a
|
|
172
|
+
// different order.
|
|
173
|
+
const PENDING_REPAIR_OPERATIONS = FURNACE_PENDING_REPAIR_OPERATIONS;
|
|
181
174
|
function parsePendingRepair(data) {
|
|
182
175
|
if (!isObject(data)) {
|
|
183
176
|
return { error: 'field "pendingRepair" must be an object' };
|
|
@@ -337,8 +330,7 @@ export async function loadFurnaceConfig(root) {
|
|
|
337
330
|
* reset, rebase, rebase --abort): every applied checksum describes content
|
|
338
331
|
* that no longer exists, but pendingRepair tracks authoring-side rollback
|
|
339
332
|
* issues in the component WORKSPACE and must survive an engine refresh.
|
|
340
|
-
* No-ops when the state file does not exist.
|
|
341
|
-
* reset logic had drifted into four separate command files.
|
|
333
|
+
* No-ops when the state file does not exist.
|
|
342
334
|
*/
|
|
343
335
|
export async function clearAppliedFurnaceState(root) {
|
|
344
336
|
const paths = getFurnacePaths(root);
|
|
@@ -374,20 +366,15 @@ export async function writeFurnaceConfig(root, config) {
|
|
|
374
366
|
}
|
|
375
367
|
/**
|
|
376
368
|
* Stamps every override's `baseVersion` to the supplied version. Used by
|
|
377
|
-
* `fireforge rebase` after a successful patch re-export so
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
369
|
+
* `fireforge rebase` after a successful patch re-export, so an ESR bump does
|
|
370
|
+
* not leave Furnace overrides in a doctor-failing drift state: `rebase`
|
|
371
|
+
* stamps patch `sourceEsrVersion` via `stampPatchVersions`, and without the
|
|
372
|
+
* matching override stamp `doctor` fails Furnace component validation on
|
|
373
|
+
* every override.
|
|
381
374
|
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
* then immediately failed Furnace component validation on every
|
|
386
|
-
* override. The stamp is deliberately unconditional — `fireforge
|
|
387
|
-
* furnace validate` is the right tool for "does this override still
|
|
388
|
-
* apply", and rebase already attested that the patch layer re-validated
|
|
389
|
-
* against the new ESR; the per-override health check belongs in a
|
|
390
|
-
* separate pass, not inline with the stamp.
|
|
375
|
+
* The stamp is deliberately unconditional — `fireforge furnace validate` is
|
|
376
|
+
* the right tool for "does this override still apply", and rebase has
|
|
377
|
+
* already attested that the patch layer re-validated against the new ESR.
|
|
391
378
|
*
|
|
392
379
|
* @param root - Root directory of the project
|
|
393
380
|
* @param version - Firefox version string to stamp onto every override
|
|
@@ -414,23 +401,20 @@ export async function stampFurnaceOverrideBaseVersions(root, version) {
|
|
|
414
401
|
* Creates a default furnace configuration.
|
|
415
402
|
*
|
|
416
403
|
* When a `binaryName` is provided, the default config carries a
|
|
417
|
-
* `tokenPrefix` derived as `--<binaryName>-`. Without
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
* the prefix from the binary name matches the convention the scaffolded
|
|
424
|
-
* tokens CSS already uses for its `--<binaryName>-*` declarations.
|
|
404
|
+
* `tokenPrefix` derived as `--<binaryName>-`. Without it, `fireforge token
|
|
405
|
+
* coverage` on a fresh project reports `0 tokens` and labels every
|
|
406
|
+
* custom-property reference as `unknown`, because the scan has no prefix to
|
|
407
|
+
* key off. Deriving the prefix from the binary name matches the convention
|
|
408
|
+
* the scaffolded tokens CSS already uses for its `--<binaryName>-*`
|
|
409
|
+
* declarations.
|
|
425
410
|
*
|
|
426
|
-
* `validateFurnaceConfig` treats `tokenPrefix` as optional, so callers
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
* `fireforge.json` and always sets one.
|
|
411
|
+
* `validateFurnaceConfig` treats `tokenPrefix` as optional, so callers on
|
|
412
|
+
* the no-arg call shape still get a valid config without a prefix; the CLI
|
|
413
|
+
* init path always has a `binaryName` from `fireforge.json` and always sets
|
|
414
|
+
* one.
|
|
431
415
|
*
|
|
432
|
-
* @param options - Optional init context; pass `{ binaryName }` to
|
|
433
|
-
*
|
|
416
|
+
* @param options - Optional init context; pass `{ binaryName }` to derive
|
|
417
|
+
* the token prefix.
|
|
434
418
|
* @returns A valid FurnaceConfig
|
|
435
419
|
*/
|
|
436
420
|
export function createDefaultFurnaceConfig(options = {}) {
|
|
@@ -496,15 +480,9 @@ export async function updateFurnaceState(root, updates) {
|
|
|
496
480
|
/**
|
|
497
481
|
* Engine-relative path of the directory `furnace preview` writes its
|
|
498
482
|
* generated Storybook story files into. Treated as Furnace-managed so
|
|
499
|
-
* `status` does not flag them as unmanaged and `lint` does not fail on
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
* 2026-04-25 eval Finding 19: a successful `furnace preview` run synced
|
|
503
|
-
* 23 stories under this prefix; afterwards `status` showed all 23 as
|
|
504
|
-
* untracked unmanaged changes and aggregate `lint` failed with 23
|
|
505
|
-
* `missing-license-header` errors. The files are tool output — operators
|
|
506
|
-
* are not expected to commit or hand-edit them — so the right shape is
|
|
507
|
-
* to bucket them with the rest of Furnace's managed material.
|
|
483
|
+
* `status` does not flag them as unmanaged and `lint` does not fail on their
|
|
484
|
+
* (intentionally bare) license headers — they are tool output, not files an
|
|
485
|
+
* operator commits or hand-edits.
|
|
508
486
|
*/
|
|
509
487
|
const FURNACE_STORYBOOK_STORIES_PREFIX = 'browser/components/storybook/stories/furnace/';
|
|
510
488
|
/**
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
export declare const CUSTOM_ELEMENTS_JS = "toolkit/content/customElements.js";
|
|
3
3
|
/** Path to jar.mn within the engine source tree (toolkit global) */
|
|
4
4
|
export declare const JAR_MN = "toolkit/content/jar.mn";
|
|
5
|
+
/**
|
|
6
|
+
* Upstream home of the MozLitElement widget sources.
|
|
7
|
+
*
|
|
8
|
+
* The trailing slash is NOT included: `build-audit-transforms.ts` needs
|
|
9
|
+
* `${WIDGETS_DIR}/` and its ordered prefix table depends on that slash, so
|
|
10
|
+
* appending it at the one site that wants it keeps the others correct.
|
|
11
|
+
*/
|
|
12
|
+
export declare const WIDGETS_DIR = "toolkit/content/widgets";
|
|
5
13
|
/** Default Fluent localization directory for toolkit global components, relative to engine root */
|
|
6
14
|
export declare const FTL_DIR = "toolkit/locales/en-US/toolkit/global";
|
|
7
15
|
/**
|
|
@@ -3,14 +3,22 @@
|
|
|
3
3
|
export const CUSTOM_ELEMENTS_JS = 'toolkit/content/customElements.js';
|
|
4
4
|
/** Path to jar.mn within the engine source tree (toolkit global) */
|
|
5
5
|
export const JAR_MN = 'toolkit/content/jar.mn';
|
|
6
|
+
/**
|
|
7
|
+
* Upstream home of the MozLitElement widget sources.
|
|
8
|
+
*
|
|
9
|
+
* The trailing slash is NOT included: `build-audit-transforms.ts` needs
|
|
10
|
+
* `${WIDGETS_DIR}/` and its ordered prefix table depends on that slash, so
|
|
11
|
+
* appending it at the one site that wants it keeps the others correct.
|
|
12
|
+
*/
|
|
13
|
+
export const WIDGETS_DIR = 'toolkit/content/widgets';
|
|
6
14
|
/** Default Fluent localization directory for toolkit global components, relative to engine root */
|
|
7
15
|
export const FTL_DIR = 'toolkit/locales/en-US/toolkit/global';
|
|
8
16
|
/**
|
|
9
17
|
* Suffix for the per-binary xpcshell scaffold parent directory. Components
|
|
10
18
|
* created with `furnace create --with-tests --xpcshell` land at
|
|
11
19
|
* `browser/base/content/test/<binaryName>${XPCSHELL_TEST_DIR_SUFFIX}/<component>/`.
|
|
12
|
-
* Centralised so `create` / `remove` / `rename` / `validate` all agree on
|
|
13
|
-
*
|
|
20
|
+
* Centralised so `create` / `remove` / `rename` / `validate` all agree on the
|
|
21
|
+
* path template.
|
|
14
22
|
*/
|
|
15
23
|
const XPCSHELL_TEST_DIR_SUFFIX = '-xpcshell';
|
|
16
24
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared CSS fragments for Furnace widgets
|
|
2
|
+
* Shared CSS fragments for Furnace widgets.
|
|
3
3
|
*
|
|
4
4
|
* Shadow-DOM isolation forces each widget stylesheet to carry its own copy
|
|
5
|
-
* of genuinely shared CSS (keyframes, resets)
|
|
5
|
+
* of genuinely shared CSS (keyframes, resets), and hand-syncing those copies
|
|
6
6
|
* drifts. Instead, a workspace stylesheet declares an include directive
|
|
7
7
|
* (a CSS block comment on its own line):
|
|
8
8
|
*
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* `@fireforge-end-include` marker so re-deploys can refresh it idempotently.
|
|
15
15
|
*
|
|
16
16
|
* Drift contract: the apply fast-path and `furnace validate` compare the
|
|
17
|
-
* *expanded* workspace source against the engine copy, so editing a
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* *expanded* workspace source against the engine copy, so editing a fragment
|
|
18
|
+
* surfaces as ordinary component drift and the next deploy refreshes every
|
|
19
|
+
* consuming widget.
|
|
20
20
|
*/
|
|
21
21
|
import type { ValidationIssue } from '../types/furnace.js';
|
|
22
22
|
export { SHARED_FRAGMENTS_DIR } from './furnace-config.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* Shared CSS fragments for Furnace widgets
|
|
3
|
+
* Shared CSS fragments for Furnace widgets.
|
|
4
4
|
*
|
|
5
5
|
* Shadow-DOM isolation forces each widget stylesheet to carry its own copy
|
|
6
|
-
* of genuinely shared CSS (keyframes, resets)
|
|
6
|
+
* of genuinely shared CSS (keyframes, resets), and hand-syncing those copies
|
|
7
7
|
* drifts. Instead, a workspace stylesheet declares an include directive
|
|
8
8
|
* (a CSS block comment on its own line):
|
|
9
9
|
*
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* `@fireforge-end-include` marker so re-deploys can refresh it idempotently.
|
|
16
16
|
*
|
|
17
17
|
* Drift contract: the apply fast-path and `furnace validate` compare the
|
|
18
|
-
* *expanded* workspace source against the engine copy, so editing a
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* *expanded* workspace source against the engine copy, so editing a fragment
|
|
19
|
+
* surfaces as ordinary component drift and the next deploy refreshes every
|
|
20
|
+
* consuming widget.
|
|
21
21
|
*/
|
|
22
22
|
import { readdir } from 'node:fs/promises';
|
|
23
23
|
import { join } from 'node:path';
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Maintains `compilerOptions.paths` entries in a consumer-owned jsconfig
|
|
3
|
-
*
|
|
4
|
-
* (field report D3).
|
|
2
|
+
* Maintains `compilerOptions.paths` entries in a consumer-owned jsconfig so
|
|
3
|
+
* typed cross-module imports of multi-file Furnace components work.
|
|
5
4
|
*
|
|
6
5
|
* When a main widget imports a sibling helper via its deployed chrome URL
|
|
7
|
-
* (`chrome://global/content/elements/<helper>.mjs`), a wildcard module
|
|
8
|
-
*
|
|
6
|
+
* (`chrome://global/content/elements/<helper>.mjs`), a wildcard module shim
|
|
7
|
+
* swallows the import: value imports degrade to `any` and
|
|
9
8
|
* `import(...).SomeType` typedefs fail with TS2694. The fix is a `paths`
|
|
10
|
-
* mapping from the chrome URL to the real workspace source. Furnace
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* mapping from the chrome URL to the real workspace source. Furnace already
|
|
10
|
+
* owns the jar.mn side of that mapping, so it maintains the jsconfig side
|
|
11
|
+
* automatically on every deploy.
|
|
13
12
|
*
|
|
14
13
|
* Ownership contract: only entries whose key starts with
|
|
15
14
|
* `chrome://global/content/elements/` AND whose mapped path resolves into
|
|
16
15
|
* the Furnace custom-components workspace are managed (added, updated,
|
|
17
|
-
* pruned). Everything else in the jsconfig — including hand-written
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* pruned). Everything else in the jsconfig — including hand-written `paths`
|
|
17
|
+
* entries pointing elsewhere — is preserved verbatim. No `baseUrl` is
|
|
18
|
+
* required or written: relative `paths` resolve against the config file's
|
|
19
|
+
* directory.
|
|
21
20
|
*/
|
|
22
21
|
import type { FurnaceConfig } from '../types/furnace.js';
|
|
23
22
|
/** Result summary of a jsconfig paths sync. */
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* Maintains `compilerOptions.paths` entries in a consumer-owned jsconfig
|
|
4
|
-
*
|
|
5
|
-
* (field report D3).
|
|
3
|
+
* Maintains `compilerOptions.paths` entries in a consumer-owned jsconfig so
|
|
4
|
+
* typed cross-module imports of multi-file Furnace components work.
|
|
6
5
|
*
|
|
7
6
|
* When a main widget imports a sibling helper via its deployed chrome URL
|
|
8
|
-
* (`chrome://global/content/elements/<helper>.mjs`), a wildcard module
|
|
9
|
-
*
|
|
7
|
+
* (`chrome://global/content/elements/<helper>.mjs`), a wildcard module shim
|
|
8
|
+
* swallows the import: value imports degrade to `any` and
|
|
10
9
|
* `import(...).SomeType` typedefs fail with TS2694. The fix is a `paths`
|
|
11
|
-
* mapping from the chrome URL to the real workspace source. Furnace
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* mapping from the chrome URL to the real workspace source. Furnace already
|
|
11
|
+
* owns the jar.mn side of that mapping, so it maintains the jsconfig side
|
|
12
|
+
* automatically on every deploy.
|
|
14
13
|
*
|
|
15
14
|
* Ownership contract: only entries whose key starts with
|
|
16
15
|
* `chrome://global/content/elements/` AND whose mapped path resolves into
|
|
17
16
|
* the Furnace custom-components workspace are managed (added, updated,
|
|
18
|
-
* pruned). Everything else in the jsconfig — including hand-written
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* pruned). Everything else in the jsconfig — including hand-written `paths`
|
|
18
|
+
* entries pointing elsewhere — is preserved verbatim. No `baseUrl` is
|
|
19
|
+
* required or written: relative `paths` resolve against the config file's
|
|
20
|
+
* directory.
|
|
22
21
|
*/
|
|
23
22
|
import { readdir } from 'node:fs/promises';
|
|
24
23
|
import { dirname, join, relative, resolve } from 'node:path';
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Marker-comment resolution shared between furnace apply and deploy.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `loadConfig` with a partial shape).
|
|
4
|
+
* When `markerComment` is unset in fireforge.json, fall back to
|
|
5
|
+
* `binaryName.toUpperCase()` so the patch-lint rule
|
|
6
|
+
* `lintModificationComments` (which keys on `${binaryName.toUpperCase()}:`)
|
|
7
|
+
* accepts furnace-emitted edits on the next `lint`/`export` round-trip. The
|
|
8
|
+
* helper tolerates the undefined-config case (a project that has not run
|
|
9
|
+
* `fireforge setup` yet) and the missing-binaryName case (test fixtures that
|
|
10
|
+
* mock `loadConfig` with a partial shape).
|
|
12
11
|
*/
|
|
13
12
|
export declare function resolveFurnaceMarkerComment(forgeConfig: {
|
|
14
13
|
markerComment?: string;
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Marker-comment resolution shared between furnace apply and deploy.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `loadConfig` with a partial shape).
|
|
5
|
+
* When `markerComment` is unset in fireforge.json, fall back to
|
|
6
|
+
* `binaryName.toUpperCase()` so the patch-lint rule
|
|
7
|
+
* `lintModificationComments` (which keys on `${binaryName.toUpperCase()}:`)
|
|
8
|
+
* accepts furnace-emitted edits on the next `lint`/`export` round-trip. The
|
|
9
|
+
* helper tolerates the undefined-config case (a project that has not run
|
|
10
|
+
* `fireforge setup` yet) and the missing-binaryName case (test fixtures that
|
|
11
|
+
* mock `loadConfig` with a partial shape).
|
|
13
12
|
*/
|
|
14
13
|
export function resolveFurnaceMarkerComment(forgeConfig) {
|
|
15
14
|
if (!forgeConfig)
|
|
@@ -86,6 +86,37 @@ export declare function rollbackActiveOperationsForSignal(signal: FurnaceShutdow
|
|
|
86
86
|
* touch this directly.
|
|
87
87
|
*/
|
|
88
88
|
export declare function getFurnaceLockPath(root: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Completes the rollback for a mutation body that owns its journal end to
|
|
91
|
+
* end, then rethrows. Never returns normally.
|
|
92
|
+
*
|
|
93
|
+
* Shaped as a catch-body handler rather than a `withJournalRollback(body)`
|
|
94
|
+
* wrapper on purpose: the eight calling bodies differ in early returns and
|
|
95
|
+
* in what they close over, and converting them to callbacks would
|
|
96
|
+
* restructure control flow through the engine's rollback path for a
|
|
97
|
+
* cosmetic gain.
|
|
98
|
+
*
|
|
99
|
+
* The ordering is the part worth centralising: `markRolledBack()` MUST run
|
|
100
|
+
* before the restore, so a restore that itself fails does not leave the
|
|
101
|
+
* lifecycle wrapper replaying the same journal on the way out. And the
|
|
102
|
+
* ORIGINAL error is rethrown unless the rollback is what failed — the
|
|
103
|
+
* operator needs to know what went wrong, and separately whether the engine
|
|
104
|
+
* could be put back.
|
|
105
|
+
*
|
|
106
|
+
* @param ctx - The furnace operation context from `runFurnaceMutation`
|
|
107
|
+
* @param journal - Rollback journal this body populated
|
|
108
|
+
* @param error - The error the body threw
|
|
109
|
+
* @param options - Project root, pending-repair tag, and message fragments
|
|
110
|
+
* @returns Never — always throws
|
|
111
|
+
*/
|
|
112
|
+
export declare function completeJournalRollback(ctx: FurnaceOperationContext, journal: RollbackJournal, error: unknown, options: {
|
|
113
|
+
projectRoot: string;
|
|
114
|
+
operation: FurnacePendingRepairOperation;
|
|
115
|
+
/** Prefix for the restore failure, e.g. `Failed to override component "x"`. */
|
|
116
|
+
failureMessage: string;
|
|
117
|
+
/** Subject recorded on the pending-repair marker, e.g. `component "x"`. */
|
|
118
|
+
subject: string;
|
|
119
|
+
}): Promise<never>;
|
|
89
120
|
/**
|
|
90
121
|
* Forcibly removes the furnace lock directory for every active operation.
|
|
91
122
|
*
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
-
import { rm } from 'node:fs/promises';
|
|
3
2
|
import { join } from 'node:path';
|
|
4
3
|
import { FurnaceError } from '../errors/furnace.js';
|
|
5
4
|
import { assert } from '../utils/assert.js';
|
|
6
5
|
import { toError } from '../utils/errors.js';
|
|
7
6
|
import { verbose, warn } from '../utils/logger.js';
|
|
8
7
|
import { FIREFORGE_DIR } from './config-paths.js';
|
|
9
|
-
import { readLockStatus, withFileLock } from './file-lock.js';
|
|
8
|
+
import { readLockStatus, releaseLockIfOwned, withFileLock } from './file-lock.js';
|
|
10
9
|
import { loadFurnaceState, updateFurnaceState } from './furnace-config.js';
|
|
11
|
-
import { restoreRollbackJournal } from './furnace-rollback.js';
|
|
10
|
+
import { restoreRollbackJournal, restoreRollbackJournalOrThrow, } from './furnace-rollback.js';
|
|
12
11
|
/** Sidecar lock filename used to serialize concurrent furnace mutations. */
|
|
13
12
|
const FURNACE_LOCK_FILENAME = 'furnace.lock';
|
|
14
13
|
/**
|
|
@@ -232,6 +231,42 @@ async function persistPendingRepair(root, operation, reason) {
|
|
|
232
231
|
export function getFurnaceLockPath(root) {
|
|
233
232
|
return join(root, FIREFORGE_DIR, FURNACE_LOCK_FILENAME);
|
|
234
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Completes the rollback for a mutation body that owns its journal end to
|
|
236
|
+
* end, then rethrows. Never returns normally.
|
|
237
|
+
*
|
|
238
|
+
* Shaped as a catch-body handler rather than a `withJournalRollback(body)`
|
|
239
|
+
* wrapper on purpose: the eight calling bodies differ in early returns and
|
|
240
|
+
* in what they close over, and converting them to callbacks would
|
|
241
|
+
* restructure control flow through the engine's rollback path for a
|
|
242
|
+
* cosmetic gain.
|
|
243
|
+
*
|
|
244
|
+
* The ordering is the part worth centralising: `markRolledBack()` MUST run
|
|
245
|
+
* before the restore, so a restore that itself fails does not leave the
|
|
246
|
+
* lifecycle wrapper replaying the same journal on the way out. And the
|
|
247
|
+
* ORIGINAL error is rethrown unless the rollback is what failed — the
|
|
248
|
+
* operator needs to know what went wrong, and separately whether the engine
|
|
249
|
+
* could be put back.
|
|
250
|
+
*
|
|
251
|
+
* @param ctx - The furnace operation context from `runFurnaceMutation`
|
|
252
|
+
* @param journal - Rollback journal this body populated
|
|
253
|
+
* @param error - The error the body threw
|
|
254
|
+
* @param options - Project root, pending-repair tag, and message fragments
|
|
255
|
+
* @returns Never — always throws
|
|
256
|
+
*/
|
|
257
|
+
export async function completeJournalRollback(ctx, journal, error, options) {
|
|
258
|
+
// This body owns its rollback end to end, so tell the lifecycle wrapper
|
|
259
|
+
// not to restore the same journal again on the way out.
|
|
260
|
+
ctx.markRolledBack();
|
|
261
|
+
try {
|
|
262
|
+
await restoreRollbackJournalOrThrow(journal, options.failureMessage);
|
|
263
|
+
}
|
|
264
|
+
catch (rollbackError) {
|
|
265
|
+
await recordFurnaceRollbackFailure(options.projectRoot, options.operation, `${options.subject}: ${toError(rollbackError).message}`);
|
|
266
|
+
throw rollbackError;
|
|
267
|
+
}
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
235
270
|
/**
|
|
236
271
|
* Forcibly removes the furnace lock directory for every active operation.
|
|
237
272
|
*
|
|
@@ -251,13 +286,15 @@ export function getFurnaceLockPath(root) {
|
|
|
251
286
|
export async function forceReleaseFurnaceLocksForActiveOperations() {
|
|
252
287
|
const paths = new Set([...activeOperations.values()].map((op) => getFurnaceLockPath(op.root)));
|
|
253
288
|
for (const lockPath of paths) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
289
|
+
// Ownership-checked, like every other release path. The bare `rm` this
|
|
290
|
+
// replaced would delete a lock a DIFFERENT process had acquired in the
|
|
291
|
+
// window between our operation dying and this sweep running — the exact
|
|
292
|
+
// race `releaseLock`'s PID verification was added to close, reopened
|
|
293
|
+
// here because the sweeper has no acquisition token to check.
|
|
294
|
+
const removed = await releaseLockIfOwned(lockPath);
|
|
295
|
+
verbose(removed
|
|
296
|
+
? `Removed furnace lock at ${lockPath} during signal teardown`
|
|
297
|
+
: `Left furnace lock at ${lockPath} in place during signal teardown: it is not owned by this process`);
|
|
261
298
|
}
|
|
262
299
|
}
|
|
263
300
|
/**
|
|
@@ -336,15 +373,15 @@ export async function runFurnaceMutation(root, kind, body, options = {}) {
|
|
|
336
373
|
}
|
|
337
374
|
catch (error) {
|
|
338
375
|
// A thrown error leaves the engine mutated exactly as a signal does,
|
|
339
|
-
// so it gets the same treatment.
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
//
|
|
376
|
+
// so it gets the same treatment. A bare finally here would
|
|
377
|
+
// deregister the operation and mark it completed, removing it from
|
|
378
|
+
// the signal handler's view too, so a body that threw outside its
|
|
379
|
+
// own catch — notably anywhere in `applyAllComponents` outside its
|
|
380
|
+
// two per-component try blocks — would leave the checkout torn with
|
|
381
|
+
// no marker.
|
|
345
382
|
//
|
|
346
383
|
// This runs inside the withFileLock callback, so the furnace lock is
|
|
347
|
-
// still held for the duration of the restore
|
|
384
|
+
// still held for the duration of the restore: a competing process
|
|
348
385
|
// cannot start mutating half-way through it.
|
|
349
386
|
await rollbackOperationForThrow(operation);
|
|
350
387
|
throw error;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared precondition ladder for the Furnace command family: engine exists,
|
|
3
|
+
* `furnace.json` exists.
|
|
4
|
+
*
|
|
5
|
+
* Kept separate from the `GeneralError` ladder in `engine-precondition.ts`
|
|
6
|
+
* because the error CLASS is load-bearing here, not cosmetic: `FurnaceError`
|
|
7
|
+
* carries its own `userMessage` and exit code 9, so a helper raising
|
|
8
|
+
* `GeneralError` would silently change both.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately NOT routed through this helper — each informs rather than
|
|
11
|
+
* refuses, and each says so at its own site: `furnace list`,
|
|
12
|
+
* `furnace status`, `furnace init`, and `verify`. `furnace validate`
|
|
13
|
+
* refusing is the intended line between inspecting and validating.
|
|
14
|
+
*/
|
|
15
|
+
import type { FurnaceConfig } from '../types/furnace.js';
|
|
16
|
+
import type { ProjectPaths } from '../types/index.js';
|
|
17
|
+
/** Options shared by the Furnace precondition assertions. */
|
|
18
|
+
export interface FurnacePreconditionOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Appended to the engine-missing refusal, e.g.
|
|
21
|
+
* `' to scaffold a chrome-doc.'`. The base message ends WITHOUT
|
|
22
|
+
* punctuation so the suffix reads as one sentence; callers passing nothing
|
|
23
|
+
* get a plain full stop.
|
|
24
|
+
*/
|
|
25
|
+
engineMissingSuffix?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Asserts that a specific engine directory exists, raising a `FurnaceError`.
|
|
29
|
+
*
|
|
30
|
+
* The path-taking form, for core helpers that already hold `engineDir` and
|
|
31
|
+
* have no project root to derive it from.
|
|
32
|
+
*
|
|
33
|
+
* @param engineDir - Absolute path to the engine checkout
|
|
34
|
+
* @param options - Optional message tailoring
|
|
35
|
+
*/
|
|
36
|
+
export declare function assertFurnaceEngineDirReady(engineDir: string, options?: FurnacePreconditionOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Asserts that the engine checkout exists, raising a `FurnaceError`.
|
|
39
|
+
*
|
|
40
|
+
* The engine rung on its own, for the Furnace commands that scaffold or
|
|
41
|
+
* mutate component sources without needing `furnace.json` to exist yet.
|
|
42
|
+
*
|
|
43
|
+
* @param projectRoot - Project root directory
|
|
44
|
+
* @param options - Optional message tailoring
|
|
45
|
+
* @returns Resolved project paths, so callers do not re-derive them
|
|
46
|
+
*/
|
|
47
|
+
export declare function assertFurnaceEngineReady(projectRoot: string, options?: FurnacePreconditionOptions): Promise<{
|
|
48
|
+
paths: ProjectPaths;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Asserts the full Furnace ladder — engine checkout, then `furnace.json` —
|
|
52
|
+
* and returns the loaded config so callers do not read it a second time.
|
|
53
|
+
*
|
|
54
|
+
* @param projectRoot - Project root directory
|
|
55
|
+
* @param options - Optional message tailoring
|
|
56
|
+
* @returns Resolved project paths and the loaded furnace config
|
|
57
|
+
*/
|
|
58
|
+
export declare function assertFurnaceReady(projectRoot: string, options?: FurnacePreconditionOptions): Promise<{
|
|
59
|
+
paths: ProjectPaths;
|
|
60
|
+
config: FurnaceConfig;
|
|
61
|
+
}>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Shared precondition ladder for the Furnace command family: engine exists,
|
|
4
|
+
* `furnace.json` exists.
|
|
5
|
+
*
|
|
6
|
+
* Kept separate from the `GeneralError` ladder in `engine-precondition.ts`
|
|
7
|
+
* because the error CLASS is load-bearing here, not cosmetic: `FurnaceError`
|
|
8
|
+
* carries its own `userMessage` and exit code 9, so a helper raising
|
|
9
|
+
* `GeneralError` would silently change both.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately NOT routed through this helper — each informs rather than
|
|
12
|
+
* refuses, and each says so at its own site: `furnace list`,
|
|
13
|
+
* `furnace status`, `furnace init`, and `verify`. `furnace validate`
|
|
14
|
+
* refusing is the intended line between inspecting and validating.
|
|
15
|
+
*/
|
|
16
|
+
import { FurnaceError } from '../errors/furnace.js';
|
|
17
|
+
import { pathExists } from '../utils/fs.js';
|
|
18
|
+
import { getProjectPaths } from './config-paths.js';
|
|
19
|
+
import { furnaceConfigExists, loadFurnaceConfig } from './furnace-config.js';
|
|
20
|
+
/**
|
|
21
|
+
* Asserts that a specific engine directory exists, raising a `FurnaceError`.
|
|
22
|
+
*
|
|
23
|
+
* The path-taking form, for core helpers that already hold `engineDir` and
|
|
24
|
+
* have no project root to derive it from.
|
|
25
|
+
*
|
|
26
|
+
* @param engineDir - Absolute path to the engine checkout
|
|
27
|
+
* @param options - Optional message tailoring
|
|
28
|
+
*/
|
|
29
|
+
export async function assertFurnaceEngineDirReady(engineDir, options = {}) {
|
|
30
|
+
if (!(await pathExists(engineDir))) {
|
|
31
|
+
throw new FurnaceError(`Engine directory not found. Run "fireforge download" first${options.engineMissingSuffix ?? '.'}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Asserts that the engine checkout exists, raising a `FurnaceError`.
|
|
36
|
+
*
|
|
37
|
+
* The engine rung on its own, for the Furnace commands that scaffold or
|
|
38
|
+
* mutate component sources without needing `furnace.json` to exist yet.
|
|
39
|
+
*
|
|
40
|
+
* @param projectRoot - Project root directory
|
|
41
|
+
* @param options - Optional message tailoring
|
|
42
|
+
* @returns Resolved project paths, so callers do not re-derive them
|
|
43
|
+
*/
|
|
44
|
+
export async function assertFurnaceEngineReady(projectRoot, options = {}) {
|
|
45
|
+
const paths = getProjectPaths(projectRoot);
|
|
46
|
+
await assertFurnaceEngineDirReady(paths.engine, options);
|
|
47
|
+
return { paths };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Asserts the full Furnace ladder — engine checkout, then `furnace.json` —
|
|
51
|
+
* and returns the loaded config so callers do not read it a second time.
|
|
52
|
+
*
|
|
53
|
+
* @param projectRoot - Project root directory
|
|
54
|
+
* @param options - Optional message tailoring
|
|
55
|
+
* @returns Resolved project paths and the loaded furnace config
|
|
56
|
+
*/
|
|
57
|
+
export async function assertFurnaceReady(projectRoot, options = {}) {
|
|
58
|
+
const { paths } = await assertFurnaceEngineReady(projectRoot, options);
|
|
59
|
+
// `loadFurnaceConfig` refuses on its own with a fuller message, but the
|
|
60
|
+
// probe stays: it produces the shorter, action-first refusal the command
|
|
61
|
+
// layer has always shown for "you have not set Furnace up yet", which is a
|
|
62
|
+
// different situation from "your furnace.json is unreadable".
|
|
63
|
+
if (!(await furnaceConfigExists(projectRoot))) {
|
|
64
|
+
throw new FurnaceError('No furnace.json found. Run "fireforge furnace create" or "fireforge furnace override" to get started.');
|
|
65
|
+
}
|
|
66
|
+
return { paths, config: await loadFurnaceConfig(projectRoot) };
|
|
67
|
+
}
|