Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,10 @@ jobs:

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
node-version: 22
cache: npm
cache-dependency-path: website/package-lock.json

- name: grab npm 12
run: |
npm i -g npm@12

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/docs-site-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@ jobs:

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
node-version: 22
cache: npm
cache-dependency-path: website/package-lock.json

- name: grab npm 12
run: |
npm i -g npm@12

- name: Install website dependencies
uses: ./.github/actions/retry
with:
Expand Down
17 changes: 6 additions & 11 deletions .github/workflows/e2e-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,8 @@ jobs:
# ── Node ───────────────────────────────────────────────────────────
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
node-version: 22
cache: npm

- name: grab npm 12
run: |
npm i -g npm@12

# Full npm ci (not --ignore-scripts): electron's postinstall
# downloads the binary we launch, and node-pty's native build is
# needed for the terminal pane.
Expand All @@ -61,7 +56,7 @@ jobs:
# fetching a manifest from raw.githubusercontent.com on EVERY job —
# a transient fetch failure fails the whole job (2026-07-28 slice-5
# incident). Pinned, the binary downloads directly; no manifest hop.
version: '0.9.28'
version: "0.9.28"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
Expand Down Expand Up @@ -111,11 +106,11 @@ jobs:
npx playwright test --reporter=list
fi
env:
CI: 'true'
CI: "true"
# Ensure no real API keys leak into the test env.
OPENROUTER_API_KEY: ''
OPENAI_API_KEY: ''
NOUS_API_KEY: ''
OPENROUTER_API_KEY: ""
OPENAI_API_KEY: ""
NOUS_API_KEY: ""

# ── Save updated baselines to cache (main only) ───────────────────
- name: Save updated baselines to cache
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/js-autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,9 @@ jobs:

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
node-version: 22
cache: npm

- name: grab npm 12
run: |
npm i -g npm@12

# --ignore-scripts: eslint only needs TS sources + eslint packages.
- uses: ./.github/actions/retry
with:
Expand Down
14 changes: 2 additions & 12 deletions .github/workflows/js-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
node-version: 22
cache: npm

- name: grab npm 12
run: |
npm i -g npm@12

- uses: ./.github/actions/retry
with:
command: npm ci --ignore-scripts
Expand Down Expand Up @@ -66,13 +61,8 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 26
node-version: 22
cache: npm

- name: grab npm 12
run: |
npm i -g npm@12

- uses: ./.github/actions/retry
with:
command: npm ci
Expand Down
51 changes: 0 additions & 51 deletions .npmrc

This file was deleted.

1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

1 change: 0 additions & 1 deletion .python-version

This file was deleted.

33 changes: 15 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ RUN apt-get -o Acquire::Retries=3 update && \
make install

FROM ghcr.io/astral-sh/uv:0.11.6-python3.13-trixie@sha256:b3c543b6c4f23a5f2df22866bd7857e5d304b67a564f4feab6ac22044dde719b AS uv_source
# Node 26 source stage. Debian trixie's bundled nodejs is pinned to 20.x
# which reached EOL in April 2026 — we copy node + npm from the upstream
# node:26 image instead (Hermes pins its toolchain to Node 26 everywhere).
# Bookworm-based slim image used so the produced binary links
# against glibc 2.36, which runs cleanly on our Debian 13 (trixie, glibc
# 2.41) runtime. Bumping to a new Node major is a one-line ARG change; see
# #4977.
FROM node:26-bookworm-slim@sha256:9e6f9357d371591e32ab6f2d8a26d63bdd0d17c29eee3f4f3e7e454d9634bf73 AS node_source
# Node 22 LTS source stage. Debian trixie's bundled nodejs is pinned to 20.x
# which reached EOL in April 2026 — we copy node + npm + corepack from the
# upstream node:22 image instead so we can stay on a supported LTS without
# waiting for Debian 14 (forky, ~mid-2027). Bookworm-based slim image used
# so the produced binary links against glibc 2.36, which runs cleanly on
# our Debian 13 (trixie, glibc 2.41) runtime. Bumping to a new Node major
# is a one-line ARG change; see #4977.
FROM node:22-bookworm-slim@sha256:7af03b14a13c8cdd38e45058fd957bf00a72bbe17feac43b1c15a689c029c732 AS node_source
FROM debian:13.4

