primcli 3.0.0-preview.5 → 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 +8 -7
- package/dist/{api-command-DIo8Rg0w.js → api-command-CRjIK1QL.js} +1258 -115
- package/dist/{listen-background-C0F9gNDD.js → listen-background-DyBYca28.js} +323 -36
- package/dist/{machine-session-BIOGBT9g.js → machine-session-3H-rNH8v.js} +5 -5
- package/dist/{notify-session-o9hEtJ_c.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 +1204 -217
- 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-Ix28GRRc.js → repeats-Dj_o6c-X-CP0h4alF.js} +173 -26
- package/dist/{scoped-chat-DcymzGgB.js → scoped-chat-CvqdlWuX.js} +1 -1
- package/dist/{signal-command-CRGoKO4A.js → signal-command-CPxRPbHK.js} +4 -4
- package/man/primitive.1 +7 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { l as runBackgroundListenSupervisor } from "../listen-background-DyBYca28.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { N as agentProfileDirectory, P as agentProfileName, R as loadConnectedAgentProfile, j as AGENT_PROFILE_ENV } from "../cli-config-Ms_0vNjq.js";
|
|
2
|
-
import { a as
|
|
3
|
-
import { d as SESSION_UUID, t as notificationScope } from "../notify-session-
|
|
4
|
-
import { It as detectAgentRuntime } from "../api-command-
|
|
2
|
+
import { a as backgroundListenStatus, i as backgroundListenRestartable, s as claimBackgroundListenRestart, t as BACKGROUND_LISTEN_RELAUNCH_ENV } from "../listen-background-DyBYca28.js";
|
|
3
|
+
import { d as SESSION_UUID, t as notificationScope } from "../notify-session-DTyg-sfS.js";
|
|
4
|
+
import { It as detectAgentRuntime } from "../api-command-CRjIK1QL.js";
|
|
5
5
|
import { d as readMailJson } from "../shared-mail-files-BAQSGxxz.js";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { spawn } from "node:child_process";
|
|
@@ -66,6 +66,7 @@ function healSelectedReceiver(options = {}) {
|
|
|
66
66
|
PRIMITIVE_CONFIG_DIR: configDir,
|
|
67
67
|
[RECEIVER_HEAL_ENV]: "0"
|
|
68
68
|
};
|
|
69
|
+
delete childEnv[BACKGROUND_LISTEN_RELAUNCH_ENV];
|
|
69
70
|
(options.spawnListener ?? spawnDetached)(listenArgv, childEnv);
|
|
70
71
|
return {
|
|
71
72
|
action: "restarting",
|
|
@@ -31,23 +31,23 @@ function readRootCredentials(configDir) {
|
|
|
31
31
|
return null;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
return `${apiBaseUrl.replace(/\/+$/, "")}/
|
|
34
|
+
function whoamiEndpoint(apiBaseUrl) {
|
|
35
|
+
return `${apiBaseUrl.replace(/\/+$/, "")}/whoami`;
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function parseRootIdentity(payload) {
|
|
38
38
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
39
39
|
const data = payload.data;
|
|
40
40
|
if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
|
|
41
|
-
const
|
|
42
|
-
if (typeof
|
|
43
|
-
|
|
41
|
+
const identity = data;
|
|
42
|
+
if (typeof identity.org_id !== "string" || !identity.org_id.trim()) return null;
|
|
43
|
+
const member = identity.member_address;
|
|
44
44
|
return {
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
memberAddress: member && typeof member.address === "string" && member.address.trim() ? member.address : null,
|
|
46
|
+
orgId: identity.org_id
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
function rootAuthLine(
|
|
50
|
-
return `Signed in as ${
|
|
49
|
+
function rootAuthLine(identity) {
|
|
50
|
+
return identity.memberAddress ? `Signed in as ${identity.memberAddress} (org ${identity.orgId})\n\n` : `Signed in (org ${identity.orgId})\n\n`;
|
|
51
51
|
}
|
|
52
52
|
function rootRequestConfig(configDir, env) {
|
|
53
53
|
const config = loadCliConfig(configDir);
|
|
@@ -60,11 +60,11 @@ function rootRequestConfig(configDir, env) {
|
|
|
60
60
|
headers: currentEnvironment?.config.headers
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
async function
|
|
63
|
+
async function fetchRootIdentity(params) {
|
|
64
64
|
const controller = new AbortController();
|
|
65
65
|
const timer = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
66
66
|
try {
|
|
67
|
-
const response = await params.fetch(
|
|
67
|
+
const response = await params.fetch(whoamiEndpoint(params.apiBaseUrl), {
|
|
68
68
|
headers: {
|
|
69
69
|
...params.headers ?? {},
|
|
70
70
|
accept: "application/json",
|
|
@@ -73,7 +73,7 @@ async function fetchRootAccount(params) {
|
|
|
73
73
|
signal: controller.signal
|
|
74
74
|
});
|
|
75
75
|
if (!response.ok) return null;
|
|
76
|
-
return
|
|
76
|
+
return parseRootIdentity(await response.json().catch(() => null));
|
|
77
77
|
} catch {
|
|
78
78
|
return null;
|
|
79
79
|
} finally {
|
|
@@ -95,14 +95,14 @@ async function rootSignedInSummary(options = {}) {
|
|
|
95
95
|
const stored = explicitApiKey ? null : readRootCredentials(configDir);
|
|
96
96
|
const apiKey = explicitApiKey || stored?.accessToken;
|
|
97
97
|
if (!apiKey) return null;
|
|
98
|
-
const
|
|
98
|
+
const identity = await fetchRootIdentity({
|
|
99
99
|
apiBaseUrl: stored?.apiBaseUrl ?? requestConfig.apiBaseUrl,
|
|
100
100
|
apiKey,
|
|
101
101
|
fetch: options.fetch ?? fetch,
|
|
102
102
|
headers: requestConfig.headers,
|
|
103
103
|
timeoutMs: options.timeoutMs ?? ROOT_AUTH_TIMEOUT_MS
|
|
104
104
|
});
|
|
105
|
-
return
|
|
105
|
+
return identity ? rootAuthLine(identity) : null;
|
|
106
106
|
}
|
|
107
107
|
function shouldShowLoggedOutSignupHint(options = {}) {
|
|
108
108
|
if ((options.argv ?? process.argv.slice(2)).length > 0) return false;
|
|
@@ -1217,9 +1217,7 @@ const listEndpoints = (options) => (options?.client ?? client).get({
|
|
|
1217
1217
|
/**
|
|
1218
1218
|
* Create a webhook endpoint
|
|
1219
1219
|
*
|
|
1220
|
-
* Creates a new webhook endpoint.
|
|
1221
|
-
* with the same URL and domain exists, it is reactivated
|
|
1222
|
-
* 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
|
|
1223
1221
|
* endpoints.
|
|
1224
1222
|
*
|
|
1225
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
|
|
@@ -1268,7 +1266,7 @@ const deleteEndpoint = (options) => (options.client ?? client).delete({
|
|
|
1268
1266
|
/**
|
|
1269
1267
|
* Get an endpoint
|
|
1270
1268
|
*
|
|
1271
|
-
* 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.
|
|
1272
1270
|
*/
|
|
1273
1271
|
const getEndpoint = (options) => (options.client ?? client).get({
|
|
1274
1272
|
security: [{
|
|
@@ -1281,10 +1279,12 @@ const getEndpoint = (options) => (options.client ?? client).get({
|
|
|
1281
1279
|
/**
|
|
1282
1280
|
* Update a webhook endpoint
|
|
1283
1281
|
*
|
|
1284
|
-
* 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).
|
|
1285
1283
|
*
|
|
1286
1284
|
*
|
|
1287
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.
|
|
1288
1288
|
*/
|
|
1289
1289
|
const updateEndpoint = (options) => (options.client ?? client).patch({
|
|
1290
1290
|
security: [{
|
|
@@ -1341,6 +1341,8 @@ const completeWebhookEvent = (options) => (options.client ?? client).post({
|
|
|
1341
1341
|
* Successful deliveries and verified-domain endpoints are exempt
|
|
1342
1342
|
* from the rate limit.
|
|
1343
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.
|
|
1344
1346
|
*/
|
|
1345
1347
|
const testEndpoint = (options) => (options.client ?? client).post({
|
|
1346
1348
|
security: [{
|
|
@@ -1374,6 +1376,8 @@ const testEndpoint = (options) => (options.client ?? client).post({
|
|
|
1374
1376
|
* delivered as if unfiltered), so `rules_valid: false` exposes a
|
|
1375
1377
|
* misconfiguration that is otherwise silent.
|
|
1376
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.
|
|
1377
1381
|
*/
|
|
1378
1382
|
const testEndpointRules = (options) => (options.client ?? client).post({
|
|
1379
1383
|
security: [{
|
|
@@ -3053,7 +3057,7 @@ const putAgentContactPolicy = (options) => (options.client ?? client).put({
|
|
|
3053
3057
|
/**
|
|
3054
3058
|
* Get current caller identity
|
|
3055
3059
|
*
|
|
3056
|
-
* 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.
|
|
3057
3061
|
*/
|
|
3058
3062
|
const whoami = (options) => (options?.client ?? client).get({
|
|
3059
3063
|
security: [{
|
|
@@ -3593,9 +3597,9 @@ const getWebhookDeliveryStats = (options) => (options?.client ?? client).get({
|
|
|
3593
3597
|
...options
|
|
3594
3598
|
});
|
|
3595
3599
|
/**
|
|
3596
|
-
* List what you created
|
|
3600
|
+
* List what you created, or what you were asked
|
|
3597
3601
|
*
|
|
3598
|
-
* 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.
|
|
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.
|
|
3599
3603
|
*/
|
|
3600
3604
|
const listActivityObjects = (options) => (options?.client ?? client).get({
|
|
3601
3605
|
security: [{
|
|
@@ -3702,7 +3706,7 @@ const createEmailRule = (options) => (options.client ?? client).post({
|
|
|
3702
3706
|
/**
|
|
3703
3707
|
* Delete a rule
|
|
3704
3708
|
*
|
|
3705
|
-
* 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.
|
|
3706
3710
|
*/
|
|
3707
3711
|
const deleteEmailRule = (options) => (options.client ?? client).delete({
|
|
3708
3712
|
security: [{
|
|
@@ -3823,7 +3827,7 @@ const listEmailRuleRequests = (options) => (options?.client ?? client).get({
|
|
|
3823
3827
|
/**
|
|
3824
3828
|
* Ask a member for a rule
|
|
3825
3829
|
*
|
|
3826
|
-
* 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. 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.
|
|
3827
3831
|
*/
|
|
3828
3832
|
const createEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3829
3833
|
security: [{
|
|
@@ -3870,7 +3874,7 @@ const deleteEmailRuleRequest = (options) => (options.client ?? client).delete({
|
|
|
3870
3874
|
/**
|
|
3871
3875
|
* Read a rule request
|
|
3872
3876
|
*
|
|
3873
|
-
* 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.
|
|
3874
3878
|
*/
|
|
3875
3879
|
const getEmailRuleRequest = (options) => (options.client ?? client).get({
|
|
3876
3880
|
security: [{
|
|
@@ -3883,7 +3887,7 @@ const getEmailRuleRequest = (options) => (options.client ?? client).get({
|
|
|
3883
3887
|
/**
|
|
3884
3888
|
* Decline a rule request
|
|
3885
3889
|
*
|
|
3886
|
-
* 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.
|
|
3887
3891
|
*/
|
|
3888
3892
|
const declineEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3889
3893
|
security: [{
|
|
@@ -3891,7 +3895,11 @@ const declineEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3891
3895
|
type: "http"
|
|
3892
3896
|
}],
|
|
3893
3897
|
url: "/email-rule-requests/{id}/decline",
|
|
3894
|
-
...options
|
|
3898
|
+
...options,
|
|
3899
|
+
headers: {
|
|
3900
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
3901
|
+
...options.headers
|
|
3902
|
+
}
|
|
3895
3903
|
});
|
|
3896
3904
|
/**
|
|
3897
3905
|
* Withdraw a rule request
|
|
@@ -3909,7 +3917,7 @@ const withdrawEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3909
3917
|
/**
|
|
3910
3918
|
* Accept a rule request
|
|
3911
3919
|
*
|
|
3912
|
-
* 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.
|
|
3913
3921
|
*/
|
|
3914
3922
|
const acceptEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3915
3923
|
security: [{
|
|
@@ -4809,7 +4817,7 @@ const updateGroup = (options) => (options.client ?? client).patch({
|
|
|
4809
4817
|
/**
|
|
4810
4818
|
* List every credential
|
|
4811
4819
|
*
|
|
4812
|
-
* 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.
|
|
4813
4821
|
*
|
|
4814
4822
|
* Person only: a dashboard session. The person's role must hold credentials:read. API keys, agent connection keys and agents are refused.
|
|
4815
4823
|
*/
|
|
@@ -4824,7 +4832,7 @@ const listCredentials = (options) => (options?.client ?? client).get({
|
|
|
4824
4832
|
/**
|
|
4825
4833
|
* Revoke a credential
|
|
4826
4834
|
*
|
|
4827
|
-
* 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.
|
|
4828
4836
|
*
|
|
4829
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.
|
|
4830
4838
|
*/
|
|
@@ -4926,7 +4934,7 @@ const getKeyBuilder = (options) => (options?.client ?? client).get({
|
|
|
4926
4934
|
/**
|
|
4927
4935
|
* List API keys
|
|
4928
4936
|
*
|
|
4929
|
-
* 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.
|
|
4930
4938
|
*
|
|
4931
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.
|
|
4932
4940
|
*/
|
|
@@ -4960,7 +4968,7 @@ const createKey = (options) => (options.client ?? client).post({
|
|
|
4960
4968
|
/**
|
|
4961
4969
|
* Rotate an API key
|
|
4962
4970
|
*
|
|
4963
|
-
* 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.
|
|
4964
4972
|
*
|
|
4965
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.
|
|
4966
4974
|
*/
|
|
@@ -4979,7 +4987,7 @@ const rotateKey = (options) => (options.client ?? client).post({
|
|
|
4979
4987
|
/**
|
|
4980
4988
|
* Get an API key
|
|
4981
4989
|
*
|
|
4982
|
-
* 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.
|
|
4983
4991
|
*
|
|
4984
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.
|
|
4985
4993
|
*/
|
|
@@ -4994,7 +5002,7 @@ const getKey = (options) => (options.client ?? client).get({
|
|
|
4994
5002
|
/**
|
|
4995
5003
|
* Change an API key
|
|
4996
5004
|
*
|
|
4997
|
-
* 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.
|
|
4998
5006
|
*
|
|
4999
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.
|
|
5000
5008
|
*/
|
|
@@ -7044,7 +7052,7 @@ function parseFromHeader(header) {
|
|
|
7044
7052
|
value: { address: address.toLowerCase() }
|
|
7045
7053
|
};
|
|
7046
7054
|
}
|
|
7047
|
-
// ../sdk-node/dist/understanding-
|
|
7055
|
+
// ../sdk-node/dist/understanding-CpocTa4f.js
|
|
7048
7056
|
/**
|
|
7049
7057
|
* AUTO-GENERATED - DO NOT EDIT
|
|
7050
7058
|
* Run `pnpm generate:validator` to regenerate.
|
|
@@ -23881,13 +23889,27 @@ const INTERACTION_EVENT_TYPES = [
|
|
|
23881
23889
|
"interaction.ack.requested"
|
|
23882
23890
|
];
|
|
23883
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
|
+
/**
|
|
23884
23905
|
* The full enumerated catalog of every current webhook event type: the five
|
|
23885
|
-
* email.*, the four opt-in sent_email.*,
|
|
23886
|
-
* interaction.<protocol>.<suffix>.
|
|
23906
|
+
* email.*, the four opt-in sent_email.*, the four opt-in
|
|
23907
|
+
* email_rule_request.*, and every interaction.<protocol>.<suffix>.
|
|
23887
23908
|
*/
|
|
23888
23909
|
const WEBHOOK_EVENT_TYPES = [
|
|
23889
23910
|
...EMAIL_EVENT_TYPES,
|
|
23890
23911
|
...SENT_EMAIL_EVENT_TYPES,
|
|
23912
|
+
...EMAIL_RULE_REQUEST_EVENT_TYPES,
|
|
23891
23913
|
...INTERACTION_EVENT_TYPES
|
|
23892
23914
|
];
|
|
23893
23915
|
const WEBHOOK_EVENT_TYPE_SET = new Set(WEBHOOK_EVENT_TYPES);
|
|
@@ -24426,7 +24448,6 @@ function ensureSearchReportsReplyState(apiClient) {
|
|
|
24426
24448
|
}
|
|
24427
24449
|
return probe;
|
|
24428
24450
|
}
|
|
24429
|
-
// src/oclif/commands/emails-poll.ts
|
|
24430
24451
|
function quoteDslValue(value) {
|
|
24431
24452
|
if (/^[^\s"]+$/.test(value)) return value;
|
|
24432
24453
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
@@ -24483,7 +24504,7 @@ function buildEmailSearchQuery(params) {
|
|
|
24483
24504
|
include_facets: "false",
|
|
24484
24505
|
limit: params.pageSize,
|
|
24485
24506
|
snippet: "false",
|
|
24486
|
-
sort: "received_at_asc"
|
|
24507
|
+
sort: params.order ?? "received_at_asc"
|
|
24487
24508
|
};
|
|
24488
24509
|
const q = combineQ(params.filters.q, params.filters.domain);
|
|
24489
24510
|
if (q) query.q = q;
|
|
@@ -24500,6 +24521,7 @@ function buildEmailSearchQuery(params) {
|
|
|
24500
24521
|
if (params.filters.to) query.to = params.filters.to;
|
|
24501
24522
|
if (params.since) query.date_from = params.since;
|
|
24502
24523
|
if (params.cursor) query.cursor = params.cursor;
|
|
24524
|
+
if (params.count === false) query.count = "false";
|
|
24503
24525
|
return query;
|
|
24504
24526
|
}
|
|
24505
24527
|
function encodeReceivedAtSearchCursor(email) {
|
|
@@ -24527,12 +24549,126 @@ function collectNewAcceptedEmails(rows, seenIds) {
|
|
|
24527
24549
|
}
|
|
24528
24550
|
return fresh;
|
|
24529
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
|
+
}
|
|
24530
24664
|
async function fetchEmailSearchPage(params) {
|
|
24531
24665
|
const result = await searchEmails({
|
|
24532
24666
|
client: params.apiClient.client,
|
|
24533
24667
|
query: buildEmailSearchQuery({
|
|
24668
|
+
count: params.count,
|
|
24534
24669
|
cursor: params.cursor,
|
|
24535
24670
|
filters: params.filters,
|
|
24671
|
+
order: params.order,
|
|
24536
24672
|
pageSize: params.pageSize,
|
|
24537
24673
|
since: params.since
|
|
24538
24674
|
}),
|
|
@@ -24562,6 +24698,7 @@ async function fetchEmailSearchPage(params) {
|
|
|
24562
24698
|
return {
|
|
24563
24699
|
ok: true,
|
|
24564
24700
|
cursor: envelope?.meta.cursor ?? cursorFromRows(rows),
|
|
24701
|
+
more: Boolean(envelope?.meta.cursor),
|
|
24565
24702
|
rows
|
|
24566
24703
|
};
|
|
24567
24704
|
}
|
|
@@ -24656,6 +24793,16 @@ async function pauseForTransientFailure(failure, attempt, options) {
|
|
|
24656
24793
|
return deadline === null || Date.now() < deadline;
|
|
24657
24794
|
}
|
|
24658
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
|
+
/**
|
|
24659
24806
|
* Run an idempotent read, retrying transient failures until the deadline.
|
|
24660
24807
|
* Resolves the first result that is not transient, or null when the
|
|
24661
24808
|
* deadline passes first (or the read itself resolved null).
|
|
@@ -25498,4 +25645,4 @@ function repeatStopCommand(emailId) {
|
|
|
25498
25645
|
if (!UUID.test(emailId)) throw new TypeError("emailId must be an email UUID");
|
|
25499
25646
|
return `primitive repeat stop --id ${emailId.toLowerCase()}`;
|
|
25500
25647
|
}
|
|
25501
|
-
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
|