@hominis/fireforge 0.15.1 → 0.15.3
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 +39 -3
- package/README.md +76 -3
- package/dist/src/commands/build.js +41 -3
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +49 -0
- package/dist/src/commands/furnace/chrome-doc-templates.js +151 -0
- package/dist/src/commands/furnace/chrome-doc.d.ts +34 -0
- package/dist/src/commands/furnace/chrome-doc.js +168 -0
- package/dist/src/commands/furnace/create-mochikit.d.ts +30 -0
- package/dist/src/commands/furnace/create-mochikit.js +70 -0
- package/dist/src/commands/furnace/create-templates.d.ts +53 -0
- package/dist/src/commands/furnace/create-templates.js +118 -0
- package/dist/src/commands/furnace/create-xpcshell.d.ts +27 -0
- package/dist/src/commands/furnace/create-xpcshell.js +53 -0
- package/dist/src/commands/furnace/create.d.ts +17 -0
- package/dist/src/commands/furnace/create.js +59 -12
- package/dist/src/commands/furnace/index.d.ts +2 -1
- package/dist/src/commands/furnace/index.js +20 -2
- package/dist/src/commands/lint.d.ts +13 -1
- package/dist/src/commands/lint.js +33 -7
- package/dist/src/commands/setup.d.ts +1 -1
- package/dist/src/commands/setup.js +3 -2
- package/dist/src/core/build-audit.d.ts +46 -0
- package/dist/src/core/build-audit.js +251 -0
- package/dist/src/core/build-baseline.d.ts +59 -0
- package/dist/src/core/build-baseline.js +83 -0
- package/dist/src/core/build-prepare.d.ts +20 -1
- package/dist/src/core/build-prepare.js +94 -4
- package/dist/src/core/furnace-apply-helpers.d.ts +1 -1
- package/dist/src/core/furnace-config-tokens.d.ts +6 -0
- package/dist/src/core/furnace-config-tokens.js +15 -0
- package/dist/src/core/furnace-config.js +10 -4
- package/dist/src/core/furnace-operation.d.ts +2 -1
- package/dist/src/core/furnace-operation.js +13 -7
- package/dist/src/core/furnace-registration-ast.d.ts +2 -2
- package/dist/src/core/furnace-registration-ast.js +1 -1
- package/dist/src/core/furnace-validate-compatibility.js +18 -7
- package/dist/src/core/furnace-validate-helpers.d.ts +31 -1
- package/dist/src/core/furnace-validate-helpers.js +101 -18
- package/dist/src/core/furnace-validate-registration.d.ts +1 -1
- package/dist/src/core/furnace-validate-registration.js +1 -1
- package/dist/src/core/mach-error-hints.d.ts +29 -0
- package/dist/src/core/mach-error-hints.js +43 -0
- package/dist/src/core/mach.d.ts +5 -2
- package/dist/src/core/mach.js +31 -4
- package/dist/src/core/marionette-preflight.d.ts +14 -7
- package/dist/src/core/marionette-preflight.js +94 -44
- package/dist/src/core/patch-lint-cross.d.ts +1 -1
- package/dist/src/core/patch-lint-cross.js +1 -1
- package/dist/src/core/patch-lint-diff-tag.d.ts +33 -0
- package/dist/src/core/patch-lint-diff-tag.js +83 -0
- package/dist/src/core/patch-lint.js +29 -9
- package/dist/src/types/commands/options.d.ts +25 -0
- package/dist/src/types/commands/patches.d.ts +9 -0
- package/dist/src/types/config.d.ts +1 -1
- package/dist/src/types/furnace.d.ts +13 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
### Furnace registration
|
|
6
6
|
|
|
7
7
|
- `furnace apply` idempotency check is marker-comment-tolerant. Previously the single-line substring match (`content.includes('["tag",')`) missed multi-line entries, and the standalone-line regex anchored on `\s*$`, which did not allow trailing `// <marker>:` comments an operator may have appended to a previously-written entry. A duplicate tag was then inserted on every re-apply, and the second `setElementCreationCallback` invocation threw `NotSupportedError: Operation is not supported` at every window-load. The idempotency check now matches on tag-name column 0 (both single- and multi-line array shapes) and tolerates trailing `//` comments on the line.
|
|
8
|
-
- New optional fireforge.json field `markerComment` (e.g. `"
|
|
8
|
+
- New optional fireforge.json field `markerComment` (e.g. `"MYBROWSER"`) is appended as a ` // MYBROWSER:` suffix to every line FireForge writes into `customElements.js`. Keeps fork modifications discoverable and re-applies idempotent without hand-tagging after each apply. The field is threaded through `applyCustomComponent` and `furnace deploy`, not just `furnace create`.
|
|
9
9
|
- `addCustomElementRegistration` and its regex fallback both accept the new marker as an optional parameter; the AST idempotency check and the regex-fallback idempotency check share a single helper (`isTagAlreadyRegistered`).
|
|
10
10
|
|
|
11
11
|
### Furnace `--localized`
|
|
@@ -17,19 +17,55 @@
|
|
|
17
17
|
|
|
18
18
|
### Furnace validate
|
|
19
19
|
|
|
20
|
-
- `missing-token-link` now reads `tokenHostDocuments` from furnace.json and scans every configured chrome document for the tokens CSS link. Warning fires only when NONE of them link the tokens CSS; the warning enumerates the documents it actually checked. Previously the check was hardcoded to `browser/base/content/browser.xhtml`, which false-positived on forks that mount components in a different chrome document (e.g. `
|
|
20
|
+
- `missing-token-link` now reads `tokenHostDocuments` from furnace.json and scans every configured chrome document for the tokens CSS link. Warning fires only when NONE of them link the tokens CSS; the warning enumerates the documents it actually checked. Previously the check was hardcoded to `browser/base/content/browser.xhtml`, which false-positived on forks that mount components in a different chrome document (e.g. `mybrowser.xhtml`). Defaults to `["browser/base/content/browser.xhtml"]` when omitted — behaviour is unchanged for projects that never set the field.
|
|
21
21
|
- `no-keyboard-handler` no longer warns when `@click` sits on a native interactive element (`<button>`, `<a href>`, `<input>`, `<select>`, `<textarea>`, `<summary>`, `<details>`, or the Firefox `moz-button`/`moz-toggle`/`moz-checkbox`/`moz-radio`/`moz-menulist` widgets). Those elements dispatch `click` on Enter and Space via the platform, so a duplicate `@keydown`/`@keypress` handler would double-fire. The rule still fires for synthetic interactive markup (e.g. `<div @click>`) and for bare `<a>` without an `href` attribute, which are the real keyboard-a11y hazards.
|
|
22
|
+
- `token-prefix-violation` stops flagging component-owned runtime CSS custom properties. Previously every `var(--foo)` that did not match `tokenPrefix` was rejected as a design-token escape, even when the property was a per-frame state channel (`--cam-x`, `--tile-z`) both written and read by the component. Two relaxations ship together: (a) a new optional `runtimeVariables: string[]` field in `furnace.json` explicitly allowlists cross-component runtime channels (e.g. set in JS, read in the child's CSS); (b) variables that are both declared (`--foo: value;`) and consumed (`var(--foo)`) inside the same CSS file are auto-exempted — no config entry required. The same relaxations apply to the patch-stack lint. The violation message now calls out `runtimeVariables` as the third escape hatch alongside `tokenPrefix` and `tokenAllowlist`.
|
|
23
|
+
- `hardcoded-text` narrowed from a bare `>…<` scan to three context-aware probes: text inside Lit `` html`…` `` template literals, string literals assigned via `.textContent = "…"` / `.innerHTML = "…"`, and XUL-attribute values set via `setAttribute("label"|"title"|"tooltiptext", "…")`. Previously the rule also matched JS comparisons (`if (x > 0 && y < 100)`), long diagnostic strings (`console.error("…")`), and identifier literals passed to `querySelector`, producing noise that trained authors to ignore validator warnings. The file-wide `// furnace-ignore: hardcoded-text` escape hatch is preserved.
|
|
22
24
|
|
|
23
25
|
### Run / test
|
|
24
26
|
|
|
25
27
|
- `fireforge run`, `fireforge watch`, `fireforge build`, and every other `mach` invocation launched with inherited stdio now forward parent `SIGINT`/`SIGTERM` to the child as `SIGTERM` and wait ~1.5 s before escalating to `SIGKILL`. A second Ctrl-C during the grace window escalates immediately (matches the usual "hit Ctrl-C twice to force-quit" UX). Previously the parent could exit before Gecko's `AsyncShutdown` / `profileBeforeChange` blockers finished flushing in-memory state, losing the last few seconds of edits. The grace window is configurable via a new `shutdownGraceMs` option on `execInherit` / `execInheritCapture`.
|
|
26
28
|
- New `fireforge test --doctor` runs a short marionette handshake preflight before (optionally) invoking `mach test`. Spawns the built browser headless, opens a TCP socket to `127.0.0.1:2828`, waits for the handshake bytes, and reports PASS/FAIL with the tail of stderr on FAIL. When `--doctor` is supplied with no test paths, it exits after the preflight — a sub-minute way to tell "marionette wedged" apart from "test failed to discover" when `mach test` hangs for the full 360 s marionette timeout. When supplied with test paths, a FAIL preflight short-circuits before `mach test` runs.
|
|
29
|
+
- `fireforge test --doctor` is now a cascade of six layered probes (engine-present → mach-available → python-available → profile-creatable → browser-spawns → marionette-handshake) with tight per-layer budgets. Previously the single 30 s socket poll gave the same generic "socket did not respond" diagnostic whether mach was missing, Python was unavailable, `/tmp` was not writable, or the browser binary crashed at startup — so operators had no lead on where to start debugging. Each layer now short-circuits with a `[layer N/6: <name>]`-prefixed detail message so the first broken layer is surfaced immediately, and a crashing browser is caught by a short settle window at layer 5 instead of wasting the full budget waiting for bytes that never come.
|
|
30
|
+
|
|
31
|
+
### Furnace build
|
|
32
|
+
|
|
33
|
+
- `fireforge build` already auto-applies Furnace components (via `prepareBuildEnvironment`) before the mach build step, but the behaviour was undocumented and silent — operators who edited `components/custom/` and then ran `fireforge build` could not distinguish "auto-apply wrote files" from "nothing changed". A loud `Furnace: source → engine sync wrote N component(s) before build (...)` banner now fires whenever apply wrote files, naming every component that was synced. The `fireforge build --help` description and help footer now call out that apply runs before the build step.
|
|
34
|
+
|
|
35
|
+
### Furnace create
|
|
36
|
+
|
|
37
|
+
- New `furnace create --xpcshell` flag scaffolds an xpcshell test harness alongside (or instead of) the browser-chrome mochitest that `--with-tests` already produces. xpcshell runs headless without a `tabbrowser`, so storage-layer / observer-driven / module-loading code on forks that do not mount the upstream browser chrome (no `openLinkIn` → `URILoadingHelper`) can be covered without the harness complaining about a missing tab strip. Writes `test_<name>_module_loads.js` and an `xpcshell.toml` manifest into `engine/browser/base/content/test/<binary-name>-xpcshell/<component-name>/`. Registration in `XPCSHELL_TESTS_MANIFESTS` is left to the operator — the moz.build that should own the entry depends on where the component lives.
|
|
38
|
+
|
|
39
|
+
### Build audit
|
|
40
|
+
|
|
41
|
+
- `fireforge build` now runs a warn-only post-build dist-tree audit after a successful mach build. The audit diffs engine-relative paths touched since the last successful build (stored as `.fireforge/last-build.json`) against the dist bundle, and warns per file that is packageable-by-convention (`.js`/`.mjs`/`.css`/`.ftl`/`.xhtml`/`app/profile/…`) but has no matching artifact, or whose dist mtime is older than the source. Surfaces the class of bug where a new pref file or widget is edited but never registered in `moz.build` / `jar.mn` / `package-manifest.in` — the 2026-04-18 `hominis.js` pref-file incident is the motivating case. The audit is warn-only and never fails a successful build.
|
|
42
|
+
- Ends every build with a `Packaged: N updated, M stale, K missing, S skipped` summary so operators can distinguish a fast-because-incremental build from a fast-because-silently-skipped one without a post-build `find`.
|
|
43
|
+
- `fireforge build` auto-runs `mach configure` before the mach build step when any `moz.build`, `moz.configure`, or `Makefile.in` changed since the last successful build. Prevents the stale-backend trap where an incremental build skips work against a recursive-make backend that no longer matches the source tree. Emits a `Backend config changed; running mach configure first...` banner so the extra step is visible, and continues the build even if configure exits non-zero.
|
|
44
|
+
- Mach build failures with known-cryptic mozbuild errors now print actionable hints. First entry in the table: `mozbuild.preprocessor.Preprocessor.Error: no preprocessor directives found` prints `Use JS_PREFERENCE_FILES instead, or add at least one #filter / #expand directive to the file.` The hint table lives in `src/core/mach-error-hints.ts` and is extensible — new cryptic errors we diagnose get one-line hints added without touching the build wrapper.
|
|
45
|
+
|
|
46
|
+
### Lint
|
|
47
|
+
|
|
48
|
+
- `fireforge lint --since <git-rev>` tags each lint issue as `[introduced]` (file touched in the diff since `<git-rev>`) or `[cumulative]` (pre-existing patch-state drift). Output gains the tag prefix and the summary line splits counts (e.g. `Lint: 2 introduced error(s), 0 introduced warning(s); 5 cumulative error(s), 1 cumulative warning(s)`). Exit code semantics are unchanged — an introduced OR cumulative error still fails lint — but triage of "is the diff I just produced clean?" no longer requires mentally subtracting pre-existing noise from every report. Without `--since` the output is unchanged.
|
|
49
|
+
|
|
50
|
+
### Furnace chrome-doc
|
|
51
|
+
|
|
52
|
+
- New `furnace chrome-doc create <name>` subcommand scaffolds a top-level chrome document (xhtml + js + css + ftl) plus the three jar.mn registrations (`browser/base/jar.mn`, `browser/themes/shared/jar.inc.mn`, `browser/locales/jar.mn`). Default emits titlebar-buttonbox markup and a `windowtype="navigator:browser"` shell; `--no-titlebar` produces a frameless overlay with the macOS `.titlebar-button { display: none }` carve-out. Mirrors the workflow for custom elements (`furnace create`) so hand-authoring mistakes — the `*` preprocessor flag, the startup-topic observer, the platform titlebar inheritance — are eliminated. All writes go through a rollback journal under the signal-handler pathway: a Ctrl+C mid-scaffold restores every touched file.
|
|
53
|
+
|
|
54
|
+
### Furnace create
|
|
55
|
+
|
|
56
|
+
- New `--test-style <mochikit|browser-chrome|xpcshell>` option for `furnace create --with-tests`. `mochikit` (the new default when `--with-tests` is set alone) scaffolds a `chrome://mochikit/...` test under `engine/toolkit/content/tests/widgets/test_<tag>.html` that loads the component module directly and smoke-asserts `customElements.whenDefined(tag)`. Runs today against forks whose top-level chrome document lacks a `tabbrowser` (the class of bug that forced `--xpcshell` for storage-layer code) because the harness doesn't traverse `URILoadingHelper.openLinkIn`. `browser-chrome` is the former default and requires a working tabbrowser; `xpcshell` is equivalent to `--xpcshell`. Backwards-compat: `--xpcshell` alone still works; conflicting flag combinations are rejected up-front.
|
|
57
|
+
|
|
58
|
+
### Run / signals
|
|
59
|
+
|
|
60
|
+
- `fireforge run` (and every other command that never registers a furnace mutation) no longer prints the alarming `Received SIGTERM; rolling back in-flight furnace mutations…` line when the CLI receives SIGINT or SIGTERM. The global signal handler now gates the rollback banner on the presence of at least one live mutation in the registry — plain launches exit silently with code 130/143 as they always did. A new regression test asserts `warn` is not called when no operations are registered.
|
|
27
61
|
|
|
28
62
|
### Internal
|
|
29
63
|
|
|
30
64
|
- Extracted `furnace-apply-ftl.ts`, `furnace-config-tokens.ts`, and `create-templates.ts` to keep apply / config / scaffolding files under the per-file LOC budget after the new features landed. `parseStringArray` is now exported from `furnace-config.ts` for cross-module reuse.
|
|
31
65
|
- New `src/core/marionette-preflight.ts` owns the `--doctor` probe and its teardown semantics.
|
|
32
66
|
- Test mocks for `furnace-registration.js` now cover the new `addLocaleFtlJarMnEntry` / `removeLocaleFtlJarMnEntry` exports; `config.js` mocks in apply-batch tests now cover `loadConfig` because the apply path reads `markerComment` from fireforge.json.
|
|
67
|
+
- Repo-wide scrub of fork-example mentions (`hominis.xhtml`, `HOMINIS` marker-comment examples, fixture tag names) in favour of a generic `mybrowser` / `MYBROWSER` placeholder. FireForge reads as fork-agnostic in docs and fixtures; the npm identity (`@hominis/fireforge`) is unchanged. Closes a v0.15.0 slip-through (one `@hominis/fireforge` reference remained in `src/core/furnace-operation.ts` as a generic example alongside the npm-identity occurrences; the code example is now fork-neutral).
|
|
68
|
+
- New modules landed under coverage-gate protection: `src/core/mach-error-hints.ts`, `src/core/build-audit.ts`, `src/core/build-baseline.ts`, `src/core/patch-lint-diff-tag.ts`, `src/commands/furnace/chrome-doc.ts`, `src/commands/furnace/chrome-doc-templates.ts`, `src/commands/furnace/create-mochikit.ts`. Per-module thresholds added to `scripts/check-coverage-thresholds.mjs`.
|
|
33
69
|
|
|
34
70
|
## 0.14.0
|
|
35
71
|
|
|
@@ -249,7 +285,7 @@
|
|
|
249
285
|
### General improvements
|
|
250
286
|
|
|
251
287
|
- getPackageRoot up to this point expected hardcoded `@hominis/fireforge`, was changed to just the package name for potential forks and more flexibility when changing project name.
|
|
252
|
-
- Some test generators were derived from early
|
|
288
|
+
- Some test generators were derived from an early downstream fork; the fork-specific names have been replaced with generic naming so the templates apply to any Firefox fork.
|
|
253
289
|
|
|
254
290
|
### Build and Git reliability
|
|
255
291
|
|
package/README.md
CHANGED
|
@@ -293,12 +293,46 @@ There are three component types:
|
|
|
293
293
|
fireforge furnace scan # discover components in the engine
|
|
294
294
|
fireforge furnace override moz-button -t css-only # fork with CSS-only restyle
|
|
295
295
|
fireforge furnace create moz-my-widget # scaffold a new component
|
|
296
|
+
fireforge furnace chrome-doc create mybrowser # scaffold a top-level chrome document
|
|
296
297
|
fireforge furnace deploy # apply to engine/ + validate
|
|
297
298
|
fireforge furnace status # workspace vs engine drift
|
|
298
299
|
fireforge furnace diff moz-button # unified diff against baseline
|
|
299
300
|
```
|
|
300
301
|
|
|
301
|
-
`furnace deploy` validates components before applying. As always, errors block, warnings are advisory. `fireforge build` and `fireforge test --build` run apply automatically. Use `fireforge doctor --repair-furnace` if the engine gets out of sync.
|
|
302
|
+
`furnace deploy` validates components before applying. As always, errors block, warnings are advisory. `fireforge build` and `fireforge test --build` run apply automatically — when apply wrote files during a build, the build prints a `Furnace: source → engine sync wrote N component(s) …` banner naming every component that was synced, so it is obvious whether engine/ was freshly updated. Use `fireforge doctor --repair-furnace` if the engine gets out of sync.
|
|
303
|
+
|
|
304
|
+
### Scaffolding top-level chrome documents
|
|
305
|
+
|
|
306
|
+
Custom elements live under `toolkit/content/widgets`, but a fork's top-level chrome document (`browser.xhtml` equivalents like `mybrowser.xhtml`, `about:*` panels, onboarding flows) lives at `browser/base/content/` and needs jar.mn, jar.inc.mn, and locales/jar.mn entries to reach the packaged bundle. `furnace chrome-doc create <name>` handles that boilerplate:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
fireforge furnace chrome-doc create mybrowser # full chrome (titlebar + windowtype)
|
|
310
|
+
fireforge furnace chrome-doc create overlay --no-titlebar # frameless overlay
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The command writes:
|
|
314
|
+
|
|
315
|
+
- `engine/browser/base/content/<name>.xhtml` — XHTML shell, optional titlebar-buttonbox, Fluent `<link>`.
|
|
316
|
+
- `engine/browser/base/content/<name>.js` — startup-topic observer fired on first idle.
|
|
317
|
+
- `engine/browser/themes/shared/<name>-chrome.css` — scoped CSS; emits the macOS `.titlebar-button { display: none }` carve-out under `--no-titlebar`.
|
|
318
|
+
- `engine/browser/locales/en-US/browser/<name>.ftl` — Fluent stub keyed on `<name>-window-title`.
|
|
319
|
+
- Appends the corresponding `jar.mn` / `jar.inc.mn` / `locales/jar.mn` entries.
|
|
320
|
+
|
|
321
|
+
Writes are transactional: a SIGINT mid-scaffold rolls back every touched file. Requires an existing engine — run `fireforge download` first.
|
|
322
|
+
|
|
323
|
+
### Picking a test harness for `furnace create`
|
|
324
|
+
|
|
325
|
+
`furnace create --with-tests` defaults to a MochiKit test at `engine/toolkit/content/tests/widgets/test_<tag>.html`. MochiKit tests load the component module via `chrome://global/` and don't need a `tabbrowser`, so they run against any fork — including bespoke chrome documents (`mybrowser.xhtml`-class) that deliberately omit the upstream browser chrome.
|
|
326
|
+
|
|
327
|
+
Three styles are available via `--test-style`:
|
|
328
|
+
|
|
329
|
+
| Style | When to use |
|
|
330
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
331
|
+
| `mochikit` | Default. Pure-UI custom elements. Runs today against non-tabbrowser chrome. Emits `test_<tag>.html` under `toolkit/content/tests/widgets/`. |
|
|
332
|
+
| `browser-chrome` | Element talks to the browser window (open URLs, manipulate tabs). Requires a working `tabbrowser` in the chrome document. Emits the `browser_<bin>_<tag>.js` scaffold and registers it in `browser/base/moz.build`. |
|
|
333
|
+
| `xpcshell` | Storage-layer, observer-driven, or ESM-loading code. Headless, no tabbrowser. Emits `test_<name>_module_loads.js` + `xpcshell.toml` (registration in `XPCSHELL_TESTS_MANIFESTS` is left to the operator). |
|
|
334
|
+
|
|
335
|
+
`--xpcshell` is preserved as an alias for `--test-style=xpcshell`; conflicting flag combinations (`--xpcshell --test-style=mochikit`) are rejected.
|
|
302
336
|
|
|
303
337
|
## Additional Commands
|
|
304
338
|
|
|
@@ -348,6 +382,26 @@ fireforge watch
|
|
|
348
382
|
fireforge token --name "--my-color" --value "light-dark(#fff, #000)"
|
|
349
383
|
```
|
|
350
384
|
|
|
385
|
+
### Diff-scoped lint (`lint --since`)
|
|
386
|
+
|
|
387
|
+
`fireforge lint --since <git-rev>` tags each issue as `[introduced]` or `[cumulative]` based on whether its file changed since `<git-rev>`:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
fireforge lint --since HEAD~1 # just the current commit
|
|
391
|
+
fireforge lint --since main # everything since main
|
|
392
|
+
fireforge lint --since abc1234 # since a specific SHA
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
The summary line splits counts — e.g. `Lint: 2 introduced error(s), 0 introduced warning(s); 5 cumulative error(s), 1 cumulative warning(s)` — so triage of "did my diff introduce any of these?" is a one-glance check on a large patch series. Exit code still fails on any error (introduced or cumulative); the flag is purely a display / audit tool. Without `--since`, output is unchanged.
|
|
396
|
+
|
|
397
|
+
### Post-build audit and auto-configure
|
|
398
|
+
|
|
399
|
+
`fireforge build` is a transactional step: after a successful mach build it audits the dist bundle against engine-relative paths touched since the last successful build, and warns per file that is packageable-by-convention (`.js`/`.mjs`/`.css`/`.ftl`/`.xhtml`/`app/profile/…`) but has no matching artifact or whose dist mtime is older than the source. Ends every build with a `Packaged: N updated, M stale, K missing, S skipped` summary. The audit is warn-only — it never fails a build that mach reported green.
|
|
400
|
+
|
|
401
|
+
The build also auto-runs `mach configure` before the mach build step when any `moz.build`, `moz.configure`, or `Makefile.in` changed since the last successful build. Prevents incremental builds from silently skipping work against a stale recursive-make backend. Emits a `Backend config changed; running mach configure first...` banner when it fires.
|
|
402
|
+
|
|
403
|
+
Mach build failures with known-cryptic mozbuild errors now print actionable hints. Example: a `JS_PREFERENCE_PP_FILES` entry with no `#filter` / `#expand` directives now prints `Hint: ...use JS_PREFERENCE_FILES instead, or add at least one #filter / #expand directive to the file.` alongside the raw mach traceback.
|
|
404
|
+
|
|
351
405
|
## Configuration
|
|
352
406
|
|
|
353
407
|
`fireforge.json` at your project root:
|
|
@@ -367,7 +421,7 @@ fireforge token --name "--my-color" --value "light-dark(#fff, #000)"
|
|
|
367
421
|
"wire": { "subscriptDir": "browser/components/mybrowser" },
|
|
368
422
|
"patchLint": {
|
|
369
423
|
"checkJs": true,
|
|
370
|
-
"rawColorAllowlist": ["
|
|
424
|
+
"rawColorAllowlist": ["mybrowser-tokens.css"]
|
|
371
425
|
},
|
|
372
426
|
"markerComment": "MYBROWSER"
|
|
373
427
|
}
|
|
@@ -375,7 +429,7 @@ fireforge token --name "--my-color" --value "light-dark(#fff, #000)"
|
|
|
375
429
|
|
|
376
430
|
**`markerComment`** (optional). Appended as a ` // <marker>:` suffix to every line FireForge writes into upstream Firefox source files (starting with `customElements.js`). Keeps fork modifications discoverable and makes re-apply idempotent without hand-tagging entries after each `furnace apply`. Reject list: empty strings, leading/trailing whitespace, newlines, `*/` (would close an enclosing block comment), control characters.
|
|
377
431
|
|
|
378
|
-
**`furnace.json.tokenHostDocuments`** (optional). List of chrome XHTML documents the `missing-token-link` validator scans for the tokens CSS link. Forks with a second chrome host (e.g. `
|
|
432
|
+
**`furnace.json.tokenHostDocuments`** (optional). List of chrome XHTML documents the `missing-token-link` validator scans for the tokens CSS link. Forks with a second chrome host (e.g. `mybrowser.xhtml` alongside `browser.xhtml`) should list every document that may own the link — the rule fires only when NONE of them link the tokens CSS. Defaults to `["browser/base/content/browser.xhtml"]` when omitted.
|
|
379
433
|
|
|
380
434
|
### `furnace create --localized` for `MozLitElement`
|
|
381
435
|
|
|
@@ -391,6 +445,25 @@ fireforge test --doctor browser/base/content/test/foo/browser_bar.js
|
|
|
391
445
|
|
|
392
446
|
Spawns the built browser headless, waits for a marionette handshake on `127.0.0.1:2828`, and reports PASS/FAIL with the tail of the browser's stderr on FAIL. Distinguishes "marionette wedged" (socket silent) from "mach test discovery failed" — both otherwise surface as a silent 360-second hang followed by `Passed: 0, Failed: 0`. Useful as a prefix on routine `fireforge test` invocations when marionette has been flaky.
|
|
393
447
|
|
|
448
|
+
The probe is a cascade of six layered checks — engine-present → mach-available → python-available → profile-creatable → browser-spawns → marionette-handshake. Each failure is tagged `[layer N/6: <name>]` so the first broken layer is surfaced immediately instead of the whole cascade blocking on the final socket poll. When the browser binary crashes at startup (missing dylib, wrong CPU arch, corrupt profile) the cascade fails at layer 5 within the settle window, not after the full socket timeout.
|
|
449
|
+
|
|
450
|
+
### Runtime CSS variables in Furnace
|
|
451
|
+
|
|
452
|
+
Design tokens imported from the fork's palette are enforced by `tokenPrefix`, but some components write and read CSS custom properties as runtime state channels (`--cam-x` per frame, `--tile-z` from a hit-test observer). Two escape hatches exist:
|
|
453
|
+
|
|
454
|
+
- **Auto-exempt** — a variable that is both declared (`--foo: 0;`) and consumed (`var(--foo)`) inside the same component's CSS file is recognised as a component-local runtime channel. No config entry required.
|
|
455
|
+
- **`furnace.json.runtimeVariables`** — explicit allowlist for names that are _written_ in JS and _read_ in a different file's CSS (cross-component runtime channels that the CSS-only auto-exempt cannot see). Entries must start with `--`.
|
|
456
|
+
|
|
457
|
+
Both rules compose with the existing `tokenPrefix` / `tokenAllowlist` checks and apply to both component validation and patch-stack lint.
|
|
458
|
+
|
|
459
|
+
### Test harness options
|
|
460
|
+
|
|
461
|
+
`fireforge furnace create --with-tests` scaffolds a **browser-chrome mochitest**. Use this when the component renders UI that depends on the tab strip (`openLinkIn` → `URILoadingHelper`, `gBrowser`, etc.).
|
|
462
|
+
|
|
463
|
+
`fireforge furnace create --xpcshell` scaffolds an **xpcshell test harness** instead. Use this when the component's code path is storage-only, observer-driven, or module-loading logic that does not touch a `tabbrowser`. xpcshell runs headless without browser chrome, so forks without an upstream tab strip can still cover these paths. The scaffolder writes `test_<name>_module_loads.js` + `xpcshell.toml` into `engine/browser/base/content/test/<binary-name>-xpcshell/<component-name>/` and prints a note: registration in `XPCSHELL_TESTS_MANIFESTS` is the operator's call (the moz.build that should own the entry depends on where the component actually lives).
|
|
464
|
+
|
|
465
|
+
The two flags can be combined — `--with-tests --xpcshell` writes both harnesses.
|
|
466
|
+
|
|
394
467
|
## Roadmap
|
|
395
468
|
|
|
396
469
|
Planned but not yet implemented:
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { InvalidArgumentError as CommanderInvalidArgumentError } from 'commander';
|
|
3
3
|
import { validateBrandOverride } from '../core/brand-validation.js';
|
|
4
|
+
import { auditBuildArtifacts } from '../core/build-audit.js';
|
|
5
|
+
import { readBuildBaseline, writeBuildBaseline } from '../core/build-baseline.js';
|
|
4
6
|
import { prepareBuildEnvironment } from '../core/build-prepare.js';
|
|
5
7
|
import { getProjectPaths, loadConfig } from '../core/config.js';
|
|
6
8
|
import { build, buildArtifactMismatchMessage, buildUI, hasBuildArtifacts } from '../core/mach.js';
|
|
7
9
|
import { GeneralError } from '../errors/base.js';
|
|
8
10
|
import { AmbiguousBuildArtifactsError, BuildError } from '../errors/build.js';
|
|
11
|
+
import { toError } from '../utils/errors.js';
|
|
9
12
|
import { checkDiskSpace, pathExists } from '../utils/fs.js';
|
|
10
13
|
import { error, info, intro, outro, verbose, warn } from '../utils/logger.js';
|
|
11
14
|
import { pickDefined } from '../utils/options.js';
|
|
@@ -60,8 +63,13 @@ export async function buildCommand(projectRoot, options) {
|
|
|
60
63
|
// Future: Load brand-specific config from fireforge.json brands section
|
|
61
64
|
info(`Brand: ${options.brand}`);
|
|
62
65
|
}
|
|
63
|
-
//
|
|
64
|
-
|
|
66
|
+
// Read the previous build baseline BEFORE prepareBuildEnvironment so the
|
|
67
|
+
// auto-configure step there can detect moz.build-family changes since the
|
|
68
|
+
// last successful build. The post-build audit below reuses the same
|
|
69
|
+
// baseline to diff engine changes against dist artifacts.
|
|
70
|
+
const previousBaseline = await readBuildBaseline(projectRoot);
|
|
71
|
+
// Shared pre-flight: branding, Furnace, mozconfig, auto-configure
|
|
72
|
+
await prepareBuildEnvironment(projectRoot, paths, config, { previousBaseline });
|
|
65
73
|
const jobs = resolveJobCount(options, config.build?.jobs);
|
|
66
74
|
// Run build
|
|
67
75
|
info(`Starting ${buildType.toLowerCase()} build...`);
|
|
@@ -90,16 +98,46 @@ export async function buildCommand(projectRoot, options) {
|
|
|
90
98
|
error(`Build failed after ${timeStr}`);
|
|
91
99
|
throw new BuildError(`Build failed with exit code ${exitCode}`, options.ui ? 'mach build faster' : 'mach build');
|
|
92
100
|
}
|
|
101
|
+
// Warn-only post-build audit: surfaces silent packaging drops (files
|
|
102
|
+
// edited in engine/ but never registered for packaging) against the
|
|
103
|
+
// previous-build baseline. Never fails the build; the worst case is a
|
|
104
|
+
// warning an operator chooses to investigate.
|
|
105
|
+
try {
|
|
106
|
+
await auditBuildArtifacts(projectRoot, paths.engine, previousBaseline);
|
|
107
|
+
}
|
|
108
|
+
catch (auditError) {
|
|
109
|
+
verbose(`Audit skipped: ${toError(auditError).message}`);
|
|
110
|
+
}
|
|
111
|
+
// Record a fresh baseline only on clean success so the next run audits
|
|
112
|
+
// against this build's HEAD. A failed build keeps the prior baseline so
|
|
113
|
+
// the next attempt still catches long-standing packaging drops.
|
|
114
|
+
try {
|
|
115
|
+
await writeBuildBaseline(projectRoot, paths.engine, config.binaryName);
|
|
116
|
+
}
|
|
117
|
+
catch (baselineError) {
|
|
118
|
+
verbose(`Could not persist build baseline: ${toError(baselineError).message}`);
|
|
119
|
+
}
|
|
93
120
|
outro(`Build completed in ${timeStr}!`);
|
|
94
121
|
}
|
|
95
122
|
/** Registers the build command on the CLI program. */
|
|
96
123
|
export function registerBuild(program, { getProjectRoot, withErrorHandling }) {
|
|
97
124
|
program
|
|
98
125
|
.command('build')
|
|
99
|
-
.description('Build the browser')
|
|
126
|
+
.description('Build the browser (auto-applies Furnace components first)')
|
|
100
127
|
.option('--ui', 'Fast UI-only rebuild')
|
|
101
128
|
.option('-j, --jobs <n>', 'Number of parallel jobs', parseJobCount)
|
|
102
129
|
.option('--brand <name>', 'Build specific brand')
|
|
130
|
+
.addHelpText('after', [
|
|
131
|
+
'',
|
|
132
|
+
'Furnace apply runs automatically before the build step, so edits in',
|
|
133
|
+
'components/custom/ and components/overrides/ are propagated to the',
|
|
134
|
+
'engine/ tree every time. The command prints a banner listing the',
|
|
135
|
+
'components synced during the current invocation.',
|
|
136
|
+
'',
|
|
137
|
+
'If you want to preview the engine state without triggering a build,',
|
|
138
|
+
'run `fireforge furnace apply` directly. For source-change-driven',
|
|
139
|
+
'rebuild loops during development, use `fireforge watch`.',
|
|
140
|
+
].join('\n'))
|
|
103
141
|
.action(withErrorHandling(async (options) => {
|
|
104
142
|
await buildCommand(getProjectRoot(), pickDefined(options));
|
|
105
143
|
}));
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-content templates for `fireforge furnace chrome-doc create`.
|
|
3
|
+
* Extracted so the command entrypoint stays under the per-file LOC budget
|
|
4
|
+
* and each template can be exercised in isolation.
|
|
5
|
+
*
|
|
6
|
+
* The templates here mirror the shape of top-level chrome documents in
|
|
7
|
+
* upstream Firefox (browser.xhtml, privatebrowsing/aboutPrivateBrowsing.html,
|
|
8
|
+
* etc.) minus the fork-specific wiring. A fork author fills in the body.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* XHTML shell for a top-level chrome document.
|
|
12
|
+
*
|
|
13
|
+
* The emitted document:
|
|
14
|
+
* - Declares `windowtype="navigator:browser"` when `withTitlebar` is true
|
|
15
|
+
* so chrome-wide stylesheets that target the browser window still apply.
|
|
16
|
+
* - Emits a titlebar-buttonbox placeholder when `withTitlebar` is true so
|
|
17
|
+
* platform-native window controls render.
|
|
18
|
+
* - Links the per-document CSS at `chrome://browser/content/<name>-chrome.css`
|
|
19
|
+
* and the Fluent bundle `browser/<name>.ftl`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateChromeDocXhtml(name: string, withTitlebar: boolean, license: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* ESM bootstrap script for the chrome document.
|
|
24
|
+
*
|
|
25
|
+
* The generated script fires a startup observer topic on the first idle
|
|
26
|
+
* callback so other chrome code can wait on the document being ready.
|
|
27
|
+
* Mirrors the pattern FireForge-built forks use to coordinate per-window
|
|
28
|
+
* init across multiple top-level documents.
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateChromeDocJs(name: string, licenseHeader: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Scoped CSS for a chrome document. When `withTitlebar` is false the
|
|
33
|
+
* macOS `.titlebar-button { display: none }` carve-out is emitted so
|
|
34
|
+
* frameless overlay-style documents don't inherit the platform window
|
|
35
|
+
* controls that `global.css` applies by default.
|
|
36
|
+
*/
|
|
37
|
+
export declare function generateChromeDocCss(name: string, withTitlebar: boolean, licenseHeader: string): string;
|
|
38
|
+
/** Fluent stub — one placeholder message keyed to the window title. */
|
|
39
|
+
export declare function generateChromeDocFtl(name: string, licenseHeader: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Single-line jar.mn entry that registers an xhtml + js pair under
|
|
42
|
+
* `content/browser/`. Emits the `*` preprocessor flag so both files flow
|
|
43
|
+
* through `#filter substitution` for FireForge brand-name substitution.
|
|
44
|
+
*/
|
|
45
|
+
export declare function jarMnEntriesForChromeDoc(name: string): string[];
|
|
46
|
+
/** jar.inc.mn entry that registers the scoped CSS under `content/browser/`. */
|
|
47
|
+
export declare function jarIncMnEntryForChromeDoc(name: string): string;
|
|
48
|
+
/** locales/jar.mn entry that registers the `.ftl` under the browser locale bundle. */
|
|
49
|
+
export declare function localeJarMnEntryForChromeDoc(name: string): string;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* File-content templates for `fireforge furnace chrome-doc create`.
|
|
4
|
+
* Extracted so the command entrypoint stays under the per-file LOC budget
|
|
5
|
+
* and each template can be exercised in isolation.
|
|
6
|
+
*
|
|
7
|
+
* The templates here mirror the shape of top-level chrome documents in
|
|
8
|
+
* upstream Firefox (browser.xhtml, privatebrowsing/aboutPrivateBrowsing.html,
|
|
9
|
+
* etc.) minus the fork-specific wiring. A fork author fills in the body.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* XHTML shell for a top-level chrome document.
|
|
13
|
+
*
|
|
14
|
+
* The emitted document:
|
|
15
|
+
* - Declares `windowtype="navigator:browser"` when `withTitlebar` is true
|
|
16
|
+
* so chrome-wide stylesheets that target the browser window still apply.
|
|
17
|
+
* - Emits a titlebar-buttonbox placeholder when `withTitlebar` is true so
|
|
18
|
+
* platform-native window controls render.
|
|
19
|
+
* - Links the per-document CSS at `chrome://browser/content/<name>-chrome.css`
|
|
20
|
+
* and the Fluent bundle `browser/<name>.ftl`.
|
|
21
|
+
*/
|
|
22
|
+
export function generateChromeDocXhtml(name, withTitlebar, license) {
|
|
23
|
+
const windowAttr = withTitlebar ? ' windowtype="navigator:browser"' : '';
|
|
24
|
+
const titlebarMarkup = withTitlebar
|
|
25
|
+
? `
|
|
26
|
+
<hbox class="titlebar-buttonbox-container">
|
|
27
|
+
<hbox class="titlebar-buttonbox"></hbox>
|
|
28
|
+
</hbox>`
|
|
29
|
+
: '';
|
|
30
|
+
return `<?xml version="1.0"?>
|
|
31
|
+
<!-- SPDX-License-Identifier: ${license} -->
|
|
32
|
+
<!DOCTYPE window>
|
|
33
|
+
<window
|
|
34
|
+
xmlns="http://www.w3.org/1999/xhtml"
|
|
35
|
+
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
36
|
+
id="${name}-window"${windowAttr}
|
|
37
|
+
data-l10n-id="${name}-window-title"
|
|
38
|
+
role="application">
|
|
39
|
+
<head>
|
|
40
|
+
<meta charset="utf-8" />
|
|
41
|
+
<title data-l10n-id="${name}-window-title"></title>
|
|
42
|
+
<link rel="localization" href="browser/${name}.ftl" />
|
|
43
|
+
<link rel="stylesheet" href="chrome://global/skin/global.css" />
|
|
44
|
+
<link rel="stylesheet" href="chrome://browser/content/${name}-chrome.css" />
|
|
45
|
+
<script src="chrome://browser/content/${name}.js"></script>
|
|
46
|
+
</head>
|
|
47
|
+
<body>${titlebarMarkup}
|
|
48
|
+
<main id="${name}-main"></main>
|
|
49
|
+
</body>
|
|
50
|
+
</window>
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* ESM bootstrap script for the chrome document.
|
|
55
|
+
*
|
|
56
|
+
* The generated script fires a startup observer topic on the first idle
|
|
57
|
+
* callback so other chrome code can wait on the document being ready.
|
|
58
|
+
* Mirrors the pattern FireForge-built forks use to coordinate per-window
|
|
59
|
+
* init across multiple top-level documents.
|
|
60
|
+
*/
|
|
61
|
+
export function generateChromeDocJs(name, licenseHeader) {
|
|
62
|
+
const topic = `${name}-startup`;
|
|
63
|
+
return `${licenseHeader}
|
|
64
|
+
|
|
65
|
+
"use strict";
|
|
66
|
+
|
|
67
|
+
// Fire a startup topic on first idle so subscribers can defer their own
|
|
68
|
+
// init until this document is ready. Observers see the document element as
|
|
69
|
+
// the subject; use \`aSubject instanceof Ci.nsIDOMWindow\` if you need the
|
|
70
|
+
// containing window instead.
|
|
71
|
+
window.addEventListener(
|
|
72
|
+
"DOMContentLoaded",
|
|
73
|
+
() => {
|
|
74
|
+
window.requestIdleCallback?.(() => {
|
|
75
|
+
try {
|
|
76
|
+
Services.obs.notifyObservers(document.documentElement, "${topic}");
|
|
77
|
+
} catch (error) {
|
|
78
|
+
// Observer notifications should never block document init — log
|
|
79
|
+
// but don't throw so a missing observer service (headless / test
|
|
80
|
+
// harness) still leaves the document usable.
|
|
81
|
+
console.error("Failed to fire ${topic} observer:", error);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
{ once: true }
|
|
86
|
+
);
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Scoped CSS for a chrome document. When `withTitlebar` is false the
|
|
91
|
+
* macOS `.titlebar-button { display: none }` carve-out is emitted so
|
|
92
|
+
* frameless overlay-style documents don't inherit the platform window
|
|
93
|
+
* controls that `global.css` applies by default.
|
|
94
|
+
*/
|
|
95
|
+
export function generateChromeDocCss(name, withTitlebar, licenseHeader) {
|
|
96
|
+
const titlebarOverrides = withTitlebar
|
|
97
|
+
? ''
|
|
98
|
+
: `
|
|
99
|
+
|
|
100
|
+
/* Frameless overlay — suppress the platform titlebar buttons that
|
|
101
|
+
global.css inherits on macOS. Without this carve-out the traffic-light
|
|
102
|
+
controls render even though the document has no titlebar-buttonbox. */
|
|
103
|
+
:root[windowtype="navigator:browser"] .titlebar-button {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
return `${licenseHeader}
|
|
108
|
+
|
|
109
|
+
:root {
|
|
110
|
+
--${name}-padding: 16px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
#${name}-window {
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
min-height: 100vh;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#${name}-main {
|
|
120
|
+
flex: 1;
|
|
121
|
+
padding: var(--${name}-padding);
|
|
122
|
+
}${titlebarOverrides}
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
/** Fluent stub — one placeholder message keyed to the window title. */
|
|
126
|
+
export function generateChromeDocFtl(name, licenseHeader) {
|
|
127
|
+
return `${licenseHeader}
|
|
128
|
+
|
|
129
|
+
${name}-window-title = ${name}
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Single-line jar.mn entry that registers an xhtml + js pair under
|
|
134
|
+
* `content/browser/`. Emits the `*` preprocessor flag so both files flow
|
|
135
|
+
* through `#filter substitution` for FireForge brand-name substitution.
|
|
136
|
+
*/
|
|
137
|
+
export function jarMnEntriesForChromeDoc(name) {
|
|
138
|
+
return [
|
|
139
|
+
`* content/browser/${name}.xhtml (content/${name}.xhtml)`,
|
|
140
|
+
` content/browser/${name}.js (content/${name}.js)`,
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
/** jar.inc.mn entry that registers the scoped CSS under `content/browser/`. */
|
|
144
|
+
export function jarIncMnEntryForChromeDoc(name) {
|
|
145
|
+
return ` content/browser/${name}-chrome.css (shared/${name}-chrome.css)`;
|
|
146
|
+
}
|
|
147
|
+
/** locales/jar.mn entry that registers the `.ftl` under the browser locale bundle. */
|
|
148
|
+
export function localeJarMnEntryForChromeDoc(name) {
|
|
149
|
+
return ` locale/browser/${name}.ftl (%${name}.ftl)`;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=chrome-doc-templates.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fireforge furnace chrome-doc create <name>` — scaffolds a top-level
|
|
3
|
+
* chrome document (xhtml + js + css + ftl + jar.mn registrations).
|
|
4
|
+
*
|
|
5
|
+
* Motivation: `furnace create` covers custom elements under
|
|
6
|
+
* `toolkit/content/widgets/`, but top-level chrome documents (the
|
|
7
|
+
* `mybrowser.xhtml`-class entry points a fork adds alongside or instead
|
|
8
|
+
* of `browser.xhtml`) are today hand-authored with error-prone jar.mn +
|
|
9
|
+
* jar.inc.mn + locales/jar.mn glue. The `*` preprocessor flag, the
|
|
10
|
+
* macOS titlebar-button carve-out, the startup-topic observer, and the
|
|
11
|
+
* Fluent linkage each have silent-break failure modes.
|
|
12
|
+
*
|
|
13
|
+
* This command writes the four source files and appends three jar.mn
|
|
14
|
+
* entries under a rollback journal identical in shape to `furnace create`.
|
|
15
|
+
* A SIGINT mid-scaffold restores every touched file; a successful run
|
|
16
|
+
* leaves the tree ready for `fireforge build`.
|
|
17
|
+
*/
|
|
18
|
+
/** Options for `furnace chrome-doc create`. */
|
|
19
|
+
export interface FurnaceChromeDocCreateOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Emit the titlebar-buttonbox markup and leave platform window controls
|
|
22
|
+
* visible. Defaults to `true` because the common case is a full chrome
|
|
23
|
+
* document (not a frameless overlay). Frameless callers pass
|
|
24
|
+
* `--no-titlebar`.
|
|
25
|
+
*/
|
|
26
|
+
titlebar?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Runs `furnace chrome-doc create <name>`.
|
|
30
|
+
* @param projectRoot Root directory of the project.
|
|
31
|
+
* @param name Chrome-doc name (e.g. `mybrowser`, `aboutonboarding`).
|
|
32
|
+
* @param options CLI-provided options.
|
|
33
|
+
*/
|
|
34
|
+
export declare function furnaceChromeDocCreateCommand(projectRoot: string, name: string, options?: FurnaceChromeDocCreateOptions): Promise<void>;
|