34eb1aaa9a
`npm install --silent` (used by `_build_web_ui` and `_update_node_dependencies`) silently rewrites package-lock.json on npm ≥ 10 (strips "peer": true etc.), leaving the working tree dirty after every `hermes update`. The next update then detects the dirty lockfile and stashes it — producing a trail of hermes-update-autostash entries for web/package-lock.json, ui-tui/package-lock.json, and root package-lock.json. Switch to `npm ci` (strict, lockfile-preserving) via a new `_run_npm_install_deterministic` helper that falls back to `npm install` when the lockfile is missing or out of sync (WIP forks). Verified locally: all three lockfiles stay byte-identical after the real _build_web_ui / _update_node_dependencies run twice back-to-back. Fallback path tested with a deliberately out-of-sync lockfile and a no-lockfile case.