hermes-agent/nix/devShell.nix
Siddharth Balyan 3ca0ef7e3f
fix(nix): hashless npm deps via importNpmLock (#48883)
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
9eb0bcd6 ("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 9eb0bcd6;
- 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>
2026-06-19 13:57:12 +05:30

40 lines
1.4 KiB
Nix

# nix/devShell.nix — Dev shell that delegates setup to each package
#
# Each npm workspace package exposes passthru.packageJsonPath (e.g.
# "ui-tui/package.json"). This file collects them all and passes the
# list to mkNpmDevShellHook, which stamps all package.jsons at once,
# then runs a single `npm i --package-lock-only` if any changed and
# `npm ci` if the lockfile changed.
{ ... }:
{
perSystem =
{ pkgs, self', ... }:
let
packages = builtins.attrValues self'.packages;
hermesNpmLib = self'.packages.default.passthru.hermesNpmLib;
# Collect all packageJsonPath values from npm workspace packages.
npmPackageJsonPaths = builtins.filter (p: p != null) (
map (p: p.passthru.packageJsonPath or null) packages
);
# Non-npm packages may have their own devShellHook (e.g. hermes-agent
# stamps pyproject.toml + uv.lock for Python venv setup).
nonNpmHooks = map (p: p.passthru.devShellHook or "") packages;
combinedNonNpm = pkgs.lib.concatStringsSep "\n" (builtins.filter (h: h != "") nonNpmHooks);
in
{
devShells.default = pkgs.mkShell {
inputsFrom = packages;
packages = with pkgs; [
uv
];
shellHook = ''
echo "Hermes Agent dev shell"
${combinedNonNpm}
${hermesNpmLib.mkNpmDevShellHook npmPackageJsonPaths}
echo "Ready. Run 'hermes' to start."
'';
};
};
}