@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,14 +3,13 @@ export interface BuildIdentity {
|
|
|
3
3
|
shortCommit: string;
|
|
4
4
|
dirty: boolean;
|
|
5
5
|
/**
|
|
6
|
-
* Content hash of the uncommitted diff, present only for a DIRTY
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* hashing the full diff on every `--version` call is not worth it.
|
|
6
|
+
* Content hash of the uncommitted diff, present only for a DIRTY installed
|
|
7
|
+
* build. Two packs from the same HEAD with different uncommitted content
|
|
8
|
+
* share `shortCommit` and the `.dirty` marker, so without this they report
|
|
9
|
+
* byte-identical `--version` strings and a report against
|
|
10
|
+
* `<semver>+g<sha>.dirty` cannot be traced back to a specific pack. Absent
|
|
11
|
+
* in a git checkout: identity there comes from live git, and hashing the
|
|
12
|
+
* full diff on every `--version` call is not worth it.
|
|
14
13
|
*/
|
|
15
14
|
dirtyHash?: string;
|
|
16
15
|
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* Build identity for `--version`.
|
|
4
|
-
* shipped as plain "0.41.0" — consumers had to fingerprint tarballs by
|
|
5
|
-
* sha256 to know which build a claim was verified against. `--version`
|
|
6
|
-
* now reports `<semver>+g<short-sha>[.dirty[.<content-hash>]]`:
|
|
3
|
+
* Build identity for `--version`.
|
|
7
4
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* Distinct builds shipping as the same plain semver leave consumers
|
|
6
|
+
* fingerprinting tarballs by sha256 to know which build a claim was verified
|
|
7
|
+
* against. `--version` reports `<semver>+g<short-sha>[.dirty[.<content-hash>]]`:
|
|
8
|
+
*
|
|
9
|
+
* - In a git checkout (dev runs via tsx), identity comes from live git — a
|
|
10
|
+
* stale `dist/build-info.json` from an old build must never win.
|
|
11
|
+
* - In an installed package, it comes from `dist/build-info.json`, stamped
|
|
12
|
+
* by scripts/generate-build-info.mjs at build/pack time.
|
|
12
13
|
* - When neither yields an identity, `--version` degrades to the plain
|
|
13
14
|
* semver. Reading identity must never throw.
|
|
14
15
|
*
|
|
15
|
-
* Deliberately NOT wired into the per-patch lint cache key: identity
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Deliberately NOT wired into the per-patch lint cache key: identity would
|
|
17
|
+
* churn the cache on every commit at the same semver for no correctness gain
|
|
18
|
+
* (`getPackageVersion` stays the cache input).
|
|
18
19
|
*/
|
|
19
20
|
import { execFileSync } from 'node:child_process';
|
|
20
21
|
import { existsSync, readFileSync } from 'node:fs';
|
|
@@ -20,9 +20,8 @@ export declare function toError(error: unknown): Error;
|
|
|
20
20
|
* The check is deliberately structural rather than `error instanceof Error`:
|
|
21
21
|
* a plain object carrying `.code` — exactly the shape {@link toError} exists
|
|
22
22
|
* to normalise — reaches errno consumers through rejected promises and
|
|
23
|
-
* cross-realm throws
|
|
24
|
-
*
|
|
25
|
-
* and so misclassified that shape as "no code".
|
|
23
|
+
* cross-realm throws, and an `instanceof Error` gate misclassifies it as "no
|
|
24
|
+
* code".
|
|
26
25
|
*/
|
|
27
26
|
export declare function getNodeErrorCode(error: unknown): string | undefined;
|
|
28
27
|
/**
|
|
@@ -32,10 +31,9 @@ export declare function getNodeErrorCode(error: unknown): string | undefined;
|
|
|
32
31
|
* Only `ESRCH` ("no such process") means dead. **`EPERM` means ALIVE**: the
|
|
33
32
|
* process exists but is owned by another uid, which happens routinely with
|
|
34
33
|
* root-owned builds, `sudo`, shared CI runners and container UID mismatches.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* is the safe direction for every caller: it refuses rather than destroys.
|
|
34
|
+
* Reading EPERM as dead in a predicate that gates a recursive delete removes
|
|
35
|
+
* a live build's tree clone or a live furnace lock out from under its owner.
|
|
36
|
+
* Any other errno is treated as "unknown, assume alive", the safe direction
|
|
37
|
+
* for every caller: it refuses rather than destroys.
|
|
40
38
|
*/
|
|
41
39
|
export declare function isProcessAlive(pid: number): boolean;
|
package/dist/src/utils/errors.js
CHANGED
|
@@ -32,9 +32,8 @@ export function toError(error) {
|
|
|
32
32
|
* The check is deliberately structural rather than `error instanceof Error`:
|
|
33
33
|
* a plain object carrying `.code` — exactly the shape {@link toError} exists
|
|
34
34
|
* to normalise — reaches errno consumers through rejected promises and
|
|
35
|
-
* cross-realm throws
|
|
36
|
-
*
|
|
37
|
-
* and so misclassified that shape as "no code".
|
|
35
|
+
* cross-realm throws, and an `instanceof Error` gate misclassifies it as "no
|
|
36
|
+
* code".
|
|
38
37
|
*/
|
|
39
38
|
export function getNodeErrorCode(error) {
|
|
40
39
|
if (typeof error === 'object' &&
|
|
@@ -52,11 +51,10 @@ export function getNodeErrorCode(error) {
|
|
|
52
51
|
* Only `ESRCH` ("no such process") means dead. **`EPERM` means ALIVE**: the
|
|
53
52
|
* process exists but is owned by another uid, which happens routinely with
|
|
54
53
|
* root-owned builds, `sudo`, shared CI runners and container UID mismatches.
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* is the safe direction for every caller: it refuses rather than destroys.
|
|
54
|
+
* Reading EPERM as dead in a predicate that gates a recursive delete removes
|
|
55
|
+
* a live build's tree clone or a live furnace lock out from under its owner.
|
|
56
|
+
* Any other errno is treated as "unknown, assume alive", the safe direction
|
|
57
|
+
* for every caller: it refuses rather than destroys.
|
|
60
58
|
*/
|
|
61
59
|
export function isProcessAlive(pid) {
|
|
62
60
|
try {
|
|
@@ -12,6 +12,25 @@ export declare function setMachineOutputMode(enabled: boolean): void;
|
|
|
12
12
|
export declare function isMachineOutputMode(): boolean;
|
|
13
13
|
/** Seals (or unseals) stdout after a machine-readable final line. */
|
|
14
14
|
export declare function setStdoutSealed(sealed: boolean): void;
|
|
15
|
+
/**
|
|
16
|
+
* True when a machine-readable payload already owns stdout.
|
|
17
|
+
*
|
|
18
|
+
* The CLI error boundary consults this before emitting a `--json` error
|
|
19
|
+
* envelope: a command that wrote its payload and THEN refused (e.g.
|
|
20
|
+
* `status --json --fail-on`) must not have a second JSON document appended,
|
|
21
|
+
* which would break the "exactly one document" half of the contract in
|
|
22
|
+
* docs/machine-output.md.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isStdoutSealed(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Checks if verbose mode is enabled.
|
|
27
|
+
*
|
|
28
|
+
* Exported so the CLI error boundary can decide whether to walk an error's
|
|
29
|
+
* `cause` chain.
|
|
30
|
+
*
|
|
31
|
+
* @returns True if verbose mode is enabled
|
|
32
|
+
*/
|
|
33
|
+
export declare function isVerbose(): boolean;
|
|
15
34
|
/**
|
|
16
35
|
* Displays a verbose/debug message (only shown if verbose mode is enabled).
|
|
17
36
|
* @param message - Message to display
|
|
@@ -49,13 +68,13 @@ export declare const NOTICE_PREFIX = "[FireForge] NOTICE:";
|
|
|
49
68
|
*
|
|
50
69
|
* These lines are not warnings about the operator's code — they explain a
|
|
51
70
|
* decision FireForge just made (escalating an incremental build to a full
|
|
52
|
-
* one, sharding a run, skipping a step). Emitted through `info` they
|
|
71
|
+
* one, sharding a run, skipping a step). Emitted through `info` they are
|
|
53
72
|
* silently dropped by agent-facing output filters that keep only warnings
|
|
54
73
|
* and errors, leaving a multi-minute build with no explanation and reading
|
|
55
74
|
* as a hang. There are very few such lines and they are exactly the ones a
|
|
56
|
-
* non-interactive operator needs, so they ride the warning channel and
|
|
57
|
-
*
|
|
58
|
-
*
|
|
75
|
+
* non-interactive operator needs, so they ride the warning channel and carry
|
|
76
|
+
* {@link NOTICE_PREFIX} so a reader can still tell them apart from a real
|
|
77
|
+
* warning.
|
|
59
78
|
*/
|
|
60
79
|
export declare function notice(message: string): void;
|
|
61
80
|
/** Logs an error message. */
|
|
@@ -80,12 +99,10 @@ export declare function cancel(message: string): void;
|
|
|
80
99
|
* Checks whether a prompt result represents a user cancellation.
|
|
81
100
|
*
|
|
82
101
|
* Narrows to `symbol` — clack returns its cancel sentinel as a symbol and
|
|
83
|
-
* `p.isCancel` is itself a type predicate.
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* the sentinel. Keep the predicate form: it is the single highest-leverage
|
|
88
|
-
* signature in the codebase for escape-hatch count.
|
|
102
|
+
* `p.isCancel` is itself a type predicate. Returning plain `boolean` erases
|
|
103
|
+
* that narrowing and forces `as string` / `as PatchCategory` casts across
|
|
104
|
+
* the command modules on the *non*-cancelled branch, where the value is
|
|
105
|
+
* already known not to be the sentinel. Keep the predicate form.
|
|
89
106
|
*/
|
|
90
107
|
export declare function isCancel(value: unknown): value is symbol;
|
|
91
108
|
/** Displays a titled note block for follow-up details. */
|
package/dist/src/utils/logger.js
CHANGED
|
@@ -9,11 +9,9 @@ let verboseMode = false;
|
|
|
9
9
|
* In machine mode, stdout belongs EXCLUSIVELY to the machine-readable
|
|
10
10
|
* payload: all human-facing diagnostics (intro/outro banners, info, warn,
|
|
11
11
|
* error, steps, notes) are routed to stderr as plain unstyled lines.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* objects on the machine contract were followed by a styled duplicate on
|
|
16
|
-
* the same stream.
|
|
12
|
+
* Otherwise clack's log helpers write styled warnings to stdout *before* the
|
|
13
|
+
* JSON body — a truncated-directory warning during `status --json` breaks
|
|
14
|
+
* every `JSON.parse(stdout)` consumer.
|
|
17
15
|
*/
|
|
18
16
|
let machineOutputMode = false;
|
|
19
17
|
/**
|
|
@@ -50,6 +48,18 @@ let stdoutSealed = false;
|
|
|
50
48
|
export function setStdoutSealed(sealed) {
|
|
51
49
|
stdoutSealed = sealed;
|
|
52
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* True when a machine-readable payload already owns stdout.
|
|
53
|
+
*
|
|
54
|
+
* The CLI error boundary consults this before emitting a `--json` error
|
|
55
|
+
* envelope: a command that wrote its payload and THEN refused (e.g.
|
|
56
|
+
* `status --json --fail-on`) must not have a second JSON document appended,
|
|
57
|
+
* which would break the "exactly one document" half of the contract in
|
|
58
|
+
* docs/machine-output.md.
|
|
59
|
+
*/
|
|
60
|
+
export function isStdoutSealed() {
|
|
61
|
+
return stdoutSealed;
|
|
62
|
+
}
|
|
53
63
|
/** True when human output must avoid stdout. */
|
|
54
64
|
function routeToStderr() {
|
|
55
65
|
return machineOutputMode || stdoutSealed;
|
|
@@ -60,9 +70,13 @@ function writeDiagnostic(prefix, message) {
|
|
|
60
70
|
}
|
|
61
71
|
/**
|
|
62
72
|
* Checks if verbose mode is enabled.
|
|
73
|
+
*
|
|
74
|
+
* Exported so the CLI error boundary can decide whether to walk an error's
|
|
75
|
+
* `cause` chain.
|
|
76
|
+
*
|
|
63
77
|
* @returns True if verbose mode is enabled
|
|
64
78
|
*/
|
|
65
|
-
function isVerbose() {
|
|
79
|
+
export function isVerbose() {
|
|
66
80
|
return verboseMode;
|
|
67
81
|
}
|
|
68
82
|
/**
|
|
@@ -128,13 +142,13 @@ export const NOTICE_PREFIX = '[FireForge] NOTICE:';
|
|
|
128
142
|
*
|
|
129
143
|
* These lines are not warnings about the operator's code — they explain a
|
|
130
144
|
* decision FireForge just made (escalating an incremental build to a full
|
|
131
|
-
* one, sharding a run, skipping a step). Emitted through `info` they
|
|
145
|
+
* one, sharding a run, skipping a step). Emitted through `info` they are
|
|
132
146
|
* silently dropped by agent-facing output filters that keep only warnings
|
|
133
147
|
* and errors, leaving a multi-minute build with no explanation and reading
|
|
134
148
|
* as a hang. There are very few such lines and they are exactly the ones a
|
|
135
|
-
* non-interactive operator needs, so they ride the warning channel and
|
|
136
|
-
*
|
|
137
|
-
*
|
|
149
|
+
* non-interactive operator needs, so they ride the warning channel and carry
|
|
150
|
+
* {@link NOTICE_PREFIX} so a reader can still tell them apart from a real
|
|
151
|
+
* warning.
|
|
138
152
|
*/
|
|
139
153
|
export function notice(message) {
|
|
140
154
|
if (routeToStderr()) {
|
|
@@ -238,12 +252,10 @@ export function cancel(message) {
|
|
|
238
252
|
* Checks whether a prompt result represents a user cancellation.
|
|
239
253
|
*
|
|
240
254
|
* Narrows to `symbol` — clack returns its cancel sentinel as a symbol and
|
|
241
|
-
* `p.isCancel` is itself a type predicate.
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* the sentinel. Keep the predicate form: it is the single highest-leverage
|
|
246
|
-
* signature in the codebase for escape-hatch count.
|
|
255
|
+
* `p.isCancel` is itself a type predicate. Returning plain `boolean` erases
|
|
256
|
+
* that narrowing and forces `as string` / `as PatchCategory` casts across
|
|
257
|
+
* the command modules on the *non*-cancelled branch, where the value is
|
|
258
|
+
* already known not to be the sentinel. Keep the predicate form.
|
|
247
259
|
*/
|
|
248
260
|
export function isCancel(value) {
|
|
249
261
|
return p.isCancel(value);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ExitCode } from '../errors/codes.js';
|
|
2
|
+
/** Current envelope version. Bump only with a documented migration. */
|
|
3
|
+
export declare const MACHINE_OUTPUT_SCHEMA_VERSION = 1;
|
|
4
|
+
/**
|
|
5
|
+
* Writes the machine-readable error envelope to stdout and throws the
|
|
6
|
+
* sentinel that carries the exit code to the entrypoint. Never returns.
|
|
7
|
+
*
|
|
8
|
+
* @param code - Stable machine-readable reason tag, e.g. `engine-missing`
|
|
9
|
+
* @param message - Human-readable explanation, identical to the non-JSON text
|
|
10
|
+
* @param exitCode - Exit code to terminate with
|
|
11
|
+
*/
|
|
12
|
+
export declare function emitMachineError(code: string, message: string, exitCode?: ExitCode): never;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* The `--json` envelope contract, in one place.
|
|
4
|
+
*
|
|
5
|
+
* Without a single owner, machine-readable output drifts into unrelated
|
|
6
|
+
* shapes: two commands sharing a `schemaVersion: 1` envelope can still
|
|
7
|
+
* disagree on failure, so a scripted consumer gets a parseable refusal from
|
|
8
|
+
* one and a bare non-zero exit from the other.
|
|
9
|
+
*
|
|
10
|
+
* The contract, documented in `docs/machine-output.md`:
|
|
11
|
+
* 1. Success writes exactly one JSON document to stdout.
|
|
12
|
+
* 2. Failure writes exactly one `{ schemaVersion, error, code }` document
|
|
13
|
+
* to stdout, then exits non-zero.
|
|
14
|
+
* 3. Machine mode is engaged BEFORE any output, so every diagnostic —
|
|
15
|
+
* including one rendered later by `withErrorHandling` — routes to
|
|
16
|
+
* stderr and cannot corrupt the payload.
|
|
17
|
+
*/
|
|
18
|
+
import { CommandError } from '../errors/base.js';
|
|
19
|
+
import { ExitCode } from '../errors/codes.js';
|
|
20
|
+
/** Current envelope version. Bump only with a documented migration. */
|
|
21
|
+
export const MACHINE_OUTPUT_SCHEMA_VERSION = 1;
|
|
22
|
+
/**
|
|
23
|
+
* Writes the machine-readable error envelope to stdout and throws the
|
|
24
|
+
* sentinel that carries the exit code to the entrypoint. Never returns.
|
|
25
|
+
*
|
|
26
|
+
* @param code - Stable machine-readable reason tag, e.g. `engine-missing`
|
|
27
|
+
* @param message - Human-readable explanation, identical to the non-JSON text
|
|
28
|
+
* @param exitCode - Exit code to terminate with
|
|
29
|
+
*/
|
|
30
|
+
export function emitMachineError(code, message, exitCode = ExitCode.GENERAL_ERROR) {
|
|
31
|
+
process.stdout.write(`${JSON.stringify({ schemaVersion: MACHINE_OUTPUT_SCHEMA_VERSION, error: message, code })}\n`);
|
|
32
|
+
throw new CommandError(exitCode);
|
|
33
|
+
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Filters an object to only include keys whose values are not undefined.
|
|
3
3
|
* Designed for use with exactOptionalPropertyTypes — the result can be
|
|
4
|
-
* spread into typed option objects without assigning undefined to optional
|
|
4
|
+
* spread into typed option objects without assigning undefined to optional
|
|
5
|
+
* properties.
|
|
6
|
+
*
|
|
7
|
+
* Constrained to `object`, not `Record<string, unknown>`: a named interface
|
|
8
|
+
* has no index signature, so the narrower constraint rejects exactly the
|
|
9
|
+
* annotations this helper is most useful with. Nothing in the body needs the
|
|
10
|
+
* index signature — the key walk goes through `Object.keys`.
|
|
11
|
+
*
|
|
12
|
+
* @param obj - Object to filter
|
|
13
|
+
* @returns The same object with every `undefined`-valued key removed
|
|
5
14
|
*/
|
|
6
|
-
export declare function pickDefined<T extends
|
|
15
|
+
export declare function pickDefined<T extends object>(obj: T): {
|
|
7
16
|
[K in keyof T]+?: Exclude<T[K], undefined>;
|
|
8
17
|
};
|
|
9
18
|
import type { Command } from 'commander';
|
|
@@ -15,11 +24,10 @@ import type { Command } from 'commander';
|
|
|
15
24
|
* as argument-validation failures; anything else re-throws out of
|
|
16
25
|
* `parseAsync`, BYPASSING `withErrorHandling` entirely and landing in the
|
|
17
26
|
* bin's `main().catch` as an unformatted `Fatal error: …` dump with exit 1.
|
|
18
|
-
* That
|
|
19
|
-
* `
|
|
20
|
-
* (
|
|
21
|
-
*
|
|
22
|
-
* helper (or throw commander's InvalidArgumentError directly).
|
|
27
|
+
* That covers a plain Error, a `GeneralError`, and even a FireForge
|
|
28
|
+
* `InvalidArgumentError`, whose `code` is a numeric ExitCode. Every
|
|
29
|
+
* `.argParser()`/option-parser callback must be wrapped with this helper (or
|
|
30
|
+
* throw commander's InvalidArgumentError directly).
|
|
23
31
|
*/
|
|
24
32
|
export declare function commanderArgParser<T>(parse: (raw: string) => T): (raw: string) => T;
|
|
25
33
|
/**
|
|
@@ -30,23 +38,32 @@ export declare function commanderArgParser<T>(parse: (raw: string) => T): (raw:
|
|
|
30
38
|
* .option('--mach-arg <arg>', 'Repeatable.', ...stringListOption())
|
|
31
39
|
* ```
|
|
32
40
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
41
|
+
* Commander types the default slot as `unknown`, so every open-coded copy
|
|
42
|
+
* carries an `[] as string[]` cast, and it is easy to mutate the accumulator
|
|
43
|
+
* in place instead of returning a new array. Returning a fresh array per
|
|
44
|
+
* call also means the default cannot be shared between two `.option()`
|
|
45
|
+
* registrations.
|
|
38
46
|
*/
|
|
39
47
|
export declare function stringListOption(): [(value: string, previous: string[]) => string[], string[]];
|
|
48
|
+
/** Environment variable naming a standing wait budget for the whole session. */
|
|
49
|
+
export declare const WAIT_LOCK_ENV_VAR = "FIREFORGE_WAIT_LOCK";
|
|
40
50
|
/**
|
|
41
51
|
* Resolves the parsed `--wait-lock [seconds]` option value into a wait budget
|
|
42
52
|
* in seconds for `withEngineSessionLock`:
|
|
43
|
-
* - absent (`undefined`) →
|
|
53
|
+
* - absent (`undefined`) → {@link WAIT_LOCK_ENV_VAR} if set, else `undefined`
|
|
54
|
+
* (the ~1 s fail-fast),
|
|
44
55
|
* - bare flag (`true`) → {@link DEFAULT_WAIT_LOCK_SECONDS},
|
|
45
56
|
* - explicit value → integer validated into 1..3600.
|
|
46
57
|
*
|
|
58
|
+
* The flag always wins over the environment: the environment expresses a
|
|
59
|
+
* default for a session, and an invocation that names a budget has said
|
|
60
|
+
* something more specific than the session did.
|
|
61
|
+
*
|
|
47
62
|
* Accepts the raw string too, so it doubles as the option's arg parser (wrap
|
|
48
63
|
* with {@link commanderArgParser} so failures surface through commander's
|
|
49
|
-
* invalid-argument channel).
|
|
64
|
+
* invalid-argument channel). In that role the value is never `undefined`, so
|
|
65
|
+
* the environment fallback cannot leak into flag PARSING — only into flag
|
|
66
|
+
* ABSENCE, which is where it belongs.
|
|
50
67
|
*/
|
|
51
68
|
export declare function resolveWaitLockSeconds(value: string | number | boolean | undefined): number | undefined;
|
|
52
69
|
/**
|
|
@@ -2,19 +2,28 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Filters an object to only include keys whose values are not undefined.
|
|
4
4
|
* Designed for use with exactOptionalPropertyTypes — the result can be
|
|
5
|
-
* spread into typed option objects without assigning undefined to optional
|
|
5
|
+
* spread into typed option objects without assigning undefined to optional
|
|
6
|
+
* properties.
|
|
7
|
+
*
|
|
8
|
+
* Constrained to `object`, not `Record<string, unknown>`: a named interface
|
|
9
|
+
* has no index signature, so the narrower constraint rejects exactly the
|
|
10
|
+
* annotations this helper is most useful with. Nothing in the body needs the
|
|
11
|
+
* index signature — the key walk goes through `Object.keys`.
|
|
12
|
+
*
|
|
13
|
+
* @param obj - Object to filter
|
|
14
|
+
* @returns The same object with every `undefined`-valued key removed
|
|
6
15
|
*/
|
|
7
16
|
export function pickDefined(obj) {
|
|
8
17
|
const result = {};
|
|
9
|
-
for (const key of Object.
|
|
10
|
-
if (
|
|
11
|
-
result[key] =
|
|
18
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
19
|
+
if (value !== undefined) {
|
|
20
|
+
result[key] = value;
|
|
12
21
|
}
|
|
13
22
|
}
|
|
14
23
|
return result;
|
|
15
24
|
}
|
|
16
25
|
import { InvalidArgumentError as CommanderInvalidArgumentError } from 'commander';
|
|
17
|
-
import { GeneralError } from '../errors/base.js';
|
|
26
|
+
import { GeneralError, InvalidArgumentError } from '../errors/base.js';
|
|
18
27
|
import { toError } from './errors.js';
|
|
19
28
|
/**
|
|
20
29
|
* Wraps an option-argument parser so its failures surface through
|
|
@@ -24,11 +33,10 @@ import { toError } from './errors.js';
|
|
|
24
33
|
* as argument-validation failures; anything else re-throws out of
|
|
25
34
|
* `parseAsync`, BYPASSING `withErrorHandling` entirely and landing in the
|
|
26
35
|
* bin's `main().catch` as an unformatted `Fatal error: …` dump with exit 1.
|
|
27
|
-
* That
|
|
28
|
-
* `
|
|
29
|
-
* (
|
|
30
|
-
*
|
|
31
|
-
* helper (or throw commander's InvalidArgumentError directly).
|
|
36
|
+
* That covers a plain Error, a `GeneralError`, and even a FireForge
|
|
37
|
+
* `InvalidArgumentError`, whose `code` is a numeric ExitCode. Every
|
|
38
|
+
* `.argParser()`/option-parser callback must be wrapped with this helper (or
|
|
39
|
+
* throw commander's InvalidArgumentError directly).
|
|
32
40
|
*/
|
|
33
41
|
export function commanderArgParser(parse) {
|
|
34
42
|
return (raw) => {
|
|
@@ -48,31 +56,81 @@ export function commanderArgParser(parse) {
|
|
|
48
56
|
* .option('--mach-arg <arg>', 'Repeatable.', ...stringListOption())
|
|
49
57
|
* ```
|
|
50
58
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
59
|
+
* Commander types the default slot as `unknown`, so every open-coded copy
|
|
60
|
+
* carries an `[] as string[]` cast, and it is easy to mutate the accumulator
|
|
61
|
+
* in place instead of returning a new array. Returning a fresh array per
|
|
62
|
+
* call also means the default cannot be shared between two `.option()`
|
|
63
|
+
* registrations.
|
|
56
64
|
*/
|
|
57
65
|
export function stringListOption() {
|
|
58
66
|
return [(value, previous) => [...previous, value], []];
|
|
59
67
|
}
|
|
60
68
|
/** Wait budget applied when `--wait-lock` is passed without a value. */
|
|
61
69
|
const DEFAULT_WAIT_LOCK_SECONDS = 60;
|
|
70
|
+
/** Environment variable naming a standing wait budget for the whole session. */
|
|
71
|
+
export const WAIT_LOCK_ENV_VAR = 'FIREFORGE_WAIT_LOCK';
|
|
72
|
+
/** Bounds shared by the flag and the environment variable. */
|
|
73
|
+
const MIN_WAIT_LOCK_SECONDS = 1;
|
|
74
|
+
const MAX_WAIT_LOCK_SECONDS = 3600;
|
|
75
|
+
/**
|
|
76
|
+
* Parses a wait budget from text, or undefined when it is not an integer in
|
|
77
|
+
* range. Shared by the flag and {@link WAIT_LOCK_ENV_VAR} so the two cannot
|
|
78
|
+
* drift on what they accept.
|
|
79
|
+
*/
|
|
80
|
+
function parseWaitLockSeconds(raw) {
|
|
81
|
+
const n = Number.parseInt(raw, 10);
|
|
82
|
+
if (!Number.isFinite(n) || n < MIN_WAIT_LOCK_SECONDS || n > MAX_WAIT_LOCK_SECONDS) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return n;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The standing wait budget from {@link WAIT_LOCK_ENV_VAR}, or undefined when
|
|
89
|
+
* it is unset or empty.
|
|
90
|
+
*
|
|
91
|
+
* Exists because a wait budget is a property of the SESSION, not of the
|
|
92
|
+
* invocation: a checkout worked by several concurrent agent sessions has a
|
|
93
|
+
* held lock as its normal state, and an unattended loop would otherwise have
|
|
94
|
+
* to thread `--wait-lock` through every command it issues — the one place
|
|
95
|
+
* it is easiest to forget, and the failure only shows up once the loop has
|
|
96
|
+
* already produced a tail of refusals.
|
|
97
|
+
*
|
|
98
|
+
* An unusable value is a usage error rather than a silent fall-back to
|
|
99
|
+
* fail-fast: the operator set it precisely because they did not want to
|
|
100
|
+
* discover the budget at refusal time.
|
|
101
|
+
*/
|
|
102
|
+
function waitLockSecondsFromEnv() {
|
|
103
|
+
const raw = process.env[WAIT_LOCK_ENV_VAR]?.trim();
|
|
104
|
+
if (raw === undefined || raw.length === 0) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const parsed = parseWaitLockSeconds(raw);
|
|
108
|
+
if (parsed === undefined) {
|
|
109
|
+
throw new InvalidArgumentError(`${WAIT_LOCK_ENV_VAR} must be an integer in ${String(MIN_WAIT_LOCK_SECONDS)}..${String(MAX_WAIT_LOCK_SECONDS)} (got "${raw}")`, WAIT_LOCK_ENV_VAR);
|
|
110
|
+
}
|
|
111
|
+
return parsed;
|
|
112
|
+
}
|
|
62
113
|
/**
|
|
63
114
|
* Resolves the parsed `--wait-lock [seconds]` option value into a wait budget
|
|
64
115
|
* in seconds for `withEngineSessionLock`:
|
|
65
|
-
* - absent (`undefined`) →
|
|
116
|
+
* - absent (`undefined`) → {@link WAIT_LOCK_ENV_VAR} if set, else `undefined`
|
|
117
|
+
* (the ~1 s fail-fast),
|
|
66
118
|
* - bare flag (`true`) → {@link DEFAULT_WAIT_LOCK_SECONDS},
|
|
67
119
|
* - explicit value → integer validated into 1..3600.
|
|
68
120
|
*
|
|
121
|
+
* The flag always wins over the environment: the environment expresses a
|
|
122
|
+
* default for a session, and an invocation that names a budget has said
|
|
123
|
+
* something more specific than the session did.
|
|
124
|
+
*
|
|
69
125
|
* Accepts the raw string too, so it doubles as the option's arg parser (wrap
|
|
70
126
|
* with {@link commanderArgParser} so failures surface through commander's
|
|
71
|
-
* invalid-argument channel).
|
|
127
|
+
* invalid-argument channel). In that role the value is never `undefined`, so
|
|
128
|
+
* the environment fallback cannot leak into flag PARSING — only into flag
|
|
129
|
+
* ABSENCE, which is where it belongs.
|
|
72
130
|
*/
|
|
73
131
|
export function resolveWaitLockSeconds(value) {
|
|
74
132
|
if (value === undefined || value === false) {
|
|
75
|
-
return
|
|
133
|
+
return waitLockSecondsFromEnv();
|
|
76
134
|
}
|
|
77
135
|
if (value === true) {
|
|
78
136
|
return DEFAULT_WAIT_LOCK_SECONDS;
|
|
@@ -80,23 +138,21 @@ export function resolveWaitLockSeconds(value) {
|
|
|
80
138
|
if (typeof value === 'number') {
|
|
81
139
|
return value;
|
|
82
140
|
}
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
-
throw new GeneralError(`--wait-lock must be an integer in
|
|
141
|
+
const parsed = parseWaitLockSeconds(value);
|
|
142
|
+
if (parsed === undefined) {
|
|
143
|
+
throw new GeneralError(`--wait-lock must be an integer in ${String(MIN_WAIT_LOCK_SECONDS)}..${String(MAX_WAIT_LOCK_SECONDS)} (got "${value}")`);
|
|
86
144
|
}
|
|
87
|
-
return
|
|
145
|
+
return parsed;
|
|
88
146
|
}
|
|
89
147
|
/**
|
|
90
148
|
* Registers `--wait-lock [seconds]` on a command that takes NO lock, so a
|
|
91
149
|
* scripted sequence can blanket-append the flag without hitting a usage
|
|
92
|
-
* error
|
|
150
|
+
* error — a command that rejects it with "unknown option" kills the whole
|
|
151
|
+
* sequence with a usage error instead of a lock message.
|
|
93
152
|
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* error instead of a lock message. The flag is accepted and ignored here —
|
|
98
|
-
* never silently repurposed — and the help text says so, so nobody reads
|
|
99
|
-
* its presence as evidence that this command waits for anything.
|
|
153
|
+
* The flag is accepted and ignored here — never silently repurposed — and
|
|
154
|
+
* the help text says so, so nobody reads its presence as evidence that this
|
|
155
|
+
* command waits for anything.
|
|
100
156
|
*
|
|
101
157
|
* The value is parsed and validated exactly as the honoring variant does:
|
|
102
158
|
* `--wait-lock nonsense` must still be a usage error everywhere, or the
|
|
@@ -134,5 +190,5 @@ export function ensureWaitLockOptionEverywhere(command) {
|
|
|
134
190
|
* `waitLockSeconds` for `withEngineSessionLock`/`withPatchDirectoryLock`.
|
|
135
191
|
*/
|
|
136
192
|
export function addWaitLockOption(command) {
|
|
137
|
-
return command.option('--wait-lock [seconds]',
|
|
193
|
+
return command.option('--wait-lock [seconds]', `Wait up to this many seconds (default 60) for another FireForge command to release the contended lock, instead of failing on the default budget. Set ${WAIT_LOCK_ENV_VAR} to apply a budget to every command in a session`, commanderArgParser((raw) => resolveWaitLockSeconds(raw)));
|
|
138
194
|
}
|
|
@@ -4,15 +4,17 @@ export declare function normalizePathSlashes(path: string): string;
|
|
|
4
4
|
* Strips a leading `engine/` (or `engine\\`) segment from a user-supplied
|
|
5
5
|
* path so the same command invocation accepts both repo-root-relative paths
|
|
6
6
|
* (`engine/browser/base/content/foo.js`) and engine-relative paths
|
|
7
|
-
* (`browser/base/content/foo.js`).
|
|
8
|
-
* default macOS and Windows filesystems treat `Engine/` and `engine/` as
|
|
9
|
-
* the same directory; a literal lowercase-only check previously left `mach`
|
|
10
|
-
* / the manifest writers resolving against a wrongly-cased prefix. Leading
|
|
11
|
-
* whitespace is ignored so tab-completed inputs don't slip past the strip.
|
|
7
|
+
* (`browser/base/content/foo.js`).
|
|
12
8
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* The match is case-insensitive because default macOS and Windows
|
|
10
|
+
* filesystems treat `Engine/` and `engine/` as the same directory; a literal
|
|
11
|
+
* lowercase-only check leaves `mach` and the manifest writers resolving
|
|
12
|
+
* against a wrongly-cased prefix. Leading whitespace is ignored so
|
|
13
|
+
* tab-completed inputs do not slip past the strip.
|
|
14
|
+
*
|
|
15
|
+
* The return value is trimmed of that leading whitespace when the prefix
|
|
16
|
+
* matched, and otherwise passed through verbatim — callers that care about
|
|
17
|
+
* internal whitespace can trim on their side.
|
|
16
18
|
*
|
|
17
19
|
* @param filePath Path as provided by the user
|
|
18
20
|
* @returns Path relative to the engine directory (or the original when the
|
package/dist/src/utils/paths.js
CHANGED
|
@@ -18,15 +18,17 @@ export function normalizePathSlashes(path) {
|
|
|
18
18
|
* Strips a leading `engine/` (or `engine\\`) segment from a user-supplied
|
|
19
19
|
* path so the same command invocation accepts both repo-root-relative paths
|
|
20
20
|
* (`engine/browser/base/content/foo.js`) and engine-relative paths
|
|
21
|
-
* (`browser/base/content/foo.js`).
|
|
22
|
-
* default macOS and Windows filesystems treat `Engine/` and `engine/` as
|
|
23
|
-
* the same directory; a literal lowercase-only check previously left `mach`
|
|
24
|
-
* / the manifest writers resolving against a wrongly-cased prefix. Leading
|
|
25
|
-
* whitespace is ignored so tab-completed inputs don't slip past the strip.
|
|
21
|
+
* (`browser/base/content/foo.js`).
|
|
26
22
|
*
|
|
27
|
-
* The
|
|
28
|
-
*
|
|
29
|
-
*
|
|
23
|
+
* The match is case-insensitive because default macOS and Windows
|
|
24
|
+
* filesystems treat `Engine/` and `engine/` as the same directory; a literal
|
|
25
|
+
* lowercase-only check leaves `mach` and the manifest writers resolving
|
|
26
|
+
* against a wrongly-cased prefix. Leading whitespace is ignored so
|
|
27
|
+
* tab-completed inputs do not slip past the strip.
|
|
28
|
+
*
|
|
29
|
+
* The return value is trimmed of that leading whitespace when the prefix
|
|
30
|
+
* matched, and otherwise passed through verbatim — callers that care about
|
|
31
|
+
* internal whitespace can trim on their side.
|
|
30
32
|
*
|
|
31
33
|
* @param filePath Path as provided by the user
|
|
32
34
|
* @returns Path relative to the engine directory (or the original when the
|