From adbfd66056a257d40b4936db687860b4872df1be Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 06:25:28 -0700 Subject: [PATCH 01/28] feat: add Hermes Agent LXC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds container scripts for Hermes Agent (Nous Research), a self-improving AI agent with LLM provider integration, terminal execution, web browsing, and multi-platform messaging support. Files: - ct/hermes-agent.sh - install/hermes-agent-install.sh - json/hermes-agent.json - ct/headers/hermes-agent Deviations from standard patterns (justified): 1. Uses upstream installer (curl-pipe) instead of fetch_and_deploy_gh_release: Hermes is a uv-managed Python application with complex dependency resolution, virtualenv management, and binary placement—not a single binary or tarball from GitHub Releases. 2. Dedicated 'hermes' service user (not running as root): The agent executes arbitrary terminal commands on behalf of the user. Running as root would give the AI unrestricted system access. This follows the protonmail-bridge service-user pattern for isolation. 3. Dashboard (port 9119) bound to localhost only, requiring SSH tunnel: The web UI provides admin access to an AI that can execute commands. SSH tunnel provides an authentication/authorization boundary. 4. /usr/bin/hermes shim script: The hermes CLI validates cwd permissions; running 'hermes' as root from /root fails. The shim cd's to /home/hermes and exec's as the hermes user via runuser. 5. setsid --wait wrapping of upstream installer: The upstream installer probes /dev/tty for interactive prompts even with --skip-setup; setsid detaches the controlling terminal. --- ct/headers/hermes-agent | 6 ++ ct/hermes-agent.sh | 68 ++++++++++++++++++ install/hermes-agent-install.sh | 121 ++++++++++++++++++++++++++++++++ json/hermes-agent.json | 52 ++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 ct/headers/hermes-agent create mode 100644 ct/hermes-agent.sh create mode 100644 install/hermes-agent-install.sh create mode 100644 json/hermes-agent.json diff --git a/ct/headers/hermes-agent b/ct/headers/hermes-agent new file mode 100644 index 00000000..671ec9d1 --- /dev/null +++ b/ct/headers/hermes-agent @@ -0,0 +1,6 @@ + __ __ ___ __ + / / / /__ _________ ___ ___ _____ / | ____ ____ ____ / /_ + / /_/ / _ \/ ___/ __ `__ \/ _ \/ ___/ / /| |/ __ `/ _ \/ __ \/ __/ + / __ / __/ / / / / / / / __(__ ) / ___ / /_/ / __/ / / / /_ +/_/ /_/\___/_/ /_/ /_/ /_/\___/____/ /_/ |_\__, /\___/_/ /_/\__/ + /____/ diff --git a/ct/hermes-agent.sh b/ct/hermes-agent.sh new file mode 100644 index 00000000..ef76b5e9 --- /dev/null +++ b/ct/hermes-agent.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: Stephen Chin (steveonjava) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://hermes-agent.nousresearch.com/ + +APP="Hermes Agent" +var_tags="${var_tags:-ai;automation;agent}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-4096}" +var_disk="${var_disk:-20}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -x /home/hermes/.local/bin/hermes ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + msg_info "Stopping Services" + systemctl stop hermes-dashboard + systemctl stop hermes-gateway + msg_ok "Stopped Services" + + msg_info "Updating ${APP}" + $STD env \ + HOME=/home/hermes \ + HERMES_HOME=/home/hermes/.hermes \ + /home/hermes/.local/bin/hermes update + chown -R hermes:hermes /home/hermes + msg_ok "Updated ${APP}" + + msg_info "Starting Services" + systemctl start hermes-gateway + systemctl start hermes-dashboard + msg_ok "Started Services" + msg_ok "Updated successfully!" + exit +} + +start +build_container +description + +msg_ok "Completed successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}ssh hermes@${IP}${CL}" +echo -e "${TAB}${BGN}hermes setup${CL}" +echo -e "${INFO}${YW} API Server (OpenAI-compatible):${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8642/v1${CL}" +echo -e "${INFO}${YW} API key stored at:${CL}" +echo -e "${TAB}${BGN}/home/hermes/.hermes/.env${CL}" +echo -e "${INFO}${YW} Web Dashboard (via SSH tunnel):${CL}" +echo -e "${TAB}${BGN}ssh -L 9119:localhost:9119 hermes@${IP}${CL}" +echo -e "${TAB}${BGN}Then open: http://localhost:9119${CL}" diff --git a/install/hermes-agent-install.sh b/install/hermes-agent-install.sh new file mode 100644 index 00000000..c1a67bd4 --- /dev/null +++ b/install/hermes-agent-install.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: Stephen Chin (steveonjava) +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://hermes-agent.nousresearch.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + git +msg_ok "Installed Dependencies" + +NODE_VERSION="22" setup_nodejs + +msg_info "Creating Hermes User" +useradd -m -s /bin/bash hermes +msg_ok "Created Hermes User" + +msg_info "Installing Hermes Agent" +$STD setsid --wait env \ + HOME=/home/hermes \ + PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ + bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent + +if [[ ! -x /home/hermes/.local/bin/hermes ]]; then + msg_error "Hermes binary not found after installation" + exit 1 +fi + +chown -R hermes:hermes /home/hermes +git config --system --add safe.directory /home/hermes/.hermes/hermes-agent 2>/dev/null || true +msg_ok "Installed Hermes Agent" + +msg_info "Installing Web Dashboard" +$STD runuser -u hermes -- \ + env HOME=/home/hermes VIRTUAL_ENV=/home/hermes/.hermes/hermes-agent/venv \ + /home/hermes/.local/bin/uv pip install 'hermes-agent[web,pty]' +msg_ok "Installed Web Dashboard" + +msg_info "Configuring API Server" +API_SERVER_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32) +cat </home/hermes/.hermes/.env +API_SERVER_ENABLED=true +API_SERVER_HOST=0.0.0.0 +API_SERVER_PORT=8642 +API_SERVER_KEY=${API_SERVER_KEY} +EOF +chmod 600 /home/hermes/.hermes/.env +chown hermes:hermes /home/hermes/.hermes/.env +msg_ok "Configured API Server" + +msg_info "Creating Service" +cat </etc/systemd/system/hermes-gateway.service +[Unit] +Description=Hermes Agent Gateway +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=hermes +Group=hermes +WorkingDirectory=/home/hermes +ExecStart=/home/hermes/.local/bin/hermes gateway run --replace +Environment="HERMES_HOME=/home/hermes/.hermes" +Environment="HOME=/home/hermes" +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now hermes-gateway +msg_ok "Created Service" + +msg_info "Creating Dashboard Service" +cat </etc/systemd/system/hermes-dashboard.service +[Unit] +Description=Hermes Agent Web Dashboard +After=network-online.target hermes-gateway.service +Wants=network-online.target + +[Service] +Type=simple +User=hermes +Group=hermes +WorkingDirectory=/home/hermes +ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open +Environment="HERMES_HOME=/home/hermes/.hermes" +Environment="HOME=/home/hermes" +Environment="PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +Environment="NODE_OPTIONS=--max-old-space-size=3072" +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now hermes-dashboard +msg_ok "Created Dashboard Service" + +msg_info "Creating Hermes Shim" +cat <<'EOF' >/usr/bin/hermes +#!/bin/bash +cd /home/hermes +exec runuser -u hermes -- /home/hermes/.local/bin/hermes "$@" +EOF +chmod +x /usr/bin/hermes +msg_ok "Created Hermes Shim" + +motd_ssh +customize +cleanup_lxc diff --git a/json/hermes-agent.json b/json/hermes-agent.json new file mode 100644 index 00000000..b8a7f150 --- /dev/null +++ b/json/hermes-agent.json @@ -0,0 +1,52 @@ +{ + "name": "Hermes Agent", + "slug": "hermes-agent", + "categories": [ + 20 + ], + "date_created": "2026-05-02", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 8642, + "documentation": "https://hermes-agent.nousresearch.com/docs", + "website": "https://hermes-agent.nousresearch.com", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/hermes.webp", + "description": "Self-improving AI agent by Nous Research. Connects to 15+ LLM providers, executes terminal commands, browses the web, and learns from experience. Supports 16 messaging platforms (Telegram, Discord, Slack, WhatsApp, Signal, Matrix, and more) with persistent memory and autonomous skill creation.", + "install_methods": [ + { + "type": "default", + "script": "ct/hermes-agent.sh", + "config_path": "/home/hermes/.hermes/", + "resources": { + "cpu": 2, + "ram": 4096, + "hdd": 20, + "os": "debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": "hermes", + "password": null + }, + "notes": [ + { + "text": "Warning: Hermes can execute terminal commands. The agent runs as a dedicated 'hermes' service user for isolation.", + "type": "warning" + }, + { + "text": "After container startup, SSH in as the 'hermes' user and run 'hermes setup' to configure your LLM provider (OpenRouter, Anthropic, OpenAI, Nous Portal, or custom endpoint).", + "type": "info" + }, + { + "text": "OpenAI-compatible API server available at http://:8642/v1. API key is stored in /home/hermes/.hermes/.env.", + "type": "info" + }, + { + "text": "Access the web dashboard via SSH tunnel: ssh -L 9119:localhost:9119 hermes@, then open http://localhost:9119", + "type": "info" + } + ] +} From ed9630a783bfa50dc1400f01a8cdb0f2a8bcd07a Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 08:08:23 -0700 Subject: [PATCH 02/28] fix(hermes-agent): enable secret redaction by default HERMES_REDACT_SECRETS is off by default, exposing API keys in chat output and session JSON files. Add HERMES_REDACT_SECRETS=true to the .env file created by the installer. Ref: https://github.com/NousResearch/hermes-agent/issues/17691 --- install/hermes-agent-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/hermes-agent-install.sh b/install/hermes-agent-install.sh index c1a67bd4..3a2fb520 100644 --- a/install/hermes-agent-install.sh +++ b/install/hermes-agent-install.sh @@ -52,6 +52,7 @@ API_SERVER_ENABLED=true API_SERVER_HOST=0.0.0.0 API_SERVER_PORT=8642 API_SERVER_KEY=${API_SERVER_KEY} +HERMES_REDACT_SECRETS=true EOF chmod 600 /home/hermes/.hermes/.env chown hermes:hermes /home/hermes/.hermes/.env From 16e774083f8b3caa44c5a244b7247c0298a10bf6 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 08:08:41 -0700 Subject: [PATCH 03/28] fix(hermes-agent): set UMask=0077 on systemd services The Anthropic OAuth helper writes credential files with the process default umask, resulting in 0644 permissions on sensitive files. Set UMask=0077 on both hermes-gateway and hermes-dashboard services so all files created at runtime are owner-only (0600/0700). Ref: https://github.com/NousResearch/hermes-agent/issues/11003 --- install/hermes-agent-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/hermes-agent-install.sh b/install/hermes-agent-install.sh index 3a2fb520..43be60ec 100644 --- a/install/hermes-agent-install.sh +++ b/install/hermes-agent-install.sh @@ -69,6 +69,7 @@ Wants=network-online.target Type=simple User=hermes Group=hermes +UMask=0077 WorkingDirectory=/home/hermes ExecStart=/home/hermes/.local/bin/hermes gateway run --replace Environment="HERMES_HOME=/home/hermes/.hermes" @@ -93,6 +94,7 @@ Wants=network-online.target Type=simple User=hermes Group=hermes +UMask=0077 WorkingDirectory=/home/hermes ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open Environment="HERMES_HOME=/home/hermes/.hermes" From e0aaacdb96e9a19d4a588df07d2f3f813ad35669 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 08:09:00 -0700 Subject: [PATCH 04/28] fix(hermes-agent): restrict /proc access in systemd services Hermes strips sensitive env vars from tool subprocesses, but child processes can recover them by reading /proc//environ. Add ProtectProc=invisible and ProcSubset=pid to both systemd services to hide other processes' /proc entries and limit /proc to the service's own PID namespace. Ref: https://github.com/NousResearch/hermes-agent/issues/4427 --- install/hermes-agent-install.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/install/hermes-agent-install.sh b/install/hermes-agent-install.sh index 43be60ec..781ad0d5 100644 --- a/install/hermes-agent-install.sh +++ b/install/hermes-agent-install.sh @@ -76,6 +76,8 @@ Environment="HERMES_HOME=/home/hermes/.hermes" Environment="HOME=/home/hermes" Restart=on-failure RestartSec=5 +ProtectProc=invisible +ProcSubset=pid [Install] WantedBy=multi-user.target @@ -103,6 +105,8 @@ Environment="PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sb Environment="NODE_OPTIONS=--max-old-space-size=3072" Restart=on-failure RestartSec=5 +ProtectProc=invisible +ProcSubset=pid [Install] WantedBy=multi-user.target From edf1a9604adb945d6e8870d2cb317bd05874ff2f Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 08:09:21 -0700 Subject: [PATCH 05/28] fix(hermes-agent): harden .hermes directory permissions The response_store.db and session JSON files under ~/.hermes/ are stored in plaintext and readable by any process with filesystem access. Set ~/.hermes to 0700 (owner-only) and ~/home/hermes to 0750 to restrict access to conversation history, credentials, and session data. Ref: https://github.com/NousResearch/hermes-agent/issues/7486 --- install/hermes-agent-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/hermes-agent-install.sh b/install/hermes-agent-install.sh index 781ad0d5..2aa66b41 100644 --- a/install/hermes-agent-install.sh +++ b/install/hermes-agent-install.sh @@ -56,6 +56,8 @@ HERMES_REDACT_SECRETS=true EOF chmod 600 /home/hermes/.hermes/.env chown hermes:hermes /home/hermes/.hermes/.env +chmod 750 /home/hermes +chmod 700 /home/hermes/.hermes msg_ok "Configured API Server" msg_info "Creating Service" From 06d9c62e54924f90d62c11b1d92cf293246ef2c6 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 09:45:59 -0700 Subject: [PATCH 06/28] fix(hermes-agent): rename files to match NSAPP derivation APP='Hermes Agent' produces NSAPP='hermesagent' via build.func's lowercase+strip-spaces logic. Rename ct/, install/, json/, and header files to match. --- ct/headers/{hermes-agent => hermesagent} | 0 ct/{hermes-agent.sh => hermesagent.sh} | 0 install/{hermes-agent-install.sh => hermesagent-install.sh} | 0 json/{hermes-agent.json => hermesagent.json} | 4 ++-- 4 files changed, 2 insertions(+), 2 deletions(-) rename ct/headers/{hermes-agent => hermesagent} (100%) rename ct/{hermes-agent.sh => hermesagent.sh} (100%) rename install/{hermes-agent-install.sh => hermesagent-install.sh} (100%) rename json/{hermes-agent.json => hermesagent.json} (96%) diff --git a/ct/headers/hermes-agent b/ct/headers/hermesagent similarity index 100% rename from ct/headers/hermes-agent rename to ct/headers/hermesagent diff --git a/ct/hermes-agent.sh b/ct/hermesagent.sh similarity index 100% rename from ct/hermes-agent.sh rename to ct/hermesagent.sh diff --git a/install/hermes-agent-install.sh b/install/hermesagent-install.sh similarity index 100% rename from install/hermes-agent-install.sh rename to install/hermesagent-install.sh diff --git a/json/hermes-agent.json b/json/hermesagent.json similarity index 96% rename from json/hermes-agent.json rename to json/hermesagent.json index b8a7f150..af5930a2 100644 --- a/json/hermes-agent.json +++ b/json/hermesagent.json @@ -1,6 +1,6 @@ { "name": "Hermes Agent", - "slug": "hermes-agent", + "slug": "hermesagent", "categories": [ 20 ], @@ -16,7 +16,7 @@ "install_methods": [ { "type": "default", - "script": "ct/hermes-agent.sh", + "script": "ct/hermesagent.sh", "config_path": "/home/hermes/.hermes/", "resources": { "cpu": 2, From aa975798a1630b246d71aae5622e4bb35ccc8e99 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 12:09:56 -0700 Subject: [PATCH 07/28] fix(hermesagent): correct SSH access instructions The hermes service account has no password or SSH keys and cannot be used to log in. Access is via root (standard PVE Helper Scripts pattern). Also add -fN flags to the dashboard tunnel command so it runs in the background without opening a shell session. --- ct/hermesagent.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index ef76b5e9..03045797 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -57,12 +57,12 @@ description msg_ok "Completed successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}ssh hermes@${IP}${CL}" +echo -e "${TAB}${GATEWAY}${BGN}ssh root@${IP}${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" echo -e "${INFO}${YW} API Server (OpenAI-compatible):${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8642/v1${CL}" echo -e "${INFO}${YW} API key stored at:${CL}" echo -e "${TAB}${BGN}/home/hermes/.hermes/.env${CL}" echo -e "${INFO}${YW} Web Dashboard (via SSH tunnel):${CL}" -echo -e "${TAB}${BGN}ssh -L 9119:localhost:9119 hermes@${IP}${CL}" +echo -e "${TAB}${BGN}ssh -fNL 9119:localhost:9119 root@${IP}${CL}" echo -e "${TAB}${BGN}Then open: http://localhost:9119${CL}" From 21dfffd158ca57e036a277edb8cc4f68905ec1aa Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 12:10:09 -0700 Subject: [PATCH 08/28] fix(hermesagent): correct JSON metadata - default_credentials: username null/null (no SSH login for hermes service account; access is via root like all PVE Helper Scripts) - Update setup note to reference root instead of hermes user - Update dashboard tunnel note to use root and -fNL flags --- json/hermesagent.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/json/hermesagent.json b/json/hermesagent.json index af5930a2..8e4ece5e 100644 --- a/json/hermesagent.json +++ b/json/hermesagent.json @@ -28,7 +28,7 @@ } ], "default_credentials": { - "username": "hermes", + "username": null, "password": null }, "notes": [ @@ -37,7 +37,7 @@ "type": "warning" }, { - "text": "After container startup, SSH in as the 'hermes' user and run 'hermes setup' to configure your LLM provider (OpenRouter, Anthropic, OpenAI, Nous Portal, or custom endpoint).", + "text": "After container startup, SSH in as root and run 'hermes setup' to configure your LLM provider (OpenRouter, Anthropic, OpenAI, Nous Portal, or custom endpoint).", "type": "info" }, { @@ -45,7 +45,7 @@ "type": "info" }, { - "text": "Access the web dashboard via SSH tunnel: ssh -L 9119:localhost:9119 hermes@, then open http://localhost:9119", + "text": "Access the web dashboard via SSH tunnel: ssh -fNL 9119:localhost:9119 root@, then open http://localhost:9119", "type": "info" } ] From be8d55fb8392fb00028dc369df4e1a40bea20c11 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 12:21:18 -0700 Subject: [PATCH 09/28] fix(hermesagent): pass --yes to hermes update to avoid interactive prompt hermes update prompts "Restore local changes now? [Y/n]" when run in a TTY context. --yes skips all interactive prompts. --- ct/hermesagent.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index 03045797..b9f2b5b0 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -38,7 +38,7 @@ function update_script() { $STD env \ HOME=/home/hermes \ HERMES_HOME=/home/hermes/.hermes \ - /home/hermes/.local/bin/hermes update + /home/hermes/.local/bin/hermes update --yes chown -R hermes:hermes /home/hermes msg_ok "Updated ${APP}" From 8afb18209511eb1b4faec367b002b2958e04fbac Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 2 May 2026 12:30:34 -0700 Subject: [PATCH 10/28] fix(hermesagent): shim handles hermes user invocation runuser requires root. When the hermes user calls the shim directly (e.g. via su - hermes), exec the binary directly instead. --- install/hermesagent-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 2aa66b41..9c4dcf12 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -120,7 +120,11 @@ msg_info "Creating Hermes Shim" cat <<'EOF' >/usr/bin/hermes #!/bin/bash cd /home/hermes -exec runuser -u hermes -- /home/hermes/.local/bin/hermes "$@" +if [[ "$(id -u)" -eq 0 ]]; then + exec runuser -u hermes -- /home/hermes/.local/bin/hermes "$@" +else + exec /home/hermes/.local/bin/hermes "$@" +fi EOF chmod +x /usr/bin/hermes msg_ok "Created Hermes Shim" From a0bffe7a4f6acd4f7717fb751744cb9e917f9484 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 3 May 2026 15:22:11 -0700 Subject: [PATCH 11/28] feat(hermesagent): replace shim+system-unit pattern with hermes-native user services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous approach used a /usr/bin/hermes shim to proxy commands from root to the hermes user, and a hand-crafted system-level systemd unit for the gateway. This worked for the default profile but broke down for named profiles: - hermes profile create generates an alias script in ~/.local/bin/ that calls hermes with -p . These aliases live in the hermes user's PATH, not root's, so root could not invoke them. - Maintaining parity would require per-profile shims, a watcher daemon to create/remove them, and system-unit mirrors for each profile gateway — all of which would need to stay in sync with hermes internals across updates. New approach — work with hermes, not around it: - loginctl enable-linger hermes: ensures the hermes user's systemd session starts at boot and persists without login. All user-unit gateways (default and per-profile) now survive reboots automatically. - Gateway service management delegated entirely to hermes: 'hermes gateway install' / 'hermes setup' create and enable the user unit natively. The install script no longer pre-installs the gateway; hermes prompts the user to do so at the end of 'hermes setup'. - hermes-dashboard.service remains a system unit (no native install command exists for it). Its After= no longer references hermes-gateway.service since there is no system-unit gateway to depend on. - /usr/bin/hermes shim removed. Root is guided to 'su - hermes' via a two- line /etc/profile.d/hermes-hint.sh message on login, with a one-liner to make the switch automatic. Once logged in as hermes, all hermes commands, profile aliases, and gateway management work natively. - update_script simplified: only hermes-dashboard (our unit) is stopped and restarted. hermes update --yes handles gateway service lifecycle itself. --- ct/hermesagent.sh | 3 +-- install/hermesagent-install.sh | 44 ++++++---------------------------- 2 files changed, 8 insertions(+), 39 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index b9f2b5b0..cd71e1b3 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -31,7 +31,6 @@ function update_script() { msg_info "Stopping Services" systemctl stop hermes-dashboard - systemctl stop hermes-gateway msg_ok "Stopped Services" msg_info "Updating ${APP}" @@ -43,7 +42,6 @@ function update_script() { msg_ok "Updated ${APP}" msg_info "Starting Services" - systemctl start hermes-gateway systemctl start hermes-dashboard msg_ok "Started Services" msg_ok "Updated successfully!" @@ -58,6 +56,7 @@ msg_ok "Completed successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" echo -e "${TAB}${GATEWAY}${BGN}ssh root@${IP}${CL}" +echo -e "${TAB}${BGN}su - hermes${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" echo -e "${INFO}${YW} API Server (OpenAI-compatible):${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8642/v1${CL}" diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 9c4dcf12..3e4d58bd 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -22,6 +22,7 @@ NODE_VERSION="22" setup_nodejs msg_info "Creating Hermes User" useradd -m -s /bin/bash hermes +loginctl enable-linger hermes msg_ok "Created Hermes User" msg_info "Installing Hermes Agent" @@ -60,38 +61,11 @@ chmod 750 /home/hermes chmod 700 /home/hermes/.hermes msg_ok "Configured API Server" -msg_info "Creating Service" -cat </etc/systemd/system/hermes-gateway.service -[Unit] -Description=Hermes Agent Gateway -After=network-online.target -Wants=network-online.target - -[Service] -Type=simple -User=hermes -Group=hermes -UMask=0077 -WorkingDirectory=/home/hermes -ExecStart=/home/hermes/.local/bin/hermes gateway run --replace -Environment="HERMES_HOME=/home/hermes/.hermes" -Environment="HOME=/home/hermes" -Restart=on-failure -RestartSec=5 -ProtectProc=invisible -ProcSubset=pid - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now hermes-gateway -msg_ok "Created Service" - msg_info "Creating Dashboard Service" cat </etc/systemd/system/hermes-dashboard.service [Unit] Description=Hermes Agent Web Dashboard -After=network-online.target hermes-gateway.service +After=network-online.target Wants=network-online.target [Service] @@ -116,18 +90,14 @@ EOF systemctl enable -q --now hermes-dashboard msg_ok "Created Dashboard Service" -msg_info "Creating Hermes Shim" -cat <<'EOF' >/usr/bin/hermes -#!/bin/bash -cd /home/hermes +msg_info "Configuring Login Guidance" +cat <<'EOF' >/etc/profile.d/hermes-hint.sh if [[ "$(id -u)" -eq 0 ]]; then - exec runuser -u hermes -- /home/hermes/.local/bin/hermes "$@" -else - exec /home/hermes/.local/bin/hermes "$@" + echo " Run 'su - hermes' to manage Hermes Agent and profiles." + echo " To auto-switch on login: echo 'exec su - hermes' >> /root/.bash_profile" fi EOF -chmod +x /usr/bin/hermes -msg_ok "Created Hermes Shim" +msg_ok "Configured Login Guidance" motd_ssh customize From 434e170ee3234374c0be1b4a9230e8a484f25324 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 9 May 2026 10:27:37 -0700 Subject: [PATCH 12/28] fix(hermesagent): move service details from CT footer to MOTD Trims the verbose 12-line CT footer to the standard pattern plus essential first-run setup steps. API server, API key, and dashboard SSH tunnel details are now displayed on every SSH login via /etc/profile.d/hermes-hint.sh instead. Addresses PR feedback from CrazyWolf13. --- ct/hermesagent.sh | 10 ++-------- install/hermesagent-install.sh | 10 +++++++--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index cd71e1b3..8c3ce1e9 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -52,16 +52,10 @@ start build_container description -msg_ok "Completed successfully!\n" +msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" echo -e "${TAB}${GATEWAY}${BGN}ssh root@${IP}${CL}" echo -e "${TAB}${BGN}su - hermes${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" -echo -e "${INFO}${YW} API Server (OpenAI-compatible):${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8642/v1${CL}" -echo -e "${INFO}${YW} API key stored at:${CL}" -echo -e "${TAB}${BGN}/home/hermes/.hermes/.env${CL}" -echo -e "${INFO}${YW} Web Dashboard (via SSH tunnel):${CL}" -echo -e "${TAB}${BGN}ssh -fNL 9119:localhost:9119 root@${IP}${CL}" -echo -e "${TAB}${BGN}Then open: http://localhost:9119${CL}" +echo -e "${INFO}${YW} Service details are shown on each SSH login.${CL}" diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 3e4d58bd..2f8aee7e 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -91,12 +91,16 @@ systemctl enable -q --now hermes-dashboard msg_ok "Created Dashboard Service" msg_info "Configuring Login Guidance" -cat <<'EOF' >/etc/profile.d/hermes-hint.sh +cat <<'HINT' >/etc/profile.d/hermes-hint.sh if [[ "$(id -u)" -eq 0 ]]; then echo " Run 'su - hermes' to manage Hermes Agent and profiles." - echo " To auto-switch on login: echo 'exec su - hermes' >> /root/.bash_profile" fi -EOF +LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}') +echo " API Server (OpenAI-compatible): http://${LOCAL_IP}:8642/v1" +echo " API key: /home/hermes/.hermes/.env" +echo " Dashboard: ssh -fNL 9119:localhost:9119 root@${LOCAL_IP}" +echo " then open http://localhost:9119" +HINT msg_ok "Configured Login Guidance" motd_ssh From 67d49e0b8a2115fe0adead1754d3025712a36af9 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 9 May 2026 10:30:59 -0700 Subject: [PATCH 13/28] fix(hermesagent): single-line apt install for single dependency --- install/hermesagent-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 2f8aee7e..7a6484a6 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -14,8 +14,7 @@ network_check update_os msg_info "Installing Dependencies" -$STD apt install -y \ - git +$STD apt install -y git msg_ok "Installed Dependencies" NODE_VERSION="22" setup_nodejs From 0b11ce168165e0a3e9c2dd75ed7c194b45432f0d Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sat, 9 May 2026 11:50:57 -0700 Subject: [PATCH 14/28] fix(hermesagent): add external script warning and remove redundant check Adds third-party script warning with user confirmation before running the upstream installer (install) and updater (update), matching the kasm/pihole pattern. Removes redundant binary existence check per reviewer feedback. Adds corresponding JSON warning note. --- ct/hermesagent.sh | 13 ++++++++++++- install/hermesagent-install.sh | 16 +++++++++++----- json/hermesagent.json | 4 ++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index 8c3ce1e9..3312d343 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -29,6 +29,17 @@ function update_script() { exit fi + msg_warn "WARNING: This script will run an external installer from a third-party source (https://hermes-agent.nousresearch.com/)." + msg_warn "The following code is NOT maintained or audited by our repository." + msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:" + msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ hermes update (https://hermes-agent.nousresearch.com/)" + echo + read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM + if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then + msg_error "Aborted by user. No changes have been made." + exit 10 + fi + msg_info "Stopping Services" systemctl stop hermes-dashboard msg_ok "Stopped Services" @@ -52,7 +63,7 @@ start build_container description -msg_ok "Completed Successfully!\n" +msg_ok "Completed successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" echo -e "${TAB}${GATEWAY}${BGN}ssh root@${IP}${CL}" diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 7a6484a6..2ccb0f6b 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -24,17 +24,23 @@ useradd -m -s /bin/bash hermes loginctl enable-linger hermes msg_ok "Created Hermes User" +msg_warn "WARNING: This script will run an external installer from a third-party source (https://hermes-agent.nousresearch.com/)." +msg_warn "The following code is NOT maintained or audited by our repository." +msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:" +msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://hermes-agent.nousresearch.com/install.sh" +echo +read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM +if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then + msg_error "Aborted by user. No changes have been made." + exit 10 +fi + msg_info "Installing Hermes Agent" $STD setsid --wait env \ HOME=/home/hermes \ PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent -if [[ ! -x /home/hermes/.local/bin/hermes ]]; then - msg_error "Hermes binary not found after installation" - exit 1 -fi - chown -R hermes:hermes /home/hermes git config --system --add safe.directory /home/hermes/.hermes/hermes-agent 2>/dev/null || true msg_ok "Installed Hermes Agent" diff --git a/json/hermesagent.json b/json/hermesagent.json index 8e4ece5e..061293ea 100644 --- a/json/hermesagent.json +++ b/json/hermesagent.json @@ -32,6 +32,10 @@ "password": null }, "notes": [ + { + "text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.", + "type": "warning" + }, { "text": "Warning: Hermes can execute terminal commands. The agent runs as a dedicated 'hermes' service user for isolation.", "type": "warning" From 1671917bab17a75f25067c4b54a2f5b48331c4ea Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 14:10:09 -0700 Subject: [PATCH 15/28] fix(hermesagent): move systemd env vars to EnvironmentFile --- install/hermesagent-install.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 2ccb0f6b..35d3939e 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -59,6 +59,10 @@ API_SERVER_HOST=0.0.0.0 API_SERVER_PORT=8642 API_SERVER_KEY=${API_SERVER_KEY} HERMES_REDACT_SECRETS=true +HERMES_HOME=/home/hermes/.hermes +HOME=/home/hermes +PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +NODE_OPTIONS=--max-old-space-size=3072 EOF chmod 600 /home/hermes/.hermes/.env chown hermes:hermes /home/hermes/.hermes/.env @@ -80,10 +84,7 @@ Group=hermes UMask=0077 WorkingDirectory=/home/hermes ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open -Environment="HERMES_HOME=/home/hermes/.hermes" -Environment="HOME=/home/hermes" -Environment="PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -Environment="NODE_OPTIONS=--max-old-space-size=3072" +EnvironmentFile=/home/hermes/.hermes/.env Restart=on-failure RestartSec=5 ProtectProc=invisible From 6a4c88c4cc71baf038713d216c597404ce8a65ac Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 14:10:26 -0700 Subject: [PATCH 16/28] fix(hermesagent): slim down login hint to su and dashboard tunnel only --- install/hermesagent-install.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 35d3939e..fed08bc1 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -96,18 +96,16 @@ EOF systemctl enable -q --now hermes-dashboard msg_ok "Created Dashboard Service" -msg_info "Configuring Login Guidance" +msg_info "Configuring Login Hints" cat <<'HINT' >/etc/profile.d/hermes-hint.sh if [[ "$(id -u)" -eq 0 ]]; then echo " Run 'su - hermes' to manage Hermes Agent and profiles." fi LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}') -echo " API Server (OpenAI-compatible): http://${LOCAL_IP}:8642/v1" -echo " API key: /home/hermes/.hermes/.env" echo " Dashboard: ssh -fNL 9119:localhost:9119 root@${LOCAL_IP}" echo " then open http://localhost:9119" HINT -msg_ok "Configured Login Guidance" +msg_ok "Configured Login Hints" motd_ssh customize From 9919be3dacd6a8ff3cb67e21509d0a10609f3dda Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 14:10:39 -0700 Subject: [PATCH 17/28] fix(hermesagent): show API key file location in CT footer --- ct/hermesagent.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index 3312d343..f885a3f2 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -69,4 +69,5 @@ echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" echo -e "${TAB}${GATEWAY}${BGN}ssh root@${IP}${CL}" echo -e "${TAB}${BGN}su - hermes${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" -echo -e "${INFO}${YW} Service details are shown on each SSH login.${CL}" +echo -e "${INFO}${YW} API key stored in:${CL}" +echo -e "${TAB}${BGN}/home/hermes/.hermes/.env${CL}" From 43cc3c83d27078c816de524ec448e4b50a1599fe Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 14:10:53 -0700 Subject: [PATCH 18/28] fix(hermesagent): set XDG_RUNTIME_DIR in hermes .profile for SSH access --- install/hermesagent-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index fed08bc1..c1a8e598 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -22,6 +22,7 @@ NODE_VERSION="22" setup_nodejs msg_info "Creating Hermes User" useradd -m -s /bin/bash hermes loginctl enable-linger hermes +echo 'export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"' >>/home/hermes/.profile msg_ok "Created Hermes User" msg_warn "WARNING: This script will run an external installer from a third-party source (https://hermes-agent.nousresearch.com/)." From b3faacb5e17ac66bd8eac29386f76f55aa3118db Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 15:18:31 -0700 Subject: [PATCH 19/28] fix(hermesagent): split env into /etc/default/hermes and .env; use NODE_OPTIONS from setup_nodejs --- install/hermesagent-install.sh | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index c1a8e598..2ea89a6a 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -25,6 +25,14 @@ loginctl enable-linger hermes echo 'export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"' >>/home/hermes/.profile msg_ok "Created Hermes User" +msg_info "Configuring Service Environment" +cat </etc/default/hermes +HOME=/home/hermes +PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +NODE_OPTIONS=${NODE_OPTIONS} +EOF +msg_ok "Configured Service Environment" + msg_warn "WARNING: This script will run an external installer from a third-party source (https://hermes-agent.nousresearch.com/)." msg_warn "The following code is NOT maintained or audited by our repository." msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:" @@ -37,12 +45,15 @@ if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then fi msg_info "Installing Hermes Agent" -$STD setsid --wait env \ - HOME=/home/hermes \ - PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ - bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent - +( + set -a + source /etc/default/hermes + set +a + $STD bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent +) chown -R hermes:hermes /home/hermes +chmod 750 /home/hermes +chmod 700 /home/hermes/.hermes git config --system --add safe.directory /home/hermes/.hermes/hermes-agent 2>/dev/null || true msg_ok "Installed Hermes Agent" @@ -54,21 +65,15 @@ msg_ok "Installed Web Dashboard" msg_info "Configuring API Server" API_SERVER_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32) +mkdir -p /home/hermes/.hermes cat </home/hermes/.hermes/.env API_SERVER_ENABLED=true API_SERVER_HOST=0.0.0.0 API_SERVER_PORT=8642 API_SERVER_KEY=${API_SERVER_KEY} HERMES_REDACT_SECRETS=true -HERMES_HOME=/home/hermes/.hermes -HOME=/home/hermes -PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -NODE_OPTIONS=--max-old-space-size=3072 EOF chmod 600 /home/hermes/.hermes/.env -chown hermes:hermes /home/hermes/.hermes/.env -chmod 750 /home/hermes -chmod 700 /home/hermes/.hermes msg_ok "Configured API Server" msg_info "Creating Dashboard Service" @@ -85,6 +90,7 @@ Group=hermes UMask=0077 WorkingDirectory=/home/hermes ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open +EnvironmentFile=/etc/default/hermes EnvironmentFile=/home/hermes/.hermes/.env Restart=on-failure RestartSec=5 From c685754144f74380fa99c410437425e593644097 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 15:30:20 -0700 Subject: [PATCH 20/28] fix(hermesagent): restore setsid to suppress installer TUI; remove redundant EnvironmentFile for .env --- install/hermesagent-install.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 2ea89a6a..7a3e8dd5 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -45,12 +45,11 @@ if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then fi msg_info "Installing Hermes Agent" -( - set -a - source /etc/default/hermes - set +a - $STD bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent -) +$STD setsid --wait env \ + HOME=/home/hermes \ + PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ + NODE_OPTIONS=${NODE_OPTIONS} \ + bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent chown -R hermes:hermes /home/hermes chmod 750 /home/hermes chmod 700 /home/hermes/.hermes @@ -91,7 +90,6 @@ UMask=0077 WorkingDirectory=/home/hermes ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open EnvironmentFile=/etc/default/hermes -EnvironmentFile=/home/hermes/.hermes/.env Restart=on-failure RestartSec=5 ProtectProc=invisible From 46746538a01edd25bc8ad0d912ebe0110ba109b9 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 15:39:22 -0700 Subject: [PATCH 21/28] fix(hermesagent): source /etc/default/hermes via setsid; drop inline env vars and HERMES_HOME --- ct/hermesagent.sh | 6 +++--- install/hermesagent-install.sh | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index f885a3f2..460933d4 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -45,10 +45,10 @@ function update_script() { msg_ok "Stopped Services" msg_info "Updating ${APP}" - $STD env \ - HOME=/home/hermes \ - HERMES_HOME=/home/hermes/.hermes \ + $STD setsid --wait bash -c ' + set -a; source /etc/default/hermes; set +a /home/hermes/.local/bin/hermes update --yes + ' chown -R hermes:hermes /home/hermes msg_ok "Updated ${APP}" diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 7a3e8dd5..99d065c4 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -45,11 +45,10 @@ if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then fi msg_info "Installing Hermes Agent" -$STD setsid --wait env \ - HOME=/home/hermes \ - PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ - NODE_OPTIONS=${NODE_OPTIONS} \ +$STD setsid --wait bash -c ' + set -a; source /etc/default/hermes; set +a bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent +' chown -R hermes:hermes /home/hermes chmod 750 /home/hermes chmod 700 /home/hermes/.hermes From 0c4678c0b4ea409ca8e224e75ae5f0203ba5edcc Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 15:44:39 -0700 Subject: [PATCH 22/28] fix(hermesagent): remove redundant web dashboard pip install; upstream installer includes web,pty extras in .[all] --- install/hermesagent-install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 99d065c4..9e630394 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -55,12 +55,6 @@ chmod 700 /home/hermes/.hermes git config --system --add safe.directory /home/hermes/.hermes/hermes-agent 2>/dev/null || true msg_ok "Installed Hermes Agent" -msg_info "Installing Web Dashboard" -$STD runuser -u hermes -- \ - env HOME=/home/hermes VIRTUAL_ENV=/home/hermes/.hermes/hermes-agent/venv \ - /home/hermes/.local/bin/uv pip install 'hermes-agent[web,pty]' -msg_ok "Installed Web Dashboard" - msg_info "Configuring API Server" API_SERVER_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32) mkdir -p /home/hermes/.hermes From 84f20e8b15bf7068bc93b83dbbbef1b39fef312d Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 17:14:48 -0700 Subject: [PATCH 23/28] fix(hermesagent): clean up footer, login hint, JSON notes and config_path --- ct/hermesagent.sh | 5 ++--- install/hermesagent-install.sh | 5 +---- json/hermesagent.json | 4 ++-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index 460933d4..0bd2bd77 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -65,9 +65,8 @@ description msg_ok "Completed successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Connect via SSH and configure your LLM provider:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}ssh root@${IP}${CL}" +echo -e "${INFO}${YW} Configure your model provider and gateway server inside the container:${CL}" echo -e "${TAB}${BGN}su - hermes${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" -echo -e "${INFO}${YW} API key stored in:${CL}" +echo -e "${INFO}${YW} Key for Hermes API Server stored in:${CL}" echo -e "${TAB}${BGN}/home/hermes/.hermes/.env${CL}" diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 9e630394..99c92f94 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -97,11 +97,8 @@ msg_ok "Created Dashboard Service" msg_info "Configuring Login Hints" cat <<'HINT' >/etc/profile.d/hermes-hint.sh if [[ "$(id -u)" -eq 0 ]]; then - echo " Run 'su - hermes' to manage Hermes Agent and profiles." + echo " Use 'su - hermes' to switch to the hermes user for running Hermes Agent." fi -LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}') -echo " Dashboard: ssh -fNL 9119:localhost:9119 root@${LOCAL_IP}" -echo " then open http://localhost:9119" HINT msg_ok "Configured Login Hints" diff --git a/json/hermesagent.json b/json/hermesagent.json index 061293ea..99858b87 100644 --- a/json/hermesagent.json +++ b/json/hermesagent.json @@ -8,7 +8,7 @@ "type": "ct", "updateable": true, "privileged": false, - "interface_port": 8642, + "interface_port": null, "documentation": "https://hermes-agent.nousresearch.com/docs", "website": "https://hermes-agent.nousresearch.com", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/hermes.webp", @@ -41,7 +41,7 @@ "type": "warning" }, { - "text": "After container startup, SSH in as root and run 'hermes setup' to configure your LLM provider (OpenRouter, Anthropic, OpenAI, Nous Portal, or custom endpoint).", + "text": "After container startup, login, switch to the hermes user (su - hermes) and run 'hermes setup' to configure your model provider and gateway server.", "type": "info" }, { From 91104fe71c20d84898f9e8d5534adfb4a52ad286 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 19:40:45 -0700 Subject: [PATCH 24/28] set security.redact_secrets: true in config.yaml on install --- install/hermesagent-install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index 99c92f94..e0d67381 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -66,6 +66,12 @@ API_SERVER_KEY=${API_SERVER_KEY} HERMES_REDACT_SECRETS=true EOF chmod 600 /home/hermes/.hermes/.env +cat </home/hermes/.hermes/config.yaml +security: + redact_secrets: true +EOF +chmod 600 /home/hermes/.hermes/config.yaml +chown hermes:hermes /home/hermes/.hermes/config.yaml msg_ok "Configured API Server" msg_info "Creating Dashboard Service" From 285870baa94e8be96aa1b5fdec929aeb5ac54af6 Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Sun, 10 May 2026 21:36:17 -0700 Subject: [PATCH 25/28] fix(hermes-agent): remove redundant redact_secrets workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hermes-agent v2026.5.7 (PR #21193, merged 2026-05-07) flipped HERMES_REDACT_SECRETS and DEFAULT_CONFIG security.redact_secrets to true by default. The explicit HERMES_REDACT_SECRETS=true in .env and the config.yaml creation block added in commit 1420682e are now redundant — Hermes writes the same values itself on a fresh install. Verified on CT 900 (v2026.5.7): _REDACT_ENABLED=True with no env override; Hermes self-writes redact_secrets: true to config.yaml. Ref: NousResearch/hermes-agent#17691 --- install/hermesagent-install.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/install/hermesagent-install.sh b/install/hermesagent-install.sh index e0d67381..28f6f85e 100644 --- a/install/hermesagent-install.sh +++ b/install/hermesagent-install.sh @@ -63,15 +63,8 @@ API_SERVER_ENABLED=true API_SERVER_HOST=0.0.0.0 API_SERVER_PORT=8642 API_SERVER_KEY=${API_SERVER_KEY} -HERMES_REDACT_SECRETS=true EOF chmod 600 /home/hermes/.hermes/.env -cat </home/hermes/.hermes/config.yaml -security: - redact_secrets: true -EOF -chmod 600 /home/hermes/.hermes/config.yaml -chown hermes:hermes /home/hermes/.hermes/config.yaml msg_ok "Configured API Server" msg_info "Creating Dashboard Service" From c6f22c4038778f72597626931a4cdea1ae5da31a Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Mon, 11 May 2026 17:27:40 -0700 Subject: [PATCH 26/28] fix(hermesagent): remove Warning prefix from notes; set config_path to .env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Drop 'WARNING: '/'Warning: ' prefixes from note texts — the type:warning field already communicates severity (per CrazyWolf13 review feedback) - Set config_path to /home/hermes/.hermes/.env (was directory path) --- json/hermesagent.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/json/hermesagent.json b/json/hermesagent.json index 99858b87..123151a7 100644 --- a/json/hermesagent.json +++ b/json/hermesagent.json @@ -17,7 +17,7 @@ { "type": "default", "script": "ct/hermesagent.sh", - "config_path": "/home/hermes/.hermes/", + "config_path": "/home/hermes/.hermes/.env", "resources": { "cpu": 2, "ram": 4096, @@ -33,11 +33,11 @@ }, "notes": [ { - "text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.", + "text": "Installation sources scripts outside of Community Scripts repo. Please check the source before installing.", "type": "warning" }, { - "text": "Warning: Hermes can execute terminal commands. The agent runs as a dedicated 'hermes' service user for isolation.", + "text": "Hermes can execute terminal commands. The agent runs as a dedicated 'hermes' service user for isolation.", "type": "warning" }, { From 96d7c7d61d5f1b24cac4a552634b04e21d7db2ad Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Mon, 11 May 2026 17:27:51 -0700 Subject: [PATCH 27/28] fix(hermesagent): replace ${APP} with literal name in msg lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve to 'Hermes Agent' in all msg_info/msg_ok/msg_error calls per CrazyWolf13 review feedback — improves readability for users reading install output. --- ct/hermesagent.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index 0bd2bd77..49304eaa 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -25,7 +25,7 @@ function update_script() { check_container_resources if [[ ! -x /home/hermes/.local/bin/hermes ]]; then - msg_error "No ${APP} Installation Found!" + msg_error "No Hermes Agent Installation Found!" exit fi @@ -44,13 +44,13 @@ function update_script() { systemctl stop hermes-dashboard msg_ok "Stopped Services" - msg_info "Updating ${APP}" + msg_info "Updating Hermes Agent" $STD setsid --wait bash -c ' set -a; source /etc/default/hermes; set +a /home/hermes/.local/bin/hermes update --yes ' chown -R hermes:hermes /home/hermes - msg_ok "Updated ${APP}" + msg_ok "Updated Hermes Agent" msg_info "Starting Services" systemctl start hermes-dashboard @@ -64,7 +64,7 @@ build_container description msg_ok "Completed successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${CREATING}${GN}Hermes Agent setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Configure your model provider and gateway server inside the container:${CL}" echo -e "${TAB}${BGN}su - hermes${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" From 0c45a4700c5ea041c2fb49af8f16e9dfb0ebc51e Mon Sep 17 00:00:00 2001 From: Stephen Chin Date: Thu, 14 May 2026 20:49:44 -0700 Subject: [PATCH 28/28] Update ct/hermesagent.sh Removed an unnecessary space. Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com> --- ct/hermesagent.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/hermesagent.sh b/ct/hermesagent.sh index 49304eaa..a2382a34 100644 --- a/ct/hermesagent.sh +++ b/ct/hermesagent.sh @@ -68,5 +68,5 @@ echo -e "${CREATING}${GN}Hermes Agent setup has been successfully initialized!${ echo -e "${INFO}${YW} Configure your model provider and gateway server inside the container:${CL}" echo -e "${TAB}${BGN}su - hermes${CL}" echo -e "${TAB}${BGN}hermes setup${CL}" -echo -e "${INFO}${YW} Key for Hermes API Server stored in:${CL}" +echo -e "${INFO}${YW}Key for Hermes API Server stored in:${CL}" echo -e "${TAB}${BGN}/home/hermes/.hermes/.env${CL}"