primcli 3.0.0-preview.4 → 3.0.0-preview.6
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 +9 -8
- package/dist/api-command-CRjIK1QL.js +52008 -0
- package/dist/{listen-background-C0F9gNDD.js → listen-background-DyBYca28.js} +323 -36
- package/dist/{machine-session-DD35Pfgd.js → machine-session-3H-rNH8v.js} +5 -5
- package/dist/{notify-session-aMGIFmeu.js → notify-session-DTyg-sfS.js} +2 -2
- package/dist/oclif/auto-signal-worker.js +3 -3
- package/dist/oclif/auto-signals.js +1 -1
- package/dist/oclif/index.js +2624 -45847
- package/dist/oclif/listen-supervisor.js +1 -1
- package/dist/oclif/receiver-heal.js +4 -3
- package/dist/oclif/root-signup-hint.js +15 -15
- package/dist/{repeats-Dj_o6c-X-BwGkVE7e.js → repeats-Dj_o6c-X-CP0h4alF.js} +207 -31
- package/dist/{scoped-chat-B-J3sdNS.js → scoped-chat-CvqdlWuX.js} +1 -1
- package/dist/{signal-command-DEArW9g5.js → signal-command-CPxRPbHK.js} +4 -4
- package/man/primitive.1 +7 -1
- package/package.json +6 -3
- package/dist/api-command-BFfgKPTp.js +0 -4583
|
@@ -165,6 +165,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
165
165
|
getRelayAutoJoin: () => getRelayAutoJoin,
|
|
166
166
|
getRepeatingSend: () => getRepeatingSend,
|
|
167
167
|
getSearchSettings: () => getSearchSettings,
|
|
168
|
+
getSendFrom: () => getSendFrom,
|
|
168
169
|
getSendPermissions: () => getSendPermissions,
|
|
169
170
|
getSentEmail: () => getSentEmail,
|
|
170
171
|
getSentHourlyStats: () => getSentHourlyStats,
|
|
@@ -180,6 +181,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
180
181
|
inviteOrganizationMember: () => inviteOrganizationMember,
|
|
181
182
|
inviteProjectMember: () => inviteProjectMember,
|
|
182
183
|
leaveOrganization: () => leaveOrganization,
|
|
184
|
+
listActivityObjects: () => listActivityObjects,
|
|
183
185
|
listAddressNotes: () => listAddressNotes,
|
|
184
186
|
listAddressNotesBatch: () => listAddressNotesBatch,
|
|
185
187
|
listAgentConnections: () => listAgentConnections,
|
|
@@ -1215,9 +1217,7 @@ const listEndpoints = (options) => (options?.client ?? client).get({
|
|
|
1215
1217
|
/**
|
|
1216
1218
|
* Create a webhook endpoint
|
|
1217
1219
|
*
|
|
1218
|
-
* Creates a new webhook endpoint.
|
|
1219
|
-
* with the same URL and domain exists, it is reactivated
|
|
1220
|
-
* instead. Subject to plan limits on the number of active
|
|
1220
|
+
* Creates a new webhook endpoint. A URL can have one endpoint per domain, route targets included (unlike the one default destination per domain), and endpoints with no domain_id count as one domain. A disabled endpoint still holds its URL; a deleted one does not. A create at a URL another endpoint has on the same domain is refused (400). A deleted endpoint's URL can be used again: the create makes a new endpoint, with a new id, and the deleted one stays as it was. Subject to plan limits on the number of active
|
|
1221
1221
|
* endpoints.
|
|
1222
1222
|
*
|
|
1223
1223
|
* **Signing.** A webhook is signed with the organization's webhook secret (`GET /account/webhook-secret`) unless it has its own. A webhook made as a person's own, or by an API key limited to some mailboxes, a third-party app or an agent delegate for itself, is made with its own secret: the response carries it once as `signing_secret`, and `GET /endpoints/{id}/signing-secret` returns it afterwards. Other webhooks, those a person who can read every mailbox makes among them, sign with the organization's secret until given their own. `signed_with` on the endpoint says which secret signs it. See the API-level "Webhook
|
|
@@ -1266,7 +1266,7 @@ const deleteEndpoint = (options) => (options.client ?? client).delete({
|
|
|
1266
1266
|
/**
|
|
1267
1267
|
* Get an endpoint
|
|
1268
1268
|
*
|
|
1269
|
-
* One endpoint, as GET /endpoints shows it, to a caller who would see it there. Any other id, a deleted endpoint's included, answers 404.
|
|
1269
|
+
* One endpoint, as GET /endpoints shows it, to a caller who would see it there. Any other id, a deleted endpoint's included, answers 404. For a webhook, delivery says whether it is being sent received mail at all, why not, and how much rule-granted mail is held while its owner cannot act.
|
|
1270
1270
|
*/
|
|
1271
1271
|
const getEndpoint = (options) => (options.client ?? client).get({
|
|
1272
1272
|
security: [{
|
|
@@ -1279,10 +1279,12 @@ const getEndpoint = (options) => (options.client ?? client).get({
|
|
|
1279
1279
|
/**
|
|
1280
1280
|
* Update a webhook endpoint
|
|
1281
1281
|
*
|
|
1282
|
-
* Updates an active webhook endpoint. Changing the URL keeps the endpoint: its id, recipient routes, signing secret, delivery history and any deliveries still owed to it stay with it, and owed deliveries go to the new URL.
|
|
1282
|
+
* Updates an active webhook endpoint. Changing the URL keeps the endpoint: its id, recipient routes, signing secret, delivery history and any deliveries still owed to it stay with it, and owed deliveries go to the new URL. A URL can have one endpoint per domain, route targets included (unlike the one default destination per domain), and endpoints with no domain_id count as one domain. A disabled endpoint still holds its URL; a deleted one does not. A change onto a URL another endpoint has on the same domain is refused (400), and a move onto a domain where another endpoint has this URL is refused (409).
|
|
1283
1283
|
*
|
|
1284
1284
|
*
|
|
1285
1285
|
* Pull destinations cannot be assigned a URL, function or recipient-routing domain. Existing endpoint deletion disconnects the destination; creating a new destination does not backfill historical events.
|
|
1286
|
+
*
|
|
1287
|
+
* Giving a webhook the organization does not own to a different key (owner_key_id), or a key's webhook back to the organization (owner_key_id null), turns it off unless the request also sets enabled: its URL was chosen under its previous owner. It then reads enabled false with disabled_reason owner_changed, and turning it on or giving it a new URL starts it again. A key that carries on for the owning key through rotation (its successor, at any depth up to 16 rotations) is not a different key: the webhook stays as it was, with the same signing secret. That does not hold when the owning key was made from a key a transfer moved or rotated away, or from one that has since been deleted: no successor carries on for it. The answer's warnings name each such change (turned_off_owner_changed, turned_on_new_url), so a client can say so.
|
|
1286
1288
|
*/
|
|
1287
1289
|
const updateEndpoint = (options) => (options.client ?? client).patch({
|
|
1288
1290
|
security: [{
|
|
@@ -1339,6 +1341,8 @@ const completeWebhookEvent = (options) => (options.client ?? client).post({
|
|
|
1339
1341
|
* Successful deliveries and verified-domain endpoints are exempt
|
|
1340
1342
|
* from the rate limit.
|
|
1341
1343
|
*
|
|
1344
|
+
*
|
|
1345
|
+
* The test is sent whether or not real mail would be. reachable says whether the endpoint answered it with a 2xx; delivery says, apart from that, whether real email.received events would be sent to the endpoint by its own conditions (on, not held, an owner that can receive mail, subscribed to the event), with every reason it would not be. A 200 from the test alone does not mean mail arrives.
|
|
1342
1346
|
*/
|
|
1343
1347
|
const testEndpoint = (options) => (options.client ?? client).post({
|
|
1344
1348
|
security: [{
|
|
@@ -1372,6 +1376,8 @@ const testEndpoint = (options) => (options.client ?? client).post({
|
|
|
1372
1376
|
* delivered as if unfiltered), so `rules_valid: false` exposes a
|
|
1373
1377
|
* misconfiguration that is otherwise silent.
|
|
1374
1378
|
*
|
|
1379
|
+
*
|
|
1380
|
+
* would_deliver also covers the endpoint's own delivery conditions for this email (delivery): it is on, neither it nor the email's route is held, its owner may receive this email, and it subscribes to the event. Which endpoint routing sends the email to is decided separately: POST /routes/simulate answers that. A 503 means those conditions could not be read just now; retry.
|
|
1375
1381
|
*/
|
|
1376
1382
|
const testEndpointRules = (options) => (options.client ?? client).post({
|
|
1377
1383
|
security: [{
|
|
@@ -1644,6 +1650,7 @@ const listRoutes = (options) => (options?.client ?? client).get({
|
|
|
1644
1650
|
* transaction, enabling per-address function routing (e.g.
|
|
1645
1651
|
* `alice@acme.com -> functionA`).
|
|
1646
1652
|
*
|
|
1653
|
+
* A route that could never deliver is refused: an exact pattern that the endpoint's owner may not receive, or that the route's own owner may not act on, answers 400 validation_error with details.reason endpoint_owner_access or route_owner_access and details.recipient. A wildcard or regex route to an owned endpoint is written, with warnings saying it delivers only what the owner may receive. A route written disabled is judged when it is turned on.
|
|
1647
1654
|
*/
|
|
1648
1655
|
const createRoute = (options) => (options.client ?? client).post({
|
|
1649
1656
|
security: [{
|
|
@@ -1709,7 +1716,7 @@ const deleteRoute = (options) => (options.client ?? client).delete({
|
|
|
1709
1716
|
/**
|
|
1710
1717
|
* Update a recipient route
|
|
1711
1718
|
*
|
|
1712
|
-
*
|
|
1719
|
+
* A route that could never deliver is refused: an exact pattern that the endpoint's owner may not receive, or that the route's own owner may not act on, answers 400 validation_error with details.reason endpoint_owner_access or route_owner_access and details.recipient. A wildcard or regex route to an owned endpoint is written, with warnings saying it delivers only what the owner may receive. A route written disabled is judged when it is turned on.
|
|
1713
1720
|
*/
|
|
1714
1721
|
const updateRoute = (options) => (options.client ?? client).patch({
|
|
1715
1722
|
security: [{
|
|
@@ -3050,7 +3057,7 @@ const putAgentContactPolicy = (options) => (options.client ?? client).put({
|
|
|
3050
3057
|
/**
|
|
3051
3058
|
* Get current caller identity
|
|
3052
3059
|
*
|
|
3053
|
-
* Current authenticated identity. member_address is null for machine credentials or an unavailable member address.
|
|
3060
|
+
* Current authenticated identity. member_address is null for machine credentials or an unavailable member address. email (your own sign-in email) and role_name (your role as the members list labels it) are set only when you are signed in as yourself, in the dashboard or with your own Primitive CLI or app login, and are null for API keys, Functions, connected agents, agent signup logins and other apps acting for you.
|
|
3054
3061
|
*/
|
|
3055
3062
|
const whoami = (options) => (options?.client ?? client).get({
|
|
3056
3063
|
security: [{
|
|
@@ -3590,6 +3597,19 @@ const getWebhookDeliveryStats = (options) => (options?.client ?? client).get({
|
|
|
3590
3597
|
...options
|
|
3591
3598
|
});
|
|
3592
3599
|
/**
|
|
3600
|
+
* List what you created, or what you were asked
|
|
3601
|
+
*
|
|
3602
|
+
* The objects the caller created, newest first, each with where it stands now, including ones since disabled, deleted or revoked where the object keeps a row: Functions, endpoints, Function triggers, pull subscriptions, recipient routes, filters, wake schedules, repeating sends and scheduled sends. An API key, an app or an agent sees what it created itself; a webhook given to an API key lists under that key. A person (a dashboard session, or their own Primitive CLI or app login) sees what they created through any credential of theirs, each item naming it, and also their API keys, personal agents, email rules and rule requests. Each kind is listed only if the caller could list it through that kind's own route; a kind it could not is named in withheld, with no count. Ids, names and states only: never a webhook URL or mail content. Needs activity:read_self. With relation=asked it lists instead what other members asked of the person, open or answered: the rule requests made to them, under their current membership, each naming the member who asked in created_through. A key, an app or an agent has none, and gets email_rule_request in withheld.
|
|
3603
|
+
*/
|
|
3604
|
+
const listActivityObjects = (options) => (options?.client ?? client).get({
|
|
3605
|
+
security: [{
|
|
3606
|
+
scheme: "bearer",
|
|
3607
|
+
type: "http"
|
|
3608
|
+
}],
|
|
3609
|
+
url: "/activity/objects",
|
|
3610
|
+
...options
|
|
3611
|
+
});
|
|
3612
|
+
/**
|
|
3593
3613
|
* Read the column catalog
|
|
3594
3614
|
*
|
|
3595
3615
|
* What a rule tree you write yourself can say: each column of the current vocabulary with its type, source, meaning, operators and the value each takes, options, and whether it takes min_confidence; and the tree's limits, its stored size included. Built from the checks a saved or tested tree must pass. A tree is {version: tree_version, vocabulary: version, when, questions}. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
@@ -3622,7 +3642,7 @@ const compileEmailRule = (options) => (options.client ?? client).post({
|
|
|
3622
3642
|
/**
|
|
3623
3643
|
* Test a rule against received mail
|
|
3624
3644
|
*
|
|
3625
|
-
* Runs a rule over received mail and reports what it would decide for each email (matched, near_miss, no_match, unclassified or not_found), with a summary: how each top-level condition and question decided and, when nothing matched, what stopped it. Test an unsaved tree from a compile response, or a saved rule by rule_id (its current version, run with its author's access). The rule reads only mail its author can read and its scope covers; an unsaved tree covers only your own mail unless evaluation_scope names more. Without email_ids, the newest emails it can read are tested, at most 200 and none older than 30 days; expected emails (expect, or a saved rule's saved expectations) are tested whatever their age. Unclassified emails more than 2 hours old are classified first and their classification saved, unless classify_missing is false; newer ones are reported unclassified, pending. The rule itself records and grants nothing. Classification and the rule's questions stop at about 90 seconds; a rerun continues the classification where it stopped. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3645
|
+
* Runs a rule over received mail and reports what it would decide for each email (matched, near_miss, no_match, unclassified, skipped or not_found), with a summary: how each top-level condition and question decided and, when nothing matched, what stopped it. Test an unsaved tree from a compile response, or a saved rule by rule_id (its current version, run with its author's access). The rule reads only mail its author can read and its scope covers; an unsaved tree covers only your own mail unless evaluation_scope names more. Without email_ids, the newest emails it can read are tested, at most 200 and none older than 30 days; expected emails (expect, or a saved rule's saved expectations) are tested whatever their age. Unclassified emails more than 2 hours old are classified first and their classification saved, unless classify_missing is false; newer ones are reported unclassified, pending. The rule itself records and grants nothing. Classification and the rule's questions stop at about 90 seconds; a rerun continues the classification where it stopped. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3626
3646
|
*/
|
|
3627
3647
|
const testEmailRule = (options) => (options.client ?? client).post({
|
|
3628
3648
|
security: [{
|
|
@@ -3686,7 +3706,7 @@ const createEmailRule = (options) => (options.client ?? client).post({
|
|
|
3686
3706
|
/**
|
|
3687
3707
|
* Delete a rule
|
|
3688
3708
|
*
|
|
3689
|
-
* Deletes a rule with its versions, its decisions and the access it granted. The author, or a caller who reads the whole organization's mail, may delete it; while it is shared with another member, only the author or someone who manages members from the dashboard. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3709
|
+
* Deletes a rule with its versions, its decisions and the access it granted. A rule that was ever shared with another member keeps the record of its share: the share ends with end_reason rule_deleted, and the member who shared can still list what it handed over, while the rule is no longer shown and reads nothing. The answer lists the shares the delete ended (ended_shares) and the keys, not revoked, that still list the rule, which now read nothing through it: those you may read as key metadata by id, name and prefix (keys), and how many others (other_keys). keys and other_keys are left out when the keys could not be read. The author, or a caller who reads the whole organization's mail, may delete it; while it is shared with another member, only the author or someone who manages members from the dashboard. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3690
3710
|
*/
|
|
3691
3711
|
const deleteEmailRule = (options) => (options.client ?? client).delete({
|
|
3692
3712
|
security: [{
|
|
@@ -3807,7 +3827,7 @@ const listEmailRuleRequests = (options) => (options?.client ?? client).get({
|
|
|
3807
3827
|
/**
|
|
3808
3828
|
* Ask a member for a rule
|
|
3809
3829
|
*
|
|
3810
|
-
* Asks another member of the organization for a rule over their own mail, from a compile response or a tree you wrote. Name them by user id, or by their member mailbox address (at most 30 lookups by address an hour). Nothing is evaluated and nothing is shared until they accept, and they may change the rule first; they see the request and can preview what it matches in their own mail. You may have at most 5 pending requests to one member and 50 in all. If you can list members (members:read), the answer also says whether they can accept it under their role (target_can_accept), and if not, why (target_warning); the request is sent either way. To find out before asking, use POST /v1/email-rule-requests/target-check. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3830
|
+
* Asks another member of the organization for a rule over their own mail, from a compile response or a tree you wrote. Name them by user id, or by their member mailbox address, or by their verified work email if you can list members (at most 30 lookups by address an hour). Nothing is evaluated and nothing is shared until they accept, and they may change the rule first; they see the request and can preview what it matches in their own mail. A message (up to 500 characters) tells them why you are asking; they see it with the request, and it cannot be changed later. You may have at most 5 pending requests to one member and 50 in all. If you can list members (members:read), the answer also says whether they can accept it under their role (target_can_accept), and if not, why (target_warning); the request is sent either way. To find out before asking, use POST /v1/email-rule-requests/target-check. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3811
3831
|
*/
|
|
3812
3832
|
const createEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3813
3833
|
security: [{
|
|
@@ -3824,7 +3844,7 @@ const createEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3824
3844
|
/**
|
|
3825
3845
|
* Check whether a member can accept a rule request
|
|
3826
3846
|
*
|
|
3827
|
-
* Says, before you ask, whether a member could accept a rule request now under their role, and if not, which permission their role lacks. Nothing is sent and nothing is recorded. Needs members:read, as listing members and their roles does. At most 60 checks an hour. Name them by user id, or by their member mailbox address (counted with asking: at most 30 lookups by address an hour). Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3847
|
+
* Says, before you ask, whether a member could accept a rule request now under their role, and if not, which permission their role lacks. Nothing is sent and nothing is recorded. Needs members:read, as listing members and their roles does. At most 60 checks an hour. Name them by user id, or by their member mailbox address or verified work email (counted with asking: at most 30 lookups by address an hour). Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3828
3848
|
*/
|
|
3829
3849
|
const checkEmailRuleRequestTarget = (options) => (options.client ?? client).post({
|
|
3830
3850
|
security: [{
|
|
@@ -3854,7 +3874,7 @@ const deleteEmailRuleRequest = (options) => (options.client ?? client).delete({
|
|
|
3854
3874
|
/**
|
|
3855
3875
|
* Read a rule request
|
|
3856
3876
|
*
|
|
3857
|
-
* A rule request: the rule as proposed, who made it and to whom, and whether each of them is still a member. A request is visible to the member who made it, the member it was made to, and the organization's owners and admins. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3877
|
+
* A rule request: the rule as proposed, who made it and to whom, and whether each of them is still a member. A request is visible to the member who made it, the member it was made to, and the organization's owners and admins. If you are the member asked, you can try the rule as proposed before answering: pass the request's tree to POST /v1/email-rules/test to test it on mail you have received. A test on mail already received shows only what has arrived. To see what the rule would do with an email that has not, such as one you would never want shared, pass the request's tree to POST /v1/email-rules/test-sample (testEmailRuleOnSample; in the Primitive CLI, primitive email-rules test-email-rule-on-sample --body-file sample.json) with an email you make up. Nothing is stored, and it needs no access beyond testing a rule of your own. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3858
3878
|
*/
|
|
3859
3879
|
const getEmailRuleRequest = (options) => (options.client ?? client).get({
|
|
3860
3880
|
security: [{
|
|
@@ -3867,7 +3887,7 @@ const getEmailRuleRequest = (options) => (options.client ?? client).get({
|
|
|
3867
3887
|
/**
|
|
3868
3888
|
* Decline a rule request
|
|
3869
3889
|
*
|
|
3870
|
-
* Declines a pending request made to you. Nothing is written but the decision. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3890
|
+
* Declines a pending request made to you. Nothing is written but the decision and, if you give one, its reason (reason, up to 500 characters), which the member who asked sees with the request. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3871
3891
|
*/
|
|
3872
3892
|
const declineEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3873
3893
|
security: [{
|
|
@@ -3875,7 +3895,11 @@ const declineEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3875
3895
|
type: "http"
|
|
3876
3896
|
}],
|
|
3877
3897
|
url: "/email-rule-requests/{id}/decline",
|
|
3878
|
-
...options
|
|
3898
|
+
...options,
|
|
3899
|
+
headers: {
|
|
3900
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
3901
|
+
...options.headers
|
|
3902
|
+
}
|
|
3879
3903
|
});
|
|
3880
3904
|
/**
|
|
3881
3905
|
* Withdraw a rule request
|
|
@@ -3893,7 +3917,7 @@ const withdrawEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3893
3917
|
/**
|
|
3894
3918
|
* Accept a rule request
|
|
3895
3919
|
*
|
|
3896
|
-
* Writes the rule as yours, over your own mailboxes only, turns it on, and shares what it matches from now on with the member who asked. Send no body to accept it as asked, or change it first with english and tree together (and an explanation, or the server writes one). Because this gives your mail to someone else, it is limited to the dashboard and the Primitive CLI: other OAuth apps and agent tokens are refused.
|
|
3920
|
+
* Writes the rule as yours, over your own mailboxes only, turns it on, and shares what it matches from now on with the member who asked. Send no body to accept it as asked, or change it first with english and tree together (and an explanation, or the server writes one). Because this gives your mail to someone else, it is limited to the dashboard and the Primitive CLI: other OAuth apps and agent tokens are refused. Before accepting, test it on your mail: pass the request's tree to POST /v1/email-rules/test. A test on mail already received shows only what has arrived. To see what the rule would do with an email that has not, such as one you would never want shared, pass the request's tree to POST /v1/email-rules/test-sample (testEmailRuleOnSample; in the Primitive CLI, primitive email-rules test-email-rule-on-sample --body-file sample.json) with an email you make up. Nothing is stored, and it needs no access beyond testing a rule of your own. Accepting also needs mail:share_own (sharing your own mail through email rules, which only shows it and never sends): a role without it is refused, whether or not it can send. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3897
3921
|
*/
|
|
3898
3922
|
const acceptEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3899
3923
|
security: [{
|
|
@@ -3962,7 +3986,7 @@ const getEmailRuleShare = (options) => (options.client ?? client).get({
|
|
|
3962
3986
|
/**
|
|
3963
3987
|
* List the emails a rule share has given
|
|
3964
3988
|
*
|
|
3965
|
-
* The emails a rule share has given, newest first, as the email list shows them, each with shared_at
|
|
3989
|
+
* The emails a rule share has given, newest first, as the email list shows them, each with shared_at. For the person it was shared with: what they can read through it now, so an ended share lists nothing, and shared_at is when the share's rule first matched the email. For the person sharing their mail: everything it has handed over while it ran, including after it ended and whatever the rule's state now, so they can see what left their mailbox, and shared_at is when it was handed over. Only those two people can list them, from the dashboard or the Primitive CLI. A page can be short or empty and still carry a cursor: keep reading until meta.cursor is null.
|
|
3966
3990
|
*/
|
|
3967
3991
|
const listEmailRuleShareEmails = (options) => (options.client ?? client).get({
|
|
3968
3992
|
security: [{
|
|
@@ -4187,6 +4211,19 @@ const getOwnGrant = (options) => (options?.client ?? client).get({
|
|
|
4187
4211
|
...options
|
|
4188
4212
|
});
|
|
4189
4213
|
/**
|
|
4214
|
+
* List the addresses this credential can send from
|
|
4215
|
+
*
|
|
4216
|
+
* The From addresses the calling credential may send from with POST /send-mail, and the one a send that names no From should use. Every address listed is one that send would accept as From for this credential, recipients aside. A connected agent's default is its own address. A person's default is their own member address, for a session and for every OAuth login of theirs, an agent's included. Any other credential has a default only when exactly one address and no domain is listed, and never a person's own member address. When there is no default, `reason` says why. `domains` lists the domains at which the credential may send from any address that is not reserved to someone else or left out of its grant; each is one GET /outbound/status lists as sendable for it. A credential that cannot send new mail, or one in an account where outbound mail is not enabled, gets no addresses and no domains. Every credential may ask about itself, a connected agent's key included, except a Function-bound key limited to its Function's own operations (403 function_scope_forbidden). It answers nothing about any other credential.
|
|
4217
|
+
*/
|
|
4218
|
+
const getSendFrom = (options) => (options?.client ?? client).get({
|
|
4219
|
+
security: [{
|
|
4220
|
+
scheme: "bearer",
|
|
4221
|
+
type: "http"
|
|
4222
|
+
}],
|
|
4223
|
+
url: "/whoami/send-from",
|
|
4224
|
+
...options
|
|
4225
|
+
});
|
|
4226
|
+
/**
|
|
4190
4227
|
* List consumer Inbox routing rules
|
|
4191
4228
|
*
|
|
4192
4229
|
* Mailbox-scoped exact visible audiences, excluding the owner and Bcc. Direct and group audiences are independent. Restores persist an explicit Conversations rule. New writes require the observed version (zero creates); only an identical latest mutation with its original expected version can be retried. Stale writes return mail_routing_conflict. Source messages and read state are unchanged. Merge paged rules by version; responses are never cached.
|
|
@@ -4577,7 +4614,7 @@ const revokeOrganizationInvitation = (options) => (options.client ?? client).del
|
|
|
4577
4614
|
...options
|
|
4578
4615
|
});
|
|
4579
4616
|
/**
|
|
4580
|
-
* Requires a current human organization membership, or an org-wide API key: a super admin key, or a custom key with no addresses or domains whose grant holds members:read. A key lists members as the person it belongs to, at that person's live grant, and only while that person still holds members:read. Narrowed, Function and connected keys are refused. No local paths or existing conversation history are shared.
|
|
4617
|
+
* Requires a current human organization membership, or an org-wide API key: a super admin key, or a custom key with no addresses or domains whose grant holds members:read. A key lists members as the person it belongs to, at that person's live grant, and only while that person still holds members:read. Narrowed, Function and connected keys are refused. A caller holding members:read also gets each person's mail_access. No local paths or existing conversation history are shared.
|
|
4581
4618
|
*/
|
|
4582
4619
|
const listOrganizationPeople = (options) => (options?.client ?? client).get({
|
|
4583
4620
|
security: [{
|
|
@@ -4690,7 +4727,7 @@ const revokeProjectInvitation = (options) => (options.client ?? client).delete({
|
|
|
4690
4727
|
/**
|
|
4691
4728
|
* List mailbox access
|
|
4692
4729
|
*
|
|
4693
|
-
* Every access entry in the organization: who (a member, group, agent or address) may read, draft or send for each mailbox or domain. An entry that reads a mailbox reads the full email; raw MIME follows the person's mail.raw:read. `depth` is deprecated: it is accepted and ignored, and new entries record content. Needs members:read: a person, or an org-wide API key whose person holds it.
|
|
4730
|
+
* Every access entry in the organization: who (a member, group, agent or address) may read, draft or send for each mailbox or domain. An entry that reads a mailbox reads the full email; raw MIME follows the person's mail.raw:read. `depth` is deprecated: it is accepted and ignored, and new entries record content. With no entries, `note` says where each member's mail access comes from instead. Needs members:read: a person, or an org-wide API key whose person holds it.
|
|
4694
4731
|
*/
|
|
4695
4732
|
const listMailboxAccess = (options) => (options?.client ?? client).get({
|
|
4696
4733
|
security: [{
|
|
@@ -4780,7 +4817,7 @@ const updateGroup = (options) => (options.client ?? client).patch({
|
|
|
4780
4817
|
/**
|
|
4781
4818
|
* List every credential
|
|
4782
4819
|
*
|
|
4783
|
-
* Every credential that can act in the organization: API keys, Function keys, agent connection keys, connected apps (OAuth), agent delegates and, where enabled, CLI logins. Secrets are never returned. A key's grant.mail_scope.depth is raw only when it holds mail.raw:read and its scope lists an address or a domain, otherwise content. Filter with kind. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4820
|
+
* Every credential that can act in the organization: API keys, Function keys, agent connection keys, connected apps (OAuth), agent delegates and, where enabled, CLI logins. Secrets are never returned. A key's grant.mail_scope.depth is raw only when it holds mail.raw:read and its scope lists an address or a domain, otherwise content. A rule the key lists that reads nothing any more (a deleted rule, or a share that ended) is listed under grant.mail_scope.ended_rules, each with its id and reason (rule_deleted or share_ended), and not under rules. Filter with kind. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4784
4821
|
*
|
|
4785
4822
|
* Person only: a dashboard session. The person's role must hold credentials:read. API keys, agent connection keys and agents are refused.
|
|
4786
4823
|
*/
|
|
@@ -4795,7 +4832,7 @@ const listCredentials = (options) => (options?.client ?? client).get({
|
|
|
4795
4832
|
/**
|
|
4796
4833
|
* Revoke a credential
|
|
4797
4834
|
*
|
|
4798
|
-
* Revoke one credential by kind and id. A Function key is rotated, never revoked (409 rotate_instead). An API key is revoked only by a person whose own access covers the key's access (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. What the credential set up
|
|
4835
|
+
* Revoke one credential by kind and id. A Function key is rotated, never revoked (409 rotate_instead). An API key is revoked only by a person whose own access covers the key's access (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. What the credential set up or owns is listed in standing_objects for review, and for an API key also what it carries on for the keys it was rotated from. An organization-owned object (org_owned true) keeps working; any other keeps working only while someone can still act for it, such as a key of the same rotation that still works, or whoever it was given to, except that a block filter an app made keeps blocking, within the reach the app had, unless the person revoking chose to stop it. An API key (kind org_key or connected_key) that is already revoked, and whose record is kept, answers 200 with already_revoked true and revoked 0, to a caller who could have revoked it; anyone else gets the answer they would get for a key that does not exist. The person's own Primitive CLI login revokes an API key (kind org_key) as the person, with no step-up unless the organization's credential policy sets cli_writes_require_approval (then it takes a keys.create step-up); every other kind (a connected key named as org_key included, 403 grant_forbidden target_not_covered), and every other app even with a step-up, is refused outside the dashboard (403). Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4799
4836
|
*
|
|
4800
4837
|
* Person only: a dashboard session or the person's own Primitive CLI token; no other OAuth app. The person's role must hold keys:manage. API keys, agent connection keys and agents are refused.
|
|
4801
4838
|
*/
|
|
@@ -4897,7 +4934,7 @@ const getKeyBuilder = (options) => (options?.client ?? client).get({
|
|
|
4897
4934
|
/**
|
|
4898
4935
|
* List API keys
|
|
4899
4936
|
*
|
|
4900
|
-
* Key metadata, never a secret: name, prefix, grant, creator, last use, expiry, suspension and whether each key works now (status). A grant's mail_scope.depth is raw only when the key holds mail.raw:read and its scope lists an address or a domain, otherwise content. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4937
|
+
* Key metadata, never a secret: name, prefix, grant, creator, last use, expiry, suspension and whether each key works now (status). Revoked keys are left out unless include_revoked is true, which lists them too with status revoked, revoked_at and revoked_by, under the same access rules as keys that work. A grant's mail_scope.depth is raw only when the key holds mail.raw:read and its scope lists an address or a domain, otherwise content. A rule the key lists that reads nothing any more (a deleted rule, or a share that ended) is listed under grant.mail_scope.ended_rules, each with its id and reason (rule_deleted or share_ended), and not under rules. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4901
4938
|
*
|
|
4902
4939
|
* Person only: a dashboard session or the person's own Primitive CLI token; no other OAuth app. The person's role must hold keys:read. API keys, agent connection keys and agents are refused.
|
|
4903
4940
|
*/
|
|
@@ -4931,7 +4968,7 @@ const createKey = (options) => (options.client ?? client).post({
|
|
|
4931
4968
|
/**
|
|
4932
4969
|
* Rotate an API key
|
|
4933
4970
|
*
|
|
4934
|
-
* Mint a successor with a new id and the same name, grant, expiry and conditions, and return its secret once. The old key keeps working for overlap_seconds, then stops: 24 hours when overlap_seconds is omitted, at most 7 days, never past its own expires_at, and at once with 0 (which is how to rotate a key whose secret leaked). previous_key_expires_at says when the old key stops. The person rotating must cover the key's access (403 grant_forbidden, details.reason target_not_covered), and a key an owner holds is rotated by an owner only (403 forbidden, details.reason owner_key_rotation), since rotating hands over the new secret. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4971
|
+
* Mint a successor with a new id and the same name, grant, expiry and conditions, and return its secret once. The old key keeps working for overlap_seconds, then stops: 24 hours when overlap_seconds is omitted, at most 7 days, never past its own expires_at, and at once with 0 (which is how to rotate a key whose secret leaked). previous_key_expires_at says when the old key stops. Rotating does not extend a key: the successor keeps the old expiry unless expires_at gives it a new one. That needs keys:manage (403 forbidden otherwise), is held to the credential policy (400 when past its maximum lifetime, with the latest expiry it allows now in the message), and someone limited to their own keys can only keep or bring it forward (403 grant_forbidden, details.reason own_key_tighten_only); the old key then never outlives the new one. The person rotating must cover the key's access (403 grant_forbidden, details.reason target_not_covered), and a key an owner holds is rotated by an owner only (403 forbidden, details.reason owner_key_rotation), since rotating hands over the new secret. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4935
4972
|
*
|
|
4936
4973
|
* Person only: a dashboard session, the person's own Primitive CLI login with no step-up (unless the organization's credential policy sets cli_writes_require_approval), or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one any other OAuth token is answered 403 step_up_required, whose details carry the dashboard URL that issues it (or 403 grant_forbidden when the person's role, or the client, could not do it anyway). The person's role must hold keys:manage. API keys and agent connection keys are refused. An agent acting for the person is refused unless it carries a step-up token the person issued in the dashboard.
|
|
4937
4974
|
*/
|
|
@@ -4950,7 +4987,7 @@ const rotateKey = (options) => (options.client ?? client).post({
|
|
|
4950
4987
|
/**
|
|
4951
4988
|
* Get an API key
|
|
4952
4989
|
*
|
|
4953
|
-
* One key's metadata, never its secret, with whether it works now (status). Its grant's mail_scope.depth is raw only when the key holds mail.raw:read and its scope lists an address or a domain, otherwise content. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4990
|
+
* One key's metadata, never its secret, with whether it works now (status). A revoked key whose record is kept is answered too, with status revoked, revoked_at and revoked_by, under the same access rules as a key that works: one the caller may not read is 404, revoked or not. Its grant's mail_scope.depth is raw only when the key holds mail.raw:read and its scope lists an address or a domain, otherwise content. A rule the key lists that reads nothing any more (a deleted rule, or a share that ended) is listed under grant.mail_scope.ended_rules, each with its id and reason (rule_deleted or share_ended), and not under rules. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4954
4991
|
*
|
|
4955
4992
|
* Person only: a dashboard session or the person's own Primitive CLI token; no other OAuth app. The person's role must hold keys:read. API keys, agent connection keys and agents are refused.
|
|
4956
4993
|
*/
|
|
@@ -4965,7 +5002,7 @@ const getKey = (options) => (options.client ?? client).get({
|
|
|
4965
5002
|
/**
|
|
4966
5003
|
* Change an API key
|
|
4967
5004
|
*
|
|
4968
|
-
* Rename a key, change its expiry, its grant or its conditions, or suspend it. Any change needs the person's own access to cover the key's access now (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. A grant change is a new version of the key and is held to the same rules as creating one (a custom grant that does not say which mail it reaches is refused with details.reason mail_scope_required), so it takes the same step-up. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
5005
|
+
* Rename a key, change its expiry, its grant or its conditions, or suspend it. A later expires_at extends the key, which is how to keep a key working past its expiry (rotating keeps it, unless the rotation gives the new key an expires_at): it is held to the credential policy (400 when past its maximum lifetime, with the latest expiry it allows now in the message), and like any loosening needs the person to be allowed to create a key with the key's access. An expired key's expiry cannot be changed (409 conflict, details.reason key_expired); make a new key instead. Any change needs the person's own access to cover the key's access now (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. A grant change is a new version of the key and is held to the same rules as creating one (a custom grant that does not say which mail it reaches is refused with details.reason mail_scope_required), so it takes the same step-up. It replaces the whole grant: send expected_grant_ref (grant.ref from GET /v1/keys/{id}) to have it refused (409 conflict, details.reason grant_changed) if the grant changed since that read; a grant change sent without it answers grant_unguarded: true. On a key limited to selected resources (grant.resources), a grant change must drop the limits on purpose with a custom grant and grant.resources {}; one that leaves them out is refused (409 conflict, details.reason key_has_resource_limits) and nothing changes. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4969
5006
|
*
|
|
4970
5007
|
* Person only: a dashboard session, the person's own Primitive CLI login with no step-up (unless the organization's credential policy sets cli_writes_require_approval), or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one any other OAuth token is answered 403 step_up_required, whose details carry the dashboard URL that issues it (or 403 grant_forbidden when the person's role, or the client, could not do it anyway). The person's role must hold keys:manage. API keys and agent connection keys are refused. An agent acting for the person is refused unless it carries a step-up token the person issued in the dashboard.
|
|
4971
5008
|
*/
|
|
@@ -5165,7 +5202,7 @@ const updateSearchSettings = (options) => (options.client ?? client).put({
|
|
|
5165
5202
|
/**
|
|
5166
5203
|
* List roles
|
|
5167
5204
|
*
|
|
5168
|
-
* Every role in the organization (built-in, template copies and custom roles), with how many members and groups hold each, the templates not yet copied, and whether roles can be assigned now. Any person (a session or OAuth token); API keys are refused.
|
|
5205
|
+
* Every role in the organization (built-in, template copies and custom roles), with how many members and groups hold each, the templates not yet copied, and whether roles can be assigned now. `unassigned` describes role restricted on a member with no role_id, which is not a role and is never in `roles`. Any person (a session or OAuth token); API keys are refused.
|
|
5169
5206
|
*/
|
|
5170
5207
|
const listRoles = (options) => (options?.client ?? client).get({
|
|
5171
5208
|
security: [{
|
|
@@ -7015,7 +7052,7 @@ function parseFromHeader(header) {
|
|
|
7015
7052
|
value: { address: address.toLowerCase() }
|
|
7016
7053
|
};
|
|
7017
7054
|
}
|
|
7018
|
-
// ../sdk-node/dist/understanding-
|
|
7055
|
+
// ../sdk-node/dist/understanding-CpocTa4f.js
|
|
7019
7056
|
/**
|
|
7020
7057
|
* AUTO-GENERATED - DO NOT EDIT
|
|
7021
7058
|
* Run `pnpm generate:validator` to regenerate.
|
|
@@ -23852,13 +23889,27 @@ const INTERACTION_EVENT_TYPES = [
|
|
|
23852
23889
|
"interaction.ack.requested"
|
|
23853
23890
|
];
|
|
23854
23891
|
/**
|
|
23892
|
+
* The rule request events (subject = a request one member made to another for
|
|
23893
|
+
* an email rule over the other's own mail). Each goes to the person who did
|
|
23894
|
+
* not act: `created` and `withdrawn` to the member asked, `accepted` and
|
|
23895
|
+
* `declined` to the member who asked. They are opt-in, and only a webhook that
|
|
23896
|
+
* person made for them receives them.
|
|
23897
|
+
*/
|
|
23898
|
+
const EMAIL_RULE_REQUEST_EVENT_TYPES = [
|
|
23899
|
+
"email_rule_request.created",
|
|
23900
|
+
"email_rule_request.accepted",
|
|
23901
|
+
"email_rule_request.declined",
|
|
23902
|
+
"email_rule_request.withdrawn"
|
|
23903
|
+
];
|
|
23904
|
+
/**
|
|
23855
23905
|
* The full enumerated catalog of every current webhook event type: the five
|
|
23856
|
-
* email.*, the four opt-in sent_email.*,
|
|
23857
|
-
* interaction.<protocol>.<suffix>.
|
|
23906
|
+
* email.*, the four opt-in sent_email.*, the four opt-in
|
|
23907
|
+
* email_rule_request.*, and every interaction.<protocol>.<suffix>.
|
|
23858
23908
|
*/
|
|
23859
23909
|
const WEBHOOK_EVENT_TYPES = [
|
|
23860
23910
|
...EMAIL_EVENT_TYPES,
|
|
23861
23911
|
...SENT_EMAIL_EVENT_TYPES,
|
|
23912
|
+
...EMAIL_RULE_REQUEST_EVENT_TYPES,
|
|
23862
23913
|
...INTERACTION_EVENT_TYPES
|
|
23863
23914
|
];
|
|
23864
23915
|
const WEBHOOK_EVENT_TYPE_SET = new Set(WEBHOOK_EVENT_TYPES);
|
|
@@ -24397,7 +24448,6 @@ function ensureSearchReportsReplyState(apiClient) {
|
|
|
24397
24448
|
}
|
|
24398
24449
|
return probe;
|
|
24399
24450
|
}
|
|
24400
|
-
// src/oclif/commands/emails-poll.ts
|
|
24401
24451
|
function quoteDslValue(value) {
|
|
24402
24452
|
if (/^[^\s"]+$/.test(value)) return value;
|
|
24403
24453
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
@@ -24454,7 +24504,7 @@ function buildEmailSearchQuery(params) {
|
|
|
24454
24504
|
include_facets: "false",
|
|
24455
24505
|
limit: params.pageSize,
|
|
24456
24506
|
snippet: "false",
|
|
24457
|
-
sort: "received_at_asc"
|
|
24507
|
+
sort: params.order ?? "received_at_asc"
|
|
24458
24508
|
};
|
|
24459
24509
|
const q = combineQ(params.filters.q, params.filters.domain);
|
|
24460
24510
|
if (q) query.q = q;
|
|
@@ -24471,6 +24521,7 @@ function buildEmailSearchQuery(params) {
|
|
|
24471
24521
|
if (params.filters.to) query.to = params.filters.to;
|
|
24472
24522
|
if (params.since) query.date_from = params.since;
|
|
24473
24523
|
if (params.cursor) query.cursor = params.cursor;
|
|
24524
|
+
if (params.count === false) query.count = "false";
|
|
24474
24525
|
return query;
|
|
24475
24526
|
}
|
|
24476
24527
|
function encodeReceivedAtSearchCursor(email) {
|
|
@@ -24498,12 +24549,126 @@ function collectNewAcceptedEmails(rows, seenIds) {
|
|
|
24498
24549
|
}
|
|
24499
24550
|
return fresh;
|
|
24500
24551
|
}
|
|
24552
|
+
/**
|
|
24553
|
+
* How long after arriving an email may become readable and still be reported
|
|
24554
|
+
* by an idle poll's re-read; how often a re-read comes; and the most pages, of
|
|
24555
|
+
* MAX_EMAIL_POLL_PAGE_SIZE each, one re-read reads.
|
|
24556
|
+
*/
|
|
24557
|
+
const LATE_MAIL_WINDOW_MS = 6e5;
|
|
24558
|
+
const LATE_MAIL_REREAD_MS = 15e3;
|
|
24559
|
+
/** How far a re-read reads back at most, however long re-reads have been cut short, unless its interval needs more. */
|
|
24560
|
+
const LATE_MAIL_MAX_LOOKBACK_MS = 36e5;
|
|
24561
|
+
/** Read back this much further, as this clock may run ahead of the server's. */
|
|
24562
|
+
const LATE_MAIL_CLOCK_SLACK_MS = 6e4;
|
|
24563
|
+
/**
|
|
24564
|
+
* Mail received from `from` (LATE_MAIL_WINDOW_MS ago when not given, and
|
|
24565
|
+
* never before `since`), oldest first. Pages come in order of when an email
|
|
24566
|
+
* was received, but an email can become readable to this credential after one
|
|
24567
|
+
* received later: it was accepted more slowly, held while its sender was
|
|
24568
|
+
* checked, or granted to a key by an email rule once classified. By then the
|
|
24569
|
+
* cursor is past its place, so an idle poll re-reads recent mail and keeps
|
|
24570
|
+
* only rows it has not seen. It reads newest first, where late mail mostly
|
|
24571
|
+
* is, so a busy stretch that holds more than the pages read loses its oldest
|
|
24572
|
+
* part rather than its newest. Best effort: a page that fails ends the
|
|
24573
|
+
* re-read with what it has, and the poll goes on; so does reaching
|
|
24574
|
+
* `deadline`. `cutShort` says it did not reach as far back as it would have:
|
|
24575
|
+
* a page failed, the deadline came, or a search the server stopped early for
|
|
24576
|
+
* time returned short pages up to the page limit. `failed` is the page that
|
|
24577
|
+
* failed, so the caller can wait as long as the server asked (Retry-After).
|
|
24578
|
+
*/
|
|
24579
|
+
async function fetchRecentEmails(params) {
|
|
24580
|
+
const fetchPage = params.fetchPage ?? fetchEmailSearchPage;
|
|
24581
|
+
const now = params.now ?? Date.now();
|
|
24582
|
+
const sinceMs = params.since ? Date.parse(params.since) : NaN;
|
|
24583
|
+
const wanted = params.from ?? now - 6e5;
|
|
24584
|
+
const from = Number.isNaN(sinceMs) ? wanted : Math.max(wanted, sinceMs);
|
|
24585
|
+
const newestFirst = [];
|
|
24586
|
+
const result = (cutShort) => ({
|
|
24587
|
+
rows: newestFirst.reverse(),
|
|
24588
|
+
cutShort
|
|
24589
|
+
});
|
|
24590
|
+
let cursor = null;
|
|
24591
|
+
for (let pages = 0; pages < 3; pages += 1) {
|
|
24592
|
+
if (params.deadline !== void 0 && params.deadline !== null && Date.now() >= params.deadline) return result(true);
|
|
24593
|
+
let page;
|
|
24594
|
+
try {
|
|
24595
|
+
page = await fetchPage({
|
|
24596
|
+
apiClient: params.apiClient,
|
|
24597
|
+
count: false,
|
|
24598
|
+
cursor,
|
|
24599
|
+
filters: params.filters,
|
|
24600
|
+
order: "received_at_desc",
|
|
24601
|
+
pageSize: 100,
|
|
24602
|
+
since: new Date(from).toISOString()
|
|
24603
|
+
});
|
|
24604
|
+
} catch {
|
|
24605
|
+
return result(true);
|
|
24606
|
+
}
|
|
24607
|
+
if (!page.ok) return {
|
|
24608
|
+
...result(true),
|
|
24609
|
+
failed: page
|
|
24610
|
+
};
|
|
24611
|
+
newestFirst.push(...page.rows);
|
|
24612
|
+
if (!page.more || !page.cursor) return result(false);
|
|
24613
|
+
cursor = page.cursor;
|
|
24614
|
+
}
|
|
24615
|
+
return result(newestFirst.length < 300);
|
|
24616
|
+
}
|
|
24617
|
+
/**
|
|
24618
|
+
* An idle poll's re-reads of recent mail (fetchRecentEmails), made once the
|
|
24619
|
+
* poll's cursor has passed some mail, with `start` when the poll that first
|
|
24620
|
+
* moved it was made.
|
|
24621
|
+
*
|
|
24622
|
+
* One is due an interval after `start`, as until then the poll has read the
|
|
24623
|
+
* same mail itself, and then an interval after the last one ended, so a slow
|
|
24624
|
+
* re-read is not followed straight away by another. The interval is
|
|
24625
|
+
* LATE_MAIL_REREAD_MS, or LATE_MAIL_REREAD_POLLS poll intervals when that is
|
|
24626
|
+
* longer. A re-read is made only on a poll that brought nothing new once it
|
|
24627
|
+
* is due, so a wait that ends before the next one is made does not report
|
|
24628
|
+
* mail that became readable since the last. `deadline` stops a re-read's
|
|
24629
|
+
* paging (fetchRecentEmails).
|
|
24630
|
+
*
|
|
24631
|
+
* Each re-read reads from LATE_MAIL_WINDOW_MS (and LATE_MAIL_CLOCK_SLACK_MS)
|
|
24632
|
+
* before the last one that was not cut short began (before `start`, at
|
|
24633
|
+
* first), so an email that becomes readable within LATE_MAIL_WINDOW_MS of
|
|
24634
|
+
* arriving is read however far apart re-reads come. That holds while it is
|
|
24635
|
+
* among the most one re-read reads, and while a re-read that is not cut short
|
|
24636
|
+
* comes within the look-back limit (LATE_MAIL_MAX_LOOKBACK_MS, or more for a
|
|
24637
|
+
* long interval) less LATE_MAIL_WINDOW_MS of it becoming readable.
|
|
24638
|
+
*/
|
|
24639
|
+
function lateMailReread(options) {
|
|
24640
|
+
const { pollIntervalMs, deadline, start } = options;
|
|
24641
|
+
const intervalMs = Math.max(LATE_MAIL_REREAD_MS, 3 * pollIntervalMs);
|
|
24642
|
+
const maxLookBackMs = Math.max(LATE_MAIL_MAX_LOOKBACK_MS, LATE_MAIL_WINDOW_MS + 2 * intervalMs);
|
|
24643
|
+
let covered = start;
|
|
24644
|
+
let ended = start;
|
|
24645
|
+
return {
|
|
24646
|
+
due: (now = Date.now()) => now - ended >= intervalMs,
|
|
24647
|
+
read: async (params) => {
|
|
24648
|
+
const begun = Date.now();
|
|
24649
|
+
const { rows, cutShort, failed } = await fetchRecentEmails({
|
|
24650
|
+
...params,
|
|
24651
|
+
deadline,
|
|
24652
|
+
from: Math.max(covered - LATE_MAIL_WINDOW_MS, begun - maxLookBackMs) - LATE_MAIL_CLOCK_SLACK_MS,
|
|
24653
|
+
now: begun
|
|
24654
|
+
});
|
|
24655
|
+
if (!cutShort) covered = begun;
|
|
24656
|
+
ended = Date.now();
|
|
24657
|
+
return {
|
|
24658
|
+
rows,
|
|
24659
|
+
failed
|
|
24660
|
+
};
|
|
24661
|
+
}
|
|
24662
|
+
};
|
|
24663
|
+
}
|
|
24501
24664
|
async function fetchEmailSearchPage(params) {
|
|
24502
24665
|
const result = await searchEmails({
|
|
24503
24666
|
client: params.apiClient.client,
|
|
24504
24667
|
query: buildEmailSearchQuery({
|
|
24668
|
+
count: params.count,
|
|
24505
24669
|
cursor: params.cursor,
|
|
24506
24670
|
filters: params.filters,
|
|
24671
|
+
order: params.order,
|
|
24507
24672
|
pageSize: params.pageSize,
|
|
24508
24673
|
since: params.since
|
|
24509
24674
|
}),
|
|
@@ -24533,6 +24698,7 @@ async function fetchEmailSearchPage(params) {
|
|
|
24533
24698
|
return {
|
|
24534
24699
|
ok: true,
|
|
24535
24700
|
cursor: envelope?.meta.cursor ?? cursorFromRows(rows),
|
|
24701
|
+
more: Boolean(envelope?.meta.cursor),
|
|
24536
24702
|
rows
|
|
24537
24703
|
};
|
|
24538
24704
|
}
|
|
@@ -24627,6 +24793,16 @@ async function pauseForTransientFailure(failure, attempt, options) {
|
|
|
24627
24793
|
return deadline === null || Date.now() < deadline;
|
|
24628
24794
|
}
|
|
24629
24795
|
/**
|
|
24796
|
+
* After a failed read the caller does not retry, wait as long as the server
|
|
24797
|
+
* asked (Retry-After), if it did, before the caller's next request. False when
|
|
24798
|
+
* the deadline came first.
|
|
24799
|
+
*/
|
|
24800
|
+
async function waitOutRetryAfter(result, options) {
|
|
24801
|
+
const failure = transientFailure(result);
|
|
24802
|
+
if (failure?.retryAfterMs === void 0) return true;
|
|
24803
|
+
return pauseForTransientFailure(failure, 0, options);
|
|
24804
|
+
}
|
|
24805
|
+
/**
|
|
24630
24806
|
* Run an idempotent read, retrying transient failures until the deadline.
|
|
24631
24807
|
* Resolves the first result that is not transient, or null when the
|
|
24632
24808
|
* deadline passes first (or the read itself resolved null).
|
|
@@ -25469,4 +25645,4 @@ function repeatStopCommand(emailId) {
|
|
|
25469
25645
|
if (!UUID.test(emailId)) throw new TypeError("emailId must be an email UUID");
|
|
25470
25646
|
return `primitive repeat stop --id ${emailId.toLowerCase()}`;
|
|
25471
25647
|
}
|
|
25472
|
-
export {
|
|
25648
|
+
export { parseFromHeader as $, startAgentClaim as $n, getSendFrom as $t, lateMailReread as A, listWakeSchedules as An, downloadEmailAttachmentArchiveMember as At, ensureSearchReportsReplyState as B, resendAgentSignupVerification as Bn, getCreditBalance as Bt, waitOutRetryAfter as C, listRepeatingSends as Cn, createWakeSchedule as Ct, encodeReceivedAtSearchCursor as D, listSentEmails as Dn, deleteRoute as Dt, cursorFromAcceptedRows as E, listSentAttachmentArchiveMembers as En, deleteMemory as Et, AWAITING_VALUES as F, putContact as Fn, getAccessMode as Ft, queryUsesAwaiting as G, searchEmails as Gn, getFunctionTestRunTrace as Gt, formatRepliesCell as H, rotateKey as Hn, getEmail as Ht, REPLY_STATE_UNSUPPORTED_CODE as I, redeemCreditCode as In, getAccount as It, SENT_EMAIL_EVENT_TYPES as J, sendEmail as Jn, getMemory as Jt, replyStateSurfaceForOperation as K, searchMemories as Kn, getInboxStatus as Kt, ReplyStateUnsupportedError as L, removeDefaultNetworkMember as Ln, getAgentContactPolicy as Lt, sinceFromFlags as M, pullWebhookEvent as Mn, downloadEmailAttachmentPart as Mt, sleep as N, putAgentContact as Nn, downloadSentAttachmentArchiveMember as Nt, fetchEmailSearchPage as O, listWakeAuthorizations as On, deleteWakeAuthorization as Ot, AWAITING_FLAG_DESCRIPTION as P, putAgentContactPolicy as Pn, downloadSentAttachmentByFilename as Pt, parseWebhookEvent as Q, simulateRoute as Qn, getRepeatingSend as Qt, assertAwaitingFilterRows as R, reorderRoutes as Rn, getContact as Rt, transientFailure as S, listOrganizationPeople as Sn, createWakeAuthorization as St, collectNewAcceptedEmails as T, listRoutes as Tn, deleteContact as Tt, hasReplyState as U, runWakeSchedule as Un, getFunction as Ut, formatAwaitingCell as V, revokeCredential as Vn, getDefaultNetworkAgent as Vt, isAwaitingRejectedError as W, sdk_gen_exports as Wn, getFunctionRouting as Wt, isEmailReceivedEvent as X, setFunctionSecret as Xn, getOutboundStatus as Xt, WEBHOOK_EVENT_TYPES as Y, setFunctionRoute as Yn, getOrgRoutingTopology as Yt, isTrustedSender as Z, setMemory as Zn, getOwnGrant as Zt, describeApiFailure as _, listFunctionLogs as _n, completeWebhookEvent as _t, REPEAT_IDLE_MAX_MINUTES as a, listActivityObjects as an, updateDefaultNetworkMember as ar, automatedRejectedError as at, retryTransient as b, listKeys as bn, createKey as bt, classifySignalContent as c, listAgentNetworks as cn, updateRepeatingSend as cr, expectedAutomatedVerdicts as ct, parseRepeatTick as d, listDefaultNetworkMembers as dn, updateWakeSchedule as dr, addDefaultNetworkMember as dt, getSentEmail as en, startAgentSignup as er, AUTOMATED_FILTER_UNSUPPORTED_CODE as et, preparePresenceAliveEmail as f, listDomains as fn, verifyAgentClaim as fr, cancelSentEmail as ft, WaitDeadlineReached as g, listEndpoints as gn, cliLogout as gt, sendPreparedSignal as h, listEmails as hn, __exportAll as hr, checkSendability as ht, REPEAT_EVERY_MAX_MINUTES as i, leaveOrganization as in, unsetFunctionRoute as ir, assertAutomatedVerdict as it, quoteDslValue as j, pollCliLogin as jn, downloadEmailAttachmentByFilename as jt, filtersFromFlags as k, listWakeDispatches as kn, deleteWakeSchedule as kt, parseInteractionEnvelope as l, listContacts as ln, updateRoute as lr, hasAutomatedVerdict as lt, repeatStopCommand as m, listEmailRuleResults as mn, whoami as mr, checkDefaultNetworkContactAdmission as mt, MAX_PRESENCE_ENVELOPE_BYTES as n, getWakeSchedule as nn, stopRepeatFromEmail as nr, AUTOMATED_VALUES as nt, REPEAT_MAX_SENDS_MAX as o, listAgentConnections as on, updateFunction as or, automatedSurfaceForOperation as ot, prepareSignalEmail as p, listEmailAttachmentArchiveMembers as pn, verifyAgentSignup as pr, cancelSentEmailByIdempotencyKey as pt, EMAIL_RULE_REQUEST_EVENT_TYPES as q, semanticSearch as qn, getKey as qt, PRESENCE_PROBE_TEXT as r, inviteAgentConnection as rn, testFunction as rr, AutomatedFilterUnsupportedError as rt, buildRepeatStopBody as s, listAgentContacts as sn, updateKey as sr, ensureSearchReportsAutomated as st, MAX_INTERACTION_BYTES as t, getThread as tn, startCliLogin as tr, AUTOMATED_FLAG_DESCRIPTION as tt, parsePresenceEnvelope as u, listDefaultNetworkAgents as un, updateWakeAuthorization as ur, isAutomatedRejectedError as ut, parseRetryAfter as v, listFunctions as vn, createEndpoint as vt, SINCE_VALUE_HELP as w, listRoles as wn, deleteAgentContact as wt, retryingOperation as x, listMailboxAccess as xn, createRoute as xt, pauseForTransientFailure as y, listGroups as yn, createFunction as yt, awaitingRejectedError as z, replyToEmail as zn, getConversation as zt };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Z as isTrustedSender, b as retryTransient, c as classifySignalContent } from "./repeats-Dj_o6c-X-CP0h4alF.js";
|
|
2
2
|
// src/oclif/presence-provenance.ts
|
|
3
3
|
function readPresenceProjection(detail) {
|
|
4
4
|
if (!detail || typeof detail !== "object") return null;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { A as bareAddress, Et as successfulSendOutcome, s as extractErrorPayload, ut as classifySendError } from "./api-command-
|
|
1
|
+
import { Dn as listSentEmails, Ht as getEmail, Jn as sendEmail, _ as describeApiFailure, h as sendPreparedSignal, p as prepareSignalEmail, vt as createEndpoint } from "./repeats-Dj_o6c-X-CP0h4alF.js";
|
|
2
|
+
import { A as bareAddress, Et as successfulSendOutcome, s as extractErrorPayload, ut as classifySendError } from "./api-command-CRjIK1QL.js";
|
|
3
3
|
import { recordSentSignal } from "./oclif/auto-signals.js";
|
|
4
4
|
import { _ as acquireListenLock, c as mailTime, d as readMailJson, f as removeMailFile, h as writeMailJson, i as mailId, l as privateMailDirectory, m as withMailLock, n as invalidSharedMail, o as mailObject, p as syncMailDirectory, r as mailAddress, s as mailString, t as SharedMailStateError, v as compareListenProcessIdentity, x as listenProcessIdentity, y as listenIdentity } from "./shared-mail-files-BAQSGxxz.js";
|
|
5
|
-
import { i as readApiBeforeDeadline, n as isPlainChatReply, o as scopedChatSenderTrust } from "./scoped-chat-
|
|
5
|
+
import { i as readApiBeforeDeadline, n as isPlainChatReply, o as scopedChatSenderTrust } from "./scoped-chat-CvqdlWuX.js";
|
|
6
6
|
import { n as tryOwnSharedMail, r as waitForSharedMailChange, t as readSharedMailOwner } from "./shared-mail-watch-BAPMsFNv.js";
|
|
7
7
|
import { Errors } from "@oclif/core";
|
|
8
8
|
import { opendirSync } from "node:fs";
|
|
9
9
|
import { createHash, randomUUID, scryptSync } from "node:crypto";
|
|
10
10
|
import { dirname, join } from "node:path";
|
|
11
11
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
12
|
-
// ../sdk-node/dist/api-
|
|
12
|
+
// ../sdk-node/dist/api-ieEDLXSB.js
|
|
13
13
|
const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
|
|
14
14
|
function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
|
|
15
15
|
let lastEventId;
|
package/man/primitive.1
CHANGED
|
@@ -218,6 +218,11 @@ run directly. If your organization requires approval, the command prints the
|
|
|
218
218
|
approval link and waits for the one-time token the page shows, or takes it with
|
|
219
219
|
.BR --step-up-token .
|
|
220
220
|
A new secret is printed once and never saved.
|
|
221
|
+
.B primitive keys update ID --expires-at TIME
|
|
222
|
+
extends a key before it expires; rotating keeps its expiry unless
|
|
223
|
+
.B rotate
|
|
224
|
+
is given
|
|
225
|
+
.BR --expires-at .
|
|
221
226
|
.B primitive keys revoke ID
|
|
222
227
|
revokes a key.
|
|
223
228
|
.B primitive whoami --check PERMISSION
|
|
@@ -232,7 +237,8 @@ signed in with
|
|
|
232
237
|
can leave; API keys are refused. The only owner of an organization cannot leave
|
|
233
238
|
it. If the server asks for a dashboard confirmation, open the page it names and
|
|
234
239
|
paste the token at the prompt, or pass it with --step-up-token. Refusals from
|
|
235
|
-
the server are printed as returned.
|
|
240
|
+
the server are printed as returned. Without a terminal and without --yes, it
|
|
241
|
+
exits 2 before anything is sent.
|
|
236
242
|
.PP
|
|
237
243
|
Run
|
|
238
244
|
.B primitive whoami
|