@hominis/fireforge 0.18.2 → 0.18.5
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/README.md +29 -16
- package/dist/src/commands/build.js +27 -12
- package/dist/src/commands/config.js +56 -3
- package/dist/src/commands/discard.js +93 -1
- package/dist/src/commands/doctor.js +17 -4
- package/dist/src/commands/download.js +21 -0
- package/dist/src/commands/export-all.js +35 -6
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +59 -8
- package/dist/src/commands/furnace/chrome-doc-templates.js +95 -12
- package/dist/src/commands/furnace/chrome-doc.js +24 -2
- package/dist/src/commands/furnace/deploy.js +10 -1
- package/dist/src/commands/furnace/init.js +28 -2
- package/dist/src/commands/furnace/remove.js +68 -0
- package/dist/src/commands/import.js +9 -1
- package/dist/src/commands/lint.js +78 -13
- package/dist/src/commands/patch/delete.js +2 -4
- package/dist/src/commands/patch/lint-ignore.js +2 -4
- package/dist/src/commands/patch/reorder.js +2 -4
- package/dist/src/commands/patch/tier.js +2 -4
- package/dist/src/commands/status.js +39 -1
- package/dist/src/commands/test.js +20 -1
- package/dist/src/commands/token.js +1 -1
- package/dist/src/core/furnace-apply.js +11 -3
- package/dist/src/core/furnace-config.js +19 -0
- package/dist/src/core/furnace-marker.d.ts +16 -0
- package/dist/src/core/furnace-marker.js +23 -0
- package/dist/src/core/git.js +66 -10
- package/dist/src/core/license-headers.d.ts +8 -0
- package/dist/src/core/license-headers.js +15 -1
- package/dist/src/core/manifest-rules.js +9 -1
- package/dist/src/core/patch-identifier-suggest.d.ts +25 -0
- package/dist/src/core/patch-identifier-suggest.js +108 -0
- package/dist/src/core/patch-lint.js +8 -0
- package/dist/src/core/register-shared-css.d.ts +28 -0
- package/dist/src/core/register-shared-css.js +67 -3
- package/package.json +1 -1
|
@@ -83,11 +83,68 @@ function legacyRegisterSharedCSS(content, name, entry, after) {
|
|
|
83
83
|
lines.splice(insertIndex, 0, entry);
|
|
84
84
|
return { result: lines.join('\n'), previousEntry, afterFallback };
|
|
85
85
|
}
|
|
86
|
+
/** Minimum gap between the target path and the source parenthesis. */
|
|
87
|
+
const MIN_SOURCE_GAP = 4;
|
|
88
|
+
/**
|
|
89
|
+
* Measures the column at which the `(source)` parenthesis opens in
|
|
90
|
+
* adjacent `skin/classic/browser/<x>.css (...)` entries inside an
|
|
91
|
+
* existing jar.inc.mn body, and returns the maximum so a newly inserted
|
|
92
|
+
* entry can align its source column to match.
|
|
93
|
+
*
|
|
94
|
+
* 2026-04-26 eval Finding 3: pre-fix `registerSharedCSS` always emitted
|
|
95
|
+
* a four-space gap between the target path and the parenthesis,
|
|
96
|
+
* regardless of how the rest of the file was aligned. Adjacent Firefox
|
|
97
|
+
* entries are typically padded to a wider column, so a freshly
|
|
98
|
+
* registered file landed at the wrong column and produced avoidable
|
|
99
|
+
* formatting churn. Returns `undefined` when no existing entries
|
|
100
|
+
* provide an alignment signal — callers fall back to the four-space
|
|
101
|
+
* default in that case.
|
|
102
|
+
*/
|
|
103
|
+
export function measureSourceColumn(content) {
|
|
104
|
+
const lines = content.split('\n');
|
|
105
|
+
let maxColumn = 0;
|
|
106
|
+
let sampled = 0;
|
|
107
|
+
// The regex guarantees `(` appears in the matched line, so the index
|
|
108
|
+
// lookup below is always >= 0. The `match` body's leading-whitespace
|
|
109
|
+
// and target-path captures are likewise guaranteed by the pattern, so
|
|
110
|
+
// we can take the literal `match[0]` (full match) length minus one to
|
|
111
|
+
// locate the `(` column without a fragile per-group lookup.
|
|
112
|
+
const lineRe = /^\s*skin\/classic\/browser\/[^\s()]+\s+\(/;
|
|
113
|
+
for (const line of lines) {
|
|
114
|
+
const match = lineRe.exec(line);
|
|
115
|
+
if (!match)
|
|
116
|
+
continue;
|
|
117
|
+
const parenIndex = match[0].length - 1;
|
|
118
|
+
if (parenIndex > maxColumn)
|
|
119
|
+
maxColumn = parenIndex;
|
|
120
|
+
sampled++;
|
|
121
|
+
}
|
|
122
|
+
return sampled > 0 ? maxColumn : undefined;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Builds a `skin/classic/browser/<name>.css (../shared/<name>.css)`
|
|
126
|
+
* line padded so the parenthesis lands at {@link sourceColumn} (when
|
|
127
|
+
* supplied) or at the default four-space gap (when {@link sourceColumn}
|
|
128
|
+
* is `undefined` or would force the parenthesis closer to the target
|
|
129
|
+
* than {@link MIN_SOURCE_GAP}).
|
|
130
|
+
*/
|
|
131
|
+
export function buildEntry(name, sourceColumn) {
|
|
132
|
+
const indent = ' ';
|
|
133
|
+
const target = `${indent}skin/classic/browser/${name}.css`;
|
|
134
|
+
const minColumn = target.length + MIN_SOURCE_GAP;
|
|
135
|
+
const column = sourceColumn !== undefined && sourceColumn >= minColumn ? sourceColumn : minColumn;
|
|
136
|
+
const padding = ' '.repeat(column - target.length);
|
|
137
|
+
return `${target}${padding}(../shared/${name}.css)`.replace(/\\/g, '/');
|
|
138
|
+
}
|
|
86
139
|
/**
|
|
87
140
|
* Registers a CSS file in browser/themes/shared/jar.inc.mn.
|
|
88
141
|
*
|
|
89
142
|
* Entry format:
|
|
90
143
|
* skin/classic/browser/{name}.css (../shared/{name}.css)
|
|
144
|
+
*
|
|
145
|
+
* The gap between target and source is sized to align with adjacent
|
|
146
|
+
* entries when the manifest already uses a wider column; falls back to
|
|
147
|
+
* a four-space minimum otherwise.
|
|
91
148
|
*/
|
|
92
149
|
export async function registerSharedCSS(engineDir, fileName, after, dryRun = false) {
|
|
93
150
|
const manifest = 'browser/themes/shared/jar.inc.mn';
|
|
@@ -96,10 +153,17 @@ export async function registerSharedCSS(engineDir, fileName, after, dryRun = fal
|
|
|
96
153
|
throw new GeneralError(`Manifest not found: ${manifest}`);
|
|
97
154
|
}
|
|
98
155
|
const name = basename(fileName, '.css');
|
|
99
|
-
const entry = ` skin/classic/browser/${name}.css (../shared/${name}.css)`.replace(/\\/g, '/');
|
|
100
156
|
const content = await readText(manifestPath);
|
|
101
|
-
|
|
102
|
-
|
|
157
|
+
const sourceColumn = measureSourceColumn(content);
|
|
158
|
+
const entry = buildEntry(name, sourceColumn);
|
|
159
|
+
// Idempotency check. `furnace chrome-doc create` writes its CSS as a
|
|
160
|
+
// `content/browser/<name>.css` entry rather than the canonical
|
|
161
|
+
// `skin/classic/browser/<name>.css` form `register` produces; recognise
|
|
162
|
+
// both shapes so a follow-up `register` invocation against an
|
|
163
|
+
// already-chrome-doc-registered file reports `skipped` instead of
|
|
164
|
+
// appending a duplicate `skin/classic/browser/...` row.
|
|
165
|
+
if (content.includes(`skin/classic/browser/${name}.css`) ||
|
|
166
|
+
content.includes(`content/browser/${name}.css`)) {
|
|
103
167
|
return { manifest, entry, skipped: true };
|
|
104
168
|
}
|
|
105
169
|
const { value } = withParserFallback(() => registerSharedCSSTokenized(content, name, entry, after), () => legacyRegisterSharedCSS(content, name, entry, after), manifest);
|