hermes-agent 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DISCLAIMER.md ADDED
@@ -0,0 +1,22 @@
1
+ # Disclaimer
2
+
3
+ This is an unofficial npm bridge for Hermes Agent.
4
+
5
+ Hermes Agent is developed by Nous Research:
6
+
7
+ https://github.com/NousResearch/hermes-agent
8
+
9
+ This project is not affiliated with, endorsed by, sponsored by, or maintained by
10
+ Nous Research. References to Hermes Agent and Nous Research are provided only to
11
+ identify the upstream open-source project that this npm package installs and
12
+ launches.
13
+
14
+ The npm package name is `hermes-agent` because it installs the upstream Python
15
+ package with the same name. This repository does not claim ownership of the
16
+ upstream Hermes Agent project, its source code, or its trademarks.
17
+
18
+ Any product names, project names, logos, or marks referenced here belong to
19
+ their respective owners and are used only to identify the upstream project.
20
+
21
+ This package is provided as-is, without warranty. Users should review the
22
+ upstream project, its license, and this package's install behavior before use.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wyrtensi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE ADDED
@@ -0,0 +1,23 @@
1
+ hermes-agent npm bridge
2
+ Copyright (c) 2026 wyrtensi
3
+ License: MIT
4
+
5
+ This repository publishes an unofficial npm bridge for Hermes Agent.
6
+
7
+ Hermes Agent is developed by Nous Research.
8
+ Upstream repository: https://github.com/NousResearch/hermes-agent
9
+ Upstream package: hermes-agent on PyPI
10
+ Upstream license: MIT
11
+ Upstream copyright notice: Copyright (c) 2025 Nous Research
12
+
13
+ This npm package does not claim ownership of Hermes Agent, the Hermes Agent
14
+ source code, the Hermes Agent name, or Nous Research marks. It only provides a
15
+ Node.js package wrapper that installs and launches the upstream Python package.
16
+
17
+ The npm package includes wrapper code from this repository. It does not vendor
18
+ or redistribute the upstream Hermes Agent source tree. During installation, the
19
+ postinstall script asks pip to install the pinned upstream Python package
20
+ version matching this npm package.
21
+
22
+ For the upstream license text, see:
23
+ https://github.com/NousResearch/hermes-agent/blob/main/LICENSE
package/PRIVACY.md ADDED
@@ -0,0 +1,34 @@
1
+ # Privacy
2
+
3
+ This npm bridge does not collect telemetry.
4
+
5
+ The package does not intentionally collect, store, or transmit:
6
+
7
+ - personal information
8
+ - analytics events
9
+ - npm tokens
10
+ - GitHub tokens
11
+ - SSH keys
12
+ - API keys
13
+ - repository contents
14
+ - shell history
15
+
16
+ During normal installation, npm runs `scripts/postinstall.js`. That script only
17
+ uses the local Node.js runtime, the local Python interpreter, and pip. Its
18
+ network activity is limited to pip downloading the pinned Python package and its
19
+ dependencies from the user's configured Python package index.
20
+
21
+ The package does not run a separate telemetry endpoint, background service,
22
+ scheduled task, or analytics uploader.
23
+
24
+ Users who do not want npm lifecycle scripts to run can install with:
25
+
26
+ ```bash
27
+ npm install -g hermes-agent --ignore-scripts
28
+ ```
29
+
30
+ Then install the upstream Python runtime manually:
31
+
32
+ ```bash
33
+ python -m pip install --upgrade hermes-agent==<npm package version>
34
+ ```
package/README.md CHANGED
@@ -1,4 +1,11 @@
1
- # hermes-agent npm package
1
+ # hermes-agent npm bridge
2
+
3
+ This is an unofficial npm bridge for Hermes Agent by Nous Research. It is not
4
+ affiliated with, endorsed by, sponsored by, or maintained by Nous Research.
5
+
6
+ Hermes Agent is developed by Nous Research and distributed separately as a
7
+ Python package. This npm package only installs and launches that upstream Python
8
+ runtime.
2
9
 
3
10
  This repository publishes the npm bridge for
