@ours.network/hermes 0.16.0 → 0.17.0-nightly.10

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 <identity>` via its `terminal` tool (backgrounded) and drains
14
+ `ours-mcp watch --application hermes <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 <identity>` in the background via
23
+ - **WATCH**: the agent runs `ours-mcp watch --application hermes <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 <identity>` in the background via its `terminal` tool and reacts
68
+ `ours-mcp watch --application hermes <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,7 +116,7 @@ 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 <identity>` via the `terminal` tool and drains with `get_messages`.
119
+ `ours-mcp watch --application hermes <identity>` via the `terminal` tool and drains with `get_messages`.
120
120
 
121
121
  ## Verify
122
122
 
@@ -23,7 +23,12 @@ const SENTINEL_END = '# <<< ours.network plugin';
23
23
  // could corrupt existing YAML.
24
24
  export function planConfigInstall(text) {
25
25
  const t = text ?? '';
26
- if (t.includes(SENTINEL)) return { action: 'noop', reason: 'ours block already present' };
26
+ if (t.includes(SENTINEL)) {
27
+ if (!t.includes(SENTINEL_END)) return { action: 'manual', reason: 'ours managed block is incomplete' };
28
+ return t.includes('--application') && t.includes('hermes')
29
+ ? { action: 'noop', reason: 'ours block already present' }
30
+ : { action: 'replace', reason: 'migrate the managed block to its durable daemon association' };
31
+ }
27
32
  if (!t.trim()) return { action: 'write', reason: 'no existing config' };
28
33
  if (/^mcp_servers:/m.test(t)) {
29
34
  return {
@@ -42,7 +47,7 @@ export function renderConfigBlock() {
42
47
  mcp_servers:
43
48
  ours:
44
49
  command: "ours-mcp"
45
- args: ["proxy"]
50
+ args: ["proxy", "--application", "hermes"]
46
51
  enabled: true
47
52
  ${SENTINEL_END}
48
53
  `;
@@ -67,9 +72,13 @@ function main() {
67
72
  process.exitCode = 3;
68
73
  return;
69
74
  }
70
- const next = plan.action === 'write' ? block : existing.replace(/\s*$/, '\n\n') + block;
75
+ const next = plan.action === 'write' ? block
76
+ : plan.action === 'replace'
77
+ ? existing.replace(new RegExp(`${SENTINEL.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?${SENTINEL_END.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n?`), block)
78
+ : existing.replace(/\s*$/, '\n\n') + block;
71
79
  writeFileSync(cfgPath, next);
72
- console.log(`ours: ${plan.action === 'write' ? 'wrote' : 'appended ours block to'} ${cfgPath}. Run /reload-mcp in Hermes.`);
80
+ const verb = plan.action === 'write' ? 'wrote' : plan.action === 'replace' ? 'updated ours block in' : 'appended ours block to';
81
+ console.log(`ours: ${verb} ${cfgPath}. Run /reload-mcp in Hermes.`);
73
82
  }
74
83
 
75
84
  if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main();
@@ -12,5 +12,5 @@
12
12
  mcp_servers:
13
13
  ours:
14
14
  command: "ours-mcp"
15
- args: ["proxy"]
15
+ args: ["proxy", "--application", "hermes"]
16
16
  enabled: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/hermes",
3
- "version": "0.16.0",
3
+ "version": "0.17.0-nightly.10",
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",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ours
3
- description: Use when the user wants to set up or configure ours or ours-fleet, onboard onto the ours network, create or switch an identity, connect with another agent or person, exchange encrypted messages or files, check incoming mail, arm live monitoring, bind a web-messenger control proxy, or spawn/configure/oversee a persistent or temporary fleet agent. Trigger phrases include "set up ours", "set up ours-fleet", "configure fleet", "spawn fleet agent", "use identity X", "send a message", "check my messages", "watch for messages", "wake me on new mail", "bind the monitoring proxy", and "set up the control panel".
3
+ description: Use when the user wants to set up or configure ours or ours-fleet, onboard onto the ours network, create or switch an identity, connect with another agent or person, exchange encrypted messages or files, check incoming mail, arm live monitoring, or spawn/configure/oversee a persistent or temporary fleet agent. Trigger phrases include "set up ours", "set up ours-fleet", "configure fleet", "spawn fleet agent", "use identity X", "send a message", "check my messages", "watch for messages", "wake me on new mail".
4
4
  metadata:
5
5
  hermes:
6
6
  tags: [ours, ours.network, a2a, adapt, e2e, messaging, identity]
@@ -21,8 +21,9 @@ are three surfaces:
21
21
 
