Bug Description
Summary
hermes update runs npm install --silent as part of its Node.js dependency update step. This allows npm to re-resolve the dependency graph and rewrite package-lock.json, leaving a dirty working tree after every update.
For a deployment/update path, the correct command is npm ci, which installs exactly from the committed lockfile without mutating it.
Context
Observed on Ubuntu 24.04 with npm 10.x after a normal hermes update run.
The dirty diff added @askjo/camoufox-browser transitive dependencies to package-lock.json,
suggesting the committed lockfile was not fully consistent with package.json at that point.
npm ci would have surfaced this inconsistency immediately rather than silently rewriting the file.
Steps to Reproduce
cd ~/.hermes/hermes-agent
git status # clean
hermes update
git status # package-lock.json now modified
git diff --stat -- package-lock.json
Expected Behavior
Expected: working tree remains clean after hermes update
Actual: package-lock.json is rewritten with ~2000+ line diff due to dependency re-resolution
Actual Behavior
cd ~/.hermes/hermes-agent
git status # clean
hermes update
git status
modified: package-lock.json
Affected Component
Setup / Installation, Other
Messaging Platform (if gateway-related)
No response
Operating System
Ubuntu 24.04
Python Version
3.11.15
Hermes Version
Hermes Agent v0.6.0 (2026.3.30)
Relevant Logs / Traceback
Root Cause Analysis (optional)
In hermes_cli/main.py around lines 3027–3032:
if (PROJECT_ROOT / "package.json").exists():
import shutil
if shutil.which("npm"):
print("→ Updating Node.js dependencies...")
subprocess.run(["npm", "install", "--silent"], cwd=PROJECT_ROOT, check=False)
npm install re-resolves the dependency graph and may rewrite package-lock.json.
Proposed Fix (optional)
Proposed fix
Replace:
subprocess.run(["npm", "install", "--silent"], cwd=PROJECT_ROOT, check=False)
With:
subprocess.run(["npm", "ci", "--silent"], cwd=PROJECT_ROOT, check=False)
npm ci:
- Installs exactly from
package-lock.json
- Does not mutate the lockfile
- Is the standard command for reproducible installs in CI/CD and deployment contexts
- Will fail fast if
package-lock.json is inconsistent with package.json, which is the correct behaviour (surface the inconsistency rather than silently mutate)
It is important that the working package-lock.json be committed
Are you willing to submit a PR for this?
Bug Description
Summary
hermes updaterunsnpm install --silentas part of its Node.js dependency update step. This allows npm to re-resolve the dependency graph and rewritepackage-lock.json, leaving a dirty working tree after every update.For a deployment/update path, the correct command is
npm ci, which installs exactly from the committed lockfile without mutating it.Context
Observed on Ubuntu 24.04 with npm 10.x after a normal
hermes updaterun.The dirty diff added
@askjo/camoufox-browsertransitive dependencies topackage-lock.json,suggesting the committed lockfile was not fully consistent with
package.jsonat that point.npm ciwould have surfaced this inconsistency immediately rather than silently rewriting the file.Steps to Reproduce
cd ~/.hermes/hermes-agent
git status # clean
hermes update
git status # package-lock.json now modified
git diff --stat -- package-lock.json
Expected Behavior
Expected: working tree remains clean after
hermes updateActual:
package-lock.jsonis rewritten with ~2000+ line diff due to dependency re-resolutionActual Behavior
cd ~/.hermes/hermes-agent
git status # clean
hermes update
git status
modified: package-lock.json
Affected Component
Setup / Installation, Other
Messaging Platform (if gateway-related)
No response
Operating System
Ubuntu 24.04
Python Version
3.11.15
Hermes Version
Hermes Agent v0.6.0 (2026.3.30)
Relevant Logs / Traceback
Root Cause Analysis (optional)
In
hermes_cli/main.pyaround lines 3027–3032:npm installre-resolves the dependency graph and may rewritepackage-lock.json.Proposed Fix (optional)
Proposed fix
Replace:
With:
npm ci:package-lock.jsonpackage-lock.jsonis inconsistent withpackage.json, which is the correct behaviour (surface the inconsistency rather than silently mutate)It is important that the working package-lock.json be committed
Are you willing to submit a PR for this?