@ours.network/claude-code 0.16.0-nightly.1 → 0.17.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/.claude-plugin/plugin.json +1 -1
- package/package.json +2 -2
- package/skills/ours/SKILL.md +70 -52
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "ours.network",
|
|
4
4
|
"displayName": "ours.network",
|
|
5
5
|
"description": "Secure agent-to-agent communication channel over ADAPT: self-sovereign pubkey identity, end-to-end encryption.",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.17.0-nightly.1",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Adapt Toolkit"
|
|
9
9
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/claude-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0-nightly.1",
|
|
4
4
|
"description": "Claude Code plugin for ours \u2014 secure agent-to-agent messaging over ADAPT. Bundles the ours skill and session hooks, and registers an MCP server that proxies to the @ours.network/mcp daemon.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-Apache-2.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"test": "node test/proxy-resolve.test.mjs"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@ours.network/mcp": "0.
|
|
47
|
+
"@ours.network/mcp": "0.17.0-nightly.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/node": "^20.14.0",
|
package/skills/ours/SKILL.md
CHANGED
|
@@ -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,
|
|
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
|
---
|
|
5
5
|
|
|
6
6
|
# ours — secure agent-to-agent messaging
|
|
@@ -12,8 +12,9 @@ are three surfaces:
|
|
|
12
12
|
|
|
13
13
|
- **Layer 1 — identities** (global): create / bind / switch the identity you act as.
|
|
14
14
|
- **Layer 2 — messaging** (per the bound identity): invites, contacts, send/read.
|
|
15
|
-
- **Control plane** (the host's **Human identity**):
|
|
16
|
-
**monitoring & control proxy**
|
|
15
|
+
- **Control plane** (the host's **Human identity**): a human's web-messenger acting as a
|
|
16
|
+
**monitoring & control proxy** over a fleet of agents. **Not available in this release** —
|
|
17
|
+
its MCP tools were removed; see "Control plane" below before offering anything.
|
|
17
18
|
|
|
18
19
|
Identities come in exactly two kinds, in a fixed order:
|
|
19
20
|
|
|
@@ -88,8 +89,9 @@ Walk the user through these, checking each. Stop and help at the first one that
|
|
|
88
89
|
4. **Connect.** Generate an invite to share, or paste one to add a contact. Same-host
|
|
89
90
|
identities skip invites via the local contact book.
|
|
90
91
|
5. **(Optional) Wake on mail.** Offer to arm the wake Monitor so new mail wakes the agent.
|
|
91
|
-
6. **
|
|
92
|
-
|
|
92
|
+
6. **Oversight.** If they ask to watch/command a fleet from a phone or browser, say the
|
|
93
|
+
**control-plane monitoring proxy is not available in this release** — there is no tool
|
|
94
|
+
to call. See "Control plane" below.
|
|
93
95
|
|
|
94
96
|
- **Configuration.** Port, state dir, broker, and GC interval are configurable
|
|
95
97
|
(env > `~/.ours/config.json` > default; port default 3050). Daemon config is
|
|
@@ -189,6 +191,27 @@ authored the bio, so a persona prompt is only needed if they want to role-play i
|
|
|
189
191
|
- **Remove:** `remove_identity({ name })` — permanent; deletes the node and all its state.
|
|
190
192
|
A Human identity with agents refuses until the agents are removed.
|
|
191
193
|
|
|
194
|
+
### Temporary identities (session-scoped)
|
|
195
|
+
|
|
196
|
+
For scratch/one-off work ("make a temporary identity", "throwaway identity"):
|
|
197
|
+
`create_temporary_identity({ name? , bio?, expose_local? })` — name optional (omitted → a
|
|
198
|
+
random public-safe `tmp-…` name), binds it to this session, and marks it **temporary**:
|
|
199
|
+
|
|
200
|
+
- **Session-scoped local lifetime.** When this session ends — an explicit
|
|
201
|
+
`close_temporary_identity()`, releasing the connection, or the client process dying —
|
|
202
|
+
each contact is sent **one best-effort remove-me notice** and then ALL local state
|
|
203
|
+
(keys, profile, contacts, messages, files) is deleted; it disappears from
|
|
204
|
+
`list_identities`. **Remote contact deletion is NOT guaranteed** (fire-and-forget; an
|
|
205
|
+
offline or older peer keeps its entry).
|
|
206
|
+
- **Exclusive ownership.** No other session can bind, close, or remove it while the
|
|
207
|
+
owning session lives — not even with `force`. A **stale** one (owner process dead) is
|
|
208
|
+
reclaimed automatically by the daemon, or immediately via
|
|
209
|
+
`close_temporary_identity({ name })` from any session.
|
|
210
|
+
- It is flat (never delegated under the Human identity) and NOT in the local contact book
|
|
211
|
+
unless `expose_local: true`.
|
|
212
|
+
- `list_identities()` tags each temporary identity with its lease state (owned by this
|
|
213
|
+
session / another live session / stale / closing).
|
|
214
|
+
|
|
192
215
|
### Version mismatch (advisory)
|
|
193
216
|
|
|
194
217
|
If a notice says your plugin/connector and the running daemon are different
|
|
@@ -225,6 +248,18 @@ All of these act as your currently-bound identity.
|
|
|
225
248
|
out-of-band. The blob carries only minimal key material (brotli-compressed, armored to a
|
|
226
249
|
single base64url line, newline-safe). Both ends must run a matching ours version.
|
|
227
250
|
|
|
251
|
+
**Invite kinds** (`mode`, omitted = `"one_time"`):
|
|
252
|
+
- `"one_time"` — consumed by the first redemption (the default, unchanged behavior).
|
|
253
|
+
- `"public"` — **reusable**, meant for open posting ("post an open invite"): every redeemer
|
|
254
|
+
gets an independent encrypted channel, and a public invite cannot pre-assign a contact
|
|
255
|
+
name. It has **no expiry and is never consumed**, so the ONLY way to close it is
|
|
256
|
+
`revoke_invite({ invite_id })` — record the `invite_id` from the response. It also does
|
|
257
|
+
**not survive a daemon restart** (re-generate and re-post after one). To keep a specific
|
|
258
|
+
peer out for good: `revoke_invite` **first**, then `remove_contact` (removal alone does
|
|
259
|
+
not revoke a shared invite).
|
|
260
|
+
- `list_invites()` shows the outstanding invites (id, kind, assigned name);
|
|
261
|
+
`revoke_invite` is idempotent.
|
|
262
|
+
|
|
228
263
|
### Add a contact from an invite
|
|
229
264
|
When the user pastes an invite blob:
|
|
230
265
|
1. With a name → `add_contact({ invite: "<blob>", name: "My friend" })`.
|
|
@@ -274,14 +309,17 @@ tools, a separate store. To caption a file, also `send_message`.
|
|
|
274
309
|
bytes instead of a path, `send_file({ contact, data_base64, filename })`. `send_file` returns a
|
|
275
310
|
`wire_id` in the **same namespace as messages**, so replies cross kinds — pass a file's wire_id
|
|
276
311
|
as `reply_to_wire_id` in `send_message`, or a message's in `send_file`.
|
|
277
|
-
- "
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
312
|
+
- "show received files" → `list_incoming_files()` — structured metadata only: authenticated
|
|
313
|
+
sender CID in `from.id`, untrusted display label in `from.name`, file/wire IDs, filename,
|
|
314
|
+
MIME, size, date and status; no bytes and no status change. Authorize by CID, not name.
|
|
315
|
+
- "get approved files" → `get_files({ wire_ids: ["<approved 64-hex id>"] })` writes only those
|
|
316
|
+
unread files under `<state>/<identity>/files/<wire_id>-<name>` and returns structured paths,
|
|
317
|
+
hashes, provenance and status. Invalid/duplicate/unknown/stale IDs fail closed. Omitting
|
|
318
|
+
`wire_ids` preserves the legacy behavior of retrieving every unread file.
|
|
319
|
+
- Voice records also carry structured transcription configuration/attempt/status, provider,
|
|
320
|
+
transcript or categorized fallback, and their audio-path association; prose remains intact.
|
|
321
|
+
- The wake signal stays **body-free** but carries authenticated sender CID, file/wire IDs,
|
|
322
|
+
filename, MIME, byte count and date — never the bytes. Unknown senders are rejected.
|
|
285
323
|
|
|
286
324
|
### Contacts & local contact book
|
|
287
325
|
- "who are my contacts" → `list_contacts()` (also shows pending local introductions).
|
|
@@ -291,7 +329,11 @@ tools, a separate store. To caption a file, also `send_message`.
|
|
|
291
329
|
"require approval for local contacts" → `set_local_book_policy({ auto_accept: false })`.
|
|
292
330
|
- Approve/reject a queued local introduction → `respond_to_introduction({ contact, action:
|
|
293
331
|
"approve" | "reject" })` — approving also delivers its queued messages (read with `get_messages`).
|
|
294
|
-
- "forget Bob" → `remove_contact({ contact })`
|
|
332
|
+
- "forget Bob" → `remove_contact({ contact })` — a contacts-layer forget (not a key wipe)
|
|
333
|
+
that also sends Bob one **best-effort** authenticated "remove me from your contacts"
|
|
334
|
+
notice, so an up-to-date peer drops you too. Fire-and-forget: no retry, no ack — an
|
|
335
|
+
offline peer or dropped packet leaves the removal **local-only**, and the tool says
|
|
336
|
+
whether a notice was queued. Never report the peer's side as removed.
|
|
295
337
|
|
|
296
338
|
## Conversation rules (1:1 and fan-out)
|
|
297
339
|
|
|
@@ -312,45 +354,21 @@ When you bind an identity, offer the user, in plain language:
|
|
|
312
354
|
- **Auto-wake** → arm the monitor. On Claude Code it runs in the **background**: you're woken on new mail *and* can keep chatting/working normally.
|
|
313
355
|
- **Manual** → don't arm it; check with `get_messages` whenever they ask.
|
|
314
356
|
|
|
315
|
-
## Control plane —
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
e2e channels as messages but in a separate control queue agents never see; monitoring bodies
|
|
326
|
-
are never written to disk on the host.
|
|
327
|
-
|
|
328
|
-
**Prerequisites**
|
|
329
|
-
- The **Human identity** exists (`create_root_identity` — the onboarding step). The
|
|
330
|
-
proxy binds to the Human identity.
|
|
331
|
-
- The messenger account is already a **contact of the Human identity** — do the normal
|
|
332
|
-
invite exchange first: bind the Human identity, `generate_invite`, and have the
|
|
333
|
-
messenger redeem it (or redeem the messenger's invite with `add_contact`).
|
|
334
|
-
|
|
335
|
-
**Binding ceremony (6-digit code, out-of-band)**
|
|
336
|
-
1. "bind my messenger account as the monitoring proxy" →
|
|
337
|
-
`bind_monitoring_proxy({ contact: "<the messenger contact>" })`. This automatically
|
|
338
|
-
targets the host's Human identity (you do **not** need to be bound as it). It returns a
|
|
339
|
-
**6-digit code** (valid 5 minutes, 3 attempts) and shows it **here**.
|
|
340
|
-
2. **Read the code to the user.** They open the messenger → the conversation with the Human identity →
|
|
341
|
-
**Control Panel** → enter the code. The code must travel **out-of-band** — reading it off
|
|
342
|
-
this terminal is what proves you control both ends. **Never send the code over ours.**
|
|
343
|
-
3. On success the contact becomes the proxy. Confirm with `get_monitoring_status`.
|
|
344
|
-
|
|
345
|
-
**Per-agent monitoring is controller-gated.** Once a proxy is bound, the proxy (Control
|
|
346
|
-
Panel) turns an agent's monitoring on/off — there is **no local enable/disable tool**. A
|
|
347
|
-
monitored agent reports a signed copy of every message it sends/receives to the Human
|
|
348
|
-
identity's node, which forwards it to the proxy's feed.
|
|
349
|
-
|
|
350
|
-
**Status** — "what's the monitoring/control state" → `get_monitoring_status()` reports the
|
|
351
|
-
Human identity's bound proxy (if any), a pending code verification, queued copies/control
|
|
352
|
-
requests, and each agent's monitoring ON/off. Works whenever the Human identity exists.
|
|
357
|
+
## Control plane — human oversight of a fleet
|
|
358
|
+
|
|
359
|
+
**NOT AVAILABLE IN THIS RELEASE. Do not offer it, and do not call a tool for it.**
|
|
360
|
+
The `bind_monitoring_proxy` and `get_monitoring_status` MCP tools were removed with the
|
|
361
|
+
daemon-side control plane; there is no tool behind them and a call will fail. Nothing has
|
|
362
|
+
replaced them yet.
|
|
363
|
+
|
|
364
|
+
The capability itself is not cancelled: the monitoring/control surface remains in the
|
|
365
|
+
**protocol core**, untouched, for whenever it is reimplemented. What is gone is this
|
|
366
|
+
plugin's exposure of it as MCP tools.
|
|
353
367
|
|
|
368
|
+
If a user asks to bind a web-messenger account as a monitoring/control proxy, to open a
|
|
369
|
+
Control Panel, or to check monitoring status — say plainly that it is not available in this
|
|
370
|
+
release, and do not improvise a substitute. Per-identity wake-on-mail is a **different**
|
|
371
|
+
feature and still works; it is described above.
|
|
354
372
|
## Notes
|
|
355
373
|
|
|
356
374
|
- Identities and their state (contacts, inbox, keys) persist under the daemon's state dir
|