Skip to content

fix(nix): hashless npm deps via importNpmLock (salvage #48213) - #48883

Merged
alt-glitch merged 1 commit into
mainfrom
salvage/48213-importnpmlock
Jun 19, 2026
Merged

fix(nix): hashless npm deps via importNpmLock (salvage #48213)#48883
alt-glitch merged 1 commit into
mainfrom
salvage/48213-importnpmlock

Conversation

@alt-glitch

Copy link
Copy Markdown
Collaborator

Salvage of #48213 by @ak2k, cherry-picked onto current main (authorship preserved) and verified end-to-end.

What

Replace fetchNpmDeps + a hand-maintained npmDepsHash with pkgs.importNpmLock.importNpmLock { npmRoot = src; } and npmConfigHook = pkgs.importNpmLock.npmConfigHook. Removes npmDepsFetcherVersion, the patchPhase newline/diff-wrapper hack, the entire mkFixLockfiles builder, and the .#fix-lockfiles package output.

Why

The single shared npmDepsHash is not portable across nixpkgs versions: fetchNpmDeps/prefetch-npm-deps ships in nixpkgs, so a flake consumer using hermes-agent.inputs.nixpkgs.follows = "nixpkgs" builds the deps FOD with their nixpkgs and gets a different hash than the committed one — a hard failure even when the hash is "correct" for the repo's pinned nixpkgs. (This is what broke a downstream NixOS consumer right after #48457 fixed the stale-hash; their newer nixos-unstable produced a different FOD hash.) importNpmLock resolves each package from the lockfile's own integrity field, so package-lock.json is the single source of truth and there is no separate hash to drift — across lockfile changes or nixpkgs versions.

Verification

  • Build matrixdefault, tui, web, desktop built green under both the repo's pinned nixpkgs and a downstream consumer's newer nixos-unstable (9ae611a, 2026-06-10). importNpmLock's npmConfigHook confirmed running for tui/web/desktop.
  • NixOS VM boot test — a consumer flake (hermes-agent as input + nixpkgs.follows) boots a VM with services.hermes-agent.enable; the gateway reaches Active: active (running) with no ModuleNotFoundError/ImportError. Container-mode (podman) system closure also builds.
  • Adversarial reviewimportNpmLock { npmRoot = src; } is the correct API (package/packageLock default from npmRoot); dropping npmDepsFetcherVersion is safe; removing the patchPhase is correct (importNpmLock's hook overwrites the lockfile rather than byte-diffing it); no dangling references to the removed fix-lockfiles/npmDepsHash machinery anywhere in the repo; mkNpmDevShellHook single-arg call site updated.

Notes

  • Unrelated pre-existing bug found while running nix flake check: the extraPythonPackages override path in nix/hermes-agent.nix has a makeWrapper line-continuation bug (--suffix PYTHONPATH loses its continuation when the optional HERMES_REVISION line is empty, e.g. self.rev == null). Not touched here — will be a separate PR.

Closes #48213.

The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to
package-lock.json that doesn't also refresh that hash breaks the bundled
hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no
nix CI catches it — the workflow that ran fix-lockfiles was removed in
9eb0bcd ("change(ci): rip out nix ci for now").

Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each
package from the lockfile's own integrity hashes, so package-lock.json is the
single source of truth and there is no separate hash to drift.

This also removes:

- the fix-lockfiles checker/refresher and its devShell wiring — it existed
  only to keep npmDepsHash in sync, so it is dead once the hash is gone, and
  its sole CI consumer was already removed in 9eb0bcd;
- the patchPhase that normalized lockfile trailing newlines — importNpmLock's
  npmConfigHook overwrites the lockfile rather than diffing it, so the
  normalization is unnecessary.

npm-lockfile-fix is retained: importNpmLock requires an integrity-complete
lockfile, which that tool guarantees when the lockfile is regenerated.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: salvage/48213-importnpmlock vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11048 on HEAD, 11048 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5780 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working area/nix Nix flake, NixOS module, container packaging P1 High — major feature broken, no workaround labels Jun 19, 2026
@alt-glitch
alt-glitch merged commit 3ca0ef7 into main Jun 19, 2026
35 checks passed
@alt-glitch
alt-glitch deleted the salvage/48213-importnpmlock branch June 19, 2026 08:27
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to
package-lock.json that doesn't also refresh that hash breaks the bundled
hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no
nix CI catches it — the workflow that ran fix-lockfiles was removed in
42ec9f0 ("change(ci): rip out nix ci for now").

Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each
package from the lockfile's own integrity hashes, so package-lock.json is the
single source of truth and there is no separate hash to drift.

This also removes:

- the fix-lockfiles checker/refresher and its devShell wiring — it existed
  only to keep npmDepsHash in sync, so it is dead once the hash is gone, and
  its sole CI consumer was already removed in 42ec9f0;
- the patchPhase that normalized lockfile trailing newlines — importNpmLock's
  npmConfigHook overwrites the lockfile rather than diffing it, so the
  normalization is unnecessary.

npm-lockfile-fix is retained: importNpmLock requires an integrity-complete
lockfile, which that tool guarantees when the lockfile is regenerated.

Co-authored-by: ak2k <19240940+ak2k@users.noreply.github.com>
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to
package-lock.json that doesn't also refresh that hash breaks the bundled
hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no
nix CI catches it — the workflow that ran fix-lockfiles was removed in
451af2d ("change(ci): rip out nix ci for now").

Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each
package from the lockfile's own integrity hashes, so package-lock.json is the
single source of truth and there is no separate hash to drift.

This also removes:

- the fix-lockfiles checker/refresher and its devShell wiring — it existed
  only to keep npmDepsHash in sync, so it is dead once the hash is gone, and
  its sole CI consumer was already removed in 451af2d;
- the patchPhase that normalized lockfile trailing newlines — importNpmLock's
  npmConfigHook overwrites the lockfile rather than diffing it, so the
  normalization is unnecessary.

npm-lockfile-fix is retained: importNpmLock requires an integrity-complete
lockfile, which that tool guarantees when the lockfile is regenerated.

Co-authored-by: ak2k <19240940+ak2k@users.noreply.github.com>
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to
package-lock.json that doesn't also refresh that hash breaks the bundled
hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no
nix CI catches it — the workflow that ran fix-lockfiles was removed in
844e016 ("change(ci): rip out nix ci for now").

Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each
package from the lockfile's own integrity hashes, so package-lock.json is the
single source of truth and there is no separate hash to drift.

This also removes:

- the fix-lockfiles checker/refresher and its devShell wiring — it existed
  only to keep npmDepsHash in sync, so it is dead once the hash is gone, and
  its sole CI consumer was already removed in 844e016;
- the patchPhase that normalized lockfile trailing newlines — importNpmLock's
  npmConfigHook overwrites the lockfile rather than diffing it, so the
  normalization is unnecessary.

npm-lockfile-fix is retained: importNpmLock requires an integrity-complete
lockfile, which that tool guarantees when the lockfile is regenerated.

Co-authored-by: ak2k <19240940+ak2k@users.noreply.github.com>
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to
package-lock.json that doesn't also refresh that hash breaks the bundled
hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no
nix CI catches it — the workflow that ran fix-lockfiles was removed in
9eb0bcd ("change(ci): rip out nix ci for now").

Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each
package from the lockfile's own integrity hashes, so package-lock.json is the
single source of truth and there is no separate hash to drift.

This also removes:

- the fix-lockfiles checker/refresher and its devShell wiring — it existed
  only to keep npmDepsHash in sync, so it is dead once the hash is gone, and
  its sole CI consumer was already removed in 9eb0bcd;
- the patchPhase that normalized lockfile trailing newlines — importNpmLock's
  npmConfigHook overwrites the lockfile rather than diffing it, so the
  normalization is unnecessary.

npm-lockfile-fix is retained: importNpmLock requires an integrity-complete
lockfile, which that tool guarantees when the lockfile is regenerated.

Co-authored-by: ak2k <19240940+ak2k@users.noreply.github.com>
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to
package-lock.json that doesn't also refresh that hash breaks the bundled
hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no
nix CI catches it — the workflow that ran fix-lockfiles was removed in
9eb0bcd ("change(ci): rip out nix ci for now").

Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each
package from the lockfile's own integrity hashes, so package-lock.json is the
single source of truth and there is no separate hash to drift.

This also removes:

- the fix-lockfiles checker/refresher and its devShell wiring — it existed
  only to keep npmDepsHash in sync, so it is dead once the hash is gone, and
  its sole CI consumer was already removed in 9eb0bcd;
- the patchPhase that normalized lockfile trailing newlines — importNpmLock's
  npmConfigHook overwrites the lockfile rather than diffing it, so the
  normalization is unnecessary.

npm-lockfile-fix is retained: importNpmLock requires an integrity-complete
lockfile, which that tool guarantees when the lockfile is regenerated.

Co-authored-by: ak2k <19240940+ak2k@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/nix Nix flake, NixOS module, container packaging P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants