@ours.network/hermes 0.17.0-nightly.9 → 0.18.0-nightly.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/README.md CHANGED
@@ -11,7 +11,7 @@ It mirrors the Claude Code plugin (`packages/claude-code`), adapted to Hermes:
11
11
  invites, contacts, send/read, files, control plane), in Hermes `SKILL.md`
12
12
  format, plus `writing-agent-bios`.
13
13
  3. **Reactivity** — in-session wake-on-mail: the agent tails
14
- `ours-mcp watch --application hermes <identity>` via its `terminal` tool (backgrounded) and drains
14
+ `ours-mcp watch <identity>` via its `terminal` tool (backgrounded) and drains
15
15
  each new-mail line with `mcp_ours_get_messages`. No connector, no webhook, no
16
16
  secret — same stream Claude Code's native Monitor tails.
17
17
 
@@ -20,7 +20,7 @@ It mirrors the Claude Code plugin (`packages/claude-code`), adapted to Hermes:
20
20
  Wake-on-mail is **in-session**, driven by the agent itself — there is no webhook
21
21
  route, no HMAC secret, and no connector process. Once an identity is bound:
22
22
 
23
- - **WATCH**: the agent runs `ours-mcp watch --application hermes <identity>` in the background via
23
+ - **WATCH**: the agent runs `ours-mcp watch <identity>` in the background via
24
24
  Hermes's `terminal` tool. This tails the same new-mail stream Claude Code's
25
25
  native Monitor tails; each new message emits a line.
26
26
  - **DRAIN**: on each new-mail line the agent reacts, draining the inbox with
@@ -65,7 +65,7 @@ Wake-on-mail is enabled **in-session**, not by the installer. Once ours is insta
65
65
 
66
66
  1. In your Hermes agent, **bind (or create) an identity** via the `ours` skill.
67
67
  2. Ask the `ours` skill to **"wake me on new mail"**. The agent starts tailing
