primcli 1.21.0 → 1.24.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 CHANGED
@@ -1,4 +1,4 @@
1
- # @primitivedotdev/cli
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 @primitivedotdev/cli
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 unscoped as [`primcli`](https://www.npmjs.com/package/primcli). `npm install -g primcli` installs an identical build with the same `primitive`/`prim` commands. Use whichever name you prefer; they track the same version.
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 @primitivedotdev/cli@latest <command>
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
@@ -124,10 +216,11 @@ The `primitive payments` command group drives non-custodial x402 USDC payments.
124
216
  # ownership message locally with your wallet key. Org is auto-resolved.
125
217
  primitive payments register-payout-address --network base-sepolia --label treasury
126
218
 
127
- # Payee: request a payment with a human USDC amount. Prints a summary by default.
219
+ # Payee: request a payment with a human USDC amount. Prints the challenge JSON
220
+ # to stdout; a one-line summary goes to stderr.
128
221
  primitive payments charge --network base-sepolia --amount-usdc 0.01
129
- # Capture the raw challenge JSON to hand to the payer.
130
- primitive payments charge --network base-sepolia --amount-usdc 0.01 --json > challenge.json
222
+ # Capture the challenge JSON to hand to the payer.
223
+ primitive payments charge --network base-sepolia --amount-usdc 0.01 > challenge.json
131
224
 
132
225
  # Payer: sign and settle the challenge locally. Reads the challenge inline,
133
226
  # from a file, or piped on stdin.
@@ -164,7 +257,7 @@ primitive payments get-spend-policy
164
257
  primitive payments update-spend-policy --max-per-payment 5000000
165
258
  ```
166
259
 
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. The signing commands print a human-readable summary by default; pass `--json` for raw JSON suitable for piping.
260
+ `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
261
 
169
262
  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
263
 
@@ -172,7 +265,7 @@ The signing commands (`register-payout-address`, `pay`, `pay-email`, and `pay-em
172
265
  export PRIMITIVE_X402_PRIVATE_KEY=0x...
173
266
  ```
174
267
 
175
- A hidden `--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.
268
+ 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
269
 
177
270
  ## Migrating from `@primitivedotdev/sdk` CLI
178
271
 
@@ -180,10 +273,10 @@ The CLI previously shipped inside `@primitivedotdev/sdk`. The shipped surface ar
180
273
 
181
274
  | Before | After |
182
275
  |--------|-------|
183
- | `npm install -g @primitivedotdev/sdk` | `npm install -g @primitivedotdev/cli` |
184
- | `npx @primitivedotdev/sdk@latest <cmd>` | `npx @primitivedotdev/cli@latest <cmd>` |
276
+ | `npm install -g @primitivedotdev/sdk` | `npm install -g primitive` |
277
+ | `npx @primitivedotdev/sdk@latest <cmd>` | `npx primitive@latest <cmd>` |
185
278
 
186
- `@primitivedotdev/sdk` continues to ship the runtime SDK (webhook, API client, contract, parser, openapi). Use it in your application code; use `@primitivedotdev/cli` in your shell and CI.
279
+ `@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
280
 
188
281
  ## License
189
282