From 319c714a11326406ae358e7cb7f97e40a740a693 Mon Sep 17 00:00:00 2001 From: 1xxalexx1 Date: Mon, 17 Aug 2026 20:49:17 +0200 Subject: [PATCH 1/2] feat(acp): add Zed registry launcher package --- packaging/acp-launcher/.npmignore | 2 + packaging/acp-launcher/LICENSE | 21 ++++++ packaging/acp-launcher/README.md | 15 ++++ packaging/acp-launcher/bin/hermes-agent.js | 76 ++++++++++++++++++++ packaging/acp-launcher/package.json | 23 ++++++ packaging/acp-launcher/test/launcher.test.js | 23 ++++++ 6 files changed, 160 insertions(+) create mode 100644 packaging/acp-launcher/.npmignore create mode 100644 packaging/acp-launcher/LICENSE create mode 100644 packaging/acp-launcher/README.md create mode 100644 packaging/acp-launcher/bin/hermes-agent.js create mode 100644 packaging/acp-launcher/package.json create mode 100644 packaging/acp-launcher/test/launcher.test.js diff --git a/packaging/acp-launcher/.npmignore b/packaging/acp-launcher/.npmignore new file mode 100644 index 000000000000..e7d08d701358 --- /dev/null +++ b/packaging/acp-launcher/.npmignore @@ -0,0 +1,2 @@ +test/ +*.log diff --git a/packaging/acp-launcher/LICENSE b/packaging/acp-launcher/LICENSE new file mode 100644 index 000000000000..9e371ccc2589 --- /dev/null +++ b/packaging/acp-launcher/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Nous Research + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packaging/acp-launcher/README.md b/packaging/acp-launcher/README.md new file mode 100644 index 000000000000..8b94a89b05eb --- /dev/null +++ b/packaging/acp-launcher/README.md @@ -0,0 +1,15 @@ +# Hermes Agent ACP launcher + +This is the small `npx` launcher used by the ACP Registry entry for Hermes +Agent. It starts the user's installed `hermes-acp` process, preserving the +normal Hermes configuration, credentials, skills, memory, and model catalog. + +Install Hermes first with the official installer: + +```sh +curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash +``` + +The launcher prefers the managed `hermes-acp` executable, then a launcher on +`PATH`, and finally falls back to `uvx --from hermes-agent[acp] hermes-acp` on +POSIX systems where `uv` is already installed. diff --git a/packaging/acp-launcher/bin/hermes-agent.js b/packaging/acp-launcher/bin/hermes-agent.js new file mode 100644 index 000000000000..a4420201d1d5 --- /dev/null +++ b/packaging/acp-launcher/bin/hermes-agent.js @@ -0,0 +1,76 @@ +#!/usr/bin/env node + +import { existsSync } from "node:fs"; +import { homedir } from "node:os"; +import { join } from "node:path"; +import { spawn } from "node:child_process"; +import { execFileSync } from "node:child_process"; + +const args = process.argv.slice(2); +const isWindows = process.platform === "win32"; +const hermesHome = process.env.HERMES_HOME || join(homedir(), ".hermes"); + +function localLaunchers() { + if (isWindows) { + return [ + join(hermesHome, "hermes-agent", "venv", "Scripts", "hermes-acp.exe"), + join(hermesHome, "hermes-agent", "venv", "Scripts", "hermes-acp.bat"), + ]; + } + return [ + join(hermesHome, "hermes-agent", "venv", "bin", "hermes-acp"), + join(homedir(), ".local", "bin", "hermes-acp"), + ]; +} + +function commandExists(command) { + try { + execFileSync(isWindows ? "where.exe" : "which", [command], { + stdio: "ignore", + }); + return true; + } catch { + return false; + } +} + +function run(command, commandArgs) { + const child = spawn(command, commandArgs, { + stdio: "inherit", + env: process.env, + windowsHide: true, + }); + child.on("error", (error) => { + console.error(`Hermes ACP launcher failed to start: ${error.message}`); + process.exitCode = 1; + }); + child.on("exit", (code, signal) => { + if (signal) { + process.kill(process.pid, signal); + } else { + process.exitCode = code ?? 1; + } + }); +} + +const launcher = localLaunchers().find((candidate) => existsSync(candidate)); +if (launcher) { + run(launcher, args); +} else if (commandExists("hermes-acp")) { + run("hermes-acp", args); +} else if (!isWindows && commandExists("uvx")) { + // This keeps the registry entry useful for machines that have uv but use a + // managed Hermes install elsewhere. The normal install path still prefers + // the user's current hermes-acp launcher above. + run("uvx", ["--from", "hermes-agent[acp]", "hermes-acp", ...args]); +} else { + const pathHint = isWindows + ? "%USERPROFILE%\\.hermes\\hermes-agent\\venv\\Scripts\\hermes-acp.exe" + : "~/.local/bin/hermes-acp"; + console.error( + "Hermes Agent is not installed. Install it from " + + "https://hermes-agent.nousresearch.com/install.sh, then retry.\n" + + `Expected ACP launcher: ${pathHint}`, + ); + process.exitCode = 1; +} diff --git a/packaging/acp-launcher/package.json b/packaging/acp-launcher/package.json new file mode 100644 index 000000000000..9e1928a25816 --- /dev/null +++ b/packaging/acp-launcher/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nousresearch/hermes-agent", + "version": "0.20.2", + "description": "ACP launcher for Hermes Agent, for Zed and other ACP-compatible editors", + "type": "module", + "bin": { + "hermes-agent": "bin/hermes-agent.js" + }, + "files": ["bin", "README.md", "LICENSE"], + "engines": { + "node": ">=18" + }, + "repository": { + "type": "git", + "url": "https://github.com/NousResearch/hermes-agent.git", + "directory": "packaging/acp-launcher" + }, + "homepage": "https://hermes-agent.nousresearch.com/docs/user-guide/features/acp", + "license": "MIT", + "scripts": { + "test": "node --test" + } +} diff --git a/packaging/acp-launcher/test/launcher.test.js b/packaging/acp-launcher/test/launcher.test.js new file mode 100644 index 000000000000..aa794b272cfe --- /dev/null +++ b/packaging/acp-launcher/test/launcher.test.js @@ -0,0 +1,23 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = dirname(fileURLToPath(import.meta.url)); +const packageRoot = join(here, ".."); + +test("package exposes the ACP launcher bin", async () => { + const packageJson = JSON.parse( + await readFile(join(packageRoot, "package.json"), "utf8"), + ); + assert.equal(packageJson.bin["hermes-agent"], "bin/hermes-agent.js"); + assert.equal(packageJson.type, "module"); +}); + +test("launcher contains the managed and uvx fallback paths", async () => { + const source = await readFile(join(packageRoot, "bin/hermes-agent.js"), "utf8"); + assert.match(source, /hermes-acp/); + assert.match(source, /--from/); + assert.match(source, /hermes-agent\[acp\]/); +}); From 5173eb3d01c6a353269cb0104657d5b089524d82 Mon Sep 17 00:00:00 2001 From: 1xxalexx1 Date: Mon, 17 Aug 2026 21:32:56 +0200 Subject: [PATCH 2/2] chore(acp): align launcher version with Hermes 0.20.3 --- packaging/acp-launcher/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/acp-launcher/package.json b/packaging/acp-launcher/package.json index 9e1928a25816..6f45009e7f5e 100644 --- a/packaging/acp-launcher/package.json +++ b/packaging/acp-launcher/package.json @@ -1,6 +1,6 @@ { "name": "@nousresearch/hermes-agent", - "version": "0.20.2", + "version": "0.20.3", "description": "ACP launcher for Hermes Agent, for Zed and other ACP-compatible editors", "type": "module", "bin": {