# Disable Python stdout buffering to ensure logs are printed immediately.
Expand All @@ -70,7 +70,7 @@ ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright
# hermes process, the dashboard, and per-profile gateways.
RUN apt-get -o Acquire::Retries=3 update && \
apt-get -o Acquire::Retries=3 install -y --no-install-recommends \
ca-certificates curl iputils-ping python3 python-is-python3 ripgrep ffmpeg gcc g++ make cmake python3-dev python3-venv libffi-dev libolm-dev libatomic1 procps git openssh-client docker-cli xz-utils && \
ca-certificates curl iputils-ping python3 python-is-python3 ripgrep ffmpeg gcc g++ make cmake python3-dev python3-venv libffi-dev libolm-dev procps git openssh-client docker-cli xz-utils && \
rm -rf /var/lib/apt/lists/*

# Prefer the fixed SQLite over Debian's vulnerable libsqlite3.so.0. Keep the
Expand Down Expand Up @@ -151,20 +151,17 @@ RUN useradd -u 10000 -m -d /opt/data hermes

COPY --chmod=0755 --from=uv_source /usr/local/bin/uv /usr/local/bin/uvx /usr/local/bin/

# Node 26: copy the node binary plus the bundled npm JS install from the
# upstream image. npm and npx are recreated as symlinks because they're
# symlinks in the source image (and need to live on PATH).
#
# No corepack: Node unbundled it upstream, so node:26 ships only npm in
# /usr/local/lib/node_modules. Nothing here needs it — no package.json
# declares a `packageManager`, and no build step shells out to yarn or pnpm.
#
# Node 22 LTS: copy the node binary plus the bundled npm + corepack JS
# installs from the upstream image. npm and npx are recreated as symlinks
# because they're symlinks in the source image (and need to live on PATH).
# See node_source stage at the top of the file for the version-bump
# rationale (#4977).
COPY --chmod=0755 --from=node_source /usr/local/bin/node /usr/local/bin/
COPY --from=node_source /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/npm
COPY --from=node_source /usr/local/lib/node_modules/corepack /usr/local/lib/node_modules/corepack
RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx && \
ln -sf /usr/local/lib/node_modules/corepack/dist/corepack.js /usr/local/bin/corepack

WORKDIR /opt/hermes

Expand Down
8 changes: 2 additions & 6 deletions agent/lsp/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from typing import Any, Dict, Optional

from hermes_cli._subprocess_compat import windows_hide_flags
from hermes_constants import find_node_executable

logger = logging.getLogger("agent.lsp.install")

Expand Down Expand Up @@ -250,12 +249,9 @@ def _install_npm(
peer deps that npm doesn't auto-pull (typescript-language-server
needs ``typescript`` next to it; intelephense ships standalone).
"""
# Managed npm first: $HERMES_HOME/node is not on an arbitrary process's
# PATH, so a bare which() misses the Node that Hermes installed and
# reports "npm not on PATH" on a machine that has a perfectly good one.
npm = find_node_executable("npm")
npm = shutil.which("npm")
if npm is None:
logger.info("[install] cannot install %s: no usable npm found", pkg)
logger.info("[install] cannot install %s: npm not on PATH", pkg)
return None
staging = hermes_lsp_bin_dir().parent # <HERMES_HOME>/lsp/
install_targets = [pkg] + list(extra_pkgs or [])
Expand Down
60 changes: 34 additions & 26 deletions apps/bootstrap-installer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,41 @@
"fix": "npm run lint:fix"
},
"dependencies": {
"@nous-research/ui": "0.18.2",
"@tailwindcss/typography": "0.5.20",
"@tailwindcss/vite": "4.3.3",
"@tauri-apps/api": "2.11.1",
"@tauri-apps/plugin-dialog": "2.7.1",
"@tauri-apps/plugin-opener": "2.5.4",
"@tauri-apps/plugin-process": "2.3.1",
"@tauri-apps/plugin-shell": "2.3.5",
"@vscode/codicons": "0.0.45",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"katex": "0.16.47",
"lucide-react": "0.577.0",
"nanostores": "1.4.0",
"radix-ui": "1.6.7",
"react": "19.2.7",
"react-dom": "19.2.7",
"tailwind-merge": "3.6.0",
"tailwindcss": "4.3.3",
"tw-shimmer": "0.4.12"
"@nous-research/ui": "0.16.0",
"@tailwindcss/vite": "^4.2.4",
"@tailwindcss/typography": "^0.5.19",
"@tauri-apps/api": "^2.0.0",
"@tauri-apps/plugin-dialog": "^2.0.0",
"@tauri-apps/plugin-opener": "^2.0.0",
"@tauri-apps/plugin-process": "^2.0.0",
"@tauri-apps/plugin-shell": "^2.0.0",
"@vscode/codicons": "^0.0.45",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"katex": "^0.16.45",
"lucide-react": "^0.577.0",
"nanostores": "^1.3.0",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.1",
"tw-shimmer": "^0.4.11"
},
"devDependencies": {
"@tauri-apps/cli": "2.11.4",
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@vitejs/plugin-react": "6.0.3",
"typescript": "6.0.3",
"vite": "8.2.0"
"@eslint/js": "^9.39.4",
"@tauri-apps/cli": "^2.0.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.2",
"eslint": "^9.39.4",
"eslint-plugin-perfectionist": "^5.9.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-unused-imports": "^4.4.1",
"globals": "^17.4.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.56.1",
"vite": "^8.0.16"
}
}
Loading
Loading