4
11
  [NousResearch/Hermes-Agent](https://github.com/NousResearch/Hermes-Agent).
@@ -9,6 +16,16 @@ The npm package name is:
9
16
  hermes-agent
10
17
  ```
11
18
 
19
+ This repository can build an alias package manifest for:
20
+
21
+ ```bash
22
+ hermesagent
23
+ ```
24
+
25
+ npm currently blocks publishing the unscoped `hermesagent` package because the
26
+ name is too similar to the existing `hermes-agent` package. The available npm
27
+ alternative is a scoped package such as `@wyrtensi/hermesagent`.
28
+
12
29
  The installed commands are:
13
30
 
14
31
  ```bash
@@ -19,6 +36,22 @@ hermes-agent
19
36
  The npm package name `hermes` is already owned by another package on npm, so this
20
37
  repository publishes `hermes-agent` and exposes `hermes` as a CLI binary.
21
38
 
39
+ ## Legal and attribution
40
+
41
+ - Wrapper license: MIT, see [LICENSE](LICENSE).
42
+ - Upstream attribution: see [NOTICE](NOTICE).
43
+ - Unofficial package disclaimer: see [DISCLAIMER.md](DISCLAIMER.md).
44
+ - Privacy notes: see [PRIVACY.md](PRIVACY.md).
45
+ - Install-script security notes: see [SECURITY.md](SECURITY.md).
46
+
47
+ For wrapper issues, use this repository:
48
+
49
+ https://github.com/wyrtensi/hermes-agent-npm/issues
50
+
51
+ For upstream Hermes Agent issues, use the upstream project:
52
+
53
+ https://github.com/NousResearch/hermes-agent/issues
54
+
22
55
  ## Install
23
56
 
24
57
  Prerequisites:
@@ -40,18 +73,25 @@ hermes --help
40
73
  hermes-agent --help
41
74
  ```
42
75
 
76
+ If a scoped alias package is published later, you do not need to install both
77
+ `hermes-agent` and the alias. If one is already installed globally, the other
78
+ package prints a warning during `postinstall`.
79
+
43
80
  During npm installation, `postinstall` installs the matching Python package:
44
81
 
45
82
  ```bash
46
83
  python -m pip install --upgrade hermes-agent==<npm package version>
47
84
  ```
48
85
 
86
+ For a detailed explanation of why this package uses `postinstall` and exactly
87
+ what the script does, see [SECURITY.md](SECURITY.md).
88
+
49
89
  ## Automated publishing
50
90
 
51
91
  `.github/workflows/npm-publish.yml` runs:
52
92
 
53
93
  - manually with `workflow_dispatch`
54
- - daily on a schedule
94
+ - hourly on a schedule
55
95
  - when a tag matching `npm-v*` is pushed
56
96
 
57
97
  The workflow:
@@ -59,9 +99,12 @@ The workflow:
59
99
  1. Fetches the current Hermes Agent version from upstream `pyproject.toml`.
60
100
  2. Updates `package.json` in the workflow workspace.
61
101
  3. Skips publishing if `hermes-agent@<version>` already exists on npm.
62
- 4. Runs `npm test`.
63
- 5. Runs `npm pack --dry-run`.
64
- 6. Publishes to npm with the `NPM_TOKEN` GitHub Actions secret.
102
+ 4. Skips publishing if the matching Python `hermes-agent==<version>` package
103
+ is not available on PyPI yet.
104
+ 5. Runs `npm test`.
105
+ 6. Runs `npm pack --dry-run`.
106
+ 7. Publishes missing npm packages through npm trusted publishing with GitHub
107
+ Actions OIDC and npm provenance.
65
108
 
66
109
  ## GitHub setup
67
110
 
@@ -71,17 +114,7 @@ Create a GitHub repository named:
71
114
  hermes-agent-npm
72
115
  ```
73
116
 
74
- Create a classic or automation npm token with publish access, then add it as a
75
- GitHub Actions secret:
76
-
77
- ```text
78
- Repository -> Settings -> Secrets and variables -> Actions -> New repository secret
79
- Name: NPM_TOKEN
80
- Value: your npm token
81
- ```
82
-
83
- After the first package version exists on npm, this repository can be switched
84
- back to npm trusted publishing if desired:
117
+ Configure npm trusted publishing for the published npm package:
85
118
 
86
119
  ```text
87
120
  npm package: hermes-agent
@@ -92,6 +125,12 @@ workflow filename: npm-publish.yml
92
125
  allowed action: npm publish
93
126
  ```
94
127
 
128
+ The trusted publisher environment name should stay empty unless the workflow job
129
+ also defines a matching GitHub Actions environment. In the package's npm
130
+ Publishing access settings, use `Require two-factor authentication and disallow
131
+ tokens` after trusted publishing is configured. GitHub Actions will keep
132
+ publishing through OIDC, while long-lived npm publish tokens are blocked.
133
+
95
134
  Then push this repository:
96
135
 
97
136
  ```bash
@@ -108,4 +147,6 @@ first publish.
108
147
  python scripts/sync_upstream_version.py
109
148
  npm test
110
149
  npm pack --dry-run
150
+ npm run build:alias
151
+ npm pack --dry-run ./dist/hermesagent
111
152
  ```
package/SECURITY.md ADDED
@@ -0,0 +1,174 @@
1
+ # Security notes for the npm postinstall script
2
+
3
+ This package intentionally includes a `postinstall` script:
4
+
5
+ ```json
6
+ {
7
+ "scripts": {
8
+ "postinstall": "node scripts/postinstall.js"
9
+ }
10
+ }
11
+ ```
12
+
13
+ Install scripts deserve careful review because they execute automatically during
14
+ `npm install`. This document explains exactly why this package has one, what it
15
+ does, and what it does not do.
16
+
17
+ ## Why postinstall exists
18
+
19
+ `hermes-agent` on npm is an unofficial small Node.js bridge for the upstream
20
+ Python project:
21
+
22
+ https://github.com/NousResearch/Hermes-Agent
23
+
24
+ This npm bridge is not affiliated with, endorsed by, sponsored by, or maintained
25
+ by Nous Research. See [DISCLAIMER.md](DISCLAIMER.md) and [NOTICE](NOTICE) for
26
+ the project attribution and legal notice.
27
+
28
+ The actual Hermes Agent runtime is distributed as the Python package
29
+ `hermes-agent`. The npm package provides convenient global commands:
30
+
31
+ ```bash
32
+ hermes
33
+ hermes-agent
34
+ ```
35
+
36
+ The canonical npm package is `hermes-agent`. The package `hermesagent` is an
37
+ alias manifest for users who search for the name without the hyphen. npm blocks
38
+ publishing the unscoped `hermesagent` package because the name is too similar to
39
+ `hermes-agent`; a scoped alias such as `@wyrtensi/hermesagent` can be published
40
+ separately if needed.
41
+
42
+ The `postinstall` step installs the matching Python package version so that a
43
+ single command prepares the npm wrapper and the Python runtime:
44
+
45
+ ```bash
46
+ npm install -g hermes-agent
47
+ ```
48
+
49
+ Without `postinstall`, users would need to run a second command manually:
50
+
51
+ ```bash
52
+ python -m pip install --upgrade hermes-agent==<npm package version>
53
+ ```
54
+
55
+ ## Exact behavior
56
+
57
+ The script is located at:
58
+
59
+ ```text
60
+ scripts/postinstall.js
61
+ ```
62
+
63
+ It performs these steps:
64
+
65
+ 1. Finds an available Python 3 interpreter.
66
+ - On Windows it tries `py -3`, then `python`, then `python3`.
67
+ - On macOS and Linux it tries `python3`, then `python`.
68
+ 2. Verifies that the interpreter is Python 3.11 or newer.
69
+ 3. Builds the pinned Python package spec from `package.json`, for example:
70
+
71
+ ```bash
72
+ hermes-agent==<npm package version>
73
+ ```
74
+
75
+ 4. Runs:
76
+
77
+ ```bash
78
+ python -m pip install --upgrade hermes-agent==<npm package version>
79
+ ```
80
+
81
+ 5. If that install fails, retries with:
82
+
83
+ ```bash
84
+ python -m pip install --upgrade --user hermes-agent==<npm package version>
85
+ ```
86
+
87
+ 6. Exits with a non-zero status if both attempts fail.
88
+
89
+ The script also checks whether the related alias package is already installed
90
+ globally. If `hermes-agent` is installed and a user installs `hermesagent`, or
91
+ the other way around, it prints a warning explaining that both packages point to
92
+ the same Hermes Agent runtime. It does not uninstall packages or modify npm
93
+ global state.
94
+
95
+ ## What the script does not do
96
+
97
+ The `postinstall` script does not:
98
+
99
+ - read SSH keys, npm tokens, GitHub tokens, or other secrets
100
+ - inspect project source files outside this npm package
101
+ - upload telemetry or analytics
102
+ - call custom remote shell scripts
103
+ - run `curl | sh`, PowerShell downloads, or arbitrary downloaded code
104
+ - modify shell profiles such as `.bashrc`, `.zshrc`, or PowerShell profiles
105
+ - add startup items, services, scheduled tasks, or background daemons
106
+ - change Git configuration
107
+ - install npm packages dynamically
108
+
109
+ Its network activity is limited to the normal package downloads performed by
110
+ `pip` from the user's configured Python package index.
111
+
112
+ ## Publishing security
113
+
114
+ The npm package is published by GitHub Actions through npm trusted publishing
115
+ with OpenID Connect. The publish workflow is allowed to publish only from:
116
+
117
+ ```text
118
+ GitHub owner: wyrtensi
119
+ GitHub repository: hermes-agent-npm
120
+ Workflow file: npm-publish.yml
121
+ Allowed npm action: npm publish
122
+ ```
123
+
124
+ The workflow does not use a long-lived npm publish token. npm package settings
125
+ should use `Require two-factor authentication and disallow tokens` so manual
126
+ publishes require 2FA and traditional npm tokens cannot publish this package.
127
+ Trusted publishing continues to work because it uses short-lived OIDC
128
+ credentials issued for the configured workflow.
129
+
130
+ ## Why the package is version-pinned
131
+
132
+ The npm package version and the Python package version are kept in sync. The
133
+ postinstall script installs the exact matching Python version:
134
+
135
+ ```bash
136
+ hermes-agent==<npm package version>
137
+ ```
138
+
139
+ This avoids silently installing a newer Python Hermes runtime than the npm
140
+ wrapper was published for.
141
+
142
+ ## How to audit locally
143
+
144
+ Review the install script:
145
+
146
+ ```bash
147
+ npm pack hermes-agent
148
+ tar -xzf hermes-agent-*.tgz
149
+ cat package/scripts/postinstall.js
150
+ cat package/lib/python-launcher.js
151
+ ```
152
+
153
+ Install without running lifecycle scripts:
154
+
155
+ ```bash
156
+ npm install -g hermes-agent --ignore-scripts
157
+ ```
158
+
159
+ Then install the Python runtime manually:
160
+
161
+ ```bash
162
+ python -m pip install --upgrade hermes-agent==<npm package version>
163
+ ```
164
+
165
+ ## Why security scanners flag this package
166
+
167
+ Some scanners flag every npm package with `preinstall`, `install`, or
168
+ `postinstall` scripts because those scripts can execute code automatically.
169
+ That warning is useful and should not be ignored.
170
+
171
+ For this package, the install script is intentionally small and exists only to
172
+ install the pinned Python Hermes Agent runtime. Users who prefer not to run npm
173
+ lifecycle scripts can use `--ignore-scripts` and install the Python package
174
+ manually.
@@ -2,4 +2,4 @@
2
2
 
3
3
  const { runHermes } = require("../lib/python-launcher");
4
4
 
5
- runHermes(process.argv[1], process.argv.slice(2));
5
+ runHermes("hermes-agent", process.argv.slice(2));
package/bin/hermes.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { runHermes } = require("../lib/python-launcher");
4
+
5
+ runHermes("hermes", process.argv.slice(2));
@@ -0,0 +1,36 @@
1
+ const CANONICAL_PACKAGE_NAME = "hermes-agent";
2
+ const ALIAS_PACKAGE_NAME = "hermesagent";
3
+
4
+ function getRelatedPackageNames(packageName) {
5
+ if (packageName === CANONICAL_PACKAGE_NAME) {
6
+ return [ALIAS_PACKAGE_NAME];
7
+ }
8
+
9
+ if (packageName === ALIAS_PACKAGE_NAME) {
10
+ return [CANONICAL_PACKAGE_NAME];
11
+ }
12
+
13
+ return [];
14
+ }
15
+
16
+ function getAliasPackageName(packageName) {
17
+ return packageName === CANONICAL_PACKAGE_NAME ? ALIAS_PACKAGE_NAME : packageName;
18
+ }
19
+
20
+ function getPackageBinNames(packageName) {
21
+ const names = ["hermes", "hermes-agent"];
22
+
23
+ if (packageName === ALIAS_PACKAGE_NAME) {
24
+ names.push(ALIAS_PACKAGE_NAME);
25
+ }
26
+
27
+ return names;
28
+ }
29
+
30
+ module.exports = {
31
+ ALIAS_PACKAGE_NAME,
32
+ CANONICAL_PACKAGE_NAME,
33
+ getAliasPackageName,
34
+ getPackageBinNames,
35
+ getRelatedPackageNames
36
+ };
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "hermes-agent",
3
- "version": "0.14.0",
4
- "description": "npm bridge for Hermes Agent 0.14.0: The self-improving AI agent \u2014 creates skills from experience, improves them during use, and runs anywhere",
3
+ "version": "0.15.1",
4
+ "description": "Unofficial npm bridge for Hermes Agent 0.15.1: The self-improving AI agent \u2014 creates skills from experience, improves them during use, and runs anywhere",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
7
7
  "bin": {
8
- "hermes": "bin/hermes-agent.js",
8
+ "hermes": "bin/hermes.js",
9
9
  "hermes-agent": "bin/hermes-agent.js"
10
10
  },
11
11
  "scripts": {
12
+ "build:alias": "node scripts/build-alias-package.js",
12
13
  "postinstall": "node scripts/postinstall.js",
13
14
  "test": "node --test"
14
15
  },
@@ -17,9 +18,9 @@
17
18
  "url": "git+https://github.com/wyrtensi/hermes-agent-npm.git"
18
19
  },
