primcli 1.33.0 → 1.35.0
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 +237 -20
- package/bin/claude-pending-mail.mjs +342 -0
- package/bin/claude-wake.mjs +204 -0
- package/bin/run.js +20 -0
- package/dist/{cli-config-Cv2-NAOd.js → cli-config-DmhlcS3s.js} +30 -350
- package/dist/json-output-KAIuP9rG.js +254 -0
- package/dist/listen-background-D6UhIbkO.js +647 -0
- package/dist/oclif/index.js +17087 -9256
- package/dist/oclif/listen-supervisor.js +2 -0
- package/dist/oclif/proxy-auto-detect.js +2 -1
- package/dist/oclif/root-signup-hint.js +1 -1
- package/dist/shared-mail-files-Cbwnf79a.js +351 -0
- package/man/primitive.1 +51 -0
- package/package.json +13 -4
package/README.md
CHANGED
|
@@ -252,9 +252,12 @@ Use task-oriented commands for normal workflows:
|
|
|
252
252
|
primitive send --to alice@example.com --body "Hello"
|
|
253
253
|
primitive reply --id <inbound-email-id> --body "Thanks"
|
|
254
254
|
primitive reply --id <inbound-email-id> --body "See attached" --attachment ./report.pdf
|
|
255
|
+
primitive reply --thread <thread-id> --body "Answering the latest message"
|
|
256
|
+
primitive reply --id <inbound-email-id> --fyi --body "Merged. No action needed."
|
|
255
257
|
primitive chat reply "See attached" --attachment ./report.pdf
|
|
256
258
|
primitive emails list
|
|
257
259
|
primitive emails get --id <inbound-email-id>
|
|
260
|
+
primitive emails get --id <inbound-email-id> --brief
|
|
258
261
|
primitive sent list
|
|
259
262
|
primitive sent delete --id <sent-email-id>
|
|
260
263
|
primitive domains list
|
|
@@ -273,7 +276,9 @@ Generated API commands remain available for compatibility and full schema parity
|
|
|
273
276
|
`primitive chat`, `primitive chat reply`, `primitive send` and `primitive reply`
|
|
274
277
|
report the same outcomes. Exit codes tell you whether a message left and whether
|
|
275
278
|
sending again is safe. With `--json`, stdout is an envelope for every outcome
|
|
276
|
-
(failures included) whose `outcome` field carries the name.
|
|
279
|
+
(failures included) whose `outcome` field carries the name. The envelope always
|
|
280
|
+
has `sent_email_id` (null until a send record is known) and `idempotency_key`,
|
|
281
|
+
including when the outcome is uncertain.
|
|
277
282
|
|
|
278
283
|
| Outcome | Exit | Meaning |
|
|
279
284
|
|---|---|---|
|
|
@@ -283,12 +288,34 @@ sending again is safe. With `--json`, stdout is an envelope for every outcome
|
|
|
283
288
|
| `not_sent` | 1 | The API rejected the request (HTTP 400, 401, 402, 403, 404, 413, 422 or 429), the command failed before sending, or the send record has status `agent_failed`, `gate_denied` or `canceled`. Nothing went out. |
|
|
284
289
|
| (usage error) | 2 | Invalid flags or arguments. Nothing went out. |
|
|
285
290
|
| `sent_awaiting_reply` | 3 | Chat only: the message was sent but no reply arrived before `--timeout`. Wait with the printed command; do not resend. |
|
|
286
|
-
| `uncertain` | 4 | Transport error, conflict, server error, or a send record with status `unknown`. The message may or may not have gone out; check `primitive sent list` before retrying. |
|
|
291
|
+
| `uncertain` | 4 | Transport error, conflict, server error, or a send record with status `unknown`. The message may or may not have gone out; reconcile with `primitive sent get --idempotency-key <key>` (or check `primitive sent list`) before retrying. |
|
|
287
292
|
|
|
288
293
|
A chat that times out prints `Message sent (id X). No reply yet after Ns. Do NOT
|
|
289
294
|
resend; wait with: <command>`, and its `--json` envelope has `"reply": null`, the
|
|
290
295
|
`sent` record, and `follow_up_commands` that only wait on or inspect that send.
|
|
291
296
|
|
|
297
|
+
Every send carries an idempotency key. Pass your own with `--idempotency-key`, or
|
|
298
|
+
let the CLI derive one from the message content, so an identical retry is still
|
|
299
|
+
deduplicated. If an outcome is uncertain, or you lost the output, reconcile by
|
|
300
|
+
key instead of resending:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
primitive sent get --idempotency-key <key> --json
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
It prints the newest send with that key. When nothing matches it exits 1 with
|
|
307
|
+
error code `not_found`. That means no record is visible yet, not that the attempt
|
|
308
|
+
created nothing: a send can still be in flight, or its record can have been
|
|
309
|
+
deleted while the key stays reserved. If you retry, retry with the same
|
|
310
|
+
`--idempotency-key`, never a new one.
|
|
311
|
+
|
|
312
|
+
A key the CLI derives itself covers the request content and the current
|
|
313
|
+
five-minute window, the same window the API uses when a request carries no key.
|
|
314
|
+
An identical send inside that window is deduplicated, a deliberate repeat later
|
|
315
|
+
still goes out, and different replies to the same email are separate sends. To
|
|
316
|
+
retry an uncertain send after the window, pass the key it reported with
|
|
317
|
+
`--idempotency-key`.
|
|
318
|
+
|
|
292
319
|
Without `--json`, `send` and `reply` keep printing the send record on stdout exactly
|
|
293
320
|
as before and add a one-line stderr summary such as `Reply sent (queued for
|
|
294
321
|
delivery, id X). Do not resend.` Before sending, `primitive reply` (and
|
|
@@ -297,6 +324,58 @@ that went out. The warning never blocks the send; if the lookup fails, the reply
|
|
|
297
324
|
still sent and stderr says the check was skipped. `--json` includes the replies as
|
|
298
325
|
`prior_replies`.
|
|
299
326
|
|
|
327
|
+
### Replying to the latest message in a thread
|
|
328
|
+
|
|
329
|
+
`primitive reply --thread <thread-id>` answers the newest inbound email in the
|
|
330
|
+
thread instead of a specific one, so an older message is never answered while
|
|
331
|
+
newer ones wait. It uses the thread's `latest_inbound_id` when the API returns
|
|
332
|
+
it and otherwise the newest inbound entry in the thread's message list. Without
|
|
333
|
+
`--json`, stderr names the email that was answered; with `--json`, the envelope
|
|
334
|
+
carries `reply_target: { thread_id, email_id, resolved_by }`. `--id` and
|
|
335
|
+
`--thread` are mutually exclusive.
|
|
336
|
+
|
|
337
|
+
### Informational replies
|
|
338
|
+
|
|
339
|
+
`primitive reply --fyi` sends a reply that needs no answer. It goes out as an
|
|
340
|
+
ordinary threaded reply carrying an `ack` signal (status `received`, see
|
|
341
|
+
[optional email signals](../docs/signal-emails.md)) whose note is the
|
|
342
|
+
plain-text body:
|
|
343
|
+
|
|
344
|
+
```text
|
|
345
|
+
Received your message.
|
|
346
|
+
|
|
347
|
+
<your body>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Receivers that classify signal content treat it as informational and do not
|
|
351
|
+
wake for it. `--fyi` takes plain text only: no HTML or attachments, at most 2000
|
|
352
|
+
characters, and trailing whitespace is dropped. With no body the reply is the
|
|
353
|
+
bare acknowledgement. It is refused when the email being answered is itself a
|
|
354
|
+
signal or interaction, so two agents cannot keep acknowledging each other.
|
|
355
|
+
`primitive send --fyi --in-reply-to <message-id>` sends the same kind of
|
|
356
|
+
acknowledgement for a message identified by its Message-Id.
|
|
357
|
+
|
|
358
|
+
An informational reply or send carries an idempotency key like any other
|
|
359
|
+
send, derived from the target and the note, so retrying the same command is
|
|
360
|
+
deduplicated. With `--json` the envelope reports it as `idempotency_key`.
|
|
361
|
+
|
|
362
|
+
## JSON output
|
|
363
|
+
|
|
364
|
+
With `--json`, stdout is exactly one JSON document, on success and on failure,
|
|
365
|
+
and stderr stays empty. Output merged with `2>&1` therefore still parses:
|
|
366
|
+
|
|
367
|
+
- Notices the command would otherwise print on stderr (hints, progress, prior
|
|
368
|
+
reply warnings) go in the document's `warnings` array.
|
|
369
|
+
- A failure adds `error` and `exit_code`. If the command printed no document of
|
|
370
|
+
its own, the CLI prints `{ "error": ..., "exit_code": ... }`.
|
|
371
|
+
- Generated API commands (`primitive sent list`, `primitive emails list`, ...)
|
|
372
|
+
keep printing only the data payload with `--json`, the same stdout as
|
|
373
|
+
without it, but do not write the `next cursor: <cursor>` line to stderr. To
|
|
374
|
+
page, add `--envelope`: it prints the full response envelope, with
|
|
375
|
+
`meta.cursor` for the next page and empty-result hints in `summary`.
|
|
376
|
+
- Commands whose `--json` output is a bare array keep that shape.
|
|
377
|
+
- `primitive listen` streams JSONL and is not covered by this rule.
|
|
378
|
+
|
|
300
379
|
## Remove mailbox history
|
|
301
380
|
|
|
302
381
|
`primitive sent delete --id <sent-email-id>` removes sender history and owned
|
|
@@ -521,7 +600,8 @@ before retrying.
|
|
|
521
600
|
|
|
522
601
|
Background receivers reconnect after a known transport interruption. A previously
|
|
523
602
|
verified session may temporarily be unloaded while its terminal reconnects; the
|
|
524
|
-
receiver waits for that same session
|
|
603
|
+
receiver waits for that same session before subscribing to it. The subscription
|
|
604
|
+
keeps the thread loaded while the receiver's native connection remains open. Each attempt
|
|
525
605
|
revalidates the original connection, exact loaded session, private socket and
|
|
526
606
|
working directory. Authorization, identity, protocol and unknown-dispatch errors
|
|
527
607
|
stop receiving instead of being retried. Reconnection never starts a missing
|
|
@@ -563,6 +643,10 @@ before dispatch. Unknown outcomes require inspection of that exact session befor
|
|
|
563
643
|
receipt state to force a retry. Definite failures before dispatch can be retried
|
|
564
644
|
by restarting the listener.
|
|
565
645
|
|
|
646
|
+
If Codex explicitly refuses external output during a Review or Compact turn,
|
|
647
|
+
the receipt is `not_submitted` and the listener retries the same event after a
|
|
648
|
+
short delay. A timeout or disconnect is still unknown and is not resent.
|
|
649
|
+
|
|
566
650
|
The CLI verifies the private socket and loaded session before each dispatch.
|
|
567
651
|
The native turn API cannot atomically fence a terminal closing between that
|
|
568
652
|
check and acceptance, so a concurrent close can leave an external event
|
|
@@ -588,7 +672,8 @@ policy CLI commands, explicit `--notify` consent, and recovery.
|
|
|
588
672
|
### Agent address notes
|
|
589
673
|
|
|
590
674
|
Connected profiles default to their own address. They can read another address's
|
|
591
|
-
organization notes with `--address`, but can write
|
|
675
|
+
organization notes with `--address`, but can write only their own, and the
|
|
676
|
+
server refuses note deletion from a connected-agent credential.
|
|
592
677
|
Owner logins must pass `--address`.
|
|
593
678
|
|
|
594
679
|
```sh
|
|
@@ -610,6 +695,40 @@ Use `--if-version <version>` or `--if-absent` to provide the condition directly.
|
|
|
610
695
|
`delete` likewise reads the current version once unless `--if-version` is
|
|
611
696
|
provided. Conflicts are never retried automatically.
|
|
612
697
|
|
|
698
|
+
### Sending from another session's profile
|
|
699
|
+
|
|
700
|
+
`send`, `reply` and `chat` warn when the connected agent profile was set up in
|
|
701
|
+
a different Claude Code or Codex session than the one running the command:
|
|
702
|
+
`This profile belongs to another session (<short id>); sending as <address>.`
|
|
703
|
+
The warning goes to stderr, or to `warnings` with `--json`, and the message is
|
|
704
|
+
still sent, since reusing a profile can be intended.
|
|
705
|
+
|
|
706
|
+
### Work claims
|
|
707
|
+
|
|
708
|
+
A work claim says what an agent is changing right now, so peers can check it
|
|
709
|
+
before editing a shared file. It is one short line naming the task and the
|
|
710
|
+
files or areas being changed, stored with an expiry in the `AGENT_WORKING`
|
|
711
|
+
address note as JSON `{"claim": "...", "until": "<ISO time>"}`. Claims are
|
|
712
|
+
advisory, not locks.
|
|
713
|
+
|
|
714
|
+
```sh
|
|
715
|
+
primitive agent working set "phone composer: apps/mobile/src/message-composer.tsx"
|
|
716
|
+
primitive agent working set "billing export: src/billing/" --until 2026-10-01T18:00:00Z
|
|
717
|
+
primitive agent working get --address peer@example.com
|
|
718
|
+
primitive agent working clear
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
Set a claim when work starts and clear it when work ends. Without `--until`, a
|
|
722
|
+
claim expires 4 hours after it is set. `clear` rewrites the claim with its
|
|
723
|
+
expiry set to now, so it reads as `none` from then on; if that write is refused
|
|
724
|
+
it deletes the note instead, when the credential is allowed to. `--json` reports
|
|
725
|
+
`{ address, cleared, method }` with `method` `expired`, `deleted` or `null`. `get` prints the claim and its expiry, or
|
|
726
|
+
`none` when there is no claim or it has expired; a plain-text value written
|
|
727
|
+
without an expiry is shown as-is. `--json` prints `{ address, state, claim,
|
|
728
|
+
until }` where `state` is `active`, `legacy` or `none`. Address rules and
|
|
729
|
+
visibility follow `agent notes`: new claims are private to the organization and
|
|
730
|
+
an update keeps the note's visibility unless `--public` or `--private` is given.
|
|
731
|
+
|
|
613
732
|
Automatic runtime configuration and notification history backfill are not
|
|
614
733
|
provided. Reply waits use targeted recovery for their
|
|
615
734
|
exact sent parent. Existing server queue retention and delivery-gap reporting
|
|
@@ -629,25 +748,39 @@ Address-scoped events contain parsed message content in `email.parsed`.
|
|
|
629
748
|
account routing metadata, and other SMTP envelope recipients are not exposed.
|
|
630
749
|
Attachments can be fetched through the authenticated email attachment API.
|
|
631
750
|
|
|
751
|
+
### Your member identity
|
|
752
|
+
|
|
753
|
+
`primitive account whoami` returns the authenticated caller, their assigned
|
|
754
|
+
member email address, and a suggestion when setup is needed. Choose an address
|
|
755
|
+
with `primitive account provision-member-address --address <email>`. Reserved
|
|
756
|
+
addresses are unavailable. If retained mail exists for an available address,
|
|
757
|
+
review the warning before retrying with `--confirm-existing-mail`. The saved
|
|
758
|
+
address remains fixed; repeating the same choice is safe. Organization
|
|
759
|
+
keys and connected-agent credentials cannot impersonate or provision a human.
|
|
760
|
+
The root `primitive whoami` retains its account summary and saved-profile behavior.
|
|
761
|
+
|
|
632
762
|
### Connect a coding session
|
|
633
763
|
|
|
634
|
-
On a trusted machine where
|
|
764
|
+
On a trusted machine where an organization member has already run `primitive signin`,
|
|
635
765
|
an exact coding session can create its own address in that signed-in organization:
|
|
636
766
|
|
|
637
767
|
```sh
|
|
638
768
|
primitive agent enroll --session <session-uuid> --name Research --contact-requests --json
|
|
639
769
|
```
|
|
640
770
|
|
|
641
|
-
For Claude Code, add `--receiver external`
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
771
|
+
For Claude Code, add `--receiver external` from that exact session. The CLI
|
|
772
|
+
installs its fail-open Stop hook after verification; the skill guides setup and
|
|
773
|
+
ongoing mail use. The server allocates a readable address on a verified managed domain, then the CLI
|
|
774
|
+
privately claims and verifies the invitation. The CLI saves a creation request
|
|
775
|
+
before dispatch, so rerunning an uncertain create recovers the same identity.
|
|
776
|
+
Recovered responses contain no invitation. For a still-pending connection, add
|
|
777
|
+
`--continue-setup` once to explicitly obtain an invitation; it cannot revoke a
|
|
778
|
+
claimed credential. An uncertain continuation or claim stays held for inspection.
|
|
779
|
+
Existing enrollment state without a creation request keeps its recovery hold. This local pilot uses the saved member
|
|
780
|
+
OAuth login, which is accessible to other local processes under the same
|
|
648
781
|
OS user. Do not use it on an untrusted runtime.
|
|
649
782
|
|
|
650
|
-
`--contact-requests` uses that
|
|
783
|
+
`--contact-requests` uses that member login to enable first-contact intake for
|
|
651
784
|
the exact new address after verification. It preserves existing agent policy
|
|
652
785
|
rules, uses a conditional write, and reads the policy back before reporting
|
|
653
786
|
`contactRequestPolicy: "enabled"`. An explicit disable or concurrent conflict
|
|
@@ -670,19 +803,103 @@ Verification submission and delivery are separate from receiver health. A queued
|
|
|
670
803
|
verification reply is accepted for delivery. Do not claim again or resend because
|
|
671
804
|
setup was interrupted. The CLI preserves its private recovery state.
|
|
672
805
|
|
|
806
|
+
### Find another agent in the organization
|
|
807
|
+
|
|
808
|
+
Connected agents appear in the private default organization network unless their
|
|
809
|
+
owner hides them or an organization manager removes them. A saved Contact is an
|
|
810
|
+
address book entry, not a network listing. To find a coworker's listed agents,
|
|
811
|
+
use the connected profile:
|
|
812
|
+
|
|
813
|
+
```sh
|
|
814
|
+
PRIMITIVE_AGENT_PROFILE=work primitive network peers --owner "Ben" --json
|
|
815
|
+
PRIMITIVE_AGENT_PROFILE=work primitive agent notes get AGENT_INFO --address peer@example.com --json
|
|
816
|
+
PRIMITIVE_AGENT_PROFILE=work primitive send --to peer@example.com --body-file ./task.txt --json
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
Use the returned cursor if the owner has more agents than one page. Last seen
|
|
820
|
+
is recorded API activity, not live presence. A listed same-organization peer
|
|
821
|
+
can receive the task email directly without a Contacts request when the sender
|
|
822
|
+
can see the network; explicit silence still applies. Network visibility permits
|
|
823
|
+
discovery and communication but does not grant task authority.
|
|
824
|
+
Known addresses can still exchange ordinary email outside the network.
|
|
825
|
+
|
|
826
|
+
With a signed-in member login, `primitive network members` shows your own
|
|
827
|
+
personal agents. Use `primitive network set <address> --see off` to stop one of
|
|
828
|
+
them browsing, or `--be-seen off` to hide it from discovery. Owners and admins
|
|
829
|
+
can manage the full roster with the same commands. Only owners and admins can
|
|
830
|
+
remove or restore a network member.
|
|
831
|
+
|
|
673
832
|
For Claude Code, use the same setup command with `--receiver external`. This
|
|
674
|
-
verifies the email challenge and
|
|
675
|
-
|
|
833
|
+
verifies the email challenge and installs a fail-open Stop hook for the exact
|
|
834
|
+
session. When the session is idle, the hook runs:
|
|
676
835
|
|
|
677
836
|
```sh
|
|
678
837
|
primitive listen --once --wake --hook-session --events email.received --timeout 604800
|
|
679
838
|
```
|
|
680
839
|
|
|
681
|
-
The hook
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
840
|
+
The installed hook checks CLI capability first and exits without blocking the
|
|
841
|
+
session if the command is unavailable. It selects the `session-<uuid>` profile,
|
|
842
|
+
receives on WebSocket, and exits 2 with one wake line so Claude can wake. It
|
|
843
|
+
exits 0 after an idle timeout or in an unpaired session. Keep the interactive
|
|
844
|
+
Claude session open; receipt content remains external input.
|
|
845
|
+
|
|
846
|
+
The wake line carries only metadata the server or local listener state
|
|
847
|
+
provides, never the subject or body:
|
|
848
|
+
|
|
849
|
+
```text
|
|
850
|
+
Primitive mail arrived: <email-id> from=<sender> relationship=<owner|member|agent|contact|other> thread=<thread-id|none> in_thread=<yes|no> attachments=<yes|no> newer=<n>. Read with primitive emails get --id <email-id> --brief. <authority sentence>
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
`relationship` comes from server admission and verification: `owner` and
|
|
854
|
+
`member` from verified organization membership, `agent` from connected-agent
|
|
855
|
+
verification or agent network admission, `contact` from an explicit contact
|
|
856
|
+
allowance. `in_thread` says whether this profile has sent in the thread.
|
|
857
|
+
`newer` appears only when the API reports newer inbound mail in the thread. A
|
|
858
|
+
sender address outside a plain character set is shown as `from=unavailable`.
|
|
859
|
+
Codex notifications carry the same fields in their JSON line.
|
|
860
|
+
|
|
861
|
+
`primitive emails get --id <id> --brief` prints a trusted envelope first
|
|
862
|
+
(sender, relationship, verification, thread, whether you have sent in it,
|
|
863
|
+
newer messages and their senders when the API reports them, attachments, the
|
|
864
|
+
sender's active `AGENT_WORKING` claim, and the sender's latest read, ack or
|
|
865
|
+
working signal on your last message in the thread), then the sender's subject
|
|
866
|
+
and `body_text`, fenced and labelled untrusted. With `--json` it prints one
|
|
867
|
+
object with `envelope`, `subject` and `body_text`.
|
|
868
|
+
|
|
869
|
+
Before a wake event is acknowledged, the listener records a pending notice for
|
|
870
|
+
the session in
|
|
871
|
+
`<config>/agent-connections/profiles/<profile>/pending-mail-<session>.json`.
|
|
872
|
+
Reading the email with `primitive emails get --id <id>` (with or without
|
|
873
|
+
`--brief`) inside that session removes it; a read outside any Claude Code or
|
|
874
|
+
Codex session leaves every session's notice in place. `primitive listen pending --session <uuid>` lists the
|
|
875
|
+
notices, and `--clear <email-id>` removes one.
|
|
876
|
+
|
|
877
|
+
To stop wakes for an unrelated conversation, mute its thread:
|
|
878
|
+
|
|
879
|
+
```sh
|
|
880
|
+
primitive threads mute --id <thread-id>
|
|
881
|
+
primitive threads muted
|
|
882
|
+
primitive threads unmute --id <thread-id>
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
A mute is kept on the server for the connected agent's address, so no session
|
|
886
|
+
using that address is woken by the thread, and email reads report it as
|
|
887
|
+
`muted`. `--session-only` instead stores the mute locally beside the profile for
|
|
888
|
+
the current Claude Code or Codex session only. A server without thread mutes
|
|
889
|
+
gets a local mute, with a note saying so: inside a session it applies to that
|
|
890
|
+
session, and outside one, or with `--all-sessions`, to every session on the
|
|
891
|
+
profile. `unmute` removes the server mute and the matching local one, and
|
|
892
|
+
`muted` lists both, each marked `stored: "server"` or `"local"`. Mail in a muted
|
|
893
|
+
thread is still received and readable; its delivery event is completed without
|
|
894
|
+
a wake.
|
|
895
|
+
|
|
896
|
+
When an email read carries the server's `collaboration.sender_relationship`,
|
|
897
|
+
the wake line and `--brief` use it for an authenticated sender, `other`
|
|
898
|
+
included (`org_agent` reads as `agent`); only when the field is absent or
|
|
899
|
+
unrecognized does the CLI derive the relationship itself. For a supported native coding session,
|
|
900
|
+
use `--receiver native`; `primitive listen --status --notify-session <uuid>`
|
|
901
|
+
reports receiving health separately from email verification. Test an actual
|
|
902
|
+
idle wake before claiming unattended delivery.
|
|
686
903
|
|
|
687
904
|
A connected `chat` command waits for one reply. Use `chat <peer> <task> --async`
|
|
688
905
|
for delegated work: it returns the send result immediately and keeps this exact
|