22
22
  - **Layer 1 — identities** (global): create / bind / switch the identity you act as.
23
23
  - **Layer 2 — messaging** (per the bound identity): invites, contacts, send/read.
24
- - **Control plane** (the host's **Human identity**): bind a human's web-messenger as a
25
- **monitoring & control proxy** that can oversee and command a fleet of agents.
24
+ - **Control plane** (the host's **Human identity**): a human's web-messenger acting as a
25
+ **monitoring & control proxy** over a fleet of agents. **Not available in this release** —
26
+ its MCP tools were removed; see "Control plane" below before offering anything.
26
27
 
27
28
  Identities come in exactly two kinds, in a fixed order:
28
29
 
@@ -99,12 +100,13 @@ Walk the user through these, checking each. Stop and help at the first one that
99
100
  4. **Connect.** Generate an invite to share, or paste one to add a contact. Same-host
100
101
  identities skip invites via the local contact book.
101
102
  5. **(Optional) Wake on mail.** Wake is enabled **in-session by you**, after an identity is
102
- bound: offer to enter **autonomous watch mode** — hold a blocking `ours-mcp watch <identity>`
103
+ bound: offer to enter **autonomous watch mode** — hold a blocking `ours-mcp watch --application hermes <identity>`
103
104
  via the `terminal` tool and react to each new message from that loop (see *Getting woken on new mail*
104
105
  below). **Be honest that this BLOCKS the session** (unlike Claude Code's background Monitor) —
105
106
  don't sell it as "just works". The installer never sets this up.
106
- 6. **(Optional) Oversight.** If they want to watch/command a fleet from a phone or
107
- browser, set up the **control-plane monitoring proxy**.
107
+ 6. **Oversight.** If they ask to watch/command a fleet from a phone or browser, say the
108
+ **control-plane monitoring proxy is not available in this release** — there is no tool
109
+ to call. See "Control plane" below.
108
110
 
109
111
  - **Configuration.** Port, state dir, broker, and GC interval are configurable
110
112
  (env > `~/.ours/config.json` > default; port default 3050). Daemon config is
@@ -188,7 +190,7 @@ the bio, so a persona prompt is only needed if they want to role-play it).
188
190
  2. **Wake check.** The `choose_identity` / `create_identity` response may prompt you to "arm a
189
191
  message monitor" — that is the Claude-Code seam, and the intent is the same in Hermes: **you**
190
192
  enable wake in-session, right after binding, by entering **autonomous watch mode** (hold a
191
- blocking `ours-mcp watch <identity>` and handle each message from that loop — see *Wake on new
193
+ blocking `ours-mcp watch --application hermes <identity>` and handle each message from that loop — see *Wake on new
192
194
  mail*). If the user wants live reactivity for the just-bound identity, offer to enter watch
193
195
  mode now.
194
196
 
@@ -362,48 +364,24 @@ When you bind an identity, offer the user, in plain language:
362
364
 
363
365
  > "Want this session to **auto-wake** when a new message arrives, or **check manually**?"
364
366
 
365
- - **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.)*
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.)*
366
368
  - **Manual** → don't arm it; ask it to check `get_messages` whenever you want. No blocking.
367
369
 
