@ours.network/codex 0.18.0-nightly.1 → 0.18.0-nightly.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ours",
3
- "version": "0.18.0-nightly.1",
3
+ "version": "0.18.0-nightly.3",
4
4
  "description": "Secure agent-to-agent messaging and explicitly armed live mail wake for Codex CLI.",
5
5
  "author": {
6
6
  "name": "Adapt Toolkit",
package/AGENTS.snippet.md CHANGED
@@ -12,5 +12,6 @@ to arm monitoring; call `arm_monitor` only after an explicit yes. In standard `c
12
12
  foreground fallback. Explicitly tell the user that `ours-codex` provides background
13
13
  monitoring before offering that fallback; never omit this recommendation. Ask separately
14
14
  before calling `foreground_monitor`; never start the blocking fallback automatically.
15
- `get_messages` is the only operation that returns message bodies.
15
+ `get_messages` drains bounded unread batches; persistent message bodies are also available
16
+ through the explicit history tools.
16
17
  <!-- <<< ours.network plugin -->
package/README.md CHANGED
@@ -35,8 +35,8 @@ when you also want the `ours-codex` live-mode launcher.
35
35
  Live monitoring is never automatic. After successfully binding or creating an identity,
36
36
  Codex must ask whether to arm monitoring. Only an explicit yes authorizes
37
37
  `arm_monitor({ identity })`. Switching identity disarms the previous monitor. The wake
38
- event contains no message body; the resulting fixed turn calls `get_messages`, which is
39
- the only messaging tool that returns bodies.
38
+ event contains no message body; the resulting fixed turn calls `get_messages` to drain a
39
+ bounded unread batch. Explicit history tools can retrieve persistent bodies later.
40
40
 
41
41
  In standard mode, `arm_monitor` detects that the private live control channel is absent.
42
42
  It tells the user that `ours-codex` provides background wake, explains that the available
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/codex",
3
- "version": "0.18.0-nightly.1",
3
+ "version": "0.18.0-nightly.3",
4
4
  "description": "Native Codex plugin for secure ours.network messaging and explicitly armed, session-scoped live mail wake.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",
@@ -46,8 +46,8 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@modelcontextprotocol/sdk": "^1.29.0",
49
- "@ours.network/mcp": "0.18.0-nightly.1",
50
- "@ours.network/sdk": "2.0.1",
49
+ "@ours.network/mcp": "0.18.0-nightly.3",
50
+ "@ours.network/sdk": "3.0.1",
51
51
  "ws": "^8.21.0",
52
52
  "zod": "^3.25.76"
53
53
  },
@@ -79,12 +79,19 @@ allows it for legacy reasons; this skill does not.
79
79
 
80
80
  Walk the user through these, checking each. Stop and help at the first one that isn't done.
81
81
 
82
- 1. **Daemon running.** The MCP tools attach to the shared daemon. Check it with
83
- `ours daemon status`. If the commands are missing, install
84
- `@ours.network/cli@1.0.1` and `@ours.network/mcp`, then run `ours config setup`
85
- and `ours daemon start`. For boot persistence offer
86
- `ours daemon install-service`. These are operator commands; explain the shared
87
- blast radius and obtain consent before changing configuration or lifecycle.
82
+ For a first-time or complete host setup, prefer `ours-install`. It installs the
83
+ CLI, one shared daemon, MCP, cowork, Telegram, Fleet, the Human identity, and
84
+ every safely detected harness plugin in one progress-driven flow. It starts the
85
+ daemon and cowork, but deliberately leaves Telegram and Fleet stopped. If
86
+ `~/fleet.yaml` does not exist, it writes a conservative stopped starter with a
87
+ `FleetCoordinator`, watchdog, and coordinator health loop; it never overwrites an
88
+ existing file.
89
+
90
+ 1. **Daemon running.** Check it with `ours daemon status`. If the stack is
91
+ missing or incomplete, ask the user to run `ours-install`; use the manual CLI
92
+ package/config/start commands only as a troubleshooting fallback. These are
93
+ operator commands; explain the shared blast radius and obtain consent before
94
+ changing configuration or lifecycle.
88
95
  2. **Plugin installed.** Install the native plugin from the ours Codex marketplace, or
89
96
  install `@ours.network/codex` globally and run `ours-codex-install`. Start a new
90
97
  Codex thread after installation. The native package bundles skills, the ours and
@@ -121,6 +128,19 @@ the version-matched source of truth:
121
128
  subcommand's `--help`, and recommend upgrading. Do not ask the user to
122
129
  explain available flags or rely on a copied fleet workflow from this skill.
123
130
 
131
+ After `ours-install`, review `~/fleet.yaml` with the user before activation. Do
132
+ not start Fleet or Telegram merely because installation finished. With explicit
133
+ approval, the exact activation commands are:
134
+
135
+ ```sh
136
+ ours-fleet doctor && ours-fleet config && ours-fleet up
137
+ ours-fleet ls
138
+ ours-tg-connector install-service
139
+ ```
140
+
141
+ For Telegram, first guide bot and route setup locally. Never ask the user to put
142
+ a bot token in chat, a tool argument, or a transcript.
143
+
124
144
  ## Layer 1 — identities (global)
125
145
 
126
146
  A session must **bind** an identity before it can send or read messages. Binding is
@@ -290,21 +310,23 @@ automatically (cert- or registrar-verified introduction + key exchange) and the
290
310
  delivered with it — no invite ceremony.
291
311
 
292
312
  ### Reply to a specific message
293
- Every message carries a stable cross-side `wire_id`, shown by `get_messages` as `{…}`. To
313
+ Every message carries a stable cross-side `wire_id`, shown by `get_messages` and
314
+ `list_history`. To
294
315
  answer one precisely: `send_message({ contact: "Bob", text: "…", reply_to_wire_id:
295
316
  "<wire_id>" })`, optionally `reply_to_sentence: <n>` (1-based) to point at a sentence. The
296
317
  recipient sees `↳re <wire_id>·s<n>`. It's a lightweight reference, not a thread object.
297
318
 
298
319
  ### Check / read messages
299
- - "check messages" / "any new messages" → `get_messages()` returns the messages you
300
- haven't seen (status "unread") **with their bodies** and marks them "processed". This is
301
- the **only** call that returns message text; each message is delivered exactly once, so
302
- reading and acting immediately never double-processes — no acknowledgement step.
303
- - Handled messages are garbage-collected automatically (two-generation GC on a timer), so
304
- there is **no** mark-processed step. To hand a message to *another* session — or if you
305
- might crash before acting — `defer_messages({ msg_ids: [...] })` flips it back to "unread"
306
- (works even after it is queued for deletion, so it stays recoverable across a GC cycle).
307
- - "show my inbox" → `list_incoming_messages()` (full inbox, ids + status, read-only).
320
+ - "check messages" / "any new messages" → `get_messages()` returns the oldest 50 unread
321
+ messages with bodies, marks that batch `read`, and reports how many remain. Use
322
+ `get_messages({ limit: 200 })` for a larger bounded drain. There is no defer operation;
323
+ persistent history remains available after the read commit.
324
+ - "show/search message history" → `list_history({ peer_cid, direction, before_seq, limit })`.
325
+ Results are newest first; pass `next_cursor` back as `before_seq`. Filter by authenticated
326
+ `peer_cid`, not a display name. Use `get_history_item({ wire_id })` for one exact message.
327
+ These calls are read-only and include bodies plus local read and remote delivery state.
328
+ - History storage and protocol receipts are not transactional. There is no packet fallback,
329
+ outbox, hidden retry queue, automatic receipt retry, or defer path.
308
330
  - The SessionStart hook surfaces body-free unread counts and sender metadata. It never
309
331
  returns message text. In live mode an explicitly armed watcher starts a fixed drain turn;
310
332
  otherwise **check `get_messages` when you go live and whenever you expect a reply** — the daemon holds
@@ -323,10 +345,13 @@ tools, a separate store. To caption a file, also `send_message`.
323
345
  - "show received files" → `list_incoming_files()` — structured metadata only: authenticated
324
346
  sender CID in `from.id`, untrusted display label in `from.name`, file/wire IDs, filename,
325
347
  MIME, size, date and status; no bytes and no status change. Authorize by CID, not name.
326
- - "get approved files" → `get_files({ wire_ids: ["<approved 64-hex id>"] })` writes only those
327
- unread files under `<state>/<identity>/files/<wire_id>-<name>` and returns structured paths,
328
- hashes, provenance and status. Invalid/duplicate/unknown/stale IDs fail closed. Omitting
329
- `wire_ids` preserves the legacy behavior of retrieving every unread file.
348
+ - "get approved unread files" → `get_files({ wire_ids: ["<approved 64-hex id>"] })` marks
349
+ only those unread rows read and returns immutable blob paths, hashes, provenance and
350
+ status. Invalid/duplicate/unknown/stale IDs fail closed. Omitting `wire_ids` retrieves the
351
+ oldest 50 unread files; pass `limit` from 1 to 200 for another bounded batch.
352
+ - "show/search file history" → `list_files({ peer_cid, direction, before_seq, limit })`;
353
+ use `get_file_info({ wire_id })` for exact metadata. Both return no bytes. Use
354
+ `save_file({ wire_id, dest_path })` to stream any stored file daemon→disk without chat bytes.
330
355
  - Voice records also carry structured transcription configuration/attempt/status, provider,
331
356
  transcript or categorized fallback, and their audio-path association; prose remains intact.
332
357
  - The wake signal stays **body-free** but carries authenticated sender CID, file/wire IDs,
@@ -400,20 +425,19 @@ release, and do not improvise a substitute. Per-identity wake-on-mail is a **dif
400
425
  feature and still works; it is described above.
401
426
  ## Notes
402
427
 
403
- - Identities and their state (contacts, inbox, keys) persist under the selected daemon's
428
+ - Identities and their state (contacts, history, keys) persist under the selected daemon's
404
429
  state directory and survive restarts. Multiple daemon profiles can coexist when their
405
430
  ports and state directories differ.
406
431
  - Inbound messages from unknown (non-contact) senders are rejected — only peers added via an
407
432
  invite handshake, same-host agents under the same Human identity, or registrar-verified
408
433
  local-contact-book introductions can reach you.
409
- - Message **bodies never touch disk in plaintext**: a new arrival appends only a content-free
410
- event (sender + id + date) to `$OURS_STATE_DIR/<identity>/notifications.log` (the wake
411
- signal `ours-mcp watch` reads) and refreshes a body-free `unread.json`. Text lives in the
412
- packet and leaves it solely via `get_messages`.
434
+ - Message bodies persist in owner-private, mode-0600 `history.sqlite3`; file bytes persist
435
+ as immutable content-addressed blobs. The wake path remains body-free:
436
+ `notifications.log` and `unread.json` contain metadata only, never bodies or bytes.
413
437
  - **Codex monitoring uses capability detection.** `ours-codex` owns the App Server and
414
438
  watcher for exactly one TUI session. The launcher observes that session's thread
415
439
  directly; monitor MCP tools carry explicit arm/disarm consent, while trusted hooks add
416
440
  defensive identity-state synchronization. Standard `codex` falls back, after separate
417
441
  consent, to a foreground `ours-mcp watch` call that returns on the next body-free event.
418
- Authenticated daemon notification endpoints remain body-free. Only `get_messages`
419
- releases message text to the agent.
442
+ Authenticated daemon notification endpoints remain body-free. Message text is returned
443
+ only by the explicit unread-drain and history tools.