primcli 1.27.0 → 1.30.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 +162 -0
- package/dist/{cli-config-BKso8oJu.js → cli-config-ikgszTi0.js} +2 -2
- package/dist/oclif/index.js +16871 -2693
- package/dist/oclif/root-signup-hint.js +1 -1
- package/man/primitive.1 +80 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -134,6 +134,33 @@ primitive emails latest --limit 5
|
|
|
134
134
|
|
|
135
135
|
Run `primitive --help` for the full command list. Per-command help (`primitive functions deploy --help`) carries enough detail that an agent can compose any operation without leaving the terminal.
|
|
136
136
|
|
|
137
|
+
## Waiting with connected credentials
|
|
138
|
+
|
|
139
|
+
After sending, wait for the existing send's reply without sending again:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
primitive emails wait --reply-to-sent-email-id <sent-id> --from peer@example.com
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The CLI reads that sent record to derive your receiving address. Optional `--to`
|
|
146
|
+
must match it. The peer stays explicit because sent records do not expose a
|
|
147
|
+
complete recipient inventory. Connected waits include existing replies by
|
|
148
|
+
default, so fast replies are not missed; use `--since <timestamp>` to narrow the
|
|
149
|
+
window. They require an authenticated peer and the exact outbound parent.
|
|
150
|
+
Interaction attachments remain pending with inspection guidance. JSONL includes
|
|
151
|
+
matching email details, or use `--table` for compact output and `--number N` for
|
|
152
|
+
multiple replies. Timeout exits 1; repeat the same wait to recover without
|
|
153
|
+
resending. Connected waits share one local address event receiver and recover
|
|
154
|
+
through exact-parent search, without scanning inbox history. Additional content
|
|
155
|
+
filters on this command require organization credentials.
|
|
156
|
+
|
|
157
|
+
Connected `primitive chat <peer> <message> --from <own-address>` registers its
|
|
158
|
+
reply wait and authenticates the receiver before sending. It records an explicit
|
|
159
|
+
idempotency key before the request. If the send response is lost, repeating the
|
|
160
|
+
same command looks up that key without sending again. A timeout retains the exact
|
|
161
|
+
parent claim for resume. A plain reply is an email response, not proof that a task
|
|
162
|
+
is complete.
|
|
163
|
+
|
|
137
164
|
## Authentication
|
|
138
165
|
|
|
139
166
|
Use `primitive signin` or `primitive login` for existing accounts. With no email, both use browser approval; `primitive signin browser` and `primitive login browser` are the explicit browser forms.
|
|
@@ -168,6 +195,35 @@ primitive deliveries replay --id <delivery-id>
|
|
|
168
195
|
|
|
169
196
|
Generated API commands remain available for compatibility and full schema parity, for example `primitive emails:list-emails` and `primitive sending:reply-to-email`.
|
|
170
197
|
|
|
198
|
+
## Send outcomes and exit codes
|
|
199
|
+
|
|
200
|
+
`primitive chat`, `primitive chat reply`, `primitive send` and `primitive reply`
|
|
201
|
+
report the same outcomes. Exit codes tell you whether a message left and whether
|
|
202
|
+
sending again is safe. With `--json`, stdout is an envelope for every outcome
|
|
203
|
+
(failures included) whose `outcome` field carries the name.
|
|
204
|
+
|
|
205
|
+
| Outcome | Exit | Meaning |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| `replied` | 0 | Chat only: the message was sent and a reply arrived. |
|
|
208
|
+
| `sent` | 0 | Accepted for delivery. `status: "queued"` is a success, not a pending failure. |
|
|
209
|
+
| `already_sent` | 0 | The server recognised an identical earlier send, or refused with HTTP 410 `sent_email_deleted` because that earlier send was deleted. Nothing new went out. Do not resend. |
|
|
210
|
+
| `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. |
|
|
211
|
+
| (usage error) | 2 | Invalid flags or arguments. Nothing went out. |
|
|
212
|
+
| `sent_awaiting_reply` | 3 | Chat only: the message was sent but no reply arrived before `--timeout`. Wait with the printed command; do not resend. |
|
|
213
|
+
| `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. |
|
|
214
|
+
|
|
215
|
+
A chat that times out prints `Message sent (id X). No reply yet after Ns. Do NOT
|
|
216
|
+
resend; wait with: <command>`, and its `--json` envelope has `"reply": null`, the
|
|
217
|
+
`sent` record, and `follow_up_commands` that only wait on or inspect that send.
|
|
218
|
+
|
|
219
|
+
Without `--json`, `send` and `reply` keep printing the send record on stdout exactly
|
|
220
|
+
as before and add a one-line stderr summary such as `Reply sent (queued for
|
|
221
|
+
delivery, id X). Do not resend.` Before sending, `primitive reply` (and
|
|
222
|
+
`primitive chat --reply`) warns on stderr when the inbound email already has a reply
|
|
223
|
+
that went out. The warning never blocks the send; if the lookup fails, the reply is
|
|
224
|
+
still sent and stderr says the check was skipped. `--json` includes the replies as
|
|
225
|
+
`prior_replies`.
|
|
226
|
+
|
|
171
227
|
## Remove mailbox history
|
|
172
228
|
|
|
173
229
|
`primitive sent delete --id <sent-email-id>` removes sender history and owned
|
|
@@ -206,6 +262,24 @@ primitive memories get state --function <function-id>
|
|
|
206
262
|
Values must be valid JSON. Strings must be quoted as JSON strings, so use
|
|
207
263
|
`'"hello"'`, not `hello`.
|
|
208
264
|
|
|
265
|
+
## Credits
|
|
266
|
+
|
|
267
|
+
Redeem a credit code for your organization and check the credit balance.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
primitive credits redeem LAUNCH50
|
|
271
|
+
primitive credits balance
|
|
272
|
+
primitive credits balance --json
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
`credits redeem` prints the credit added and its expiry. On a refusal it prints
|
|
276
|
+
the server's message (for example an invalid or already redeemed code) and
|
|
277
|
+
exits non-zero. Redeeming needs an organization owner or admin; with an API key,
|
|
278
|
+
the key's creator must currently be an owner or admin. Each run sends a new
|
|
279
|
+
Idempotency-Key; pass `--idempotency-key <key>` to retry the same redemption
|
|
280
|
+
safely. On any failure the command prints the key it used to stderr, so you can
|
|
281
|
+
run the same command again with `--idempotency-key <key>`.
|
|
282
|
+
|
|
209
283
|
## Recipient routing
|
|
210
284
|
|
|
211
285
|
Bind a recipient address to a destination so inbound mail resolves to a single
|
|
@@ -317,3 +391,91 @@ timeout; Ctrl-C exits 130. Bare `primitive listen` prints one raw JSON event per
|
|
|
317
391
|
line. Use `--transport poll` explicitly for HTTP polling. Accept or enqueue each
|
|
318
392
|
event within 30 seconds. Closing preserves pending work, and retries can deliver
|
|
319
393
|
an event more than once.
|
|
394
|
+
|
|
395
|
+
### Native session email notifications
|
|
396
|
+
|
|
397
|
+
With a connected-agent credential already configured, notify one exact loaded
|
|
398
|
+
Codex session of authenticated mail from explicitly approved senders:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
primitive listen --notify-session <session-uuid> --sender person@example.com
|
|
402
|
+
primitive listen --notify-session <session-uuid> --sender first@example.com,second@example.com
|
|
403
|
+
primitive listen --status --notify-session <session-uuid>
|
|
404
|
+
primitive listen --status --notify-session <session-uuid> --limit 100 --cursor <nextCursor>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
This first notification path uses the native local-session Unix socket in
|
|
408
|
+
Codex 0.156.1. Live runtime behavior was verified on macOS; Linux uses the same
|
|
409
|
+
Unix transport but has not been verified against a live runtime. The session must already be open in a terminal with
|
|
410
|
+
native daemon support enabled. If its socket is unavailable, this is an
|
|
411
|
+
unsupported runtime setup: the CLI reports the gap and exits before creating a
|
|
412
|
+
subscription. It does not launch a daemon, start/resume a conversation, install a
|
|
413
|
+
connector, or change model, approval, or sandbox settings. Windows and other
|
|
414
|
+
harnesses are not supported by this path. `CODEX_HOME` selects the native runtime
|
|
415
|
+
home when it differs from `~/.codex`.
|
|
416
|
+
|
|
417
|
+
Notification mode registers an `email.received`-only subscription and refuses
|
|
418
|
+
mixed existing filters before leasing events. Native notification mode requires
|
|
419
|
+
WebSocket and the shared saved subscription; `--transport poll` and a custom
|
|
420
|
+
`--subscription` are rejected. Generic stdout, exec, and forwarding listeners
|
|
421
|
+
retain their separate transport and subscription options. The `local-mail-*`
|
|
422
|
+
subscription namespace is reserved for shared receiving. An unexpected non-email
|
|
423
|
+
event remains uncompleted. In notification mode, `--once` means one candidate
|
|
424
|
+
processed during this invocation, including a policy or routine-status skip.
|
|
425
|
+
Waiter-owned replies and existing accepted notification receipts do not count.
|
|
426
|
+
It does not promise one session notification.
|
|
427
|
+
|
|
428
|
+
The foreground listener receives only the connected credential's assigned
|
|
429
|
+
address. `--sender` requires exact addresses with authenticated From-domain
|
|
430
|
+
evidence. Domain authentication does not independently prove a person's identity.
|
|
431
|
+
Notifications contain email/event IDs, the approved sender, and an inspection
|
|
432
|
+
command. Email bodies, subjects, attachments, and terminal transcripts are not
|
|
433
|
+
injected into the session. Verified routine ack/read/working/typing interactions
|
|
434
|
+
are suppressed; mixed content and unsupported protocols remain external mail
|
|
435
|
+
notifications. Inbound IDs are saved before the server delivery is acknowledged.
|
|
436
|
+
When parsing or authentication is pending, the listener retries those exact IDs
|
|
437
|
+
locally using current email details; an ingress acknowledgement does not mean
|
|
438
|
+
a native notification was accepted.
|
|
439
|
+
|
|
440
|
+
Local private receipts are scoped to the API environment, connected credential,
|
|
441
|
+
and exact session. Accepted means queued, not read or answered. A lost queue
|
|
442
|
+
response or interrupted submission is held as unknown across restarts because
|
|
443
|
+
the runtime does not deduplicate client message IDs. Inspect these receipts with
|
|
444
|
+
`--status`; it does not connect to a runtime or receive mail. Status returns up
|
|
445
|
+
to 100 receipts by default (maximum `--limit 1000`) and a `nextCursor` for the
|
|
446
|
+
next page. Individual private receipt files and an event index preserve evidence
|
|
447
|
+
without a lifetime aggregate-size cap; interrupted index writes recover locally
|
|
448
|
+
before dispatch. Unknown outcomes require inspection of that exact session before a manual resend. Do not delete
|
|
449
|
+
receipt state to force a retry. Definite failures before dispatch can be retried
|
|
450
|
+
by restarting the listener.
|
|
451
|
+
|
|
452
|
+
The CLI verifies the private socket and loaded session before each dispatch.
|
|
453
|
+
The native queue API cannot atomically fence a terminal closing between that
|
|
454
|
+
check and acceptance, so a concurrent close can leave input queued for that
|
|
455
|
+
same session. The CLI never retargets a different session.
|
|
456
|
+
|
|
457
|
+
Connected chat, exact-parent `emails wait`, and native notification listeners
|
|
458
|
+
share one receiver for the same local installation, API environment, and connected
|
|
459
|
+
credential. Expected replies stay with their wait; other approved mail can notify
|
|
460
|
+
the selected session. Another foreground participant can resume receiving when
|
|
461
|
+
the owner exits. Generic stdout, exec, forwarding, and `emails watch` remain
|
|
462
|
+
separate consumers.
|
|
463
|
+
|
|
464
|
+
Automatic runtime configuration, contact-policy synchronization, and notification
|
|
465
|
+
history backfill are not provided. Reply waits use targeted recovery for their
|
|
466
|
+
exact sent parent. Existing server queue retention and delivery-gap reporting
|
|
467
|
+
still apply; keep a foreground listener running for ongoing notifications.
|
|
468
|
+
|
|
469
|
+
### Connected-agent listeners
|
|
470
|
+
|
|
471
|
+
Use the agent's existing connected-address credential with the same listener API.
|
|
472
|
+
The server automatically restricts its private subscription to inbound email for
|
|
473
|
+
that address. No owner credential, recipient filter, or relay is required. Names
|
|
474
|
+
are isolated per credential. Revoking or replacing the credential removes its
|
|
475
|
+
subscriptions and queued deliveries; reconnect with the new credential to start
|
|
476
|
+
receiving new events.
|
|
477
|
+
|
|
478
|
+
Address-scoped events contain parsed message content in `email.parsed`.
|
|
479
|
+
`email.content.raw` and `email.content.download` are null. Signed download links,
|
|
480
|
+
account routing metadata, and other SMTP envelope recipients are not exposed.
|
|
481
|
+
Attachments can be fetched through the authenticated email attachment API.
|
|
@@ -863,7 +863,7 @@ function credentialsPath(configDir) {
|
|
|
863
863
|
function credentialsLockPath(configDir) {
|
|
864
864
|
return join(configDir, CREDENTIALS_LOCK_DIR);
|
|
865
865
|
}
|
|
866
|
-
function normalize(url, fallback) {
|
|
866
|
+
function normalize$1(url, fallback) {
|
|
867
867
|
const trimmed = url?.trim();
|
|
868
868
|
if (!trimmed) return fallback;
|
|
869
869
|
return trimmed.replace(/\/+$/, "");
|
|
@@ -889,7 +889,7 @@ function canonicalizeKnownApiBaseUrl(url) {
|
|
|
889
889
|
return url;
|
|
890
890
|
}
|
|
891
891
|
function normalizeApiBaseUrl(url) {
|
|
892
|
-
return canonicalizeKnownApiBaseUrl(normalize(url, DEFAULT_API_BASE_URL));
|
|
892
|
+
return canonicalizeKnownApiBaseUrl(normalize$1(url, DEFAULT_API_BASE_URL));
|
|
893
893
|
}
|
|
894
894
|
function cliAccessTokenExpiresAt(expiresInSeconds, now = Date.now) {
|
|
895
895
|
return new Date(now() + expiresInSeconds * 1e3).toISOString();
|