19
20
  "bugs": {
20
- "url": "https://github.com/NousResearch/Hermes-Agent/issues"
21
+ "url": "https://github.com/wyrtensi/hermes-agent-npm/issues"
21
22
  },
22
- "homepage": "https://github.com/NousResearch/Hermes-Agent#readme",
23
+ "homepage": "https://github.com/wyrtensi/hermes-agent-npm#readme",
23
24
  "engines": {
24
25
  "node": ">=20.0.0"
25
26
  },
@@ -27,10 +28,15 @@
27
28
  "bin/",
28
29
  "lib/",
29
30
  "scripts/postinstall.js",
30
- "README.md"
31
+ "DISCLAIMER.md",
32
+ "LICENSE",
33
+ "NOTICE",
34
+ "PRIVACY.md",
35
+ "README.md",
36
+ "SECURITY.md"
31
37
  ],
32
38
  "hermesAgent": {
33
- "pythonPackageVersion": "0.14.0",
39
+ "pythonPackageVersion": "0.15.1",
34
40
  "upstreamRepository": "nousresearch/hermes-agent"
35
41
  }
36
42
  }
@@ -1,10 +1,55 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { spawnSync } = require("node:child_process");
4
+ const path = require("node:path");
5
+ const packageJson = require("../package.json");
6
+ const { getRelatedPackageNames } = require("../lib/package-metadata");
4
7
  const { findPython, getPythonPackageSpec } = require("../lib/python-launcher");
