configuredElectronFlags() inlined HERMES_HOME normalization, so it missed
the two cases resolveDesktopHermesHome() handles: HERMES_DATA_DIR_SUFFIX
channel installs and profiles/-rooted HERMES_HOME values. Both read
config.yaml from a different home than main.ts does, silently dropping
desktop.electron_flags on the relaunch. Use the shared resolver and cover
both shapes with bundle-entry regression tests.
The bundler rewrite predates #113247, and merging it back kept main.ts as
the esbuild entry. entry.ts, which picks the ozone platform and relaunches
before main loads, was no longer bundled: the WSLg Wayland relaunch never
ran. Bundle entry.ts again and run the built electron-main.mjs in a test
to prove the relaunch ships.
afterPack now asserts the packaged backend-readiness matcher before any
platform work (#60772). The Linux toolchain fixture never packed an
app.asar, so the guard aborted with 'Missing packaged app.asar' before
the payload-link repair it exists to exercise. Seed the same
unpacked-mirror fixture after-pack.test.mjs uses.
afterPack now verifies the packaged dist/electron-main.mjs still carries
the dual-token readiness matcher before any platform work, turning
source/packaged-artifact skew (#60772) into a build failure instead of a
user-side boot loop.
Co-authored-by: embwl0x <embwl0x@users.noreply.github.com>
click-session flake (#97982): a bare scrollIntoView() smooth scroll could be dropped under load, and the script
slept a fixed 3000ms before reading state. Extract click-session-helpers.mjs:
instant centered scroll, a bounded poll-for-composer loop instead of the
fixed sleep, and correct nested CDP envelope unwrapping (the old read logged
undefined).
Intel-Mac installer docs (#99033): the Hermes-Setup.dmg bootstrap installer
is built for Apple Silicon only, so Intel Macs hit "not supported on this
Mac". The desktop release pipeline already builds a native darwin-x64
bundle, so the docs now scope the arm64 limit to the bootstrap installer and
name the darwin-x64 bundle (or the CLI plus `hermes desktop`) as the Intel
path, in the desktop README and the platform-support build-targets section.
cua-driver autostart opt-in (#97389): Windows installs registered the
cua-driver-serve scheduled task on every install, with no opt-out, and
treated the task as an install-readiness requirement. Gate the
install-ready check and _repair_cua_driver_autostart_windows on the new
computer_use.autostart config key (default false = on-demand, fails
closed), extract the registration PowerShell into a testable helper, and
document the opt-in (EN + zh-Hans). Windows-only code path: unit tests
cover the registration args and the config gate; live Windows
verification pending.
Importing a script from `node -e` leaves process.argv[1] undefined, and
pathToFileURL(undefined) throws on import. The bootstrap installer's
signing step imports batch-sign-binaries.mjs this way, and it crashed
when that pulled in sanitize-pe-signatures.mjs.
User installs failed with 'resvg-py is missing' because the web/desktop
source builds rendered icons on whatever python was on PATH. The default
brand outputs are now committed; source_build, apps/desktop build.mjs and
the npm/docusaurus pre-hooks consume them directly. Flavored release
bundles (canary/commit) still render into their own product dir.
icons-freshness-check now regenerates and fails on any byte diff.
side-by-side.windows.test.mjs copies desktop_prepare.py into a temp
source tree but not what it imports (scripts.releases.versioning ->
semver, hermes_cli.update_channel -> pm), so on win32 the channel
request validation in product-identity.cjs dies with
ModuleNotFoundError before any packing. The test is skipped off
Windows, which is why no CI lane reported it. Copy the package trees,
matching channel-build-version.test.ts.
The fixture imports pm and scripts.bundles, which only the prepared
runtime provides. Falling back to py/python3 on PATH failed later with
an unrelated ImportError; fail up front with a clear message instead.
- assert-dist-built now parses every emitted dist/assets/*.js chunk as an
ES module (node --input-type=module --check via spawnSync) before the
build reports success
- a silent bundler output loss (observed twice: a 10-byte identifier token
missing from the main chunk) previously shipped a syntactically invalid
bundle that white-screens Electron with Uncaught SyntaxError
- the loud failure feeds the existing update-path honest-retry and
stage-and-swap, so a corrupted build retries instead of shipping
- vitest coverage: invalid chunk fails with the chunk name in the error,
valid chunks (incl. import.meta / template literals) still pass
Fixes#105184
Conflicts:
- hermes_bootstrap.py: main calls install_never_free_environ() in the
apply-on-import block right after the console fixes, where pm-clean runs its
PM block (activation, relaunch, environ writes) instead of
activate_durable_lazy_target(). It now runs ahead of the whole PM block,
main's order, so the glibc < 2.41 guard is in before anything writes
os.environ.
- tests/test_hermes_bootstrap.py: pm-clean dissolved the entry-point class and
dropped its source-reading test; main's new
test_library_imports_of_dual_use_entry_modules_stay_side_effect_free lands
as a module-level function.
Every rung of the macOS SDK resolver is a read: a failing xcode-select, an
SDKROOT that names no installed SDK, or a bare directory posing as one falls
to the next rung, ending in the xcrun selection the builders used before.
An unusable SDKROOT is reported on stderr and ignored, which matches how
`xcrun --sdk macosx` treated it. SDKSettings.plist proves a directory is an
SDK, since xcrun accepts any existing path.
Native coverage builds both universal helpers with a stale SDKROOT, a plain
directory as SDKROOT, and an older installed SDK when the host has one.
Resolve SDKROOT through xcrun before passing a sysroot to clang. Exercise both real universal helper builds with default, absolute and named SDK selection, and retain resolver precedence and fallback coverage.
`xcrun --sdk macosx` resolves to the highest-versioned SDK installed, not the
one the active toolchain ships with. On a host whose SDKs outrank its Command
Line Tools (e.g. MacOSX27.0.sdk alongside CLT 26.6), the .tbd stubs declare
architectures the linker cannot parse, so every native helper fails to link
and the desktop build dies at the `desktop` stage.
The comment added for #113708 assumed `--sdk macosx` names the toolchain's own
default SDK; it does not. Resolve the MacOSX.sdk symlink under the active
developer dir instead, which is the SDK that toolchain actually pairs with, and
honour SDKROOT so CI and packagers can pin their own.
The two native tests that compile fixtures inline hit the same wall, so they
take the shared helper too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Conflict resolutions and semantic fixups:
- utils.py / hermes_yaml.py: main widened ruamel's round-trip emitter so a long
double-quoted scalar is never folded after an escaped backslash. pm-clean builds
every rt emitter through hermes_yaml.roundtrip_yaml(), so the width lives there
(ROUNDTRIP_YAML_WIDTH moves with it); xai_retirement imports it from hermes_yaml.
- hermes_cli/banner.py: keep pm-clean's removal of the banner update check. Main's
GIT_NO_LAZY_FETCH fix for it applies to its replacement, source_check: every
read-only probe (source_git_env) now refuses promisor lazy fetches, and the
partial-clone test targets that probe (red without the flag).
- .github/workflows/tests.yml: keep setup-pm; main's uv pin bump does not apply.
Main's WAL-capable SQLite gates are kept, run against $HERMES_PYTHON (the
PM-pinned interpreter, SQLite 3.53.1). The e2e step takes main's
--include-integration invocation.
- apps/desktop: package.json has no build block here, so main's macOS locale-marker
restore joins the darwin branch of the existing after-pack.mjs, and its test
loads the hook from electron-builder.config.cjs and imports PlatformPackager
from app-builder-lib's root (electron-builder 27 exports no ./out paths). The
win32 row is dropped: this hook sanitizes and signs PE trees on win32 by design.
- reconciliation.ts: main's rowId hydration (#119326) was merged into the first of
pm-clean's split helpers only; the resolver is now one helper both halves use.
- en.ts: both sides' keys kept. tests/tools/test_lazy_deps.py stays deleted.
- Tests main added with `import yaml` use hermes_yaml, like the rest of the tree.
Adapt #93931 to the current packaging lifecycle with real packager paths.
Retain the non-blocking restore from 0fbb1bc337539902d1132af4a02412b52e73d6ed,
exclude Chromium gender packs, and leave Windows stamping in afterExtract.
(cherry picked from commit c37a15c2fe5665081e7c9e6bfbe93a4c2f3aadfe)
Co-authored-by: brooklyn! <brooklyn.bb.nicholson@gmail.com>
Change-detectors, tautologies, source-reading tests, redundant duplicates,
mock-echo tests and dead/unrunnable tests. Per-test rationale in the lane
ledger (category + reason for every removal).
Change-detectors, tautologies, source-reading tests, redundant duplicates,
mock-echo tests and dead/unrunnable tests. Per-test rationale in the lane
ledger (category + reason for every removal).
The Windows HUD helper is compiled /platform:anycpu with the in-box csc. IL-only
assemblies carry COFF machine 0x14c, so audit-bundle-arch flagged it as ia32 on
win32-x64 and win32-arm64. The CLR JITs it to the host arch; only
32BITREQUIRED/32BITPREFERRED pin it to x86, and those still fail the audit.
The macOS digest-order test emitted the strict PM failure from its expected
negative case into the shared Vitest log. That traceback looked like a second
packaging failure even though the test passed.
Run corrupt and missing fact checks in a captured child process. Keep the PM
reader strict, verify both errors, and retain the real builder ordering proof
for valid payload facts.
Windows VERSIONINFO and the MSIX package version were two derivations of
one fact, and the sideload one counted minutes since the last stable, which
overflows a 16-bit field after 45 days. Both now come from
storePackageVersionAt's year.hourOfYear.secondOfHour.0, so a later build
always sorts above an earlier one and the cap has nothing left to cap.
before-build.mjs builds the msix-extensions.xml fragment and the hidden
CLI <Application> entries from string templates, interpolating the
display name and the payload-declared launcher stems raw. A value with
`&`, `<` or `"` would corrupt the manifest makeappx reads (an opaque
0x80080204 at best, a differently named alias at worst). Every
interpolated attribute now goes through xmlAttribute().
Merge origin/main at 8e806ae1b2. Keep native helper compilation in
prepareDesktopNativeDependencies and keep bundling/beforePack consume-only.
Bind helper sources and headers into preparation identities and cache keys;
copy admitted executable resources beside node_modules and preserve signing
semantics in product freshness checks.
Verified desktop typecheck, focused native/packaging/UI and gateway/cache
tests, and the real Linux preparation/copy/Xvfb execution path. Incoming
upstream anti-slop findings remain unchanged; no baseline was raised.
- check_no_tmp_literals: resolve scratch via tempfile/os.tmpdir; the termux
container mount point is one marked variable per script
- ruff TID251: desktop E2E fixtures may reach PM internals like tests do;
the pm.runtime_stage ban message no longer names a module that never existed
- auth_codex: build the capped httpx stream subclass on first use so importing
hermes_cli.auth_codex no longer forces httpx (the lazy proxy in auth_constants
was defeated by a module-scope base class; broke lanes without httpx)
- desktop-smoke: launchApp is a parameter; the bundle-env test substitutes a
refusing launcher instead of letting Playwright spawn a dying binary
(3 unhandled rejections failed the tests-js lane)
Resolved toward the branch: PM provisions uv/python (main's install.ps1 uv-shim
salvage + its test and workflow steps dropped), the shim re-exec stays retired,
package.json carries no electron-builder block (afterExtract identity stamp wired
into electron-builder.config.cjs instead; after-pack.mjs keeps signing only),
Desktop workspace-deps helpers stay retired. Main's scratch-dir bootstrap
(export_scratch_tmp_env) is taken and re-run after profile resolution.
Throwaway HERMES_HOME, perf JSON/cpuprofile outputs and typing-lag profiles now land in the Hermes scratch dir; the CONTRIBUTING anti-pattern mention keeps its literal with a no-tmp marker.
Eval probes wrote fixtures, receipts and evidence to hard-coded /tmp paths and
two live A/B tasks literally instructed the model to work in /tmp. They now
derive locations from tempfile.gettempdir() / os.tmpdir() (env overrides kept),
usage examples use relative output names, and the desktop e2e screenshot dirs,
perf scripts and the short-session repro fixture stop naming /tmp. Also adds
the explicit encoding= the windows-footgun check wants in the touched files.
An interrupted extract leaves node_modules/get-windows without package.json
and npm never revisits an existing directory, so the tree stayed broken on
every later update until a manual `npm install get-windows`. Delete such a
dir (workspace hoist or app-local copy) in _install_desktop_workspace_deps
before npm runs so the same update re-extracts it; the staging repair hint
now points at `hermes desktop --force-build` instead of the manual install.
Also drops the unused `exists` injection on findHalfInstalledGetWindowsDir
and the stale "exported for tests" note on missingGetWindowsWarning.
The unresolvable-package case already degraded, but a half-extracted install
(#90829) that keeps package.json while losing lib/binding (win32) or the
macOS helper (darwin) still threw from stageGetWindowsInto and before-pack
rethrew, so the Desktop rebuild died on the optional dep anyway. Stage the
fail-soft JS surface without a binding on win32 (the win32-arm64 precedent),
skip staging on darwin without the helper, and treat a failing native
installer the same way; the runtime reports read_window_below as unavailable
in every one of those states. The classify gate still refuses a present
binary compiled for the wrong platform.
Follow-up to the cherry-picked #109251 (which stops a missing optional
get-windows from killing `npm run build` on win32-x64/darwin):
- The reporter's install (#90829) was not "npm skipped an optional dep" but a
Windows in-place update interrupted by a running Desktop/gateway
(TAR_ENTRY_ERROR): node_modules/get-windows exists with its binding but no
package.json, so require.resolve fails while npm never revisits the
directory. Degrading silently would leave read_window_below dead forever.
`findHalfInstalledGetWindowsDir` walks the same node_modules ancestors
require.resolve does; when the dir is there the warning names it and the
repair (`npm install get-windows --save-exact` in apps/desktop, then
`hermes desktop --force-build`).
- Warning text lives in `missingGetWindowsWarning` (pure, exported) and the
locator is injectable, so tests assert behaviour instead of source text.
- Tests: the old per-platform "fails when absent" cases are replaced by one
every-platform degrade invariant and one half-install → repair-hint case
(both red on origin/main). Docs: desktop.md build-troubleshooting note.
Follow-up to the salvaged #106846 commit (@JoaoMarcos44):
- after-extract.mjs: spell out WHY the stamp moved (electron-builder's
beforeCopyExtraFiles rebuilds the PE with resedit for the ELECTRONASAR
resource; rcedit then cannot commit to that exe, deterministically —
#105629), and why disableAsarIntegrity was not taken.
- after-extract.test.mjs: two invariants — the hook wiring (afterExtract set,
afterPack unset, ASAR integrity still on) and the stamp target
(electron.exe on win32, nothing on other platforms). Red on origin/main.
- set-exe-identity.mjs / scripts/install.ps1: comments still named the
afterPack hook / after-pack.mjs.