@atomicmemory/hermes-plugin 0.1.10 → 0.1.12

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/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ ## 0.1.12 - 2026-05-14
4
+
5
+ ### Fixed
6
+
7
+ - Added the Core Quickstart bearer key to the installer next-step output so the published package matches the local quickstart docs.
8
+
9
+ ## 0.1.11 - 2026-05-14
10
+
11
+ ### Added
12
+
13
+ - Added the packaged Hermes provider installer exposed through the `atomicmemory-hermes` npm binary.
14
+
15
+ ### Fixed
16
+
17
+ - Preserved the Python SDK import path when Hermes is installed from the packaged npm artifact.
18
+
19
+ ## 0.1.10 - 2026-05-14
20
+
21
+ ### Added
22
+
23
+ - Initial public npm package for the AtomicMemory Hermes plugin.
package/README.md CHANGED
@@ -24,19 +24,20 @@ hooks, tool schemas. Memory semantics flow through the published Python SDK.
24
24
 
25
25
  ## Prerequisites
26
26
 
27
- - Hermes Agent installed and `HERMES_HOME` set
27
+ - Hermes Agent installed
28
28
  - AtomicMemory core URL exported as `ATOMICMEMORY_API_URL`
29
+ - AtomicMemory bearer key exported as `ATOMICMEMORY_API_KEY` when using the Core Quickstart or any protected service
29
30
 
30
- ## Install (dev)
31
+ ## Install
31
32
 
32
- The simplest dev install symlinks the plugin into Hermes' memory directory.
33
- Hermes installs the published `atomicmemory` SDK from `plugin.yaml`.
33
+ Install the provider from the published npm package. The installer copies the
34
+ Python provider files into Hermes' memory-provider directory; no repository
35
+ clone is required.
34
36
 
35
37
  ```bash
36
- cd /path/to/atomicmemory-integrations
37
- mkdir -p "$HERMES_HOME/plugins/memory"
38
- ln -s "$(pwd)/plugins/hermes" "$HERMES_HOME/plugins/memory/atomicmemory"
39
- export ATOMICMEMORY_API_URL="http://localhost:3050"
38
+ npx -y @atomicmemory/hermes-plugin install
39
+ export ATOMICMEMORY_API_URL="http://127.0.0.1:3050"
40
+ export ATOMICMEMORY_API_KEY="local-dev-key"
40
41
  ```
41
42
 
42
43
  Then select and verify the provider:
@@ -48,6 +49,14 @@ hermes memory status
48
49
  # confirm "atomicmemory" is active