5
8
 
6
9
  const candidate = findPython();
7
10
  const packageSpec = getPythonPackageSpec();
11
+ const packageName = packageJson.name;
12
+
13
+ function warnIfRelatedPackageInstalled() {
14
+ const relatedPackages = getRelatedPackageNames(packageName);
15
+
16
+ if (relatedPackages.length === 0) {
17
+ return;
18
+ }
19
+
20
+ const npmRootCommand = process.env.npm_execpath
21
+ ? { command: process.execPath, args: [process.env.npm_execpath, "root", "-g"] }
22
+ : { command: process.platform === "win32" ? "npm.cmd" : "npm", args: ["root", "-g"] };
23
+
24
+ const rootResult = spawnSync(npmRootCommand.command, npmRootCommand.args, {
25
+ encoding: "utf8",
26
+ windowsHide: true
27
+ });
28
+
29
+ if (rootResult.status !== 0) {
30
+ return;
31
+ }
32
+
33
+ const globalRoot = rootResult.stdout.trim();
34
+
35
+ for (const relatedPackage of relatedPackages) {
36
+ const relatedPackageJson = path.join(globalRoot, relatedPackage, "package.json");
37
+
38
+ try {
39
+ if (require("node:fs").existsSync(relatedPackageJson)) {
40
+ console.warn(
41
+ `${relatedPackage} is already installed globally. ` +
42
+ `${packageName} is an alias package for the same Hermes Agent runtime; ` +
43
+ "you do not need to install both."
44
+ );
45
+ }
46
+ } catch {
47
+ return;
48
+ }
49
+ }
50
+ }
51
+
52
+ warnIfRelatedPackageInstalled();
8
53
 
9
54
  if (!candidate) {
10
55
  console.error("Hermes Agent requires Python 3.11 or newer.");