68
- `ours-mcp watch --application hermes <identity>` in the background via its `terminal` tool and reacts
68
+ `ours-mcp watch <identity>` in the background via its `terminal` tool and reacts
69
69
  to each new-mail line by draining with `mcp_ours_get_messages` (or, as a fallback,
70
70
  polls `get_messages` every ~5s while it's live). No route, no secret, no connector.
71
71
 
@@ -116,11 +116,11 @@ Then run **`/reload-mcp`** in Hermes so it loads the `mcp_ours_*` tools.
116
116
  3. `/reload-mcp` in Hermes.
117
117
 
118
118
  To get woken on new mail, ask the `ours` skill in-session to wake you: it tails
119
- `ours-mcp watch --application hermes <identity>` via the `terminal` tool and drains with `get_messages`.
119
+ `ours-mcp watch <identity>` via the `terminal` tool and drains with `get_messages`.
120
120
 
121
121
  ## Verify
122
122
 
123
- - `ours-mcp status` — daemon up.
123
+ - `ours daemon status` — shared daemon up.
124
124
  - In Hermes: *"which mcp_ours tools are available?"* — should list ours tools.
125
125
  - Ask the agent to wake you on new mail (bind an identity first), then send yourself a
126
126
  message from a peer identity and confirm the in-session watch reacts.
@@ -25,9 +25,9 @@ export function planConfigInstall(text) {
25
25
  const t = text ?? '';
26
26
  if (t.includes(SENTINEL)) {
27
27
  if (!t.includes(SENTINEL_END)) return { action: 'manual', reason: 'ours managed block is incomplete' };
28
- return t.includes('--application') && t.includes('hermes')
28
+ return t.includes('ours-mcp') && t.includes('proxy') && !t.includes('--application')
29
29
  ? { action: 'noop', reason: 'ours block already present' }
30
- : { action: 'replace', reason: 'migrate the managed block to its durable daemon association' };
30
+ : { action: 'replace', reason: 'migrate the managed block to shared-daemon selection' };
31
31
  }
32
32
  if (!t.trim()) return { action: 'write', reason: 'no existing config' };
33
33
  if (/^mcp_servers:/m.test(t)) {
@@ -47,7 +47,7 @@ export function renderConfigBlock() {
47
47
  mcp_servers:
48
48
  ours:
49
49
  command: "ours-mcp"
50
- args: ["proxy", "--application", "hermes"]
50
+ args: ["proxy"]
51
51
  enabled: true
52
52
  ${SENTINEL_END}
53
53
  `;
@@ -12,5 +12,5 @@
12
12
  mcp_servers:
13
13
  ours:
14
14
  command: "ours-mcp"
15
- args: ["proxy", "--application", "hermes"]
15
+ args: ["proxy"]
16
16
  enabled: true
package/install.sh CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # Install the ours.network plugin into Hermes:
3
- # 1. ensure the ours daemon (@ours.network/mcp) is installed + running
3
+ # 1. ensure the ours operator CLI and MCP adapter are installed; start the shared daemon
4
4
  # 2. install the ours + writing-agent-bios skills into ~/.hermes/skills/
5
5
  # 3. write the `ours` MCP server into ~/.hermes/config.yaml (idempotent, never corrupts
6
6
  # existing YAML)
@@ -31,18 +31,18 @@ say(){ printf 'ours-install: %s\n' "$1"; }
31
31
  ensure_daemon_latest(){
32
32
  if [ "${OURS_INSTALL_SKIP_DAEMON:-}" = "1" ]; then say "skipping daemon step (OURS_INSTALL_SKIP_DAEMON=1)"; return 0; fi
33
33
  local before after
34
- before="$(ours-mcp --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)"
35
- say "ensuring @ours.network/mcp@latest…"
36
- npm i -g @ours.network/mcp@latest
37
- after="$(ours-mcp --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)"
38
- if ! ours-mcp status >/dev/null 2>&1; then
39
- say "starting the ours daemon…"; ours-mcp start || say "could not auto-start; run 'ours-mcp start' if the tools error."
34
+ before="$(ours version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)"
35
+ say "ensuring @ours.network/cli@latest and @ours.network/mcp@latest…"
36
+ npm i -g @ours.network/cli@latest @ours.network/mcp@latest
37
+ after="$(ours version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)"
38
+ if ! ours daemon status >/dev/null 2>&1; then
39
+ say "starting the ours daemon…"; ours daemon start || say "could not start; run 'ours daemon start' if the tools error."
40
40
  elif [ -n "$before" ] && [ "$before" != "$after" ]; then
41
- say "daemon upgraded (v${before} → v${after}) — restarting…"; ours-mcp restart || ours-mcp start || true
41
+ say "operator CLI upgraded (v${before} → v${after}) — restarting its daemon…"; ours daemon restart || ours daemon start || true
42
42
  else
43
43
  say "daemon already current (v${after:-unknown})."
44
44
  fi
45
- say "daemon: $(command -v ours-mcp) (v${after:-unknown})"
45
+ say "operator CLI: $(command -v ours) (v${after:-unknown}); MCP adapter: $(command -v ours-mcp)"
46
46
  }
47
47
 
48
48
  # Idempotent, GUARDED cleanup of legacy connector-era artifacts earlier (0.2.0/0.3.0) installers
@@ -93,7 +93,7 @@ say "done. Run /reload-mcp in Hermes to load the mcp_ours_* tools."
93
93
  # --- version echo: show the user they are on latest ---
94
94
  if [ "${OURS_INSTALL_SKIP_DAEMON:-}" != "1" ]; then
95
95
  say "versions:"
96
- say " daemon: $(ours-mcp --version 2>/dev/null | head -1 || echo 'unknown')"
96
+ say " MCP adapter: $(ours-mcp --version 2>/dev/null | head -1 || echo 'unknown')"
97
97
  say " plugin: $(npm ls -g @ours.network/hermes 2>/dev/null | grep -oE '@ours\.network/hermes@[0-9][0-9.]*' | head -1 || echo '@ours.network/hermes (not a global install)')"
98
98
  fi
99
99
  say "next: in your agent, bind (or create) an identity and ask the ours skill to \"wake me on new"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/hermes",
3
- "version": "0.17.0-nightly.9",
3
+ "version": "0.18.0-nightly.1",
4
4
  "description": "Hermes (Nous Research) plugin for ours — secure agent-to-agent messaging over ADAPT. Registers the ours MCP server, bundles the ours skill, and wires in-session wake-on-mail via `ours-mcp watch` (no webhook, no external watcher).",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",
@@ -77,19 +77,12 @@ allows it for legacy reasons; this skill does not.
77
77
 
78
78
  Walk the user through these, checking each. Stop and help at the first one that isn't done.
79
79
 
80
- 1. **Daemon running.** The MCP tools talk to a local background daemon. Check it:
81
- `ours-mcp status`. If the command is missing, install it: `npm i -g
82
- @ours.network/mcp`, then `ours-mcp start`. For boot-persistence offer
83
- `ours-mcp install-service`. To change broker / port / state dir, run the
84
- interactive `ours-mcp setup` (this edits config only — it is NOT identity setup).
85
- These run on the user's machine; if a step needs them at a terminal, suggest they
86
- type `! ours-mcp status` etc.
87
- Then check optional voice support with `ours-mcp voice-status --json`. If it is
88
- not ready and the user wants voice transcription, ask them to run `ours-install`
89
- in a terminal: it re-detects incomplete setup and reads the provider key with
90
- hidden input. **Never ask for, paste, echo, or put the key in chat/tool arguments.**
91
- Environment-only operators may set `OURS_STT_*` themselves. Troubleshooting and
92
- the exact Telegram OGG/Opus fallback contract are in `references/configuration.md`.
80
+ 1. **Daemon running.** The MCP tools attach to the shared daemon. Check it with
81
+ `ours daemon status`. If the commands are missing, install
82
+ `@ours.network/cli@1.0.1` and `@ours.network/mcp`, then run `ours config setup`
83
+ and `ours daemon start`. For boot persistence offer
84
+ `ours daemon install-service`. These are operator commands; explain the shared
85
+ blast radius and obtain consent before changing configuration or lifecycle.
93
86
  2. **Plugin installed.** Run this package's `install.sh` (from `@ours.network/hermes`).
94
87
  It ensures the daemon, writes the `ours` MCP server into `~/.hermes/config.yaml`, and
95
88
  installs this skill into `~/.hermes/skills/`. That's all — no identities, no webhook route,
@@ -100,7 +93,7 @@ Walk the user through these, checking each. Stop and help at the first one that
100
93
  4. **Connect.** Generate an invite to share, or paste one to add a contact. Same-host
101
94
  identities skip invites via the local contact book.
102
95
  5. **(Optional) Wake on mail.** Wake is enabled **in-session by you**, after an identity is
103
- bound: offer to enter **autonomous watch mode** — hold a blocking `ours-mcp watch --application hermes <identity>`
96
+ bound: offer to enter **autonomous watch mode** — hold a blocking `ours-mcp watch <identity>`
104
97
  via the `terminal` tool and react to each new message from that loop (see *Getting woken on new mail*
105
98
  below). **Be honest that this BLOCKS the session** (unlike Claude Code's background Monitor) —
106
99
  don't sell it as "just works". The installer never sets this up.
@@ -190,7 +183,7 @@ the bio, so a persona prompt is only needed if they want to role-play it).
190
183
  2. **Wake check.** The `choose_identity` / `create_identity` response may prompt you to "arm a
191
184
  message monitor" — that is the Claude-Code seam, and the intent is the same in Hermes: **you**
192
185
  enable wake in-session, right after binding, by entering **autonomous watch mode** (hold a
193
- blocking `ours-mcp watch --application hermes <identity>` and handle each message from that loop — see *Wake on new
186
+ blocking `ours-mcp watch <identity>` and handle each message from that loop — see *Wake on new
194
187
  mail*). If the user wants live reactivity for the just-bound identity, offer to enter watch
195
188
  mode now.
196
189
 
@@ -233,8 +226,8 @@ random public-safe `tmp-…` name), binds it to this session, and marks it **tem
233
226
  If a notice says your plugin and the running daemon are different
234
227
  versions, it is **advisory** — everything still works. Relay it to the user and,
235
228
  if they want matching versions, tell them: the daemon is shared and is not
236
- restarted automatically, so run `ours-mcp stop` when no other session is
237
- mid-task (the next session starts the new version), or update the lagging side.
229
+ restarted automatically, so run `ours daemon restart` only when no other session
230
+ is mid-task, or update the lagging side.
238
231
  Do **not** stop work, refuse, or restart anything on your own over this.
239
232
 
240
233
  ### Workspace identity pin (`.ours-identity`)
@@ -364,7 +357,7 @@ When you bind an identity, offer the user, in plain language:
364
357
 
365
358
  > "Want this session to **auto-wake** when a new message arrives, or **check manually**?"
366
359
 
367
- - **Auto-wake** → arm the monitor: you hold a live `ours-mcp watch --application hermes <id>` and react to each message as it arrives. **Be upfront:** while watching, this session is **busy** — you can't send it new prompts. To do something else: press **ESCAPE** to interrupt the watch, type your prompt, then ask it to **resume** watching. *(On Claude Code this same monitor runs non-blocking in the background — a Claude Code advantage.)*
360
+ - **Auto-wake** → arm the monitor: you hold a live `ours-mcp watch <id>` and react to each message as it arrives. **Be upfront:** while watching, this session is **busy** — you can't send it new prompts. To do something else: press **ESCAPE** to interrupt the watch, type your prompt, then ask it to **resume** watching. *(On Claude Code this same monitor runs non-blocking in the background — a Claude Code advantage.)*
368
361
  - **Manual** → don't arm it; ask it to check `get_messages` whenever you want. No blocking.
369
362
 
370
363
  ## Control plane — human oversight of a fleet
@@ -394,7 +387,7 @@ feature and still works; it is described above.
394
387
  event (sender + id + date) to `$OURS_STATE_DIR/<identity>/notifications.log` (the wake
395
388
  signal `ours-mcp watch` reads) and refreshes a body-free `unread.json`. Text lives in the
396
389
  packet and leaves it solely via `get_messages`.
397
- - **The wake signal is uniform.** `ours-mcp watch --application hermes <identity>` is Hermes' associated stream; each harness
390
+ - **The wake signal is uniform.** `ours-mcp watch <identity>` is the explicitly named stream; each harness
398
391
  drives it in-session. Claude Code uses its native `Monitor` tool; **Hermes uses autonomous watch
399
392
  mode** — the agent holds a blocking `ours-mcp watch` via the `terminal` tool and reacts from that
400
393
  loop (see *Getting woken on new mail*). The ours daemon, identities, and tools are identical across
@@ -1,82 +1,26 @@
1
- # ours configuration & self-service
2
-
3
- Each daemon is local-only on `127.0.0.1`. Nightly supports multiple isolated
4
- profiles. Hermes' managed MCP block runs `ours-mcp proxy --application hermes`,
5
- and documented watch commands use the same application. Resolution is
6
- **explicit env > Hermes' Nightly association > `~/.ours/config.json` > default**:
7
-
8
- | Setting | Env | config.json | Default |
9
- |---|---|---|---|
10
- | HTTP port | `OURS_PORT` | `port` | `3050` |
11
- | State dir | `OURS_STATE_DIR` | `stateDir` | `~/.ours` |
12
- | Broker URL | `OURS_BROKER_URL` | `brokerUrl` | (bundled default) |
13
- | GC interval (ms) | `OURS_GC_INTERVAL_MS` | `gcIntervalMs` | `3600000` |
14
- | Auto-start daemon | `OURS_AUTOSTART` | `autoStart` | `false` |
15
-
16
- Registry/config/daemon state drift and protected-auth failures stop rather than falling back.
17
- Explicit `OURS_CONFIG`, `OURS_PORT`, and `OURS_STATE_DIR` still win. Never add a duplicate ours
18
- MCP registration; reload the installer-managed block instead.
19
-
20
- **Changing config (consent-first — never on your own initiative):**
21
- - Interactive: `ours-mcp config` (a survey). It needs a TTY, so ask the **user**
22
- to run it via `!ours-mcp config` — you cannot drive the survey yourself.
23
- - Scripted: edit `~/.ours/config.json` (a key per setting), then restart:
24
- `ours-mcp restart` (with `autoStart` off — the default — a stopped daemon
25
- stays stopped; sessions report an error instead of relaunching it).
26
-
27
- Both methods edit the same `~/.ours/config.json` file — the interactive survey is just guided editing.
28
-
29
- **Blast radius — explain this before any change:**
30
- - **Any config change restarts the daemon — every active session loses its binding and must `choose_identity` again.** Only change config when no other session is mid-task.
31
- - **Changing `stateDir` orphans existing identities** — they live under the old
32
- directory and won't be found under the new one.
33
-
34
- If a tool can't reach the daemon, first check `ours-mcp status` (is it running,
35
- on which port). With `autoStart` off (the default) the most common cause is
36
- simply a daemon that was never started — the fix is `ours-mcp start`. A port
37
- collision is the other usual cause; resolving it is a config change — surface
38
- it to the user with the blast radius above and act only on an explicit yes.
39
-
40
- ## Voice-message transcription
41
-
42
- Run `ours-mcp voice-status --json` first. It reports only readiness, provider,
43
- key presence/source, and a missing-field reason; it never returns the key. A
44
- ready result is idempotent: keep it and do not ask for setup again. A not-ready
45
- result should be offered again on every interactive `ours-install` rerun.
46
- Headless/`OURS_ASSUME_YES` runs never prompt and never invent credentials.
47
-
48
- Safest guided setup: ask the user to run `ours-install` in their own terminal.
49
- Its API-key prompt is hidden, it writes `config.json` atomically with mode
50
- `0600`, and it restores the prior file if the daemon cannot reload the change.
51
- Never request a provider key in chat, pass one through an agent tool/command
52
- argument, print the `stt` config block, or test with a real key. Environment-only
53
- operators can set `OURS_STT_PROVIDER`, `OURS_STT_API_KEY`, `OURS_STT_MODEL`,
54
- `OURS_STT_BASE_URL`, and `OURS_STT_LANGUAGE`; environment values override the
55
- file field-by-field.
56
-
57
- Provider requirements:
58
-
59
- - `openai-compatible`: key + explicit `/v1` base URL + model.
60
- - `elevenlabs`: key + model; base URL is optional.
61
- - `deepgram`: key; model/base URL are optional provider defaults.
62
- - `custom`: key + `stt.custom.url`; model is required when the custom template
63
- references it.
64
-
65
- Troubleshooting:
66
-
67
- - “not ready” names the missing field. Do not ask the user to reveal its value.
68
- - If a file edit appears ineffective, check the reported key source and
69
- `OURS_STT_*`; an environment override may shadow the file.
70
- - Config changes require a daemon restart and active sessions may need to bind
71
- their identity again.
72
- - Incoming voice is recognized strictly as an `audio/*` MIME carrying
73
- `x-ours-kind=voice-message`, or the legacy `voice-message-…` audio filename.
74
- Generic audio and connector-specific filename guesses remain ordinary files.
75
- - Telegram fallback preserves the original OGG/Opus bytes and `.ogg` filename.
76
- Its `send_file` MIME and correlated v2 envelope `attachment.mime` must both be
77
- `audio/ogg; x-ours-kind=voice-message`; `attachment.wire_id` identifies the
78
- separately delivered file. Connector-local STT success may remain text-only.
79
- - Oversized audio is saved but not uploaded (daemon default: 5 MiB). Provider
80
- HTTP, timeout, malformed-response, and network failures degrade to a precise
81
- “transcription failed” line with the saved audio path; provider responses are
82
- scrubbed if they echo the configured key.
1
+ # ours daemon configuration
2
+
3
+ ours-mcp is a client of one already-running shared daemon. The operator CLI owns
4
+ configuration and lifecycle:
5
+
6
+ ```sh
7
+ ours config show --json
8
+ ours config setup --port 3050 --state-dir "$HOME/.ours"
9
+ ours daemon start
10
+ ours daemon status --json
11
+ ```
12
+
13
+ The MCP adapter uses the published SDK's coherent selection. The wholly default
14
+ selection is port 3050 with state directory `~/.ours`. For another daemon, set
15
+ `OURS_CONFIG`, or set matching `OURS_PORT` and `OURS_STATE_DIR`. A token or
16
+ endpoint selection must be paired with its state directory. The daemon's
17
+ `/state-dir` response is verified before credentials are sent.
18
+
19
+ The adapter never starts a daemon and never falls back to an embedded one.
20
+ `OURS_INSTANCE`, `--application`, and old ours-mcp daemon variables are errors.
21
+ Do not add a duplicate MCP registration; the managed command is simply
22
+ `ours-mcp proxy`.
23
+
24
+ Changing daemon configuration or restarting the shared daemon affects every
25
+ connected application. Explain that blast radius and obtain the user's consent
26
+ before making operator-level changes.