primcli 1.22.0 → 1.25.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 +124 -12
- package/dist/oclif/index.js +5485 -393
- package/man/primitive.1 +47 -0
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# primitive
|
|
2
2
|
|
|
3
3
|
Official Primitive CLI. Deploy Primitive Functions, send and inspect mail, manage endpoints, all from the terminal.
|
|
4
4
|
|
|
@@ -10,24 +10,116 @@ primitive whoami
|
|
|
10
10
|
Or with npm:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm install -g
|
|
13
|
+
npm install -g primitive
|
|
14
14
|
primitive whoami
|
|
15
15
|
# `prim` is installed as a short alias for the same CLI.
|
|
16
16
|
prim whoami
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
The same CLI is also published
|
|
19
|
+
The same CLI is also published as [`primcli`](https://www.npmjs.com/package/primcli) and under the legacy scoped name [`@primitivedotdev/cli`](https://www.npmjs.com/package/@primitivedotdev/cli). Each installs an identical build with the same `primitive`/`prim` commands. Use whichever name you prefer; they track the same version.
|
|
20
20
|
|
|
21
21
|
Or with no install:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npx @
|
|
24
|
+
npx primitive@latest <command>
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
This package wraps the [@primitivedotdev/sdk](https://www.npmjs.com/package/@primitivedotdev/sdk) runtime client with one-shot commands. For in-handler use (calling Primitive from inside a Function), import `createPrimitiveClient` from `@primitivedotdev/sdk/api` directly; the CLI is for operator and deploy workflows.
|
|
28
28
|
|
|
29
29
|
## Quickstart
|
|
30
30
|
|
|
31
|
+
### Receive webhook events without a public endpoint
|
|
32
|
+
|
|
33
|
+
With an existing Primitive account and inbox, sign in or set `PRIMITIVE_API_KEY`.
|
|
34
|
+
Run `primitive listen` to print existing webhook events as JSONL. Status goes to
|
|
35
|
+
stderr. No public URL or separate destination setup is required.
|
|
36
|
+
|
|
37
|
+
For an agent, use a short hook that saves each event into its durable inbox:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
primitive listen init --language python
|
|
41
|
+
cd primitive-listener
|
|
42
|
+
primitive listen --subscription my-agent --exec 'python3 accept_event.py'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The starter works locally and refuses to overwrite an existing directory. Its
|
|
46
|
+
SQLite inbox is application-owned example code. Replace `accept_event` with your
|
|
47
|
+
agent's existing durable input function. Exit 0 means the input was saved; run
|
|
48
|
+
model work separately so the listener can keep receiving while the agent thinks.
|
|
49
|
+
The hook has a 30-second deadline. Do not spawn a background agent from the hook.
|
|
50
|
+
`--exec` requires macOS or Linux for process-group cleanup. On Windows, use
|
|
51
|
+
`--forward-to` with your agent's local HTTP acceptance handler.
|
|
52
|
+
|
|
53
|
+
The CLI passes the unchanged event body on stdin, plus `PRIMITIVE_EVENT_ID`,
|
|
54
|
+
`PRIMITIVE_DELIVERY_ID`, and `PRIMITIVE_EVENT_TYPE` in the hook environment.
|
|
55
|
+
Deduplicate by `PRIMITIVE_EVENT_ID`, which stays the same on redelivery. Delivery
|
|
56
|
+
IDs identify individual attempts. Related events need not contain an email or a
|
|
57
|
+
body-level event ID. The generated processing example shows existing Python SDK
|
|
58
|
+
conversation and reply calls; sending requires an explicit choice.
|
|
59
|
+
|
|
60
|
+
To run an existing HTTP webhook handler locally:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
primitive listen --subscription local-webhook --forward-to http://localhost:3000/webhook
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This mode forwards the exact signed body and existing webhook headers. Configure
|
|
67
|
+
the handler with your existing account webhook secret and normal signature
|
|
68
|
+
verification. The CLI never forwards your API credentials. It does not follow
|
|
69
|
+
redirects or disable TLS verification. A response must finish within 30 seconds
|
|
70
|
+
and remain within 1 MiB. Existing confirmation headers retain their meaning,
|
|
71
|
+
including account content-discard behavior; exec and stdout do not confirm
|
|
72
|
+
content discard.
|
|
73
|
+
|
|
74
|
+
Use `--events email.received,interaction.ack.received` to select events on a new
|
|
75
|
+
subscription. Omitting `--events` when resuming preserves its selection. A
|
|
76
|
+
conflicting selection requires a different subscription name. Ctrl-C disconnects
|
|
77
|
+
without deleting the destination; restart with the same name to receive pending
|
|
78
|
+
events. On the same machine, a second listener cannot consume that subscription
|
|
79
|
+
while the first holds it. The same name on different machines shares consumption;
|
|
80
|
+
different names receive independent copies. With no name, the CLI saves a private
|
|
81
|
+
default identity scoped to your API host and account.
|
|
82
|
+
|
|
83
|
+
`--number N` exits after N successful, server-confirmed completions. A crash after
|
|
84
|
+
the hook saves input but before completion can redeliver it. Bare stdout is for
|
|
85
|
+
inspection: a successful pipe write does not prove a downstream agent saved the
|
|
86
|
+
event. Use the durable hook for ingestion.
|
|
87
|
+
|
|
88
|
+
The server retains pending references for 24 hours, subject to source-content
|
|
89
|
+
availability and queue capacity. The listener reports delivery gaps instead of
|
|
90
|
+
silently claiming it is caught up. Saving download links does not preserve
|
|
91
|
+
attachment bytes or extend their expiry. To remove a destination, use its ID from
|
|
92
|
+
the readiness message: `primitive endpoints delete --id DESTINATION_ID`.
|
|
93
|
+
|
|
94
|
+
### Low-level delivery API
|
|
95
|
+
|
|
96
|
+
The generated `endpoints pull-webhook-event` and `endpoints complete-webhook-event`
|
|
97
|
+
commands expose the local-delivery API when enabled on your API host. These are
|
|
98
|
+
single API calls; a receive loop must retain the destination identity and report
|
|
99
|
+
each attempt's outcome. Use `--help` to inspect the request fields:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
primitive endpoints pull-webhook-event --help
|
|
103
|
+
primitive endpoints complete-webhook-event --help
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Completion uses a mode-specific JSON body. For a successful process handler:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
primitive endpoints complete-webhook-event --id ENDPOINT_ID --raw-body '{"queue_id":"QUEUE_ID","delivery_id":"DELIVERY_ID","lease_token":"LEASE_TOKEN","mode":"exec","exit_code":0,"duration_ms":12}'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Use the IDs and lease token returned by pull. HTTP forwarding reports
|
|
113
|
+
`mode: "http"` with `status_code`; stdout reports `mode: "stdout"` with
|
|
114
|
+
`write_succeeded`. Transport failures must also be reported. Successful handler
|
|
115
|
+
acceptance is separate from any later agent reasoning.
|
|
116
|
+
|
|
117
|
+
Pull delivery preserves existing webhook bodies and supplies canonical event and
|
|
118
|
+
attempt IDs separately. Deduplicate by event ID. A successful completion can be
|
|
119
|
+
retried with the same queue, attempt, token, and outcome. Check the returned gap
|
|
120
|
+
count as well as the backlog; queue retention does not extend email-content
|
|
121
|
+
retention. Conversation retrieval and threaded replies use the existing SDK API.
|
|
122
|
+
|
|
31
123
|
```bash
|
|
32
124
|
primitive signin
|
|
33
125
|
primitive whoami
|
|
@@ -64,6 +156,7 @@ primitive chat reply "See attached" --attachment ./report.pdf
|
|
|
64
156
|
primitive emails list
|
|
65
157
|
primitive emails get --id <inbound-email-id>
|
|
66
158
|
primitive sent list
|
|
159
|
+
primitive sent delete --id <sent-email-id>
|
|
67
160
|
primitive domains list
|
|
68
161
|
primitive functions templates
|
|
69
162
|
primitive functions init my-fn --template email-reply
|
|
@@ -75,6 +168,24 @@ primitive deliveries replay --id <delivery-id>
|
|
|
75
168
|
|
|
76
169
|
Generated API commands remain available for compatibility and full schema parity, for example `primitive emails:list-emails` and `primitive sending:reply-to-email`.
|
|
77
170
|
|
|
171
|
+
## Remove mailbox history
|
|
172
|
+
|
|
173
|
+
`primitive sent delete --id <sent-email-id>` removes sender history and owned
|
|
174
|
+
attachments. It does not recall delivery or delete recipient copies. Cancel
|
|
175
|
+
scheduled sends before deleting them. A 409 means the record is not currently
|
|
176
|
+
eligible; a 500 or 503 may mean some files were removed already, so retry the same
|
|
177
|
+
DELETE. Repeating a completed deletion succeeds.
|
|
178
|
+
|
|
179
|
+
After disconnecting an agent, an owner or admin logged in with OAuth can run
|
|
180
|
+
`primitive agent-connections remove-agent-connection --address agent@example.com`.
|
|
181
|
+
This removes the revoked connection record while preserving mail, notes and the
|
|
182
|
+
external runtime. Active connections return 409; missing records return 404.
|
|
183
|
+
Organization API keys cannot remove connections.
|
|
184
|
+
|
|
185
|
+
Send and reply can return HTTP 410 `sent_email_deleted` when a prior send was
|
|
186
|
+
deleted. Its occupied idempotency key or automatic reply suppression stays reserved.
|
|
187
|
+
Do not generate a new key or send again to bypass this refusal.
|
|
188
|
+
|
|
78
189
|
## Primitive Memories
|
|
79
190
|
|
|
80
191
|
Memories are durable JSON key-value records scoped to your org by default. Use
|
|
@@ -124,10 +235,11 @@ The `primitive payments` command group drives non-custodial x402 USDC payments.
|
|
|
124
235
|
# ownership message locally with your wallet key. Org is auto-resolved.
|
|
125
236
|
primitive payments register-payout-address --network base-sepolia --label treasury
|
|
126
237
|
|
|
127
|
-
# Payee: request a payment with a human USDC amount. Prints
|
|
238
|
+
# Payee: request a payment with a human USDC amount. Prints the challenge JSON
|
|
239
|
+
# to stdout; a one-line summary goes to stderr.
|
|
128
240
|
primitive payments charge --network base-sepolia --amount-usdc 0.01
|
|
129
|
-
# Capture the
|
|
130
|
-
primitive payments charge --network base-sepolia --amount-usdc 0.01
|
|
241
|
+
# Capture the challenge JSON to hand to the payer.
|
|
242
|
+
primitive payments charge --network base-sepolia --amount-usdc 0.01 > challenge.json
|
|
131
243
|
|
|
132
244
|
# Payer: sign and settle the challenge locally. Reads the challenge inline,
|
|
133
245
|
# from a file, or piped on stdin.
|
|
@@ -164,7 +276,7 @@ primitive payments get-spend-policy
|
|
|
164
276
|
primitive payments update-spend-policy --max-per-payment 5000000
|
|
165
277
|
```
|
|
166
278
|
|
|
167
|
-
`charge` is the friendly verb that matches the SDK `charge` and accepts `--amount-usdc`; `create-challenge` is the lower-level command that takes base-unit `--amount`. Either creates a challenge.
|
|
279
|
+
`charge` is the friendly verb that matches the SDK `charge` and accepts `--amount-usdc`; `create-challenge` is the lower-level command that takes base-unit `--amount`. Either creates a challenge. All four signing commands accept `--json`. `register-payout-address` and `pay` print a human-readable summary by default and raw JSON with `--json`; `pay-email` and `pay-email-step` print JSON by default (the send result and the `interaction.json` bytes, respectively), and `--json` switches them to a fuller envelope object.
|
|
168
280
|
|
|
169
281
|
The signing commands (`register-payout-address`, `pay`, `pay-email`, and `pay-email-step`) need your wallet key. `pay-email` is the recommended payer path for the email-native flow: it signs and sends in one step. `pay-email-step` signs only and emits the `interaction.json` artifact for advanced use where you want to deliver it yourself. Set the key in `PRIMITIVE_X402_PRIVATE_KEY` (a `0x`-prefixed hex private key) so it never lands in shell history or the process list:
|
|
170
282
|
|
|
@@ -172,7 +284,7 @@ The signing commands (`register-payout-address`, `pay`, `pay-email`, and `pay-em
|
|
|
172
284
|
export PRIMITIVE_X402_PRIVATE_KEY=0x...
|
|
173
285
|
```
|
|
174
286
|
|
|
175
|
-
A
|
|
287
|
+
A `--private-key` flag is available as an escape hatch for scripted use, but the environment variable is preferred. The non-signing commands (`charge`, `get-challenge`, `list-payout-addresses`, `get-spend-policy`, `update-spend-policy`) need only your Primitive API key. Run `primitive payments <command> --help` for the full flag list of any command.
|
|
176
288
|
|
|
177
289
|
## Migrating from `@primitivedotdev/sdk` CLI
|
|
178
290
|
|
|
@@ -180,10 +292,10 @@ The CLI previously shipped inside `@primitivedotdev/sdk`. The shipped surface ar
|
|
|
180
292
|
|
|
181
293
|
| Before | After |
|
|
182
294
|
|--------|-------|
|
|
183
|
-
| `npm install -g @primitivedotdev/sdk` | `npm install -g
|
|
184
|
-
| `npx @primitivedotdev/sdk@latest <cmd>` | `npx @
|
|
295
|
+
| `npm install -g @primitivedotdev/sdk` | `npm install -g primitive` |
|
|
296
|
+
| `npx @primitivedotdev/sdk@latest <cmd>` | `npx primitive@latest <cmd>` |
|
|
185
297
|
|
|
186
|
-
`@primitivedotdev/sdk` continues to ship the runtime SDK (webhook, API client, contract, parser, openapi). Use it in your application code; use
|
|
298
|
+
`@primitivedotdev/sdk` continues to ship the runtime SDK (webhook, API client, contract, parser, openapi). Use it in your application code; use `primitive` in your shell and CI.
|
|
187
299
|
|
|
188
300
|
## License
|
|
189
301
|
|