@hominis/fireforge 0.40.0 → 0.41.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 +79 -0
- package/README.md +16 -10
- package/dist/bin/fireforge.js +25 -4
- package/dist/build-info.json +9 -0
- package/dist/src/cli.js +20 -3
- package/dist/src/commands/bootstrap.js +5 -1
- package/dist/src/commands/discard.js +2 -22
- package/dist/src/commands/doctor/post-rebase-audit.js +27 -4
- package/dist/src/commands/doctor-check-core.d.ts +20 -0
- package/dist/src/commands/doctor-check-core.js +28 -0
- package/dist/src/commands/doctor-external-toolchains.js +2 -0
- package/dist/src/commands/doctor-furnace-manifest-sync.js +144 -46
- package/dist/src/commands/doctor-furnace.js +13 -11
- package/dist/src/commands/doctor-orphaned-harness.js +2 -1
- package/dist/src/commands/doctor.js +2 -2
- package/dist/src/commands/export-all.js +9 -1
- package/dist/src/commands/export-flow.js +13 -3
- package/dist/src/commands/export-placement-conflicts.d.ts +17 -0
- package/dist/src/commands/export-placement-conflicts.js +74 -0
- package/dist/src/commands/export-placement-gate.js +1 -1
- package/dist/src/commands/export-shared.d.ts +8 -1
- package/dist/src/commands/export-shared.js +16 -7
- package/dist/src/commands/export.js +2 -2
- package/dist/src/commands/furnace/apply.js +4 -3
- package/dist/src/commands/furnace/chrome-doc-remove.js +13 -2
- package/dist/src/commands/furnace/chrome-doc.js +13 -2
- package/dist/src/commands/furnace/create-browser-test.d.ts +5 -0
- package/dist/src/commands/furnace/create-browser-test.js +5 -0
- package/dist/src/commands/furnace/create.js +2 -2
- package/dist/src/commands/furnace/diff.js +2 -1
- package/dist/src/commands/furnace/init.js +4 -6
- package/dist/src/commands/furnace/override.js +2 -2
- package/dist/src/commands/furnace/remove-mutations.d.ts +40 -0
- package/dist/src/commands/furnace/remove-mutations.js +171 -0
- package/dist/src/commands/furnace/remove.js +21 -128
- package/dist/src/commands/furnace/rename-browser-test.js +54 -5
- package/dist/src/commands/furnace/scan.js +27 -36
- package/dist/src/commands/furnace/status.js +30 -28
- package/dist/src/commands/furnace/validate.js +25 -18
- package/dist/src/commands/import.js +6 -20
- package/dist/src/commands/lint-per-patch.js +12 -59
- package/dist/src/commands/lint-per-run-checkjs.d.ts +64 -0
- package/dist/src/commands/lint-per-run-checkjs.js +102 -0
- package/dist/src/commands/lint.js +4 -4
- package/dist/src/commands/manifest.js +1 -1
- package/dist/src/commands/package.js +9 -16
- package/dist/src/commands/patch/compact.js +5 -5
- package/dist/src/commands/patch/delete.js +5 -5
- package/dist/src/commands/patch/lint-ignore.js +3 -2
- package/dist/src/commands/patch/move-files-create.js +22 -4
- package/dist/src/commands/patch/move-files-into.js +14 -10
- package/dist/src/commands/patch/move-files.js +6 -5
- package/dist/src/commands/patch/rename.d.ts +2 -2
- package/dist/src/commands/patch/rename.js +151 -50
- package/dist/src/commands/patch/reorder.d.ts +9 -0
- package/dist/src/commands/patch/reorder.js +14 -10
- package/dist/src/commands/patch/split-plan.d.ts +13 -6
- package/dist/src/commands/patch/split-plan.js +22 -12
- package/dist/src/commands/patch/split.d.ts +1 -1
- package/dist/src/commands/patch/split.js +23 -9
- package/dist/src/commands/patch/staged-dependency-validate.d.ts +15 -0
- package/dist/src/commands/patch/staged-dependency-validate.js +49 -0
- package/dist/src/commands/patch/staged-dependency.js +10 -0
- package/dist/src/commands/re-export-adjacent.js +5 -6
- package/dist/src/commands/re-export-bulk-scan.d.ts +13 -0
- package/dist/src/commands/re-export-bulk-scan.js +142 -2
- package/dist/src/commands/re-export-drift.d.ts +74 -0
- package/dist/src/commands/re-export-drift.js +234 -0
- package/dist/src/commands/re-export-files.js +5 -3
- package/dist/src/commands/re-export-lint.d.ts +97 -0
- package/dist/src/commands/re-export-lint.js +210 -0
- package/dist/src/commands/re-export-options.js +8 -0
- package/dist/src/commands/re-export-register.d.ts +18 -0
- package/dist/src/commands/re-export-register.js +61 -0
- package/dist/src/commands/re-export-scan.js +13 -7
- package/dist/src/commands/re-export-single.d.ts +20 -0
- package/dist/src/commands/re-export-single.js +261 -0
- package/dist/src/commands/re-export.d.ts +0 -4
- package/dist/src/commands/re-export.js +113 -268
- package/dist/src/commands/rebase/abort.js +13 -4
- package/dist/src/commands/rebase/continue.js +11 -4
- package/dist/src/commands/rebase/index.js +19 -29
- package/dist/src/commands/rebase/patch-loop.js +12 -0
- package/dist/src/commands/reset.js +4 -23
- package/dist/src/commands/resolve.js +2 -9
- package/dist/src/commands/run.js +11 -21
- package/dist/src/commands/source.js +3 -9
- package/dist/src/commands/status-check.d.ts +13 -0
- package/dist/src/commands/status-check.js +31 -13
- package/dist/src/commands/status-json.d.ts +31 -0
- package/dist/src/commands/status-json.js +76 -0
- package/dist/src/commands/status-output.d.ts +1 -0
- package/dist/src/commands/status-output.js +10 -1
- package/dist/src/commands/status-ownership.d.ts +52 -0
- package/dist/src/commands/status-ownership.js +57 -0
- package/dist/src/commands/status.js +184 -175
- package/dist/src/commands/test-build-phase.d.ts +19 -0
- package/dist/src/commands/test-build-phase.js +168 -0
- package/dist/src/commands/test-diagnose.js +30 -2
- package/dist/src/commands/test-modes.d.ts +9 -1
- package/dist/src/commands/test-modes.js +46 -13
- package/dist/src/commands/test-register.js +59 -27
- package/dist/src/commands/test-run.d.ts +29 -3
- package/dist/src/commands/test-run.js +41 -4
- package/dist/src/commands/test-verdict.d.ts +32 -0
- package/dist/src/commands/test-verdict.js +48 -0
- package/dist/src/commands/test.d.ts +9 -0
- package/dist/src/commands/test.js +100 -123
- package/dist/src/commands/token-coverage.js +4 -9
- package/dist/src/commands/tree.d.ts +3 -0
- package/dist/src/commands/tree.js +171 -25
- package/dist/src/commands/verify.js +2 -2
- package/dist/src/commands/watch.js +22 -21
- package/dist/src/commands/wire.js +1 -1
- package/dist/src/core/ast-utils.d.ts +11 -0
- package/dist/src/core/ast-utils.js +11 -0
- package/dist/src/core/build-audit-platform.js +6 -1
- package/dist/src/core/build-audit-registration.js +2 -0
- package/dist/src/core/build-audit-resolve.d.ts +13 -0
- package/dist/src/core/build-audit-resolve.js +34 -13
- package/dist/src/core/build-audit.js +4 -20
- package/dist/src/core/build-baseline-types.d.ts +29 -8
- package/dist/src/core/build-baseline-types.js +2 -1
- package/dist/src/core/build-baseline.d.ts +10 -2
- package/dist/src/core/build-baseline.js +39 -8
- package/dist/src/core/build-prepare.d.ts +4 -0
- package/dist/src/core/build-prepare.js +7 -1
- package/dist/src/core/config-paths.d.ts +1 -1
- package/dist/src/core/config-paths.js +2 -0
- package/dist/src/core/config-validate-test-toolchains.js +3 -2
- package/dist/src/core/config-validate.js +34 -36
- package/dist/src/core/config.js +16 -3
- package/dist/src/core/coverage-extend.d.ts +89 -0
- package/dist/src/core/coverage-extend.js +188 -0
- package/dist/src/core/destructive.js +3 -1
- package/dist/src/core/discard-baseline.js +18 -4
- package/dist/src/core/engine-precondition.d.ts +35 -0
- package/dist/src/core/engine-precondition.js +50 -0
- package/dist/src/core/engine-session-lock.d.ts +38 -1
- package/dist/src/core/engine-session-lock.js +78 -4
- package/dist/src/core/file-lock.d.ts +7 -0
- package/dist/src/core/file-lock.js +20 -30
- package/dist/src/core/firefox.js +5 -2
- package/dist/src/core/furnace-apply-helpers.d.ts +12 -1
- package/dist/src/core/furnace-apply-helpers.js +12 -3
- package/dist/src/core/furnace-apply-output.js +9 -0
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +63 -0
- package/dist/src/core/furnace-apply-overwrite-warn.js +123 -0
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +11 -0
- package/dist/src/core/furnace-apply-undeploy-actions.js +49 -0
- package/dist/src/core/furnace-apply.d.ts +16 -4
- package/dist/src/core/furnace-apply.js +39 -43
- package/dist/src/core/furnace-config.js +2 -0
- package/dist/src/core/furnace-css-fragments.js +2 -0
- package/dist/src/core/furnace-jsconfig.js +14 -7
- package/dist/src/core/furnace-registration-ast.js +8 -8
- package/dist/src/core/furnace-registration-remove.js +6 -3
- package/dist/src/core/furnace-registration.js +9 -12
- package/dist/src/core/furnace-rollback.js +1 -1
- package/dist/src/core/furnace-scanner.js +2 -1
- package/dist/src/core/furnace-stale-export.js +2 -1
- package/dist/src/core/furnace-state-persist.d.ts +4 -6
- package/dist/src/core/furnace-validate-compatibility.js +4 -7
- package/dist/src/core/furnace-validate-helpers.js +33 -1
- package/dist/src/core/furnace-validate-registration.js +16 -0
- package/dist/src/core/furnace-validate.js +4 -2
- package/dist/src/core/git-diff.js +37 -2
- package/dist/src/core/lint-cache.d.ts +1 -1
- package/dist/src/core/lint-cache.js +33 -10
- package/dist/src/core/mach-build-artifacts.d.ts +63 -1
- package/dist/src/core/mach-build-artifacts.js +108 -2
- package/dist/src/core/mach-resource-shim.js +1 -0
- package/dist/src/core/marionette-port.d.ts +16 -0
- package/dist/src/core/marionette-port.js +93 -8
- package/dist/src/core/marionette-preflight.js +6 -5
- package/dist/src/core/patch-apply.d.ts +20 -13
- package/dist/src/core/patch-apply.js +32 -33
- package/dist/src/core/patch-export.js +3 -5
- package/dist/src/core/patch-lint-checkjs.d.ts +25 -3
- package/dist/src/core/patch-lint-checkjs.js +78 -7
- package/dist/src/core/patch-lint-chrome-jsdoc.js +9 -0
- package/dist/src/core/patch-lint-creators.d.ts +30 -0
- package/dist/src/core/patch-lint-creators.js +45 -0
- package/dist/src/core/patch-lint-cross.d.ts +1 -17
- package/dist/src/core/patch-lint-cross.js +16 -32
- package/dist/src/core/patch-lint-jsdoc.d.ts +3 -1
- package/dist/src/core/patch-lint-jsdoc.js +15 -5
- package/dist/src/core/patch-lint-module-registration.d.ts +15 -0
- package/dist/src/core/patch-lint-module-registration.js +88 -0
- package/dist/src/core/patch-lint-mozbuild.js +99 -11
- package/dist/src/core/patch-lint-reexports.d.ts +1 -0
- package/dist/src/core/patch-lint-reexports.js +1 -0
- package/dist/src/core/patch-lint.d.ts +8 -0
- package/dist/src/core/patch-lint.js +84 -6
- package/dist/src/core/patch-lock.d.ts +12 -1
- package/dist/src/core/patch-lock.js +40 -4
- package/dist/src/core/patch-manifest-consistency.js +15 -3
- package/dist/src/core/patch-parse.d.ts +8 -0
- package/dist/src/core/patch-parse.js +10 -0
- package/dist/src/core/patch-policy.d.ts +7 -0
- package/dist/src/core/patch-policy.js +4 -1
- package/dist/src/core/patch-transform.d.ts +10 -0
- package/dist/src/core/patch-transform.js +13 -2
- package/dist/src/core/rebase-session.d.ts +44 -2
- package/dist/src/core/rebase-session.js +114 -17
- package/dist/src/core/register-browser-content.js +2 -1
- package/dist/src/core/register-shared-css.js +2 -1
- package/dist/src/core/smoke-patterns.d.ts +0 -8
- package/dist/src/core/smoke-patterns.js +3 -2
- package/dist/src/core/status-binary.d.ts +55 -0
- package/dist/src/core/status-binary.js +124 -0
- package/dist/src/core/status-classify.d.ts +6 -1
- package/dist/src/core/status-classify.js +101 -73
- package/dist/src/core/test-harness-crash.d.ts +32 -1
- package/dist/src/core/test-harness-crash.js +59 -4
- package/dist/src/core/test-path-scope.js +2 -0
- package/dist/src/core/test-stale-check.js +1 -20
- package/dist/src/core/toolchain-preflight.js +24 -26
- package/dist/src/core/tree-guard.d.ts +1 -1
- package/dist/src/core/tree-guard.js +67 -12
- package/dist/src/core/tree-store.d.ts +86 -10
- package/dist/src/core/tree-store.js +310 -72
- package/dist/src/core/typecheck.js +2 -1
- package/dist/src/core/wire-destroy.js +14 -3
- package/dist/src/core/wire-init.js +37 -40
- package/dist/src/core/wire-subscript.js +11 -3
- package/dist/src/core/wire-utils.js +4 -4
- package/dist/src/core/xpcshell-appdir.js +3 -0
- package/dist/src/errors/base.d.ts +13 -0
- package/dist/src/errors/base.js +13 -0
- package/dist/src/errors/rebase.d.ts +13 -0
- package/dist/src/errors/rebase.js +17 -0
- package/dist/src/types/commands/options.d.ts +86 -1
- package/dist/src/types/commands/patches.d.ts +8 -0
- package/dist/src/types/furnace.d.ts +7 -0
- package/dist/src/utils/build-info.d.ts +31 -0
- package/dist/src/utils/build-info.js +98 -0
- package/dist/src/utils/concurrency.d.ts +8 -0
- package/dist/src/utils/concurrency.js +21 -0
- package/dist/src/utils/errors.d.ts +39 -0
- package/dist/src/utils/errors.js +55 -0
- package/dist/src/utils/fs.js +5 -12
- package/dist/src/utils/logger.d.ts +14 -2
- package/dist/src/utils/logger.js +43 -13
- package/dist/src/utils/options.d.ts +21 -4
- package/dist/src/utils/options.js +26 -6
- package/dist/src/utils/package-root.js +7 -4
- package/dist/src/utils/process-group.js +13 -2
- package/dist/src/utils/stdio-drain.d.ts +28 -0
- package/dist/src/utils/stdio-drain.js +54 -0
- package/dist/src/utils/validation.d.ts +23 -2
- package/dist/src/utils/validation.js +29 -3
- package/package.json +9 -9
|
@@ -10,6 +10,8 @@ export declare function setVerbose(enabled: boolean): void;
|
|
|
10
10
|
export declare function setMachineOutputMode(enabled: boolean): void;
|
|
11
11
|
/** True when machine-output mode is active. */
|
|
12
12
|
export declare function isMachineOutputMode(): boolean;
|
|
13
|
+
/** Seals (or unseals) stdout after a machine-readable final line. */
|
|
14
|
+
export declare function setStdoutSealed(sealed: boolean): void;
|
|
13
15
|
/**
|
|
14
16
|
* Displays a verbose/debug message (only shown if verbose mode is enabled).
|
|
15
17
|
* @param message - Message to display
|
|
@@ -54,7 +56,17 @@ export declare function formatErrorText(message: string): string;
|
|
|
54
56
|
export declare function spinner(initialMessage: string): SpinnerHandle;
|
|
55
57
|
/** Emits a cancellation message. */
|
|
56
58
|
export declare function cancel(message: string): void;
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Checks whether a prompt result represents a user cancellation.
|
|
61
|
+
*
|
|
62
|
+
* Narrows to `symbol` — clack returns its cancel sentinel as a symbol and
|
|
63
|
+
* `p.isCancel` is itself a type predicate. This wrapper erased that narrowing
|
|
64
|
+
* by returning plain `boolean` until 0.41.0, which forced eleven `as string`
|
|
65
|
+
* / `as PatchCategory` / `as OverrideType` casts across six command modules
|
|
66
|
+
* on the *non*-cancelled branch, where the value is already known not to be
|
|
67
|
+
* the sentinel. Keep the predicate form: it is the single highest-leverage
|
|
68
|
+
* signature in the codebase for escape-hatch count.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isCancel(value: unknown): value is symbol;
|
|
59
71
|
/** Displays a titled note block for follow-up details. */
|
|
60
72
|
export declare function note(message: string, title?: string): void;
|
package/dist/src/utils/logger.js
CHANGED
|
@@ -34,6 +34,26 @@ export function setMachineOutputMode(enabled) {
|
|
|
34
34
|
export function isMachineOutputMode() {
|
|
35
35
|
return machineOutputMode;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Whether stdout is sealed behind a machine-readable final line.
|
|
39
|
+
*
|
|
40
|
+
* The `FIREFORGE-VERDICT:` contract promises that line as the run's LAST
|
|
41
|
+
* stdout write — but emit-then-throw failure paths rethrow into
|
|
42
|
+
* `withErrorHandling`, whose clack error/cancel rendering lands on stdout
|
|
43
|
+
* in non-machine mode, displacing the verdict from the final line. The
|
|
44
|
+
* verdict sink seals stdout the moment it writes; every later logger call
|
|
45
|
+
* routes to stderr through the same diagnostic channel machine mode uses.
|
|
46
|
+
* `withErrorHandling`'s finally clears the seal (alongside machine mode).
|
|
47
|
+
*/
|
|
48
|
+
let stdoutSealed = false;
|
|
49
|
+
/** Seals (or unseals) stdout after a machine-readable final line. */
|
|
50
|
+
export function setStdoutSealed(sealed) {
|
|
51
|
+
stdoutSealed = sealed;
|
|
52
|
+
}
|
|
53
|
+
/** True when human output must avoid stdout. */
|
|
54
|
+
function routeToStderr() {
|
|
55
|
+
return machineOutputMode || stdoutSealed;
|
|
56
|
+
}
|
|
37
57
|
/** Writes a plain diagnostic line to stderr (machine-mode side channel). */
|
|
38
58
|
function writeDiagnostic(prefix, message) {
|
|
39
59
|
process.stderr.write(`${prefix}${message}\n`);
|
|
@@ -52,7 +72,7 @@ function isVerbose() {
|
|
|
52
72
|
export function verbose(message) {
|
|
53
73
|
if (!isVerbose())
|
|
54
74
|
return;
|
|
55
|
-
if (
|
|
75
|
+
if (routeToStderr()) {
|
|
56
76
|
writeDiagnostic('[debug] ', message);
|
|
57
77
|
return;
|
|
58
78
|
}
|
|
@@ -63,19 +83,19 @@ function supportsInteractiveSpinner() {
|
|
|
63
83
|
}
|
|
64
84
|
/** Displays the top-level intro banner for a command. */
|
|
65
85
|
export function intro(message) {
|
|
66
|
-
if (
|
|
86
|
+
if (routeToStderr())
|
|
67
87
|
return;
|
|
68
88
|
p.intro(message);
|
|
69
89
|
}
|
|
70
90
|
/** Displays the closing outro banner for a command. */
|
|
71
91
|
export function outro(message) {
|
|
72
|
-
if (
|
|
92
|
+
if (routeToStderr())
|
|
73
93
|
return;
|
|
74
94
|
p.outro(message);
|
|
75
95
|
}
|
|
76
96
|
/** Logs an informational message. */
|
|
77
97
|
export function info(message) {
|
|
78
|
-
if (
|
|
98
|
+
if (routeToStderr()) {
|
|
79
99
|
writeDiagnostic('', message);
|
|
80
100
|
return;
|
|
81
101
|
}
|
|
@@ -83,7 +103,7 @@ export function info(message) {
|
|
|
83
103
|
}
|
|
84
104
|
/** Logs a success message. */
|
|
85
105
|
export function success(message) {
|
|
86
|
-
if (
|
|
106
|
+
if (routeToStderr()) {
|
|
87
107
|
writeDiagnostic('', message);
|
|
88
108
|
return;
|
|
89
109
|
}
|
|
@@ -91,7 +111,7 @@ export function success(message) {
|
|
|
91
111
|
}
|
|
92
112
|
/** Logs a warning message. */
|
|
93
113
|
export function warn(message) {
|
|
94
|
-
if (
|
|
114
|
+
if (routeToStderr()) {
|
|
95
115
|
writeDiagnostic('warning: ', message);
|
|
96
116
|
return;
|
|
97
117
|
}
|
|
@@ -99,7 +119,7 @@ export function warn(message) {
|
|
|
99
119
|
}
|
|
100
120
|
/** Logs an error message. */
|
|
101
121
|
export function error(message) {
|
|
102
|
-
if (
|
|
122
|
+
if (routeToStderr()) {
|
|
103
123
|
writeDiagnostic('error: ', message);
|
|
104
124
|
return;
|
|
105
125
|
}
|
|
@@ -107,7 +127,7 @@ export function error(message) {
|
|
|
107
127
|
}
|
|
108
128
|
/** Logs an in-progress step message. */
|
|
109
129
|
export function step(message) {
|
|
110
|
-
if (
|
|
130
|
+
if (routeToStderr()) {
|
|
111
131
|
writeDiagnostic('', message);
|
|
112
132
|
return;
|
|
113
133
|
}
|
|
@@ -115,7 +135,7 @@ export function step(message) {
|
|
|
115
135
|
}
|
|
116
136
|
/** Logs a plain message without a status prefix. */
|
|
117
137
|
export function message(message) {
|
|
118
|
-
if (
|
|
138
|
+
if (routeToStderr()) {
|
|
119
139
|
writeDiagnostic('', message);
|
|
120
140
|
return;
|
|
121
141
|
}
|
|
@@ -135,7 +155,7 @@ export function formatErrorText(message) {
|
|
|
135
155
|
* @returns Spinner handle with message(), stop(), and error() methods
|
|
136
156
|
*/
|
|
137
157
|
export function spinner(initialMessage) {
|
|
138
|
-
if (
|
|
158
|
+
if (routeToStderr()) {
|
|
139
159
|
// Spinner progress is diagnostics; keep stdout clean for the payload.
|
|
140
160
|
return {
|
|
141
161
|
message: (msg) => {
|
|
@@ -182,19 +202,29 @@ export function spinner(initialMessage) {
|
|
|
182
202
|
}
|
|
183
203
|
/** Emits a cancellation message. */
|
|
184
204
|
export function cancel(message) {
|
|
185
|
-
if (
|
|
205
|
+
if (routeToStderr()) {
|
|
186
206
|
writeDiagnostic('cancelled: ', message);
|
|
187
207
|
return;
|
|
188
208
|
}
|
|
189
209
|
p.cancel(message);
|
|
190
210
|
}
|
|
191
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
* Checks whether a prompt result represents a user cancellation.
|
|
213
|
+
*
|
|
214
|
+
* Narrows to `symbol` — clack returns its cancel sentinel as a symbol and
|
|
215
|
+
* `p.isCancel` is itself a type predicate. This wrapper erased that narrowing
|
|
216
|
+
* by returning plain `boolean` until 0.41.0, which forced eleven `as string`
|
|
217
|
+
* / `as PatchCategory` / `as OverrideType` casts across six command modules
|
|
218
|
+
* on the *non*-cancelled branch, where the value is already known not to be
|
|
219
|
+
* the sentinel. Keep the predicate form: it is the single highest-leverage
|
|
220
|
+
* signature in the codebase for escape-hatch count.
|
|
221
|
+
*/
|
|
192
222
|
export function isCancel(value) {
|
|
193
223
|
return p.isCancel(value);
|
|
194
224
|
}
|
|
195
225
|
/** Displays a titled note block for follow-up details. */
|
|
196
226
|
export function note(message, title) {
|
|
197
|
-
if (
|
|
227
|
+
if (routeToStderr()) {
|
|
198
228
|
writeDiagnostic('', title ? `${title}: ${message}` : message);
|
|
199
229
|
return;
|
|
200
230
|
}
|
|
@@ -22,6 +22,21 @@ import type { Command } from 'commander';
|
|
|
22
22
|
* helper (or throw commander's InvalidArgumentError directly).
|
|
23
23
|
*/
|
|
24
24
|
export declare function commanderArgParser<T>(parse: (raw: string) => T): (raw: string) => T;
|
|
25
|
+
/**
|
|
26
|
+
* Commander plumbing for a repeatable string option, as a spreadable
|
|
27
|
+
* `[accumulator, default]` pair:
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* .option('--mach-arg <arg>', 'Repeatable.', ...stringListOption())
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Seven call sites open-coded this, each with its own `[] as string[]`
|
|
34
|
+
* default — commander types that slot as `unknown`, so every one carried the
|
|
35
|
+
* cast. Two of the seven also mutated the accumulator in place rather than
|
|
36
|
+
* returning a new array. Returning a fresh array per call additionally means
|
|
37
|
+
* the default cannot be shared between two `.option()` registrations.
|
|
38
|
+
*/
|
|
39
|
+
export declare function stringListOption(): [(value: string, previous: string[]) => string[], string[]];
|
|
25
40
|
/**
|
|
26
41
|
* Resolves the parsed `--wait-lock [seconds]` option value into a wait budget
|
|
27
42
|
* in seconds for `withEngineSessionLock`:
|
|
@@ -35,9 +50,11 @@ export declare function commanderArgParser<T>(parse: (raw: string) => T): (raw:
|
|
|
35
50
|
*/
|
|
36
51
|
export declare function resolveWaitLockSeconds(value: string | number | boolean | undefined): number | undefined;
|
|
37
52
|
/**
|
|
38
|
-
* Registers the shared `--wait-lock [seconds]` flag on
|
|
39
|
-
* command
|
|
40
|
-
*
|
|
41
|
-
*
|
|
53
|
+
* Registers the shared `--wait-lock [seconds]` flag on a lock-taking
|
|
54
|
+
* command (the engine session lock for engine-mutating commands, the patch
|
|
55
|
+
* directory lock for queue-mutating ones). The parsed option value is `true`
|
|
56
|
+
* for the bare flag or a validated integer; feed it through
|
|
57
|
+
* {@link resolveWaitLockSeconds} at the call site to obtain the
|
|
58
|
+
* `waitLockSeconds` for `withEngineSessionLock`/`withPatchDirectoryLock`.
|
|
42
59
|
*/
|
|
43
60
|
export declare function addWaitLockOption(command: Command): Command;
|
|
@@ -15,6 +15,7 @@ export function pickDefined(obj) {
|
|
|
15
15
|
}
|
|
16
16
|
import { InvalidArgumentError as CommanderInvalidArgumentError } from 'commander';
|
|
17
17
|
import { GeneralError } from '../errors/base.js';
|
|
18
|
+
import { toError } from './errors.js';
|
|
18
19
|
/**
|
|
19
20
|
* Wraps an option-argument parser so its failures surface through
|
|
20
21
|
* commander's own invalid-argument channel.
|
|
@@ -35,10 +36,27 @@ export function commanderArgParser(parse) {
|
|
|
35
36
|
return parse(raw);
|
|
36
37
|
}
|
|
37
38
|
catch (error) {
|
|
38
|
-
throw new CommanderInvalidArgumentError(error
|
|
39
|
+
throw new CommanderInvalidArgumentError(toError(error).message);
|
|
39
40
|
}
|
|
40
41
|
};
|
|
41
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Commander plumbing for a repeatable string option, as a spreadable
|
|
45
|
+
* `[accumulator, default]` pair:
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* .option('--mach-arg <arg>', 'Repeatable.', ...stringListOption())
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Seven call sites open-coded this, each with its own `[] as string[]`
|
|
52
|
+
* default — commander types that slot as `unknown`, so every one carried the
|
|
53
|
+
* cast. Two of the seven also mutated the accumulator in place rather than
|
|
54
|
+
* returning a new array. Returning a fresh array per call additionally means
|
|
55
|
+
* the default cannot be shared between two `.option()` registrations.
|
|
56
|
+
*/
|
|
57
|
+
export function stringListOption() {
|
|
58
|
+
return [(value, previous) => [...previous, value], []];
|
|
59
|
+
}
|
|
42
60
|
/** Wait budget applied when `--wait-lock` is passed without a value. */
|
|
43
61
|
const DEFAULT_WAIT_LOCK_SECONDS = 60;
|
|
44
62
|
/**
|
|
@@ -69,11 +87,13 @@ export function resolveWaitLockSeconds(value) {
|
|
|
69
87
|
return n;
|
|
70
88
|
}
|
|
71
89
|
/**
|
|
72
|
-
* Registers the shared `--wait-lock [seconds]` flag on
|
|
73
|
-
* command
|
|
74
|
-
*
|
|
75
|
-
*
|
|
90
|
+
* Registers the shared `--wait-lock [seconds]` flag on a lock-taking
|
|
91
|
+
* command (the engine session lock for engine-mutating commands, the patch
|
|
92
|
+
* directory lock for queue-mutating ones). The parsed option value is `true`
|
|
93
|
+
* for the bare flag or a validated integer; feed it through
|
|
94
|
+
* {@link resolveWaitLockSeconds} at the call site to obtain the
|
|
95
|
+
* `waitLockSeconds` for `withEngineSessionLock`/`withPatchDirectoryLock`.
|
|
76
96
|
*/
|
|
77
97
|
export function addWaitLockOption(command) {
|
|
78
|
-
return command.option('--wait-lock [seconds]', 'Wait up to this many seconds (default 60) for another FireForge
|
|
98
|
+
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', commanderArgParser((raw) => resolveWaitLockSeconds(raw)));
|
|
79
99
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { getNodeErrorCode, toError } from './errors.js';
|
|
6
|
+
import { isObject } from './validation.js';
|
|
5
7
|
function validatePackageMetadata(data, filePath) {
|
|
6
8
|
if (typeof data !== 'object' || data === null) {
|
|
7
9
|
throw new Error(`Invalid package metadata in ${filePath}: expected an object`);
|
|
@@ -48,10 +50,11 @@ export function getPackageRoot() {
|
|
|
48
50
|
// to a wrong ancestor package (any parent exposing bin.fireforge) or
|
|
49
51
|
// end in the unhelpful generic "could not locate" error, hiding the
|
|
50
52
|
// actual syntax problem.
|
|
51
|
-
const code = error
|
|
53
|
+
const code = getNodeErrorCode(error);
|
|
52
54
|
if (code !== 'ENOENT' && code !== 'ENOTDIR') {
|
|
53
|
-
throw new Error(`Found ${packagePath} but could not parse it: ` +
|
|
54
|
-
|
|
55
|
+
throw new Error(`Found ${packagePath} but could not parse it: ` + toError(error).message, {
|
|
56
|
+
cause: error,
|
|
57
|
+
});
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
const parent = dirname(current);
|
|
@@ -63,7 +66,7 @@ export function getPackageRoot() {
|
|
|
63
66
|
}
|
|
64
67
|
/** @internal */
|
|
65
68
|
export function isFireForgePackageMetadata(pkg) {
|
|
66
|
-
if (
|
|
69
|
+
if (!isObject(pkg.bin)) {
|
|
67
70
|
return false;
|
|
68
71
|
}
|
|
69
72
|
const bin = pkg.bin;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* two modules do not import each other cyclically.
|
|
7
7
|
*/
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
|
+
import { getNodeErrorCode } from './errors.js';
|
|
9
10
|
import { verbose, warn } from './logger.js';
|
|
10
11
|
/**
|
|
11
12
|
* Sends `signal` to the child's whole tree: the process GROUP on POSIX
|
|
@@ -99,8 +100,14 @@ async function listGroupSurvivors(pgid) {
|
|
|
99
100
|
process.kill(-pgid, 0);
|
|
100
101
|
return [{ pid: -1, command: 'unknown (pgrep unavailable; group still has live members)' }];
|
|
101
102
|
}
|
|
102
|
-
catch {
|
|
103
|
-
|
|
103
|
+
catch (error) {
|
|
104
|
+
// Same errno semantics as `isProcessAlive` (which cannot be called here —
|
|
105
|
+
// it probes a single positive pid): only ESRCH proves the group is gone.
|
|
106
|
+
// EPERM means it exists under another uid, and an unrecognized failure is
|
|
107
|
+
// not evidence of absence — report survivors in both cases.
|
|
108
|
+
if (getNodeErrorCode(error) === 'ESRCH')
|
|
109
|
+
return [];
|
|
110
|
+
return [{ pid: -1, command: 'unknown (pgrep unavailable; group liveness probe denied)' }];
|
|
104
111
|
}
|
|
105
112
|
}
|
|
106
113
|
function describeSurvivors(list) {
|
|
@@ -133,6 +140,8 @@ export async function sweepProcessGroup(pgid, graceMs = SWEEP_GRACE_MS) {
|
|
|
133
140
|
process.kill(-pgid, 'SIGTERM');
|
|
134
141
|
}
|
|
135
142
|
catch {
|
|
143
|
+
// The group vanished between the listing and the signal — nothing left to
|
|
144
|
+
// escalate against, so report the survivors collected so far.
|
|
136
145
|
return { survivors };
|
|
137
146
|
}
|
|
138
147
|
await sweepDelay(graceMs);
|
|
@@ -142,6 +151,8 @@ export async function sweepProcessGroup(pgid, graceMs = SWEEP_GRACE_MS) {
|
|
|
142
151
|
process.kill(-pgid, 'SIGKILL');
|
|
143
152
|
}
|
|
144
153
|
catch {
|
|
154
|
+
// The group died during the grace period, so the SIGKILL escalation has
|
|
155
|
+
// nothing to signal.
|
|
145
156
|
return { survivors };
|
|
146
157
|
}
|
|
147
158
|
await sweepDelay(Math.min(200, graceMs));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded stdio drain for delayed process exits (FORGE I1).
|
|
3
|
+
*
|
|
4
|
+
* `process.exit()` discards whatever is still queued in an async writable —
|
|
5
|
+
* and stdout IS async when it is a pipe, with a 64 KiB kernel buffer on
|
|
6
|
+
* macOS/Linux. The observed failure: `status --json --fail-on` writes a
|
|
7
|
+
* 176 KB payload, the refusal makes `bin/fireforge.ts` exit non-zero, and a
|
|
8
|
+
* piped consumer receives exactly 65 536 bytes. The bin entry point awaits
|
|
9
|
+
* this helper before every delayed exit; the helper itself never calls
|
|
10
|
+
* `process.exit` (the process-boundary test keeps that a bin-only right).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* The structural slice of `Writable` the drain wait needs — accepted instead
|
|
14
|
+
* of `NodeJS.WriteStream` so unit tests can drive synthetic streams.
|
|
15
|
+
*/
|
|
16
|
+
export interface DrainableStream {
|
|
17
|
+
readonly destroyed: boolean;
|
|
18
|
+
readonly writableFinished: boolean;
|
|
19
|
+
readonly writableLength: number;
|
|
20
|
+
on(event: 'drain' | 'error' | 'close', listener: () => void): unknown;
|
|
21
|
+
off(event: 'drain' | 'error' | 'close', listener: () => void): unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Waits (bounded by `timeoutMs`) for every given stream — stdout and stderr
|
|
25
|
+
* by default — to drain. Resolution is unconditional; the caller exits
|
|
26
|
+
* either way, the bound only decides how much queued output survives.
|
|
27
|
+
*/
|
|
28
|
+
export declare function waitForStdioDrain(timeoutMs: number, streams?: readonly DrainableStream[]): Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Bounded stdio drain for delayed process exits (FORGE I1).
|
|
4
|
+
*
|
|
5
|
+
* `process.exit()` discards whatever is still queued in an async writable —
|
|
6
|
+
* and stdout IS async when it is a pipe, with a 64 KiB kernel buffer on
|
|
7
|
+
* macOS/Linux. The observed failure: `status --json --fail-on` writes a
|
|
8
|
+
* 176 KB payload, the refusal makes `bin/fireforge.ts` exit non-zero, and a
|
|
9
|
+
* piped consumer receives exactly 65 536 bytes. The bin entry point awaits
|
|
10
|
+
* this helper before every delayed exit; the helper itself never calls
|
|
11
|
+
* `process.exit` (the process-boundary test keeps that a bin-only right).
|
|
12
|
+
*/
|
|
13
|
+
/** True when nothing the process is about to lose remains queued. */
|
|
14
|
+
function isFlushed(stream) {
|
|
15
|
+
return stream.destroyed || stream.writableFinished || stream.writableLength === 0;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolves once `stream` has drained its queued writes, and always within
|
|
19
|
+
* `timeoutMs`. Never rejects: `'error'` and `'close'` (an EPIPE'd pipe —
|
|
20
|
+
* `installBrokenPipeHandler` already swallows the error itself) resolve
|
|
21
|
+
* immediately, because a destroyed pipe can never drain and must not stall
|
|
22
|
+
* the exit behind it.
|
|
23
|
+
*/
|
|
24
|
+
function waitForStreamDrain(stream, timeoutMs) {
|
|
25
|
+
if (isFlushed(stream)) {
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
}
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
const settle = () => {
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
stream.off('drain', onDrain);
|
|
32
|
+
stream.off('error', settle);
|
|
33
|
+
stream.off('close', settle);
|
|
34
|
+
resolve();
|
|
35
|
+
};
|
|
36
|
+
const onDrain = () => {
|
|
37
|
+
if (isFlushed(stream)) {
|
|
38
|
+
settle();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const timer = setTimeout(settle, timeoutMs);
|
|
42
|
+
stream.on('drain', onDrain);
|
|
43
|
+
stream.on('error', settle);
|
|
44
|
+
stream.on('close', settle);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Waits (bounded by `timeoutMs`) for every given stream — stdout and stderr
|
|
49
|
+
* by default — to drain. Resolution is unconditional; the caller exits
|
|
50
|
+
* either way, the bound only decides how much queued output survives.
|
|
51
|
+
*/
|
|
52
|
+
export async function waitForStdioDrain(timeoutMs, streams = [process.stdout, process.stderr]) {
|
|
53
|
+
await Promise.all(streams.map((stream) => waitForStreamDrain(stream, timeoutMs)));
|
|
54
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FirefoxProduct } from '../types/config.js';
|
|
1
2
|
/**
|
|
2
3
|
* Checks whether a value is a string.
|
|
3
4
|
* @param value - Value to check
|
|
@@ -62,11 +63,31 @@ export declare function isValidFirefoxVersion(version: string): boolean;
|
|
|
62
63
|
* Accepts formats like "build1", "build2", "build12" (no leading zero).
|
|
63
64
|
*/
|
|
64
65
|
export declare function isValidFirefoxCandidate(candidate: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Valid Firefox product identifiers.
|
|
68
|
+
*
|
|
69
|
+
* `satisfies readonly FirefoxProduct[]` links the runtime list to the union at
|
|
70
|
+
* `types/config.ts:5` in ONE direction: it rejects an entry here that the union
|
|
71
|
+
* does not declare. It cannot see a union member missing from this list —
|
|
72
|
+
* widening a `readonly T[]` check never fails for being short. The reverse
|
|
73
|
+
* direction is covered by the exhaustive switch in
|
|
74
|
+
* `utils/__tests__/validation.test.ts`, which fails to compile when the union
|
|
75
|
+
* grows.
|
|
76
|
+
*
|
|
77
|
+
* Two further copies of this list existed before 0.41.0 — an inline literal
|
|
78
|
+
* inside the validator below and `SOURCE_PRODUCTS` in `commands/source.ts` —
|
|
79
|
+
* neither linked to the union.
|
|
80
|
+
*/
|
|
81
|
+
export declare const FIREFOX_PRODUCTS: readonly ["firefox", "firefox-esr", "firefox-beta", "firefox-devedition"];
|
|
65
82
|
/**
|
|
66
83
|
* Validates a Firefox product string.
|
|
67
|
-
*
|
|
84
|
+
*
|
|
85
|
+
* A type predicate, matching its siblings {@link isValidPatchCategory} and
|
|
86
|
+
* {@link isValidProjectLicense}. It returned plain `boolean` until 0.41.0,
|
|
87
|
+
* which forced `as FirefoxProduct` casts at both call sites even though the
|
|
88
|
+
* `.includes` check IS the runtime proof.
|
|
68
89
|
*/
|
|
69
|
-
export declare function isValidFirefoxProduct(product: string):
|
|
90
|
+
export declare function isValidFirefoxProduct(product: string): product is FirefoxProduct;
|
|
70
91
|
/**
|
|
71
92
|
* Valid project license SPDX identifiers.
|
|
72
93
|
*/
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Used to safely narrow types from unknown values.
|
|
5
5
|
*/
|
|
6
6
|
import { InvalidArgumentError } from '../errors/base.js';
|
|
7
|
+
import { escapeRegex } from './regex.js';
|
|
7
8
|
/**
|
|
8
9
|
* Checks whether a value is a string.
|
|
9
10
|
* @param value - Value to check
|
|
@@ -94,12 +95,37 @@ export function isValidFirefoxVersion(version) {
|
|
|
94
95
|
export function isValidFirefoxCandidate(candidate) {
|
|
95
96
|
return /^build[1-9]\d{0,3}$/.test(candidate);
|
|
96
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Valid Firefox product identifiers.
|
|
100
|
+
*
|
|
101
|
+
* `satisfies readonly FirefoxProduct[]` links the runtime list to the union at
|
|
102
|
+
* `types/config.ts:5` in ONE direction: it rejects an entry here that the union
|
|
103
|
+
* does not declare. It cannot see a union member missing from this list —
|
|
104
|
+
* widening a `readonly T[]` check never fails for being short. The reverse
|
|
105
|
+
* direction is covered by the exhaustive switch in
|
|
106
|
+
* `utils/__tests__/validation.test.ts`, which fails to compile when the union
|
|
107
|
+
* grows.
|
|
108
|
+
*
|
|
109
|
+
* Two further copies of this list existed before 0.41.0 — an inline literal
|
|
110
|
+
* inside the validator below and `SOURCE_PRODUCTS` in `commands/source.ts` —
|
|
111
|
+
* neither linked to the union.
|
|
112
|
+
*/
|
|
113
|
+
export const FIREFOX_PRODUCTS = [
|
|
114
|
+
'firefox',
|
|
115
|
+
'firefox-esr',
|
|
116
|
+
'firefox-beta',
|
|
117
|
+
'firefox-devedition',
|
|
118
|
+
];
|
|
97
119
|
/**
|
|
98
120
|
* Validates a Firefox product string.
|
|
99
|
-
*
|
|
121
|
+
*
|
|
122
|
+
* A type predicate, matching its siblings {@link isValidPatchCategory} and
|
|
123
|
+
* {@link isValidProjectLicense}. It returned plain `boolean` until 0.41.0,
|
|
124
|
+
* which forced `as FirefoxProduct` casts at both call sites even though the
|
|
125
|
+
* `.includes` check IS the runtime proof.
|
|
100
126
|
*/
|
|
101
127
|
export function isValidFirefoxProduct(product) {
|
|
102
|
-
return
|
|
128
|
+
return FIREFOX_PRODUCTS.includes(product);
|
|
103
129
|
}
|
|
104
130
|
/**
|
|
105
131
|
* Valid project license SPDX identifiers.
|
|
@@ -262,7 +288,7 @@ export function normalizeTokenName(name) {
|
|
|
262
288
|
*/
|
|
263
289
|
export function normalizePatchDisplayName(name, category) {
|
|
264
290
|
const stem = name.trim().replace(/\.patch$/i, '');
|
|
265
|
-
const escaped = category
|
|
291
|
+
const escaped = escapeRegex(category);
|
|
266
292
|
const prefixes = [
|
|
267
293
|
new RegExp(`^\\d+[-_ ]+${escaped}[-_ ]+`, 'i'),
|
|
268
294
|
new RegExp(`^${escaped}[-_ ]+`, 'i'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hominis/fireforge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"description": "FireForge — a build tool for customizing Firefox",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"fireforge": "tsx bin/fireforge.ts",
|
|
21
|
-
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
21
|
+
"build": "npm run clean && tsc -p tsconfig.build.json && node ./scripts/generate-build-info.mjs",
|
|
22
22
|
"clean": "node ./scripts/clean.mjs",
|
|
23
|
-
"lint": "eslint src/ bin/ scripts/ eslint.config.js vitest.config.ts vitest.pack.config.ts",
|
|
24
|
-
"lint:ci": "eslint src/ bin/ scripts/ eslint.config.js vitest.config.ts vitest.pack.config.ts --max-warnings 0",
|
|
25
|
-
"lint:fix": "eslint src/ bin/ scripts/ eslint.config.js vitest.config.ts vitest.pack.config.ts --fix",
|
|
23
|
+
"lint": "eslint src/ bin/ scripts/ eslint-rules/ eslint.config.js vitest.config.ts vitest.pack.config.ts",
|
|
24
|
+
"lint:ci": "eslint src/ bin/ scripts/ eslint-rules/ eslint.config.js vitest.config.ts vitest.pack.config.ts --max-warnings 0",
|
|
25
|
+
"lint:fix": "eslint src/ bin/ scripts/ eslint-rules/ eslint.config.js vitest.config.ts vitest.pack.config.ts --fix",
|
|
26
26
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
27
27
|
"deadcode:check": "knip",
|
|
28
28
|
"cycles:check": "dpdm --no-output --no-tree --no-warning --exit-code circular:1 src/index.ts bin/fireforge.ts",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"whitespace:check": "node ./scripts/check-worktree-whitespace.mjs",
|
|
35
35
|
"pack:verify": "vitest run --config vitest.pack.config.ts",
|
|
36
36
|
"pack:dry-run": "npm pack --dry-run --json --silent",
|
|
37
|
-
"format": "prettier --write --ignore-unknown \"src/**/*.ts\" \"bin/**/*.ts\" \"scripts/**/*.mjs\" \"package.json\" \"eslint.config.js\" \"vitest.config.ts\" \"vitest.pack.config.ts\" \"tsconfig.json\" \"tsconfig.build.json\" \".lintstagedrc.json\" \".prettierignore\" \".prettierrc\" \".gitignore\" \"README.md\" \"CHANGELOG.md\" \"docs/**/*.md\" \"knip.json\"
|
|
38
|
-
"format:check": "prettier --check --ignore-unknown \"src/**/*.ts\" \"bin/**/*.ts\" \"scripts/**/*.mjs\" \"package.json\" \"eslint.config.js\" \"vitest.config.ts\" \"vitest.pack.config.ts\" \"tsconfig.json\" \"tsconfig.build.json\" \".lintstagedrc.json\" \".prettierignore\" \".prettierrc\" \".gitignore\" \"README.md\" \"CHANGELOG.md\" \"docs/**/*.md\" \"knip.json\"
|
|
37
|
+
"format": "prettier --write --ignore-unknown \"src/**/*.ts\" \"bin/**/*.ts\" \"scripts/**/*.mjs\" \"eslint-rules/**/*.js\" \"package.json\" \"eslint.config.js\" \"vitest.config.ts\" \"vitest.pack.config.ts\" \"tsconfig.json\" \"tsconfig.build.json\" \".lintstagedrc.json\" \".prettierignore\" \".prettierrc\" \".gitignore\" \"README.md\" \"CHANGELOG.md\" \"docs/**/*.md\" \"knip.json\"",
|
|
38
|
+
"format:check": "prettier --check --ignore-unknown \"src/**/*.ts\" \"bin/**/*.ts\" \"scripts/**/*.mjs\" \"eslint-rules/**/*.js\" \"package.json\" \"eslint.config.js\" \"vitest.config.ts\" \"vitest.pack.config.ts\" \"tsconfig.json\" \"tsconfig.build.json\" \".lintstagedrc.json\" \".prettierignore\" \".prettierrc\" \".gitignore\" \"README.md\" \"CHANGELOG.md\" \"docs/**/*.md\" \"knip.json\"",
|
|
39
39
|
"prepare": "node -e \"import('./scripts/prepare.mjs').catch((error) => { if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_MODULE_NOT_FOUND') process.exit(0); throw error; })\"",
|
|
40
|
-
"prepack": "npm run build",
|
|
40
|
+
"prepack": "npm run build && node ./scripts/generate-build-info.mjs --loud",
|
|
41
41
|
"release:check": "npm run format:check && npm run whitespace:check && npm run lint:ci && npm run typecheck && npm run deadcode:check && npm run cycles:check && npm run test:coverage && npm run pack:verify && npm run pack:dry-run",
|
|
42
42
|
"prepublishOnly": "npm run release:check"
|
|
43
43
|
},
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"eslint-plugin-simple-import-sort": "^14.0.0",
|
|
74
74
|
"fast-check": "^4.6.0",
|
|
75
75
|
"husky": "^9.1.7",
|
|
76
|
-
"knip": "6.
|
|
76
|
+
"knip": "6.32.0",
|
|
77
77
|
"lint-staged": "^17.0.4",
|
|
78
78
|
"prettier": "3.9.6",
|
|
79
79
|
"tsx": "^4.7.0",
|