368
- ## Control plane — bind a monitoring proxy (human oversight of a fleet)
369
-
370
- This is **separate** from the wake-on-mail watch above. The control plane lets a **person's
371
- web-messenger account** (the ours web messenger, shipping as part of the upcoming ours-control-plane)
372
- oversee and command all agents under this host's **Human identity** from a **Control
373
- Panel**: view a **live monitoring feed** of monitored agents' traffic, create agents, edit
374
- their bios **and personas**, toggle each agent's monitoring, open a chat with any agent (the
375
- Human identity commands the agent to mint an invite — no out-of-band step), and remove agents. A
376
- coordinator can also set a worker's local persona via the cluster; the agent still asks the
377
- user before adopting it. All of it rides the same
378
- e2e channels as messages but in a separate control queue agents never see; monitoring bodies
379
- are never written to disk on the host.
380
-
381
- **Prerequisites**
382
- - The **Human identity** exists (`create_root_identity` — the onboarding step). The
383
- proxy binds to the Human identity.
384
- - The messenger account is already a **contact of the Human identity** — do the normal
385
- invite exchange first: bind the Human identity, `generate_invite`, and have the
386
- messenger redeem it (or redeem the messenger's invite with `add_contact`).
387
-
388
- **Binding ceremony (6-digit code, out-of-band)**
389
- 1. "bind my messenger account as the monitoring proxy" →
390
- `bind_monitoring_proxy({ contact: "<the messenger contact>" })`. This automatically
391
- targets the host's Human identity (you do **not** need to be bound as it). It returns a
392
- **6-digit code** (valid 5 minutes, 3 attempts) and shows it **here**.
393
- 2. **Read the code to the user.** They open the messenger → the conversation with the Human identity →
394
- **Control Panel** → enter the code. The code must travel **out-of-band** — reading it off
395
- this terminal is what proves you control both ends. **Never send the code over ours.**
396
- 3. On success the contact becomes the proxy. Confirm with `get_monitoring_status`.
397
-
398
- **Per-agent monitoring is controller-gated.** Once a proxy is bound, the proxy (Control
399
- Panel) turns an agent's monitoring on/off — there is **no local enable/disable tool**. A
400
- monitored agent reports a signed copy of every message it sends/receives to the Human
401
- identity's node, which forwards it to the proxy's feed.
402
-
403
- **Status** — "what's the monitoring/control state" → `get_monitoring_status()` reports the
404
- Human identity's bound proxy (if any), a pending code verification, queued copies/control
405
- requests, and each agent's monitoring ON/off. Works whenever the Human identity exists.
370
+ ## Control plane — human oversight of a fleet
406
371
 
372
+ **NOT AVAILABLE IN THIS RELEASE. Do not offer it, and do not call a tool for it.**
373
+ The `bind_monitoring_proxy` and `get_monitoring_status` MCP tools were removed with the
374
+ daemon-side control plane; there is no tool behind them and a call will fail. Nothing has
375
+ replaced them yet.
376
+
377
+ The capability itself is not cancelled: the monitoring/control surface remains in the
378
+ **protocol core**, untouched, for whenever it is reimplemented. What is gone is this
379
+ plugin's exposure of it as MCP tools.
380
+
381
+ If a user asks to bind a web-messenger account as a monitoring/control proxy, to open a
382
+ Control Panel, or to check monitoring status — say plainly that it is not available in this
383
+ release, and do not improvise a substitute. Per-identity wake-on-mail is a **different**
384
+ feature and still works; it is described above.
407
385
  ## Notes
408
386
 
409
387
  - Identities and their state (contacts, inbox, keys) persist under the daemon's state dir
@@ -416,7 +394,7 @@ requests, and each agent's monitoring ON/off. Works whenever the Human identity
416
394
  event (sender + id + date) to `$OURS_STATE_DIR/<identity>/notifications.log` (the wake
417
395
  signal `ours-mcp watch` reads) and refreshes a body-free `unread.json`. Text lives in the
418
396
  packet and leaves it solely via `get_messages`.
419
- - **The wake signal is uniform.** `ours-mcp watch <identity>` is the common stream; each harness
397
+ - **The wake signal is uniform.** `ours-mcp watch --application hermes <identity>` is Hermes' associated stream; each harness
420
398
  drives it in-session. Claude Code uses its native `Monitor` tool; **Hermes uses autonomous watch
421
399
  mode** — the agent holds a blocking `ours-mcp watch` via the `terminal` tool and reacts from that
422
400
  loop (see *Getting woken on new mail*). The ours daemon, identities, and tools are identical across
@@ -1,8 +1,9 @@
1
1
  # ours configuration & self-service
2
2
 
3
- The daemon is a **shared, host-wide singleton** reachable only on `127.0.0.1`
4
- (loopback there is no host knob, by design). Configuration is resolved
5
- **env var > `~/.ours/config.json` > built-in default**:
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**:
6
7
 
7
8
  | Setting | Env | config.json | Default |
8
9
  |---|---|---|---|
@@ -12,10 +13,9 @@ The daemon is a **shared, host-wide singleton** reachable only on `127.0.0.1`
12
13
  | GC interval (ms) | `OURS_GC_INTERVAL_MS` | `gcIntervalMs` | `3600000` |
13
14
  | Auto-start daemon | `OURS_AUTOSTART` | `autoStart` | `false` |
14
15
 
15
- **The port is shared.** Every process that dials the daemon — the `ours-mcp proxy` MCP
16
- server and `ours-mcp watch` connects to `127.0.0.1:<OURS_PORT>`, and the daemon binds the
17
- same port (both read `OURS_PORT`/`config.json`). Change it **once in shared config**, never
18
- per-side, or a dialer won't find the daemon.
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
19
 
20
20
  **Changing config (consent-first — never on your own initiative):**
21
21
  - Interactive: `ours-mcp config` (a survey). It needs a TTY, so ask the **user**