49
50
  ```
50
51
 
52
+ For source development, symlink the checkout instead:
53
+
54
+ ```bash
55
+ cd /path/to/atomicmemory-integrations
56
+ mkdir -p "$HERMES_HOME/plugins/memory"
57
+ ln -s "$(pwd)/plugins/hermes" "$HERMES_HOME/plugins/memory/atomicmemory"
58
+ ```
59
+
51
60
  ## Config
52
61
 
53
62
  Hermes' setup wizard prompts for a minimal pair (`scope_user`, `memory_scope`).
@@ -62,7 +71,7 @@ have a default API URL and fails to start if `ATOMICMEMORY_API_URL` is unset.
62
71
  | Env var | Purpose |
63
72
  |---|---|
64
73
  | `ATOMICMEMORY_API_URL` | AtomicMemory core URL. Required. |
65
- | `ATOMICMEMORY_API_KEY` | Bearer credential for AtomicMemory core. Optional. |
74
+ | `ATOMICMEMORY_API_KEY` | Bearer credential for the Core Quickstart service or any protected AtomicMemory core. |
66
75
  | `ATOMICMEMORY_PROVIDER` | SDK provider name. Defaults to `atomicmemory`. |
67
76
  | `ATOMICMEMORY_SCOPE_USER` | Hermes user identity. Defaults to `$USER`. |
68
77
  | `ATOMICMEMORY_MEMORY_SCOPE` | `shared` (default) or `siloed`. |
@@ -144,7 +153,7 @@ run while AtomicMemory is temporarily unavailable.
144
153
 
145
154
  | Symptom | Likely cause |
146
155
  |---|---|
147
- | Provider does not appear in `hermes memory setup` | Wrong install path. Memory providers must live under `$HERMES_HOME/plugins/memory/<name>/`, not `$HERMES_HOME/plugins/<name>/`. |
156
+ | Provider does not appear in `hermes memory setup` | Wrong install path. User-installed memory providers must live under `$HERMES_HOME/plugins/memory/<name>/`. |
148
157
  | `is_available()` returns False | `ATOMICMEMORY_API_URL` unset, or the Hermes Python environment did not install the `atomicmemory` dependency from `plugin.yaml`. |
149
158
  | Import fails at startup | The Hermes Python environment is missing the SDK dependency from `plugin.yaml`. |
150
159
  | Calls fail with `PROVIDER_UNSUPPORTED` while `memory_scope=siloed` | The configured SDK provider is not the AtomicMemory core (e.g. it's `mem0`). Either switch `ATOMICMEMORY_PROVIDER=atomicmemory` or move to `memory_scope=shared`. |
package/install.mjs ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Install the AtomicMemory Hermes provider from the published npm package.
4
+ *
5
+ * Hermes memory providers are filesystem plugins under
6
+ * `$HERMES_HOME/plugins/memory/<name>`. The npm package already contains the
7
+ * Python provider files, so this installer copies only that managed provider
8
+ * surface into the active Hermes profile without requiring a Git checkout.
9
+ */
10
+
11
+ import { copyFileSync, mkdirSync, readFileSync } from 'node:fs';
12
+ import { basename, dirname, join, resolve } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+
15
+ const packageDir = dirname(fileURLToPath(import.meta.url));
16
+
17
+ function main(argv) {
18
+ const options = parseArgs(argv);
19
+ if (options.help) {
20
+ printHelp();
21
+ return;
22
+ }
23
+ if (options.command !== 'install') {
24
+ throw new Error(`Unknown command '${options.command}'. Expected 'install'.`);
25
+ }
26
+ const target = options.target ?? defaultTarget();
27
+ installProvider(target);
28
+ printNextSteps(target);
29
+ }
30
+
31
+ function parseArgs(argv) {
32
+ const options = { command: 'install', target: undefined, help: false };
33
+ const args = [...argv];
34
+ if (args[0] && !args[0].startsWith('-')) {
35
+ options.command = args.shift();
36
+ }
37
+ while (args.length > 0) {
38
+ const arg = args.shift();
39
+ if (arg === '--help' || arg === '-h') {
40
+ options.help = true;
41
+ continue;
42
+ }
43
+ if (arg === '--target') {
44
+ const value = args.shift();
45
+ if (!value) throw new Error('--target requires a path');
46
+ options.target = resolve(value);
47
+ continue;
48
+ }
49
+ throw new Error(`Unknown option '${arg}'`);
50
+ }
51
+ return options;
52
+ }
53
+
54
+ function defaultTarget() {
55
+ const hermesHome = process.env.HERMES_HOME || defaultHermesHome();
56
+ return join(hermesHome, 'plugins', 'memory', 'atomicmemory');
57
+ }
58
+
59
+ function defaultHermesHome() {
60
+ const home = process.env.HOME;
61
+ if (!home) {
62
+ throw new Error('Set HERMES_HOME or HOME before installing the Hermes provider.');
63
+ }
64
+ return join(home, '.hermes');
65
+ }
66
+
67
+ function installProvider(target) {
68
+ mkdirSync(target, { recursive: true });
69
+ for (const file of providerFiles()) {
70
+ copyFileSync(join(packageDir, file), join(target, basename(file)));
71
+ }
72
+ }
73
+
74
+ function providerFiles() {
75
+ const pkg = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf8'));
76
+ return pkg.files.filter((file) => file.endsWith('.py') || file === 'plugin.yaml' || file === 'README.md');
77
+ }
78
+
79
+ function printNextSteps(target) {
80
+ console.log(`Installed AtomicMemory Hermes provider to ${target}`);
81
+ console.log('');
82
+ console.log('Next:');
83
+ console.log(' export ATOMICMEMORY_API_URL="http://127.0.0.1:3050"');
84
+ console.log(' export ATOMICMEMORY_API_KEY="local-dev-key"');
85
+ console.log(' hermes memory setup');
86
+ console.log(' hermes memory status');
87
+ }
88
+
89
+ function printHelp() {
90
+ console.log(`Usage: atomicmemory-hermes [install] [--target <dir>]
91
+
92
+ Installs the AtomicMemory Hermes memory provider into:
93
+ $HERMES_HOME/plugins/memory/atomicmemory
94
+
95
+ When HERMES_HOME is unset, defaults to:
96
+ $HOME/.hermes/plugins/memory/atomicmemory`);
97
+ }
98
+
99
+ try {
100
+ main(process.argv.slice(2));
101
+ } catch (error) {
102
+ console.error(error instanceof Error ? error.message : String(error));
103
+ process.exit(1);
104
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomicmemory/hermes-plugin",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "AtomicMemory native Hermes memory provider — Python SDK-backed, cross-tool memory by default.",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -12,7 +12,11 @@
12
12
  "url": "git+https://github.com/atomicstrata/atomicmemory-integrations.git",
13
13
  "directory": "plugins/hermes"
14
14
  },
15
+ "bin": {
16
+ "atomicmemory-hermes": "install.mjs"
17
+ },
15
18
  "files": [
19
+ "CHANGELOG.md",
16
20
  "__init__.py",
17
21
  "client.py",
18
22
  "config.py",
@@ -20,6 +24,8 @@
20
24
  "tools.py",
21
25
  "breaker.py",
22
26
  "worker.py",
27
+ "install.mjs",
28
+ "pyproject.toml",
23
29
  "plugin.yaml",
24
30
  "README.md"
25
31
  ],
package/plugin.yaml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: atomicmemory
2
- version: 0.1.10
2
+ version: 0.1.11
3
3
  description: "AtomicMemory native Hermes memory provider — Python SDK-backed, cross-tool memory by default."
4
4
  pip_dependencies:
5
5
  - "atomicmemory>=1.0.1,<2.0.0"
package/pyproject.toml ADDED
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "atomicmemory-hermes"
7
+ version = "0.1.11"
8
+ description = "AtomicMemory native Hermes memory provider."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "Apache-2.0"
12
+ authors = [{ name = "Atomic Strata" }]
13
+ dependencies = ["atomicmemory>=1.0.1,<2.0.0"]
14
+
15
+ [project.urls]
16
+ Repository = "https://github.com/atomicstrata/atomicmemory-integrations"
17
+ Documentation = "https://docs.atomicstrata.ai/integrations/coding-agents/hermes/local"
18
+
19
+ [project.entry-points."hermes_agent.plugins"]
20
+ atomicmemory = "atomicmemory_hermes:register"
21
+
22
+ [tool.setuptools]
23
+ packages = ["atomicmemory_hermes"]
24
+
25
+ [tool.setuptools.package-dir]
26
+ atomicmemory_hermes = "."
27
+
28
+ [tool.setuptools.package-data]
29
+ atomicmemory_hermes = ["plugin.yaml", "README.md"]
package/python_sdk.py CHANGED
@@ -252,15 +252,7 @@ def _is_atomicmemory_module(name: str) -> bool:
252
252
 
253
253
 
254
254
  def _plugin_roots() -> set[Path]:
255
- roots = {Path(__file__).resolve().parent}
256
- module = sys.modules.get("atomicmemory")
257
- file_name = getattr(module, "__file__", None)
258
- if file_name:
259
- try:
260
- roots.add(Path(file_name).resolve().parent)
261
- except OSError:
262
- pass
263
- return roots
255
+ return {Path(__file__).resolve().parent}
264
256
 
265
257
 
266
258
  def _remove_plugin_import_roots(plugin_roots: set[Path]) -> list[tuple[int, str]]: