@primitivedotdev/sdk 0.16.0 → 0.18.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.
@@ -31,8 +31,25 @@ export const getStorageStats = (options) => (options?.client ?? client).get({
31
31
  /**
32
32
  * Get webhook signing secret
33
33
  *
34
- * Returns the webhook signing secret for your account. If no secret
35
- * exists yet, one is generated automatically on first access.
34
+ * Returns the webhook signing secret for your account. If no
35
+ * secret exists yet, one is generated automatically on first
36
+ * access.
37
+ *
38
+ * Signing is account-scoped, not per-endpoint. Every webhook
39
+ * delivery from any of your registered endpoints is signed
40
+ * with this single secret. Rotate via
41
+ * `POST /account/webhook-secret/rotate`.
42
+ *
43
+ * **Secret format**: the returned string looks base64-shaped
44
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
45
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
46
+ * delivery body. Base64-decoding before HMAC will silently
47
+ * produce mismatched signatures.
48
+ *
49
+ * See the API-level "Webhook signing" section for the full
50
+ * wire format (header name, signed string shape, hash algo,
51
+ * tolerance) including a language-agnostic verification
52
+ * recipe.
36
53
  *
37
54
  */
38
55
  export const getWebhookSecret = (options) => (options?.client ?? client).get({
@@ -125,12 +142,20 @@ export const verifyDomain = (options) => (options.client ?? client).post({
125
142
  * List inbound emails
126
143
  *
127
144
  * Returns a paginated list of INBOUND emails received at your
128
- * verified domains. Outbound messages sent via /send-mail are not
129
- * included; this endpoint is the inbox view, not a unified
130
- * send/receive history.
145
+ * verified domains. Outbound messages sent via /send-mail are
146
+ * not included; this endpoint is the inbox view, not a
147
+ * unified send/receive history.
148
+ *
149
+ * Supports filtering by domain, status, date range, and
150
+ * free-text search across subject, sender, and recipient
151
+ * fields.
131
152
  *
132
- * Supports filtering by domain, status, date range, and free-text
133
- * search across subject, sender, and recipient fields.
153
+ * For a compact text-table summary of the most recent N
154
+ * inbounds (no filters, no cursor pagination), the CLI ships
155
+ * `primitive emails:latest` as a one-line-per-email shortcut.
156
+ * It's TTY-aware so id columns are full UUIDs when piped, and
157
+ * a `--json` flag returns the same envelope this endpoint
158
+ * does. Use whichever fits the call site.
134
159
  *
135
160
  */
136
161
  export const listEmails = (options) => (options?.client ?? client).get({
@@ -288,9 +313,22 @@ export const listEndpoints = (options) => (options?.client ?? client).get({
288
313
  /**
289
314
  * Create a webhook endpoint
290
315
  *
291
- * Creates a new webhook endpoint. If a deactivated endpoint with the
292
- * same URL and domain exists, it is reactivated instead.
293
- * Subject to plan limits on the number of active endpoints.
316
+ * Creates a new webhook endpoint. If a deactivated endpoint
317
+ * with the same URL and domain exists, it is reactivated
318
+ * instead. Subject to plan limits on the number of active
319
+ * endpoints.
320
+ *
321
+ * **Signing is account-scoped, not per-endpoint.** This call
322
+ * does not return any signing material; every endpoint on the
323
+ * account uses the same webhook secret, fetched via
324
+ * `GET /account/webhook-secret`. See the API-level "Webhook
325
+ * signing" section for the full wire format (header name,
326
+ * signed string, hash algo, secret format, tolerance) and a
327
+ * language-agnostic verification recipe.
328
+ *
329
+ * After creating the endpoint, fire a test delivery against
330
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
331
+ * accepts the signature.
294
332
  *
295
333
  */
296
334
  export const createEndpoint = (options) => (options.client ?? client).post({
@@ -1,2 +1,2 @@
1
- import { $ as AddDomainData, $i as RequestOptions, $n as ListDomainsErrors, $r as SendPermissionAddress, $t as DownloadAttachmentsResponses, A as getSendPermissions, Ai as UpdateEndpointError, An as GetSentEmailData, Ar as ReplayEmailWebhooksError, At as DeleteEndpointError, B as replayDelivery, Bi as UpdateFilterResponses, Bn as GetWebhookSecretData, Br as ResourceId, Bt as DeliverySummary, C as deleteEndpoint, Ci as UpdateDomainData, Cn as GetEmailResponse, Cr as PaginationMeta, Ct as DeleteDomainResponses, D as downloadRawEmail, Di as UpdateDomainResponse, Dn as GetSendPermissionsErrors, Dr as ReplayDeliveryResponse, Dt as DeleteEmailResponse, E as downloadAttachments, Ei as UpdateDomainInput, En as GetSendPermissionsError, Er as ReplayDeliveryErrors, Et as DeleteEmailErrors, F as listDomains, Fi as UpdateFilterData, Fn as GetStorageStatsData, Fr as ReplyToEmailData, Ft as DeleteFilterError, G as testEndpoint, Gi as VerifyDomainResponse, Gn as Limit, Gr as RotateWebhookSecretResponses, Gt as DiscardEmailContentResponse, H as replyToEmail, Hi as VerifyDomainData, Hn as GetWebhookSecretErrors, Hr as RotateWebhookSecretError, Ht as DiscardEmailContentData, I as listEmails, Ii as UpdateFilterError, In as GetStorageStatsError, Ir as ReplyToEmailError, It as DeleteFilterErrors, J as updateEndpoint, Ji as Client, Jn as ListDeliveriesErrors, Jr as SendEmailErrors, Jt as DomainVerifyResult, K as updateAccount, Ki as VerifyDomainResponses, Kn as ListDeliveriesData, Kr as SendEmailData, Kt as DiscardEmailContentResponses, L as listEndpoints, Li as UpdateFilterErrors, Ln as GetStorageStatsErrors, Lr as ReplyToEmailErrors, Lt as DeleteFilterResponse, M as getStorageStats, Mi as UpdateEndpointInput, Mn as GetSentEmailErrors, Mr as ReplayEmailWebhooksResponse, Mt as DeleteEndpointResponse, N as getWebhookSecret, Ni as UpdateEndpointResponse, Nn as GetSentEmailResponse, Nr as ReplayEmailWebhooksResponses, Nt as DeleteEndpointResponses, O as getAccount, Oi as UpdateDomainResponses, On as GetSendPermissionsResponse, Or as ReplayDeliveryResponses, Ot as DeleteEmailResponses, P as listDeliveries, Pi as UpdateEndpointResponses, Pn as GetSentEmailResponses, Pr as ReplayResult, Pt as DeleteFilterData, Q as AccountUpdated, Qi as Options$1, Qn as ListDomainsError, Qr as SendMailResult, Qt as DownloadAttachmentsResponse, R as listFilters, Ri as UpdateFilterInput, Rn as GetStorageStatsResponse, Rr as ReplyToEmailResponse, Rt as DeleteFilterResponses, S as deleteEmail, Si as UpdateAccountResponses, Sn as GetEmailErrors, Sr as ListSentEmailsResponses, St as DeleteDomainResponse, T as discardEmailContent, Ti as UpdateDomainErrors, Tn as GetSendPermissionsData, Tr as ReplayDeliveryError, Tt as DeleteEmailError, U as rotateWebhookSecret, Ui as VerifyDomainError, Un as GetWebhookSecretResponse, Ur as RotateWebhookSecretErrors, Ut as DiscardEmailContentError, V as replayEmailWebhooks, Vi as VerifiedDomain, Vn as GetWebhookSecretError, Vr as RotateWebhookSecretData, Vt as DiscardContentResult, W as sendEmail, Wi as VerifyDomainErrors, Wn as GetWebhookSecretResponses, Wr as RotateWebhookSecretResponse, Wt as DiscardEmailContentErrors, X as verifyDomain, Xi as Config, Xn as ListDeliveriesResponses, Xr as SendEmailResponses, Xt as DownloadAttachmentsError, Y as updateFilter, Yi as ClientOptions$1, Yn as ListDeliveriesResponse, Yr as SendEmailResponse, Yt as DownloadAttachmentsData, Z as Account, Zi as CreateClientConfig, Zn as ListDomainsData, Zr as SendMailInput, Zt as DownloadAttachmentsErrors, _ as Options, _i as UpdateAccountData, _n as GetAccountErrors, _r as ListFiltersResponses, _t as CreateFilterResponses, a as PrimitiveApiError, ai as SentEmailDetail, an as EmailDetail, ar as ListEmailsResponse, at as ClientOptions, b as createFilter, bi as UpdateAccountInput, bn as GetEmailData, br as ListSentEmailsErrors, bt as DeleteDomainError, c as PrimitiveClientOptions, ci as StorageStats, cn as EmailSummary, cr as ListEndpointsError, ct as CreateEndpointErrors, d as SendResult, di as TestEndpointError, dn as ErrorResponse, dr as ListEndpointsResponses, dt as CreateEndpointResponses, ea as RequestResult, ei as SendPermissionAnyRecipient, en as DownloadRawEmailData, er as ListDomainsResponse, et as AddDomainError, f as SendThreadInput, fi as TestEndpointErrors, fn as Filter, fr as ListEnvelope, ft as CreateFilterData, g as operations, gi as UnverifiedDomain, gn as GetAccountError, gr as ListFiltersResponse, gt as CreateFilterResponse, h as createPrimitiveClient, hi as TestResult, hn as GetAccountData, hr as ListFiltersErrors, ht as CreateFilterInput, i as PrimitiveApiClientOptions, ii as SendPermissionsMeta, in as DownloadRawEmailResponses, ir as ListEmailsErrors, it as AddDomainResponses, j as getSentEmail, ji as UpdateEndpointErrors, jn as GetSentEmailError, jr as ReplayEmailWebhooksErrors, jt as DeleteEndpointErrors, k as getEmail, ki as UpdateEndpointData, kn as GetSendPermissionsResponses, kr as ReplayEmailWebhooksData, kt as DeleteEndpointData, l as ReplyInput, li as SuccessEnvelope, ln as EmailWebhookStatus, lr as ListEndpointsErrors, lt as CreateEndpointInput, m as createPrimitiveApiClient, mi as TestEndpointResponses, mn as GateFix, mr as ListFiltersError, mt as CreateFilterErrors, n as ForwardInput, na as Auth, ni as SendPermissionRule, nn as DownloadRawEmailErrors, nr as ListEmailsData, nt as AddDomainInput, o as PrimitiveApiErrorDetails, oi as SentEmailStatus, on as EmailDetailReply, or as ListEmailsResponses, ot as CreateEndpointData, p as client, pi as TestEndpointResponse, pn as GateDenial, pr as ListFiltersData, pt as CreateFilterError, q as updateDomain, qi as WebhookSecret, qn as ListDeliveriesError, qr as SendEmailError, qt as Domain, r as PrimitiveApiClient, ri as SendPermissionYourDomain, rn as DownloadRawEmailResponse, rr as ListEmailsError, rt as AddDomainResponse, s as PrimitiveClient, si as SentEmailSummary, sn as EmailStatus, sr as ListEndpointsData, st as CreateEndpointError, t as DEFAULT_BASE_URL, ta as ResponseStyle, ti as SendPermissionManagedZone, tn as DownloadRawEmailError, tr as ListDomainsResponses, tt as AddDomainErrors, u as SendInput, ui as TestEndpointData, un as Endpoint, ur as ListEndpointsResponse, ut as CreateEndpointResponse, v as addDomain, vi as UpdateAccountError, vn as GetAccountResponse, vr as ListSentEmailsData, vt as Cursor, w as deleteFilter, wi as UpdateDomainError, wn as GetEmailResponses, wr as ReplayDeliveryData, wt as DeleteEmailData, x as deleteDomain, xi as UpdateAccountResponse, xn as GetEmailError, xr as ListSentEmailsResponse, xt as DeleteDomainErrors, y as createEndpoint, yi as UpdateAccountErrors, yn as GetAccountResponses, yr as ListSentEmailsError, yt as DeleteDomainData, z as listSentEmails, zi as UpdateFilterResponse, zn as GetStorageStatsResponses, zr as ReplyToEmailResponses, zt as DeliveryStatus } from "../index-SK_HbwVN.js";
1
+ import { $ as AddDomainData, $i as RequestOptions, $n as ListDomainsErrors, $r as SendPermissionAddress, $t as DownloadAttachmentsResponses, A as getSendPermissions, Ai as UpdateEndpointError, An as GetSentEmailData, Ar as ReplayEmailWebhooksError, At as DeleteEndpointError, B as replayDelivery, Bi as UpdateFilterResponses, Bn as GetWebhookSecretData, Br as ResourceId, Bt as DeliverySummary, C as deleteEndpoint, Ci as UpdateDomainData, Cn as GetEmailResponse, Cr as PaginationMeta, Ct as DeleteDomainResponses, D as downloadRawEmail, Di as UpdateDomainResponse, Dn as GetSendPermissionsErrors, Dr as ReplayDeliveryResponse, Dt as DeleteEmailResponse, E as downloadAttachments, Ei as UpdateDomainInput, En as GetSendPermissionsError, Er as ReplayDeliveryErrors, Et as DeleteEmailErrors, F as listDomains, Fi as UpdateFilterData, Fn as GetStorageStatsData, Fr as ReplyToEmailData, Ft as DeleteFilterError, G as testEndpoint, Gi as VerifyDomainResponse, Gn as Limit, Gr as RotateWebhookSecretResponses, Gt as DiscardEmailContentResponse, H as replyToEmail, Hi as VerifyDomainData, Hn as GetWebhookSecretErrors, Hr as RotateWebhookSecretError, Ht as DiscardEmailContentData, I as listEmails, Ii as UpdateFilterError, In as GetStorageStatsError, Ir as ReplyToEmailError, It as DeleteFilterErrors, J as updateEndpoint, Ji as Client, Jn as ListDeliveriesErrors, Jr as SendEmailErrors, Jt as DomainVerifyResult, K as updateAccount, Ki as VerifyDomainResponses, Kn as ListDeliveriesData, Kr as SendEmailData, Kt as DiscardEmailContentResponses, L as listEndpoints, Li as UpdateFilterErrors, Ln as GetStorageStatsErrors, Lr as ReplyToEmailErrors, Lt as DeleteFilterResponse, M as getStorageStats, Mi as UpdateEndpointInput, Mn as GetSentEmailErrors, Mr as ReplayEmailWebhooksResponse, Mt as DeleteEndpointResponse, N as getWebhookSecret, Ni as UpdateEndpointResponse, Nn as GetSentEmailResponse, Nr as ReplayEmailWebhooksResponses, Nt as DeleteEndpointResponses, O as getAccount, Oi as UpdateDomainResponses, On as GetSendPermissionsResponse, Or as ReplayDeliveryResponses, Ot as DeleteEmailResponses, P as listDeliveries, Pi as UpdateEndpointResponses, Pn as GetSentEmailResponses, Pr as ReplayResult, Pt as DeleteFilterData, Q as AccountUpdated, Qi as Options$1, Qn as ListDomainsError, Qr as SendMailResult, Qt as DownloadAttachmentsResponse, R as listFilters, Ri as UpdateFilterInput, Rn as GetStorageStatsResponse, Rr as ReplyToEmailResponse, Rt as DeleteFilterResponses, S as deleteEmail, Si as UpdateAccountResponses, Sn as GetEmailErrors, Sr as ListSentEmailsResponses, St as DeleteDomainResponse, T as discardEmailContent, Ti as UpdateDomainErrors, Tn as GetSendPermissionsData, Tr as ReplayDeliveryError, Tt as DeleteEmailError, U as rotateWebhookSecret, Ui as VerifyDomainError, Un as GetWebhookSecretResponse, Ur as RotateWebhookSecretErrors, Ut as DiscardEmailContentError, V as replayEmailWebhooks, Vi as VerifiedDomain, Vn as GetWebhookSecretError, Vr as RotateWebhookSecretData, Vt as DiscardContentResult, W as sendEmail, Wi as VerifyDomainErrors, Wn as GetWebhookSecretResponses, Wr as RotateWebhookSecretResponse, Wt as DiscardEmailContentErrors, X as verifyDomain, Xi as Config, Xn as ListDeliveriesResponses, Xr as SendEmailResponses, Xt as DownloadAttachmentsError, Y as updateFilter, Yi as ClientOptions$1, Yn as ListDeliveriesResponse, Yr as SendEmailResponse, Yt as DownloadAttachmentsData, Z as Account, Zi as CreateClientConfig, Zn as ListDomainsData, Zr as SendMailInput, Zt as DownloadAttachmentsErrors, _ as Options, _i as UpdateAccountData, _n as GetAccountErrors, _r as ListFiltersResponses, _t as CreateFilterResponses, a as PrimitiveApiError, ai as SentEmailDetail, an as EmailDetail, ar as ListEmailsResponse, at as ClientOptions, b as createFilter, bi as UpdateAccountInput, bn as GetEmailData, br as ListSentEmailsErrors, bt as DeleteDomainError, c as PrimitiveClientOptions, ci as StorageStats, cn as EmailSummary, cr as ListEndpointsError, ct as CreateEndpointErrors, d as SendResult, di as TestEndpointError, dn as ErrorResponse, dr as ListEndpointsResponses, dt as CreateEndpointResponses, ea as RequestResult, ei as SendPermissionAnyRecipient, en as DownloadRawEmailData, er as ListDomainsResponse, et as AddDomainError, f as SendThreadInput, fi as TestEndpointErrors, fn as Filter, fr as ListEnvelope, ft as CreateFilterData, g as operations, gi as UnverifiedDomain, gn as GetAccountError, gr as ListFiltersResponse, gt as CreateFilterResponse, h as createPrimitiveClient, hi as TestResult, hn as GetAccountData, hr as ListFiltersErrors, ht as CreateFilterInput, i as PrimitiveApiClientOptions, ii as SendPermissionsMeta, in as DownloadRawEmailResponses, ir as ListEmailsErrors, it as AddDomainResponses, j as getSentEmail, ji as UpdateEndpointErrors, jn as GetSentEmailError, jr as ReplayEmailWebhooksErrors, jt as DeleteEndpointErrors, k as getEmail, ki as UpdateEndpointData, kn as GetSendPermissionsResponses, kr as ReplayEmailWebhooksData, kt as DeleteEndpointData, l as ReplyInput, li as SuccessEnvelope, ln as EmailWebhookStatus, lr as ListEndpointsErrors, lt as CreateEndpointInput, m as createPrimitiveApiClient, mi as TestEndpointResponses, mn as GateFix, mr as ListFiltersError, mt as CreateFilterErrors, n as ForwardInput, na as Auth, ni as SendPermissionRule, nn as DownloadRawEmailErrors, nr as ListEmailsData, nt as AddDomainInput, o as PrimitiveApiErrorDetails, oi as SentEmailStatus, on as EmailDetailReply, or as ListEmailsResponses, ot as CreateEndpointData, p as client, pi as TestEndpointResponse, pn as GateDenial, pr as ListFiltersData, pt as CreateFilterError, q as updateDomain, qi as WebhookSecret, qn as ListDeliveriesError, qr as SendEmailError, qt as Domain, r as PrimitiveApiClient, ri as SendPermissionYourDomain, rn as DownloadRawEmailResponse, rr as ListEmailsError, rt as AddDomainResponse, s as PrimitiveClient, si as SentEmailSummary, sn as EmailStatus, sr as ListEndpointsData, st as CreateEndpointError, t as DEFAULT_BASE_URL, ta as ResponseStyle, ti as SendPermissionManagedZone, tn as DownloadRawEmailError, tr as ListDomainsResponses, tt as AddDomainErrors, u as SendInput, ui as TestEndpointData, un as Endpoint, ur as ListEndpointsResponse, ut as CreateEndpointResponse, v as addDomain, vi as UpdateAccountError, vn as GetAccountResponse, vr as ListSentEmailsData, vt as Cursor, w as deleteFilter, wi as UpdateDomainError, wn as GetEmailResponses, wr as ReplayDeliveryData, wt as DeleteEmailData, x as deleteDomain, xi as UpdateAccountResponse, xn as GetEmailError, xr as ListSentEmailsResponse, xt as DeleteDomainErrors, y as createEndpoint, yi as UpdateAccountErrors, yn as GetAccountResponses, yr as ListSentEmailsError, yt as DeleteDomainData, z as listSentEmails, zi as UpdateFilterResponse, zn as GetStorageStatsResponses, zr as ReplyToEmailResponses, zt as DeliveryStatus } from "../index-CHWqMBs6.js";
2
2
  export { Account, AccountUpdated, AddDomainData, AddDomainError, AddDomainErrors, AddDomainInput, AddDomainResponse, AddDomainResponses, Auth, ClientOptions, CreateClientConfig, CreateEndpointData, CreateEndpointError, CreateEndpointErrors, CreateEndpointInput, CreateEndpointResponse, CreateEndpointResponses, CreateFilterData, CreateFilterError, CreateFilterErrors, CreateFilterInput, CreateFilterResponse, CreateFilterResponses, Cursor, DEFAULT_BASE_URL, DeleteDomainData, DeleteDomainError, DeleteDomainErrors, DeleteDomainResponse, DeleteDomainResponses, DeleteEmailData, DeleteEmailError, DeleteEmailErrors, DeleteEmailResponse, DeleteEmailResponses, DeleteEndpointData, DeleteEndpointError, DeleteEndpointErrors, DeleteEndpointResponse, DeleteEndpointResponses, DeleteFilterData, DeleteFilterError, DeleteFilterErrors, DeleteFilterResponse, DeleteFilterResponses, DeliveryStatus, DeliverySummary, DiscardContentResult, DiscardEmailContentData, DiscardEmailContentError, DiscardEmailContentErrors, DiscardEmailContentResponse, DiscardEmailContentResponses, Domain, DomainVerifyResult, DownloadAttachmentsData, DownloadAttachmentsError, DownloadAttachmentsErrors, DownloadAttachmentsResponse, DownloadAttachmentsResponses, DownloadRawEmailData, DownloadRawEmailError, DownloadRawEmailErrors, DownloadRawEmailResponse, DownloadRawEmailResponses, EmailDetail, EmailDetailReply, EmailStatus, EmailSummary, EmailWebhookStatus, Endpoint, ErrorResponse, Filter, ForwardInput, GateDenial, GateFix, GetAccountData, GetAccountError, GetAccountErrors, GetAccountResponse, GetAccountResponses, GetEmailData, GetEmailError, GetEmailErrors, GetEmailResponse, GetEmailResponses, GetSendPermissionsData, GetSendPermissionsError, GetSendPermissionsErrors, GetSendPermissionsResponse, GetSendPermissionsResponses, GetSentEmailData, GetSentEmailError, GetSentEmailErrors, GetSentEmailResponse, GetSentEmailResponses, GetStorageStatsData, GetStorageStatsError, GetStorageStatsErrors, GetStorageStatsResponse, GetStorageStatsResponses, GetWebhookSecretData, GetWebhookSecretError, GetWebhookSecretErrors, GetWebhookSecretResponse, GetWebhookSecretResponses, Limit, ListDeliveriesData, ListDeliveriesError, ListDeliveriesErrors, ListDeliveriesResponse, ListDeliveriesResponses, ListDomainsData, ListDomainsError, ListDomainsErrors, ListDomainsResponse, ListDomainsResponses, ListEmailsData, ListEmailsError, ListEmailsErrors, ListEmailsResponse, ListEmailsResponses, ListEndpointsData, ListEndpointsError, ListEndpointsErrors, ListEndpointsResponse, ListEndpointsResponses, ListEnvelope, ListFiltersData, ListFiltersError, ListFiltersErrors, ListFiltersResponse, ListFiltersResponses, ListSentEmailsData, ListSentEmailsError, ListSentEmailsErrors, ListSentEmailsResponse, ListSentEmailsResponses, Options, PaginationMeta, PrimitiveApiClient, PrimitiveApiClientOptions, PrimitiveApiError, PrimitiveApiErrorDetails, PrimitiveClient, PrimitiveClientOptions, Client as PrimitiveGeneratedApiClient, ClientOptions$1 as PrimitiveGeneratedApiClientOptions, Config as PrimitiveGeneratedApiConfig, Options$1 as PrimitiveGeneratedApiOptions, RequestOptions as PrimitiveGeneratedApiRequestOptions, RequestResult as PrimitiveGeneratedApiRequestResult, ReplayDeliveryData, ReplayDeliveryError, ReplayDeliveryErrors, ReplayDeliveryResponse, ReplayDeliveryResponses, ReplayEmailWebhooksData, ReplayEmailWebhooksError, ReplayEmailWebhooksErrors, ReplayEmailWebhooksResponse, ReplayEmailWebhooksResponses, ReplayResult, ReplyInput, ReplyToEmailData, ReplyToEmailError, ReplyToEmailErrors, ReplyToEmailResponse, ReplyToEmailResponses, ResourceId, ResponseStyle, RotateWebhookSecretData, RotateWebhookSecretError, RotateWebhookSecretErrors, RotateWebhookSecretResponse, RotateWebhookSecretResponses, SendEmailData, SendEmailError, SendEmailErrors, SendEmailResponse, SendEmailResponses, SendInput, SendMailInput, SendMailResult, SendPermissionAddress, SendPermissionAnyRecipient, SendPermissionManagedZone, SendPermissionRule, SendPermissionYourDomain, SendPermissionsMeta, SendResult, SendThreadInput, SentEmailDetail, SentEmailStatus, SentEmailSummary, StorageStats, SuccessEnvelope, TestEndpointData, TestEndpointError, TestEndpointErrors, TestEndpointResponse, TestEndpointResponses, TestResult, UnverifiedDomain, UpdateAccountData, UpdateAccountError, UpdateAccountErrors, UpdateAccountInput, UpdateAccountResponse, UpdateAccountResponses, UpdateDomainData, UpdateDomainError, UpdateDomainErrors, UpdateDomainInput, UpdateDomainResponse, UpdateDomainResponses, UpdateEndpointData, UpdateEndpointError, UpdateEndpointErrors, UpdateEndpointInput, UpdateEndpointResponse, UpdateEndpointResponses, UpdateFilterData, UpdateFilterError, UpdateFilterErrors, UpdateFilterInput, UpdateFilterResponse, UpdateFilterResponses, VerifiedDomain, VerifyDomainData, VerifyDomainError, VerifyDomainErrors, VerifyDomainResponse, VerifyDomainResponses, WebhookSecret, addDomain, client, createEndpoint, createFilter, createPrimitiveApiClient, createPrimitiveClient, deleteDomain, deleteEmail, deleteEndpoint, deleteFilter, discardEmailContent, downloadAttachments, downloadRawEmail, getAccount, getEmail, getSendPermissions, getSentEmail, getStorageStats, getWebhookSecret, listDeliveries, listDomains, listEmails, listEndpoints, listFilters, listSentEmails, operations, replayDelivery, replayEmailWebhooks, replyToEmail, rotateWebhookSecret, sendEmail, testEndpoint, updateAccount, updateDomain, updateEndpoint, updateFilter, verifyDomain };
@@ -687,8 +687,25 @@ const getStorageStats = (options) => (options?.client ?? client$1).get({
687
687
  /**
688
688
  * Get webhook signing secret
689
689
  *
690
- * Returns the webhook signing secret for your account. If no secret
691
- * exists yet, one is generated automatically on first access.
690
+ * Returns the webhook signing secret for your account. If no
691
+ * secret exists yet, one is generated automatically on first
692
+ * access.
693
+ *
694
+ * Signing is account-scoped, not per-endpoint. Every webhook
695
+ * delivery from any of your registered endpoints is signed
696
+ * with this single secret. Rotate via
697
+ * `POST /account/webhook-secret/rotate`.
698
+ *
699
+ * **Secret format**: the returned string looks base64-shaped
700
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
701
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
702
+ * delivery body. Base64-decoding before HMAC will silently
703
+ * produce mismatched signatures.
704
+ *
705
+ * See the API-level "Webhook signing" section for the full
706
+ * wire format (header name, signed string shape, hash algo,
707
+ * tolerance) including a language-agnostic verification
708
+ * recipe.
692
709
  *
693
710
  */
694
711
  const getWebhookSecret = (options) => (options?.client ?? client$1).get({
@@ -802,12 +819,20 @@ const verifyDomain = (options) => (options.client ?? client$1).post({
802
819
  * List inbound emails
803
820
  *
804
821
  * Returns a paginated list of INBOUND emails received at your
805
- * verified domains. Outbound messages sent via /send-mail are not
806
- * included; this endpoint is the inbox view, not a unified
807
- * send/receive history.
822
+ * verified domains. Outbound messages sent via /send-mail are
823
+ * not included; this endpoint is the inbox view, not a
824
+ * unified send/receive history.
808
825
  *
809
- * Supports filtering by domain, status, date range, and free-text
810
- * search across subject, sender, and recipient fields.
826
+ * Supports filtering by domain, status, date range, and
827
+ * free-text search across subject, sender, and recipient
828
+ * fields.
829
+ *
830
+ * For a compact text-table summary of the most recent N
831
+ * inbounds (no filters, no cursor pagination), the CLI ships
832
+ * `primitive emails:latest` as a one-line-per-email shortcut.
833
+ * It's TTY-aware so id columns are full UUIDs when piped, and
834
+ * a `--json` flag returns the same envelope this endpoint
835
+ * does. Use whichever fits the call site.
811
836
  *
812
837
  */
813
838
  const listEmails = (options) => (options?.client ?? client$1).get({
@@ -992,9 +1017,22 @@ const listEndpoints = (options) => (options?.client ?? client$1).get({
992
1017
  /**
993
1018
  * Create a webhook endpoint
994
1019
  *
995
- * Creates a new webhook endpoint. If a deactivated endpoint with the
996
- * same URL and domain exists, it is reactivated instead.
997
- * Subject to plan limits on the number of active endpoints.
1020
+ * Creates a new webhook endpoint. If a deactivated endpoint
1021
+ * with the same URL and domain exists, it is reactivated
1022
+ * instead. Subject to plan limits on the number of active
1023
+ * endpoints.
1024
+ *
1025
+ * **Signing is account-scoped, not per-endpoint.** This call
1026
+ * does not return any signing material; every endpoint on the
1027
+ * account uses the same webhook secret, fetched via
1028
+ * `GET /account/webhook-secret`. See the API-level "Webhook
1029
+ * signing" section for the full wire format (header name,
1030
+ * signed string, hash algo, secret format, tolerance) and a
1031
+ * language-agnostic verification recipe.
1032
+ *
1033
+ * After creating the endpoint, fire a test delivery against
1034
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
1035
+ * accepts the signature.
998
1036
  *
999
1037
  */
1000
1038
  const createEndpoint = (options) => (options.client ?? client$1).post({
@@ -2711,8 +2711,25 @@ declare const getStorageStats: <ThrowOnError extends boolean = false>(options?:
2711
2711
  /**
2712
2712
  * Get webhook signing secret
2713
2713
  *
2714
- * Returns the webhook signing secret for your account. If no secret
2715
- * exists yet, one is generated automatically on first access.
2714
+ * Returns the webhook signing secret for your account. If no
2715
+ * secret exists yet, one is generated automatically on first
2716
+ * access.
2717
+ *
2718
+ * Signing is account-scoped, not per-endpoint. Every webhook
2719
+ * delivery from any of your registered endpoints is signed
2720
+ * with this single secret. Rotate via
2721
+ * `POST /account/webhook-secret/rotate`.
2722
+ *
2723
+ * **Secret format**: the returned string looks base64-shaped
2724
+ * (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
2725
+ * Use it AS-IS as a UTF-8 string when computing HMAC over a
2726
+ * delivery body. Base64-decoding before HMAC will silently
2727
+ * produce mismatched signatures.
2728
+ *
2729
+ * See the API-level "Webhook signing" section for the full
2730
+ * wire format (header name, signed string shape, hash algo,
2731
+ * tolerance) including a language-agnostic verification
2732
+ * recipe.
2716
2733
  *
2717
2734
  */
2718
2735
  declare const getWebhookSecret: <ThrowOnError extends boolean = false>(options?: Options<GetWebhookSecretData, ThrowOnError>) => RequestResult<GetWebhookSecretResponses, GetWebhookSecretErrors, ThrowOnError, "fields">;
@@ -2769,12 +2786,20 @@ declare const verifyDomain: <ThrowOnError extends boolean = false>(options: Opti
2769
2786
  * List inbound emails
2770
2787
  *
2771
2788
  * Returns a paginated list of INBOUND emails received at your
2772
- * verified domains. Outbound messages sent via /send-mail are not
2773
- * included; this endpoint is the inbox view, not a unified
2774
- * send/receive history.
2789
+ * verified domains. Outbound messages sent via /send-mail are
2790
+ * not included; this endpoint is the inbox view, not a
2791
+ * unified send/receive history.
2775
2792
  *
2776
- * Supports filtering by domain, status, date range, and free-text
2777
- * search across subject, sender, and recipient fields.
2793
+ * Supports filtering by domain, status, date range, and
2794
+ * free-text search across subject, sender, and recipient
2795
+ * fields.
2796
+ *
2797
+ * For a compact text-table summary of the most recent N
2798
+ * inbounds (no filters, no cursor pagination), the CLI ships
2799
+ * `primitive emails:latest` as a one-line-per-email shortcut.
2800
+ * It's TTY-aware so id columns are full UUIDs when piped, and
2801
+ * a `--json` flag returns the same envelope this endpoint
2802
+ * does. Use whichever fits the call site.
2778
2803
  *
2779
2804
  */
2780
2805
  declare const listEmails: <ThrowOnError extends boolean = false>(options?: Options<ListEmailsData, ThrowOnError>) => RequestResult<ListEmailsResponses, ListEmailsErrors, ThrowOnError, "fields">;
@@ -2884,9 +2909,22 @@ declare const listEndpoints: <ThrowOnError extends boolean = false>(options?: Op
2884
2909
  /**
2885
2910
  * Create a webhook endpoint
2886
2911
  *
2887
- * Creates a new webhook endpoint. If a deactivated endpoint with the
2888
- * same URL and domain exists, it is reactivated instead.
2889
- * Subject to plan limits on the number of active endpoints.
2912
+ * Creates a new webhook endpoint. If a deactivated endpoint
2913
+ * with the same URL and domain exists, it is reactivated
2914
+ * instead. Subject to plan limits on the number of active
2915
+ * endpoints.
2916
+ *
2917
+ * **Signing is account-scoped, not per-endpoint.** This call
2918
+ * does not return any signing material; every endpoint on the
2919
+ * account uses the same webhook secret, fetched via
2920
+ * `GET /account/webhook-secret`. See the API-level "Webhook
2921
+ * signing" section for the full wire format (header name,
2922
+ * signed string, hash algo, secret format, tolerance) and a
2923
+ * language-agnostic verification recipe.
2924
+ *
2925
+ * After creating the endpoint, fire a test delivery against
2926
+ * it via `POST /endpoints/{id}/test` to confirm your verifier
2927
+ * accepts the signature.
2890
2928
  *
2891
2929
  */
2892
2930
  declare const createEndpoint: <ThrowOnError extends boolean = false>(options: Options<CreateEndpointData, ThrowOnError>) => RequestResult<CreateEndpointResponses, CreateEndpointErrors, ThrowOnError, "fields">;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { A as UnknownEvent, C as ParsedDataFailed, D as RawContentDownloadOnly, E as RawContent, M as WebhookAttachment, N as WebhookEvent, O as RawContentInline, S as ParsedDataComplete, T as ParsedStatus, _ as ForwardResultInline, a as DmarcPolicy, b as KnownWebhookEvent, c as EmailAnalysis, d as EventType, f as ForwardAnalysis, g as ForwardResultAttachmentSkipped, h as ForwardResultAttachmentAnalyzed, i as DkimSignature, j as ValidateEmailAuthResult, k as SpfResult, l as EmailAuth, m as ForwardResult, n as AuthVerdict, o as DmarcResult, p as ForwardOriginalSender, r as DkimResult, s as EmailAddress, t as AuthConfidence, u as EmailReceivedEvent, v as ForwardVerdict, w as ParsedError, x as ParsedData, y as ForwardVerification } from "./types-9vXGZjPd.js";
2
2
  import { a as buildReplySubject, c as parseHeaderAddress, i as buildForwardSubject, n as ReceivedEmailAddress, o as formatAddress, r as ReceivedEmailThread, s as normalizeReceivedEmail, t as ReceivedEmail } from "./received-email-DNjpq_Wt.js";
3
- import { a as PrimitiveApiError, c as PrimitiveClientOptions, d as SendResult, f as SendThreadInput, h as createPrimitiveClient, l as ReplyInput, n as ForwardInput, p as client, s as PrimitiveClient, u as SendInput } from "./index-SK_HbwVN.js";
3
+ import { a as PrimitiveApiError, c as PrimitiveClientOptions, d as SendResult, f as SendThreadInput, h as createPrimitiveClient, l as ReplyInput, n as ForwardInput, p as client, s as PrimitiveClient, u as SendInput } from "./index-CHWqMBs6.js";
4
4
  import { A as VerifyOptions, B as PAYLOAD_ERRORS, C as signStandardWebhooksPayload, D as PRIMITIVE_CONFIRMED_HEADER, E as LEGACY_SIGNATURE_HEADER, F as VerifyDownloadTokenResult, G as VERIFICATION_ERRORS, H as RAW_EMAIL_ERRORS, I as generateDownloadToken, J as WebhookPayloadErrorCode, K as WebhookErrorCode, L as verifyDownloadToken, M as verifyWebhookSignature, N as GenerateDownloadTokenOptions, O as PRIMITIVE_SIGNATURE_HEADER, P as VerifyDownloadTokenOptions, Q as WebhookVerificationErrorCode, R as safeValidateEmailReceivedEvent, S as StandardWebhooksVerifyOptions, T as LEGACY_CONFIRMED_HEADER, U as RawEmailDecodeError, V as PrimitiveWebhookError, W as RawEmailDecodeErrorCode, X as WebhookValidationErrorCode, Y as WebhookValidationError, Z as WebhookVerificationError, _ as emailReceivedEventJsonSchema, a as confirmedHeaders, b as STANDARD_WEBHOOK_TIMESTAMP_HEADER, c as handleWebhook, d as isRawIncluded, f as parseWebhookEvent, g as validateEmailAuth, h as WEBHOOK_VERSION, i as WebhookHeaders, j as signWebhookPayload, k as SignResult, l as isDownloadExpired, m as verifyRawEmailDownload, n as HandleWebhookOptions, o as decodeRawEmail, p as receive, q as WebhookPayloadError, r as ReceiveRequestOptions, s as getDownloadTimeRemaining, t as DecodeRawEmailOptions, u as isEmailReceivedEvent, v as STANDARD_WEBHOOK_ID_HEADER, w as verifyStandardWebhooksSignature, x as StandardWebhooksSignResult, y as STANDARD_WEBHOOK_SIGNATURE_HEADER, z as validateEmailReceivedEvent } from "./index-CbEivn3S.js";
5
5
 
6
6
  //#region src/index.d.ts
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as parseHeaderAddress, i as normalizeReceivedEmail, n as buildReplySubject, r as formatAddress, t as buildForwardSubject } from "./received-email-D6tKtWwW.js";
2
- import { a as client, i as PrimitiveClient, r as PrimitiveApiError, s as createPrimitiveClient } from "./api-CTf0cUsi.js";
2
+ import { a as client, i as PrimitiveClient, r as PrimitiveApiError, s as createPrimitiveClient } from "./api-DrAZhxS-.js";
3
3
  import { A as PRIMITIVE_CONFIRMED_HEADER, B as RAW_EMAIL_ERRORS, C as STANDARD_WEBHOOK_ID_HEADER, D as verifyStandardWebhooksSignature, E as signStandardWebhooksPayload, F as verifyDownloadToken, G as WebhookVerificationError, H as VERIFICATION_ERRORS, I as safeValidateEmailReceivedEvent, L as validateEmailReceivedEvent, M as signWebhookPayload, N as verifyWebhookSignature, O as LEGACY_CONFIRMED_HEADER, P as generateDownloadToken, R as PAYLOAD_ERRORS, S as emailReceivedEventJsonSchema, T as STANDARD_WEBHOOK_TIMESTAMP_HEADER, U as WebhookPayloadError, V as RawEmailDecodeError, W as WebhookValidationError, _ as DmarcResult, a as isDownloadExpired, b as ParsedStatus, c as parseWebhookEvent, d as WEBHOOK_VERSION, f as validateEmailAuth, g as DmarcPolicy, h as DkimResult, i as handleWebhook, j as PRIMITIVE_SIGNATURE_HEADER, k as LEGACY_SIGNATURE_HEADER, l as receive, m as AuthVerdict, n as decodeRawEmail, o as isEmailReceivedEvent, p as AuthConfidence, r as getDownloadTimeRemaining, s as isRawIncluded, t as confirmedHeaders, u as verifyRawEmailDownload, v as EventType, w as STANDARD_WEBHOOK_SIGNATURE_HEADER, x as SpfResult, y as ForwardVerdict, z as PrimitiveWebhookError } from "./webhook-zkN4wUTs.js";
4
4
  //#region src/index.ts
5
5
  const primitive = {
@@ -302,6 +302,45 @@ export function writeErrorWithHints(payload) {
302
302
  process.stderr.write(`${ERROR_CODE_HINTS[code]}\n`);
303
303
  }
304
304
  }
305
+ // Format milliseconds as a short human-readable wall-clock duration.
306
+ // Sub-second uses 2 decimal places (e.g. `0.18s`); seconds use 2
307
+ // decimals up to 60s (`12.34s`); minute-plus uses `Mm SS.SSs`.
308
+ // Display-only; the underlying ms value is what the caller computed.
309
+ export function formatElapsed(ms) {
310
+ const seconds = ms / 1000;
311
+ if (seconds < 60)
312
+ return `${seconds.toFixed(2)}s`;
313
+ const minutes = Math.floor(seconds / 60);
314
+ const rem = seconds - minutes * 60;
315
+ return `${minutes}m ${rem.toFixed(2)}s`;
316
+ }
317
+ // Run `fn` and, when `enabled` is true, write a one-line wall-clock
318
+ // timing report to stderr after it completes. Stderr keeps the row
319
+ // data on stdout grep/jq-friendly. The timer captures the full
320
+ // duration of the function (HTTPS round trip, server-side gate +
321
+ // agent + delivery, polling, etc.), not just the API call's
322
+ // server-side processing.
323
+ //
324
+ // Used by every `--time` callsite across the CLI: generated
325
+ // operation commands and hand-coded shortcuts (send, whoami,
326
+ // emails:latest, describe). Pulled out as a helper so timing is
327
+ // uniform across commands and a single render-format change
328
+ // propagates everywhere.
329
+ export async function runWithTiming(enabled, fn) {
330
+ if (!enabled)
331
+ return fn();
332
+ const start = Date.now();
333
+ try {
334
+ return await fn();
335
+ }
336
+ finally {
337
+ process.stderr.write(`[time: ${formatElapsed(Date.now() - start)}]\n`);
338
+ }
339
+ }
340
+ // Shared `--time` flag definition every CLI command spreads into its
341
+ // own static flags. Lives here so the flag's description and short
342
+ // name stay consistent across the hand-coded and generated commands.
343
+ export const TIME_FLAG_DESCRIPTION = "Print the wall-clock duration of this command to stderr after it completes (e.g. `[time: 1.34s]`). Useful for measuring `--wait` send latency, comparing CLI overhead, or capturing timing in scripts.";
305
344
  // Reserved flag names the body-field expander must never overwrite.
306
345
  // `--raw-body` and `--body-file` are the JSON escape hatches.
307
346
  // `--api-key`, `--base-url`, `--output` are infra. Path and query
@@ -363,6 +402,9 @@ function buildFlags(operation) {
363
402
  description: "API base URL (defaults to PRIMITIVE_API_URL or production)",
364
403
  env: "PRIMITIVE_API_URL",
365
404
  }),
405
+ time: Flags.boolean({
406
+ description: TIME_FLAG_DESCRIPTION,
407
+ }),
366
408
  };
367
409
  for (const parameter of [...operation.pathParams, ...operation.queryParams]) {
368
410
  flags[flagName(parameter.name)] = flagForParameter(parameter);
@@ -460,101 +502,103 @@ export function createOperationCommand(operation) {
460
502
  async run() {
461
503
  const { flags } = await this.parse(OperationCommand);
462
504
  const parsedFlags = flags;
463
- const apiClient = new PrimitiveApiClient({
464
- apiKey: typeof parsedFlags["api-key"] === "string"
465
- ? parsedFlags["api-key"]
466
- : undefined,
467
- baseUrl: typeof parsedFlags["base-url"] === "string"
468
- ? parsedFlags["base-url"]
469
- : undefined,
470
- });
471
- // Two body sources, merged: explicit JSON via --body /
472
- // --body-file (the base) plus per-field flags (the
473
- // overrides). Per-field flag values take precedence on key
474
- // conflicts so a caller can pass a base payload via --body
475
- // and override one field on the command line.
476
- let body;
477
- if (operation.hasJsonBody) {
478
- const explicit = readJsonBody(parsedFlags);
479
- const overrides = collectBodyFieldFlags(parsedFlags, bodyFieldFlagToProperty);
480
- if (Object.keys(overrides).length > 0) {
481
- if (explicit === undefined) {
482
- body = overrides;
483
- }
484
- else if (explicit !== null &&
485
- typeof explicit === "object" &&
486
- !Array.isArray(explicit)) {
487
- body = { ...explicit, ...overrides };
505
+ await runWithTiming(parsedFlags.time === true, async () => {
506
+ const apiClient = new PrimitiveApiClient({
507
+ apiKey: typeof parsedFlags["api-key"] === "string"
508
+ ? parsedFlags["api-key"]
509
+ : undefined,
510
+ baseUrl: typeof parsedFlags["base-url"] === "string"
511
+ ? parsedFlags["base-url"]
512
+ : undefined,
513
+ });
514
+ // Two body sources, merged: explicit JSON via --body /
515
+ // --body-file (the base) plus per-field flags (the
516
+ // overrides). Per-field flag values take precedence on key
517
+ // conflicts so a caller can pass a base payload via --body
518
+ // and override one field on the command line.
519
+ let body;
520
+ if (operation.hasJsonBody) {
521
+ const explicit = readJsonBody(parsedFlags);
522
+ const overrides = collectBodyFieldFlags(parsedFlags, bodyFieldFlagToProperty);
523
+ if (Object.keys(overrides).length > 0) {
524
+ if (explicit === undefined) {
525
+ body = overrides;
526
+ }
527
+ else if (explicit !== null &&
528
+ typeof explicit === "object" &&
529
+ !Array.isArray(explicit)) {
530
+ body = { ...explicit, ...overrides };
531
+ }
532
+ else {
533
+ // Caller passed --raw-body as null, an array, or a
534
+ // primitive AND also passed per-field flags. We can't
535
+ // merge per-field overrides into a non-object body
536
+ // shape, and silently dropping either source would
537
+ // leave the caller's actual intent unclear. Refuse
538
+ // loudly so the next attempt is unambiguous.
539
+ const explicitKind = explicit === null
540
+ ? "null"
541
+ : Array.isArray(explicit)
542
+ ? "array"
543
+ : typeof explicit;
544
+ const overrideFlags = Object.keys(overrides)
545
+ .map((p) => `--${flagName(p)}`)
546
+ .join(", ");
547
+ throw new Errors.CLIError(`--raw-body must be a JSON object when also passing per-field flags (got ${explicitKind}); supplied per-field flags: ${overrideFlags}. Either drop --raw-body and rely on the per-field flags, or move every field into the JSON --raw-body and drop the flags.`);
548
+ }
488
549
  }
489
550
  else {
490
- // Caller passed --raw-body as null, an array, or a
491
- // primitive AND also passed per-field flags. We can't
492
- // merge per-field overrides into a non-object body
493
- // shape, and silently dropping either source would
494
- // leave the caller's actual intent unclear. Refuse
495
- // loudly so the next attempt is unambiguous.
496
- const explicitKind = explicit === null
497
- ? "null"
498
- : Array.isArray(explicit)
499
- ? "array"
500
- : typeof explicit;
501
- const overrideFlags = Object.keys(overrides)
502
- .map((p) => `--${flagName(p)}`)
503
- .join(", ");
504
- throw new Errors.CLIError(`--raw-body must be a JSON object when also passing per-field flags (got ${explicitKind}); supplied per-field flags: ${overrideFlags}. Either drop --raw-body and rely on the per-field flags, or move every field into the JSON --raw-body and drop the flags.`);
551
+ body = explicit;
505
552
  }
506
553
  }
507
- else {
508
- body = explicit;
554
+ if (operation.bodyRequired && body === undefined) {
555
+ throw new Errors.CLIError(`Operation ${operation.operationId} requires a body. Pass each field as a --flag (see --help) or supply JSON via --raw-body / --body-file.`);
509
556
  }
510
- }
511
- if (operation.bodyRequired && body === undefined) {
512
- throw new Errors.CLIError(`Operation ${operation.operationId} requires a body. Pass each field as a --flag (see --help) or supply JSON via --raw-body / --body-file.`);
513
- }
514
- const operationFn = operations[operation.sdkName];
515
- const result = await operationFn({
516
- body,
517
- client: apiClient.client,
518
- parseAs: operation.binaryResponse ? "blob" : "auto",
519
- path: collectValues(operation.pathParams, parsedFlags),
520
- query: collectValues(operation.queryParams, parsedFlags),
521
- responseStyle: "fields",
522
- });
523
- if (result.error) {
524
- writeErrorWithHints(extractErrorPayload(result.error));
525
- process.exitCode = 1;
526
- return;
527
- }
528
- if (operation.binaryResponse) {
529
- const blob = result.data;
530
- const bytes = Buffer.from(await blob.arrayBuffer());
531
- const output = parsedFlags.output;
532
- if (typeof output === "string") {
533
- writeFileSync(output, bytes);
557
+ const operationFn = operations[operation.sdkName];
558
+ const result = await operationFn({
559
+ body,
560
+ client: apiClient.client,
561
+ parseAs: operation.binaryResponse ? "blob" : "auto",
562
+ path: collectValues(operation.pathParams, parsedFlags),
563
+ query: collectValues(operation.queryParams, parsedFlags),
564
+ responseStyle: "fields",
565
+ });
566
+ if (result.error) {
567
+ writeErrorWithHints(extractErrorPayload(result.error));
568
+ process.exitCode = 1;
534
569
  return;
535
570
  }
536
- process.stdout.write(bytes);
537
- return;
538
- }
539
- const envelope = result.data;
540
- const cursor = envelope?.meta?.cursor;
541
- if (cursor) {
542
- process.stderr.write(`next cursor: ${cursor}\n`);
543
- }
544
- // Empty-result hint. When a list-style operation returns
545
- // an empty array, emit an operation-specific note to
546
- // stderr so a naive caller can distinguish "nothing here"
547
- // from "something isn't set up." Stdout still gets the
548
- // raw `[]` so machine-readable output is unchanged. The
549
- // AGX walkthrough flagged this: `list-deliveries` returning
550
- // `[]` left the agent unsure whether they had an empty
551
- // delivery log or no endpoints configured at all.
552
- if (Array.isArray(envelope?.data) && envelope.data.length === 0) {
553
- const hint = EMPTY_RESULT_HINTS[operation.sdkName];
554
- if (hint)
555
- process.stderr.write(`${hint}\n`);
556
- }
557
- this.log(JSON.stringify(envelope?.data ?? null, null, 2));
571
+ if (operation.binaryResponse) {
572
+ const blob = result.data;
573
+ const bytes = Buffer.from(await blob.arrayBuffer());
574
+ const output = parsedFlags.output;
575
+ if (typeof output === "string") {
576
+ writeFileSync(output, bytes);
577
+ return;
578
+ }
579
+ process.stdout.write(bytes);
580
+ return;
581
+ }
582
+ const envelope = result.data;
583
+ const cursor = envelope?.meta?.cursor;
584
+ if (cursor) {
585
+ process.stderr.write(`next cursor: ${cursor}\n`);
586
+ }
587
+ // Empty-result hint. When a list-style operation returns
588
+ // an empty array, emit an operation-specific note to
589
+ // stderr so a naive caller can distinguish "nothing here"
590
+ // from "something isn't set up." Stdout still gets the
591
+ // raw `[]` so machine-readable output is unchanged. The
592
+ // AGX walkthrough flagged this: `list-deliveries` returning
593
+ // `[]` left the agent unsure whether they had an empty
594
+ // delivery log or no endpoints configured at all.
595
+ if (Array.isArray(envelope?.data) && envelope.data.length === 0) {
596
+ const hint = EMPTY_RESULT_HINTS[operation.sdkName];
597
+ if (hint)
598
+ process.stderr.write(`${hint}\n`);
599
+ }
600
+ this.log(JSON.stringify(envelope?.data ?? null, null, 2));
601
+ });
558
602
  }
559
603
  }
560
604
  return OperationCommand;
@@ -566,9 +610,9 @@ export function createOperationCommand(operation) {
566
610
  // `sdkName` for the operation. Operations without an entry fall
567
611
  // back to no hint (silent empty array, same as before).
568
612
  const EMPTY_RESULT_HINTS = {
569
- listDeliveries: "(no results) Often means no webhook endpoints are configured to receive deliveries. Run `primitive endpoints:list-endpoints` to check.",
613
+ listDeliveries: "(no results) No webhook deliveries logged yet. If you have an endpoint configured but expected to see test fires here: test deliveries from `primitive endpoints:test-endpoint` are NOT logged in this list, they're synchronous and visible only in the test-endpoint command's response. Real deliveries are logged when an inbound `email.received` event fans out to your endpoints. If you have no endpoints, run `primitive endpoints:list-endpoints` to check.",
570
614
  listEndpoints: "(no results) No webhook endpoints configured. Add one with `primitive endpoints:create-endpoint --url <your-url>`.",
571
- listEmails: "(no results) No inbound emails received yet on this account.",
615
+ listEmails: "(no results) No inbound emails received yet on this account. Send one to a verified domain to populate this list. For a compact view, prefer `primitive emails:latest`.",
572
616
  listDomains: "(no results) No domains on this account. Add one with `primitive domains:add-domain --domain <yourdomain.example>`.",
573
617
  listFilters: "(no results) No filter rules configured.",
574
618
  };