primcli 3.0.0-preview.10 → 3.0.0-preview.12

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.
@@ -1,4 +1,4 @@
1
- import { B as ensureSearchReportsReplyState, Ht as getEmail, J as SENT_EMAIL_EVENT_TYPES, K as replyStateSurfaceForOperation, L as ReplyStateUnsupportedError, R as assertAwaitingFilterRows, W as isAwaitingRejectedError, Wn as sdk_gen_exports, Y as WEBHOOK_EVENT_TYPES, Zt as getOwnGrant, at as automatedRejectedError, ct as expectedAutomatedVerdicts, gn as listEndpoints, it as assertAutomatedVerdict, ot as automatedSurfaceForOperation, q as EMAIL_RULE_REQUEST_EVENT_TYPES, rt as AutomatedFilterUnsupportedError, st as ensureSearchReportsAutomated, tn as getThread, ut as isAutomatedRejectedError, v as parseRetryAfter, z as awaitingRejectedError } from "./repeats-Dj_o6c-X-CDaE-kdZ.js";
1
+ import { B as ensureSearchReportsReplyState, Gn as sdk_gen_exports, J as EMAIL_RULE_REQUEST_EVENT_TYPES, K as replyStateSurfaceForOperation, L as ReplyStateUnsupportedError, Qt as getOwnGrant, R as assertAwaitingFilterRows, Ut as getEmail, W as isAwaitingRejectedError, X as WEBHOOK_EVENT_TYPES, Y as SENT_EMAIL_EVENT_TYPES, _n as listEndpoints, at as assertAutomatedVerdict, ct as ensureSearchReportsAutomated, dt as isAutomatedRejectedError, it as AutomatedFilterUnsupportedError, lt as expectedAutomatedVerdicts, nn as getThread, ot as automatedRejectedError, q as EMAIL_RULE_OBJECTION_EVENT_TYPES, st as automatedSurfaceForOperation, v as parseRetryAfter, z as awaitingRejectedError } from "./repeats-Dj_o6c-X-wjmw2Jbx.js";
2
2
  import { C as saveCliCredentials, F as agentProfilesDirectory, H as requireDefaultLoginProfile, N as agentProfileDirectory, R as loadConnectedAgentProfile, S as resolveCliAuth, W as PrimitiveApiClient, _ as deleteCliCredentials, b as loadCliCredentials, c as resolveConfigEnvironment, d as validateCliHeaderName, f as validateCliHeaderValue, i as loadCliConfig, j as AGENT_PROFILE_ENV, m as cliAccessTokenExpiresAt, p as acquireCliCredentialsLock, w as saveSignupCredentials, x as normalizeApiBaseUrl, y as detectPrimitiveKeyEnvMisname } from "./cli-config-Ms_0vNjq.js";
3
3
  import "./oclif/global-org-flag.js";
4
4
  import { a as thrownErrorBody } from "./json-output-ch756TXV.js";
@@ -780,7 +780,7 @@ const operationManifest = [
780
780
  "binaryResponse": false,
781
781
  "bodyRequired": false,
782
782
  "command": "list-activity-objects",
783
- "description": "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, rule requests and objections to rules over their mail (objections only on the dashboard or the Primitive CLI). 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, and the objections to rules they wrote, under their current membership, each naming the member who asked or objected in created_through. A key, an app or an agent has none, and gets both kinds in withheld.",
783
+ "description": "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, rule requests and objections to rules over their mail (objections only on the dashboard or the Primitive CLI). 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, and the objections to rules they wrote, under their current membership, each naming the member who asked or objected in created_through. A key, an app or an agent has none, and gets both kinds in withheld. With relation=concerning it lists instead what other members did that concerns the person's own mail: each time a rule started covering one of their mailboxes or saved a new version while covering it, named as the rule was then, naming its author in created_through, under their current membership; only on the dashboard or the Primitive CLI. A key, an app or an agent has none, and gets email_rule_coverage in withheld. A notice never reads as ended. Notices are written by a periodic job and can lag: until the notices record a rule starting to cover you, the first page lists that rule as pending (pending_complete says whether that check finished), and as_of says about when the notices last looked. For what covers you now, read GET /email-rules/covering-me.",
784
784
  "hasJsonBody": false,
785
785
  "method": "GET",
786
786
  "operationId": "listActivityObjects",
@@ -789,14 +789,18 @@ const operationManifest = [
789
789
  "queryParams": [
790
790
  {
791
791
  "default": "created",
792
- "description": "created (the default) or asked.",
793
- "enum": ["created", "asked"],
792
+ "description": "created (the default), asked or concerning.",
793
+ "enum": [
794
+ "created",
795
+ "asked",
796
+ "concerning"
797
+ ],
794
798
  "name": "relation",
795
799
  "required": false,
796
800
  "type": "string"
797
801
  },
798
802
  {
799
- "description": "Only these kinds, comma-separated: function, endpoint, function_trigger, pull_subscription, recipient_route, filter_rule, wake_schedule, repeating_send, scheduled_send, api_key, agent_connection, email_rule, email_rule_request, email_rule_objection. Defaults to every kind the caller can have created (a person's own kinds only for a person). With relation=asked, only email_rule_request and email_rule_objection, which are also the default.",
803
+ "description": "Only these kinds, comma-separated: function, endpoint, function_trigger, pull_subscription, recipient_route, filter_rule, wake_schedule, repeating_send, scheduled_send, api_key, agent_connection, email_rule, email_rule_request, email_rule_objection, email_rule_coverage. Defaults to every kind the caller can have created (a person's own kinds only for a person). With relation=asked, only email_rule_request and email_rule_objection, which are also the default; with relation=concerning, only email_rule_coverage, the default. email_rule_coverage is listed only with relation=concerning.",
800
804
  "enum": null,
801
805
  "name": "kind",
802
806
  "required": false,
@@ -816,7 +820,7 @@ const operationManifest = [
816
820
  },
817
821
  {
818
822
  "default": 50,
819
- "description": "Objects per page, from 1 to 200; defaults to 50.",
823
+ "description": "Objects per page, from 1 to 200; defaults to 50. With relation=concerning the first page may also hold pending items beyond it.",
820
824
  "enum": null,
821
825
  "maximum": 200,
822
826
  "minimum": 1,
@@ -850,16 +854,16 @@ const operationManifest = [
850
854
  "properties": {
851
855
  "kind": {
852
856
  "type": "string",
853
- "description": "One of: function, endpoint, function_trigger, pull_subscription, recipient_route, filter_rule, wake_schedule, repeating_send, scheduled_send, api_key, agent_connection, email_rule, email_rule_request, email_rule_objection."
857
+ "description": "One of: function, endpoint, function_trigger, pull_subscription, recipient_route, filter_rule, wake_schedule, repeating_send, scheduled_send, api_key, agent_connection, email_rule, email_rule_request, email_rule_objection, email_rule_coverage."
854
858
  },
855
859
  "id": { "type": "string" },
856
860
  "name": {
857
- "description": "The name the object is known by: an endpoint's display name, a route's or filter's pattern, a Function's name, a send's From address, a wake schedule's command and the address it wakes, an API key's name, an agent's address, a rule's or rule request's name, and for an objection the name its rule had when the objection was made. Never a webhook URL and never mail content.",
861
+ "description": "The name the object is known by: an endpoint's display name, a route's or filter's pattern, a Function's name, a send's From address, a wake schedule's command and the address it wakes, an API key's name, an agent's address, a rule's or rule request's name, and for an objection or a coverage notice the name its rule had then. Never a webhook URL and never mail content.",
858
862
  "type": ["string", "null"]
859
863
  },
860
864
  "state": {
861
865
  "type": "string",
862
- "description": "Where it stands now: enabled, disabled, deleted or replaced (endpoints and routes), enabled or disabled (filters, wake schedules), live, suspended or deleted (Functions), active, paused or ended (repeating sends), scheduled (scheduled sends), active, suspended, expired or revoked (API keys), pending, claimed, connected or revoked (agents), draft, observe or active (email rules), pending, accepted, declined or withdrawn (rule requests and objections)."
866
+ "description": "Where it stands now: enabled, disabled, deleted or replaced (endpoints and routes), enabled or disabled (filters, wake schedules), live, suspended or deleted (Functions), active, paused or ended (repeating sends), scheduled (scheduled sends), active, suspended, expired or revoked (API keys), pending, claimed, connected or revoked (agents), draft, observe or active (email rules), pending, accepted, declined or withdrawn (rule requests and objections), and for a coverage notice what it told: started (a rule began covering your mailbox), new_version, or baseline (it already covered you when notices began). pending: a rule started covering your mailbox and the notices have not recorded that start yet (a restart within an hour of the last start notice is recorded without a new one); its id is then the rule's, and created_at when the rule last changed."
863
867
  },
864
868
  "created_at": {
865
869
  "type": "string",
@@ -873,21 +877,21 @@ const operationManifest = [
873
877
  "owned_now": {
874
878
  "type": "string",
875
879
  "enum": ["you", "someone_else"],
876
- "description": "you: it is still yours: never transferred, or transferred back to you. someone_else: it was transferred and another person holds it now, or, with relation=asked, another member made it."
880
+ "description": "you: it is still yours: never transferred, or transferred back to you. someone_else: it was transferred and another person holds it now, or, with relation=asked or concerning, another member made it."
877
881
  },
878
882
  "created_through": {
879
883
  "type": "object",
880
884
  "properties": {
881
885
  "kind": {
882
886
  "type": "string",
883
- "description": "The kind of credential it was created through: org_key, function_key, connected_key, oauth, agent_delegate or member (the person themselves). With relation=asked, member: the member who asked or objected."
887
+ "description": "The kind of credential it was created through: org_key, function_key, connected_key, oauth, agent_delegate or member (the person themselves). With relation=asked, member: the member who asked or objected; with relation=concerning, member: the rule's author."
884
888
  },
885
889
  "id": {
886
- "description": "In a person's view, the person's own user id for member, and an API key's id where they may read their keys (for a person limited to their own keys, only a key they still hold). Null otherwise, and always null in one credential's view, where it is the calling credential itself. With relation=asked, the user id of the member who asked or objected.",
890
+ "description": "In a person's view, the person's own user id for member, and an API key's id where they may read their keys (for a person limited to their own keys, only a key they still hold). Null otherwise, and always null in one credential's view, where it is the calling credential itself. With relation=asked, the user id of the member who asked or objected; with relation=concerning, of the rule's author.",
887
891
  "type": ["string", "null"]
888
892
  },
889
893
  "name": {
890
- "description": "In a person's view, what that credential of theirs is called: an app login by its app, an API key by its name, an agent's key by its address. Null otherwise, and for the person themselves. With relation=asked, the name of the member who asked or objected.",
894
+ "description": "In a person's view, what that credential of theirs is called: an app login by its app, an API key by its name, an agent's key by its address. Null otherwise, and for the person themselves. With relation=asked, the name of the member who asked or objected; with relation=concerning, of the rule's author.",
891
895
  "type": ["string", "null"]
892
896
  }
893
897
  },
@@ -938,6 +942,15 @@ const operationManifest = [
938
942
  "next_cursor": {
939
943
  "description": "Pass as cursor to read the next page; null on the last page. A page can hold fewer items than limit, or none, while next_cursor is set.",
940
944
  "type": ["string", "null"]
945
+ },
946
+ "as_of": {
947
+ "type": ["string", "null"],
948
+ "format": "date-time",
949
+ "description": "With relation=concerning only: about when the notices last looked at your organization; null if never or unread. Coverage since may have no notice yet."
950
+ },
951
+ "pending_complete": {
952
+ "description": "With relation=concerning, on the first page only: whether the check for rules that started covering you without their start notice (state pending, listed ahead of the notices and beyond limit) was finished. false: some may be missing. Absent where there is nothing to check.",
953
+ "type": "boolean"
941
954
  }
942
955
  },
943
956
  "required": [
@@ -6685,6 +6698,35 @@ const operationManifest = [
6685
6698
  "format": "uuid",
6686
6699
  "description": "With `group=message`: the send of this message, when you can read it (under a connected agent key, only its own sends)."
6687
6700
  },
6701
+ "imported": {
6702
+ "type": ["object", "null"],
6703
+ "description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
6704
+ "required": [
6705
+ "from",
6706
+ "method",
6707
+ "verification",
6708
+ "at"
6709
+ ],
6710
+ "properties": {
6711
+ "from": {
6712
+ "type": "string",
6713
+ "enum": ["google_workspace"]
6714
+ },
6715
+ "method": {
6716
+ "type": "string",
6717
+ "enum": ["primitive_direct"]
6718
+ },
6719
+ "verification": {
6720
+ "type": "string",
6721
+ "enum": ["provider_fetched"]
6722
+ },
6723
+ "at": {
6724
+ "type": "string",
6725
+ "format": "date-time",
6726
+ "description": "When Primitive acquired this historical message."
6727
+ }
6728
+ }
6729
+ },
6688
6730
  "snippet": {
6689
6731
  "type": ["string", "null"],
6690
6732
  "maxLength": 200,
@@ -6707,6 +6749,7 @@ const operationManifest = [
6707
6749
  "automated_reasons",
6708
6750
  "from_verified",
6709
6751
  "from_header_email",
6752
+ "imported",
6710
6753
  "snippet"
6711
6754
  ]
6712
6755
  }, {
@@ -9469,7 +9512,7 @@ const operationManifest = [
9469
9512
  "binaryResponse": false,
9470
9513
  "bodyRequired": false,
9471
9514
  "command": "get-key",
9472
- "description": "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.\n\nPerson 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.",
9515
+ "description": "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. grant.mail_scope.rule_versions gives each rule it lists directly its current_version, state and version_saved_at. 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.\n\nPerson 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.",
9473
9516
  "hasJsonBody": false,
9474
9517
  "method": "GET",
9475
9518
  "operationId": "getKey",
@@ -9562,6 +9605,24 @@ const operationManifest = [
9562
9605
  "rotated_to": {
9563
9606
  "description": "The id of the newest key rotated from this key that the caller may read; null until it is rotated, or when the caller may read no key rotated from it. A revoked one is still named: GET /v1/keys/{id} answers it.",
9564
9607
  "type": ["string", "null"]
9608
+ },
9609
+ "address_warnings": {
9610
+ "type": "array",
9611
+ "items": {
9612
+ "type": "object",
9613
+ "properties": {
9614
+ "address": { "type": "string" },
9615
+ "reason": { "type": "string" },
9616
+ "description": { "type": "string" }
9617
+ },
9618
+ "required": [
9619
+ "address",
9620
+ "reason",
9621
+ "description"
9622
+ ],
9623
+ "additionalProperties": {}
9624
+ },
9625
+ "description": "Notes on the key's grant, worked out from it on every read: whole_mailbox, an address or domain listed beside email rules, which the key reads in full; no_send_address, with address empty, a key that can send but lists only email rules. The notes that need the organization's mailboxes and domains (member_address, unowned_domain) are given only when the grant is written. Only rules not deleted and shares not ended count. Empty, or absent, for a key on a template, and empty for a revoked key."
9565
9626
  }
9566
9627
  },
9567
9628
  "required": [
@@ -10296,6 +10357,24 @@ const operationManifest = [
10296
10357
  "agent_address",
10297
10358
  "person"
10298
10359
  ]
10360
+ },
10361
+ "address_warnings": {
10362
+ "type": "array",
10363
+ "items": {
10364
+ "type": "object",
10365
+ "properties": {
10366
+ "address": { "type": "string" },
10367
+ "reason": { "type": "string" },
10368
+ "description": { "type": "string" }
10369
+ },
10370
+ "required": [
10371
+ "address",
10372
+ "reason",
10373
+ "description"
10374
+ ],
10375
+ "additionalProperties": {}
10376
+ },
10377
+ "description": "Notes on the key's grant, worked out from it on every read: whole_mailbox, an address or domain listed beside email rules, which the key reads in full; no_send_address, with address empty, a key that can send but lists only email rules. The notes that need the organization's mailboxes and domains (member_address, unowned_domain) are given only when the grant is written. Only rules not deleted and shares not ended count. Empty, or absent, for a key on a template, and empty for a revoked key."
10299
10378
  }
10300
10379
  },
10301
10380
  "required": [
@@ -10335,7 +10414,7 @@ const operationManifest = [
10335
10414
  "binaryResponse": false,
10336
10415
  "bodyRequired": false,
10337
10416
  "command": "list-keys",
10338
- "description": "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.\n\nPerson 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.",
10417
+ "description": "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. grant.mail_scope.rule_versions gives each rule it lists directly its current_version, state and version_saved_at. 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.\n\nPerson 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.",
10339
10418
  "hasJsonBody": false,
10340
10419
  "method": "GET",
10341
10420
  "operationId": "listKeys",
@@ -10439,6 +10518,24 @@ const operationManifest = [
10439
10518
  "rotated_to": {
10440
10519
  "description": "The id of the newest key rotated from this key that the caller may read; null until it is rotated, or when the caller may read no key rotated from it. A revoked one is still named: GET /v1/keys/{id} answers it.",
10441
10520
  "type": ["string", "null"]
10521
+ },
10522
+ "address_warnings": {
10523
+ "type": "array",
10524
+ "items": {
10525
+ "type": "object",
10526
+ "properties": {
10527
+ "address": { "type": "string" },
10528
+ "reason": { "type": "string" },
10529
+ "description": { "type": "string" }
10530
+ },
10531
+ "required": [
10532
+ "address",
10533
+ "reason",
10534
+ "description"
10535
+ ],
10536
+ "additionalProperties": {}
10537
+ },
10538
+ "description": "Notes on the key's grant, worked out from it on every read: whole_mailbox, an address or domain listed beside email rules, which the key reads in full; no_send_address, with address empty, a key that can send but lists only email rules. The notes that need the organization's mailboxes and domains (member_address, unowned_domain) are given only when the grant is written. Only rules not deleted and shares not ended count. Empty, or absent, for a key on a template, and empty for a revoked key."
10442
10539
  }
10443
10540
  },
10444
10541
  "required": [
@@ -12951,7 +13048,7 @@ const operationManifest = [
12951
13048
  "binaryResponse": false,
12952
13049
  "bodyRequired": false,
12953
13050
  "command": "accept-email-rule-objection",
12954
- "description": "Accepts a pending objection to a rule you wrote: turns the rule off (state draft), as updating it would, and records the objection accepted, together. You can turn the rule on again later. 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. Only on your own dashboard session or the Primitive CLI.",
13051
+ "description": "Accepts a pending objection to a rule you wrote: turns the rule off (state draft), as updating it would, and records the objection accepted, together. You can turn the rule on again later. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
12955
13052
  "hasJsonBody": false,
12956
13053
  "method": "POST",
12957
13054
  "operationId": "acceptEmailRuleObjection",
@@ -13088,7 +13185,7 @@ const operationManifest = [
13088
13185
  "binaryResponse": false,
13089
13186
  "bodyRequired": true,
13090
13187
  "command": "create-email-rule-objection",
13091
- "description": "Asks the author of a rule that covers one of your own mailboxes now to turn it off. Only a rule that covers you now: one you see only because it once decided on your mail cannot be objected to. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. You may have one pending objection per rule and 50 in all, and object to the same rule again only 10 minutes after you last did, whatever became of it. 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. Only on your own dashboard session or the Primitive CLI.",
13188
+ "description": "Asks the author of a rule that covers one of your own mailboxes now to turn it off. Only a rule that covers you now: one you see only because it once decided on your mail cannot be objected to. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. You may have one pending objection per rule and 50 in all, and object to the same rule again only 10 minutes after you last did, whatever became of it. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
13092
13189
  "hasJsonBody": true,
13093
13190
  "method": "POST",
13094
13191
  "operationId": "createEmailRuleObjection",
@@ -13236,7 +13333,7 @@ const operationManifest = [
13236
13333
  "binaryResponse": false,
13237
13334
  "bodyRequired": false,
13238
13335
  "command": "decline-email-rule-objection",
13239
- "description": "Declines a pending objection to a rule you wrote, optionally saying why; the rule stays as it is. 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. Only on your own dashboard session or the Primitive CLI.",
13336
+ "description": "Declines a pending objection to a rule you wrote, optionally saying why; the rule stays as it is. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
13240
13337
  "hasJsonBody": true,
13241
13338
  "method": "POST",
13242
13339
  "operationId": "declineEmailRuleObjection",
@@ -13382,7 +13479,7 @@ const operationManifest = [
13382
13479
  "binaryResponse": false,
13383
13480
  "bodyRequired": false,
13384
13481
  "command": "get-email-rule-covering-me",
13385
- "description": "One rule that covers one of your own mailboxes, read-only, with its current version; or one that no longer does but decided on mail at your own mailbox (covers_now false), shown as the version that last decided on your mail, without its current name. You see its name, wording, current tree, state, kind and author, and which of your own mailboxes it reaches. Its wording and tree are shown as written, so they can name other addresses (a condition on who an email is from or to). You do not see the other inboxes and domains its scope names, its saved expectations, or the keys, shares and webhooks that use it. 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. Only on your own dashboard session or the Primitive CLI.",
13482
+ "description": "One rule that covers one of your own mailboxes, read-only, with its current version; or one that no longer does but decided on mail at your own mailbox (covers_now false), shown as the version that last decided on your mail, without its current name. You see its name, wording, current tree, state, kind and author, and which of your own mailboxes it reaches. Its wording and tree are shown as written, so they can name other addresses (a condition on who an email is from or to). While it covers you, you also see who receives what it matches (receivers): how many API keys, webhooks and shares, the member each belongs to (or the organization), and the sites the webhooks deliver to. You do not see which keys, webhooks or shares they are (no ids, names, prefixes, or URLs beyond the site), the other inboxes and domains its scope names, or its saved expectations. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
13386
13483
  "hasJsonBody": false,
13387
13484
  "method": "GET",
13388
13485
  "operationId": "getEmailRuleCoveringMe",
@@ -13478,6 +13575,157 @@ const operationManifest = [
13478
13575
  "exclusiveMinimum": 0,
13479
13576
  "description": "Null when covers_now is false."
13480
13577
  },
13578
+ "receivers": {
13579
+ "description": "Null when covers_now is false (who receives it now is not about your mail), or when it could not be read in time.",
13580
+ "anyOf": [{
13581
+ "type": "object",
13582
+ "properties": {
13583
+ "keys": {
13584
+ "type": "array",
13585
+ "items": {
13586
+ "type": "object",
13587
+ "properties": {
13588
+ "owner": { "anyOf": [{
13589
+ "type": "object",
13590
+ "properties": {
13591
+ "kind": {
13592
+ "type": "string",
13593
+ "const": "member"
13594
+ },
13595
+ "user_id": {
13596
+ "type": "string",
13597
+ "description": "The member's user id.",
13598
+ "format": "uuid"
13599
+ },
13600
+ "name": {
13601
+ "description": "Their name; null when they have none set.",
13602
+ "type": ["string", "null"]
13603
+ }
13604
+ },
13605
+ "required": [
13606
+ "kind",
13607
+ "user_id",
13608
+ "name"
13609
+ ]
13610
+ }, {
13611
+ "type": "object",
13612
+ "properties": { "kind": {
13613
+ "type": "string",
13614
+ "const": "organization",
13615
+ "description": "Held by no member: an organization key, or one whose holder has left."
13616
+ } },
13617
+ "required": ["kind"]
13618
+ }] },
13619
+ "count": {
13620
+ "type": "integer",
13621
+ "exclusiveMinimum": 0
13622
+ }
13623
+ },
13624
+ "required": ["owner", "count"]
13625
+ },
13626
+ "description": "API keys that work now (not revoked, expired or suspended) and hold mail:read, whose access lists the rule or its live share. Owner: who holds each, or the organization."
13627
+ },
13628
+ "webhooks": {
13629
+ "type": "array",
13630
+ "items": {
13631
+ "type": "object",
13632
+ "properties": {
13633
+ "owner": { "anyOf": [{
13634
+ "type": "object",
13635
+ "properties": {
13636
+ "kind": {
13637
+ "type": "string",
13638
+ "const": "member"
13639
+ },
13640
+ "user_id": {
13641
+ "type": "string",
13642
+ "description": "The member's user id.",
13643
+ "format": "uuid"
13644
+ },
13645
+ "name": {
13646
+ "description": "Their name; null when they have none set.",
13647
+ "type": ["string", "null"]
13648
+ }
13649
+ },
13650
+ "required": [
13651
+ "kind",
13652
+ "user_id",
13653
+ "name"
13654
+ ]
13655
+ }, {
13656
+ "type": "object",
13657
+ "properties": { "kind": {
13658
+ "type": "string",
13659
+ "const": "organization",
13660
+ "description": "Held by no member: an organization key, or one whose holder has left."
13661
+ } },
13662
+ "required": ["kind"]
13663
+ }] },
13664
+ "count": {
13665
+ "type": "integer",
13666
+ "exclusiveMinimum": 0
13667
+ },
13668
+ "hosts": {
13669
+ "description": "Distinct sites they deliver to (a host's registrable domain, or a tunnel, preview or function service alone), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
13670
+ "type": "array",
13671
+ "items": { "type": "string" }
13672
+ },
13673
+ "hosts_not_listed": {
13674
+ "description": "Hosts past those listed.",
13675
+ "type": "integer",
13676
+ "minimum": 0
13677
+ }
13678
+ },
13679
+ "required": ["owner", "count"]
13680
+ },
13681
+ "description": "Webhooks taking received mail, bounces or reports that are sent what it matches: those of the key delivery acts as, when it lists the rule or its live share (owner: its holder, or the organization), and those of the member it is shared with (owner: that member)."
13682
+ },
13683
+ "shares": {
13684
+ "type": "array",
13685
+ "items": {
13686
+ "type": "object",
13687
+ "properties": {
13688
+ "beneficiary": {
13689
+ "type": "object",
13690
+ "properties": {
13691
+ "kind": {
13692
+ "type": "string",
13693
+ "const": "member"
13694
+ },
13695
+ "user_id": {
13696
+ "type": "string",
13697
+ "description": "The member's user id.",
13698
+ "format": "uuid"
13699
+ },
13700
+ "name": {
13701
+ "description": "Their name; null when they have none set.",
13702
+ "type": ["string", "null"]
13703
+ }
13704
+ },
13705
+ "required": [
13706
+ "kind",
13707
+ "user_id",
13708
+ "name"
13709
+ ]
13710
+ },
13711
+ "count": {
13712
+ "type": "integer",
13713
+ "exclusiveMinimum": 0
13714
+ }
13715
+ },
13716
+ "required": ["beneficiary", "count"]
13717
+ },
13718
+ "description": "The rule's live share (at most one), by its member, if they can read it and it is among their newest 20 shares."
13719
+ }
13720
+ },
13721
+ "required": [
13722
+ "keys",
13723
+ "webhooks",
13724
+ "shares"
13725
+ ],
13726
+ "description": "Who receives what the rule shares now, by person and count; empty unless it is an active grant rule."
13727
+ }, { "type": "null" }]
13728
+ },
13481
13729
  "created_at": {
13482
13730
  "type": "string",
13483
13731
  "format": "date-time"
@@ -13570,6 +13818,7 @@ const operationManifest = [
13570
13818
  "is_author",
13571
13819
  "covers",
13572
13820
  "current_version",
13821
+ "receivers",
13573
13822
  "created_at",
13574
13823
  "covers_now",
13575
13824
  "current"
@@ -13584,7 +13833,7 @@ const operationManifest = [
13584
13833
  "binaryResponse": false,
13585
13834
  "bodyRequired": false,
13586
13835
  "command": "get-email-rule-objection",
13587
- "description": "One objection you can see. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. 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. Only on your own dashboard session or the Primitive CLI.",
13836
+ "description": "One objection you can see. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
13588
13837
  "hasJsonBody": false,
13589
13838
  "method": "GET",
13590
13839
  "operationId": "getEmailRuleObjection",
@@ -13715,7 +13964,7 @@ const operationManifest = [
13715
13964
  "binaryResponse": false,
13716
13965
  "bodyRequired": false,
13717
13966
  "command": "list-email-rule-decisions-on-my-mail",
13718
- "description": "What a rule that covers your mailboxes, or decided on your mail, decided about mail at your own mailboxes, newest first: never about anyone else's mail. Each decision is in the words of the version that made it, which can be earlier than the current one: the questions it asked about that email (question_answers) and the columns its conditions read (parts). 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. Only on your own dashboard session or the Primitive CLI.",
13967
+ "description": "What a rule that covers your mailboxes, or decided on your mail, decided about mail at your own mailboxes, newest first: never about anyone else's mail. Each decision is in the words of the version that made it, which can be earlier than the current one: the questions it asked about that email (question_answers) and the columns its conditions read (parts). Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
13719
13968
  "hasJsonBody": false,
13720
13969
  "method": "GET",
13721
13970
  "operationId": "listEmailRuleDecisionsOnMyMail",
@@ -13838,7 +14087,7 @@ const operationManifest = [
13838
14087
  "binaryResponse": false,
13839
14088
  "bodyRequired": false,
13840
14089
  "command": "list-email-rule-objections",
13841
- "description": "Objections you made, objections to rules you wrote, or every objection you can see, newest first. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. 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. Only on your own dashboard session or the Primitive CLI.",
14090
+ "description": "Objections you made, objections to rules you wrote, or every objection you can see, newest first. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
13842
14091
  "hasJsonBody": false,
13843
14092
  "method": "GET",
13844
14093
  "operationId": "listEmailRuleObjections",
@@ -14008,7 +14257,7 @@ const operationManifest = [
14008
14257
  "binaryResponse": false,
14009
14258
  "bodyRequired": false,
14010
14259
  "command": "list-email-rules-covering-me",
14011
- "description": "Every email rule that covers one of your own mailboxes now, yours included, newest first, in any state. A rule covers you when the scope it runs with now reaches one of your own mailboxes (your member mailbox, or a personal agent's address): one whose author reads all your mail (author scope, for an author who reads the organization's mail or holds an access entry for your mailbox), or one that names your mailbox or its domain (selected). Another member's own_mailboxes rule never covers you. You see its name, wording, current tree, state, kind and author, and which of your own mailboxes it reaches. Its wording and tree are shown as written, so they can name other addresses (a condition on who an email is from or to). You do not see the other inboxes and domains its scope names, its saved expectations, or the keys, shares and webhooks that use it. A page can hold fewer rules than limit, or none, and still carry a cursor (one request reads a bounded number of rules): keep reading until meta.cursor is null. 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. Only on your own dashboard session or the Primitive CLI.",
14260
+ "description": "Every email rule that covers one of your own mailboxes now, yours included, newest first, in any state. A rule covers you when the scope it runs with now reaches one of your own mailboxes (your member mailbox, or a personal agent's address): one whose author reads all your mail (author scope, for an author who reads the organization's mail or holds an access entry for your mailbox), or one that names your mailbox or its domain (selected). Another member's own_mailboxes rule never covers you. You see its name, wording, current tree, state, kind and author, and which of your own mailboxes it reaches. Its wording and tree are shown as written, so they can name other addresses (a condition on who an email is from or to). While it covers you, you also see who receives what it matches (receivers): how many API keys, webhooks and shares, the member each belongs to (or the organization), and the sites the webhooks deliver to. You do not see which keys, webhooks or shares they are (no ids, names, prefixes, or URLs beyond the site), the other inboxes and domains its scope names, or its saved expectations. A page can hold fewer rules than limit, or none, and still carry a cursor (one request reads a bounded number of rules): keep reading until meta.cursor is null. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
14012
14261
  "hasJsonBody": false,
14013
14262
  "method": "GET",
14014
14263
  "operationId": "listEmailRulesCoveringMe",
@@ -14108,6 +14357,157 @@ const operationManifest = [
14108
14357
  "type": ["integer", "null"],
14109
14358
  "exclusiveMinimum": 0
14110
14359
  },
14360
+ "receivers": {
14361
+ "description": "Null when it could not be read in time; try again.",
14362
+ "anyOf": [{
14363
+ "type": "object",
14364
+ "properties": {
14365
+ "keys": {
14366
+ "type": "array",
14367
+ "items": {
14368
+ "type": "object",
14369
+ "properties": {
14370
+ "owner": { "anyOf": [{
14371
+ "type": "object",
14372
+ "properties": {
14373
+ "kind": {
14374
+ "type": "string",
14375
+ "const": "member"
14376
+ },
14377
+ "user_id": {
14378
+ "type": "string",
14379
+ "description": "The member's user id.",
14380
+ "format": "uuid"
14381
+ },
14382
+ "name": {
14383
+ "description": "Their name; null when they have none set.",
14384
+ "type": ["string", "null"]
14385
+ }
14386
+ },
14387
+ "required": [
14388
+ "kind",
14389
+ "user_id",
14390
+ "name"
14391
+ ]
14392
+ }, {
14393
+ "type": "object",
14394
+ "properties": { "kind": {
14395
+ "type": "string",
14396
+ "const": "organization",
14397
+ "description": "Held by no member: an organization key, or one whose holder has left."
14398
+ } },
14399
+ "required": ["kind"]
14400
+ }] },
14401
+ "count": {
14402
+ "type": "integer",
14403
+ "exclusiveMinimum": 0
14404
+ }
14405
+ },
14406
+ "required": ["owner", "count"]
14407
+ },
14408
+ "description": "API keys that work now (not revoked, expired or suspended) and hold mail:read, whose access lists the rule or its live share. Owner: who holds each, or the organization."
14409
+ },
14410
+ "webhooks": {
14411
+ "type": "array",
14412
+ "items": {
14413
+ "type": "object",
14414
+ "properties": {
14415
+ "owner": { "anyOf": [{
14416
+ "type": "object",
14417
+ "properties": {
14418
+ "kind": {
14419
+ "type": "string",
14420
+ "const": "member"
14421
+ },
14422
+ "user_id": {
14423
+ "type": "string",
14424
+ "description": "The member's user id.",
14425
+ "format": "uuid"
14426
+ },
14427
+ "name": {
14428
+ "description": "Their name; null when they have none set.",
14429
+ "type": ["string", "null"]
14430
+ }
14431
+ },
14432
+ "required": [
14433
+ "kind",
14434
+ "user_id",
14435
+ "name"
14436
+ ]
14437
+ }, {
14438
+ "type": "object",
14439
+ "properties": { "kind": {
14440
+ "type": "string",
14441
+ "const": "organization",
14442
+ "description": "Held by no member: an organization key, or one whose holder has left."
14443
+ } },
14444
+ "required": ["kind"]
14445
+ }] },
14446
+ "count": {
14447
+ "type": "integer",
14448
+ "exclusiveMinimum": 0
14449
+ },
14450
+ "hosts": {
14451
+ "description": "Distinct sites they deliver to (a host's registrable domain, or a tunnel, preview or function service alone), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
14452
+ "type": "array",
14453
+ "items": { "type": "string" }
14454
+ },
14455
+ "hosts_not_listed": {
14456
+ "description": "Hosts past those listed.",
14457
+ "type": "integer",
14458
+ "minimum": 0
14459
+ }
14460
+ },
14461
+ "required": ["owner", "count"]
14462
+ },
14463
+ "description": "Webhooks taking received mail, bounces or reports that are sent what it matches: those of the key delivery acts as, when it lists the rule or its live share (owner: its holder, or the organization), and those of the member it is shared with (owner: that member)."
14464
+ },
14465
+ "shares": {
14466
+ "type": "array",
14467
+ "items": {
14468
+ "type": "object",
14469
+ "properties": {
14470
+ "beneficiary": {
14471
+ "type": "object",
14472
+ "properties": {
14473
+ "kind": {
14474
+ "type": "string",
14475
+ "const": "member"
14476
+ },
14477
+ "user_id": {
14478
+ "type": "string",
14479
+ "description": "The member's user id.",
14480
+ "format": "uuid"
14481
+ },
14482
+ "name": {
14483
+ "description": "Their name; null when they have none set.",
14484
+ "type": ["string", "null"]
14485
+ }
14486
+ },
14487
+ "required": [
14488
+ "kind",
14489
+ "user_id",
14490
+ "name"
14491
+ ]
14492
+ },
14493
+ "count": {
14494
+ "type": "integer",
14495
+ "exclusiveMinimum": 0
14496
+ }
14497
+ },
14498
+ "required": ["beneficiary", "count"]
14499
+ },
14500
+ "description": "The rule's live share (at most one), by its member, if they can read it and it is among their newest 20 shares."
14501
+ }
14502
+ },
14503
+ "required": [
14504
+ "keys",
14505
+ "webhooks",
14506
+ "shares"
14507
+ ],
14508
+ "description": "Who receives what the rule shares now, by person and count; empty unless it is an active grant rule."
14509
+ }, { "type": "null" }]
14510
+ },
14111
14511
  "created_at": {
14112
14512
  "type": "string",
14113
14513
  "format": "date-time"
@@ -14122,6 +14522,7 @@ const operationManifest = [
14122
14522
  "is_author",
14123
14523
  "covers",
14124
14524
  "current_version",
14525
+ "receivers",
14125
14526
  "created_at"
14126
14527
  ]
14127
14528
  }
@@ -14135,7 +14536,7 @@ const operationManifest = [
14135
14536
  "binaryResponse": false,
14136
14537
  "bodyRequired": false,
14137
14538
  "command": "withdraw-email-rule-objection",
14138
- "description": "Withdraws a pending objection you made, and clears its message. 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. Only on your own dashboard session or the Primitive CLI.",
14539
+ "description": "Withdraws a pending objection you made, and clears its message. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
14139
14540
  "hasJsonBody": false,
14140
14541
  "method": "POST",
14141
14542
  "operationId": "withdrawEmailRuleObjection",
@@ -14272,7 +14673,7 @@ const operationManifest = [
14272
14673
  "binaryResponse": false,
14273
14674
  "bodyRequired": false,
14274
14675
  "command": "accept-email-rule-request",
14275
- "description": "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: each email in full with its attachments, but never raw. It does not go back through mail already received. 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. To try it on an email that has not arrived, pass the request's tree to POST /v1/email-rules/test-sample with one you make up, or have look-alikes written (POST /v1/email-rules/look-alikes with request_id); neither stores anything. expectation_samples are kept on the rule it writes. Accepting also needs mail:share_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.",
14676
+ "description": "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: each email in full with its attachments, but never raw. It does not go back through mail already received. 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. To try it on an email that has not arrived, pass the request's tree to POST /v1/email-rules/test-sample with one you make up, or have look-alikes written (POST /v1/email-rules/look-alikes with request_id); neither stores anything. expectation_samples are kept on the rule it writes. Accepting also needs mail:share_own. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
14276
14677
  "hasJsonBody": true,
14277
14678
  "method": "POST",
14278
14679
  "operationId": "acceptEmailRuleRequest",
@@ -14356,7 +14757,7 @@ const operationManifest = [
14356
14757
  }
14357
14758
  },
14358
14759
  "warnings": {
14359
- "description": "The compile response's warnings. Stored as sent.",
14760
+ "description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
14360
14761
  "maxItems": 10,
14361
14762
  "type": "array",
14362
14763
  "items": {
@@ -14390,6 +14791,30 @@ const operationManifest = [
14390
14791
  "required": ["checked", "matched"]
14391
14792
  }, { "type": "null" }]
14392
14793
  },
14794
+ "conditions_breadth": {
14795
+ "description": "Ignored.",
14796
+ "anyOf": [{
14797
+ "type": "object",
14798
+ "properties": {
14799
+ "checked": {
14800
+ "type": "integer",
14801
+ "minimum": 0,
14802
+ "description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes (for a grant rule, those you may share), the ones you can still read."
14803
+ },
14804
+ "matched": {
14805
+ "type": "integer",
14806
+ "minimum": 0,
14807
+ "description": "Of those, how many they hold for (for a do-not-share rule, one they cannot decide counts)."
14808
+ }
14809
+ },
14810
+ "required": ["checked", "matched"]
14811
+ }, { "type": "null" }]
14812
+ },
14813
+ "kind": {
14814
+ "description": "Only grant.",
14815
+ "type": "string",
14816
+ "const": "grant"
14817
+ },
14393
14818
  "expectation_samples": {
14394
14819
  "description": "Made-up emails the rule must match or not, such as look-alikes it must never match, kept on the rule this accept writes.",
14395
14820
  "minItems": 1,
@@ -14558,7 +14983,16 @@ const operationManifest = [
14558
14983
  "warnings": {
14559
14984
  "type": "array",
14560
14985
  "items": { "type": "string" },
14561
- "description": "As the member who asked sent them, normally from their compile. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
14986
+ "description": "As the member who asked sent them, normally from their compile, then every compiler note on the rule's tree and words they lack. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
14987
+ },
14988
+ "server_explanation": {
14989
+ "description": "What the rule as asked actually does: Primitive's own reading of the request's tree, never the words of the member who asked or of a model. Null when the tree no longer reads as one.",
14990
+ "type": ["string", "null"]
14991
+ },
14992
+ "server_notes": {
14993
+ "description": "Primitive's own notes on the rule as asked, worked out from its tree and description each time the request is read, and to the member asked while pending, how to test it on look-alikes. Unlike warnings, never written by the member who asked, though a note can quote their words or tree values.",
14994
+ "type": "array",
14995
+ "items": { "type": "string" }
14562
14996
  },
14563
14997
  "compiled_by": { "type": "string" },
14564
14998
  "vocabulary": { "type": "string" },
@@ -14655,7 +15089,7 @@ const operationManifest = [
14655
15089
  "type": ["boolean", "null"]
14656
15090
  },
14657
15091
  "notice": {
14658
- "description": "For the member asked, while pending: what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
15092
+ "description": "For the member asked, while pending: what the rule actually does (server_explanation), Primitive's warnings, then what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
14659
15093
  "type": ["string", "null"]
14660
15094
  }
14661
15095
  },
@@ -15058,7 +15492,7 @@ const operationManifest = [
15058
15492
  "binaryResponse": false,
15059
15493
  "bodyRequired": true,
15060
15494
  "command": "check-email-rule-request-target",
15061
- "description": "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.",
15495
+ "description": "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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
15062
15496
  "hasJsonBody": true,
15063
15497
  "method": "POST",
15064
15498
  "operationId": "checkEmailRuleRequestTarget",
@@ -15140,7 +15574,7 @@ const operationManifest = [
15140
15574
  "binaryResponse": false,
15141
15575
  "bodyRequired": true,
15142
15576
  "command": "compile-email-rule",
15143
- "description": "Turns a plain-English description of which received emails to match into a rule tree over the column contract, with an explanation of what it matches, the assumptions made, and warnings for what the columns cannot express. Where the columns fall short it adds up to five yes/no questions, asked only after the conditions match; they read the subject, the new text and attachment file names, never attachment contents. Nothing is saved. For a rule with no questions, breadth counts, read only, how much of your recent classified mail its conditions match. include_sql returns the SQL it renders to. kind do_not_share compiles for recall. 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.",
15577
+ "description": "Turns a plain-English description of which received emails to match into a rule tree over the column contract, with an explanation of what it matches, the assumptions made, and warnings for what the columns cannot express. Where the columns fall short it adds up to five yes/no questions, asked only after the conditions match; they read the subject, the new text and attachment file names, never attachment contents. Nothing is saved. For a rule with no questions, breadth counts, read only, how much of your recent classified mail its conditions match; for a grant rule with questions, conditions_breadth counts its conditions alone. include_sql returns the SQL it renders to. kind do_not_share compiles for recall. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
15144
15578
  "hasJsonBody": true,
15145
15579
  "method": "POST",
15146
15580
  "operationId": "compileEmailRule",
@@ -15223,12 +15657,17 @@ const operationManifest = [
15223
15657
  "warnings": {
15224
15658
  "type": "array",
15225
15659
  "items": { "type": "string" },
15226
- "description": "Parts of the description the column contract cannot express, and how the rule handles them. It also has notes on reading automated, from_mailing_list or sender_relationship, a sender address the description does not give, and a grant worded as a prohibition. When the rule has no questions and its conditions hold for all of the caller's recent classified mail (what a test of it covers by default), or for at least 90% of at least 20 emails, the first warning says so. That count is not made for a caller whose access shows headers only, or who could not run a test of the rule, and may also be skipped when the compile ran long or the count fails."
15660
+ "description": "Parts of the description the column contract cannot express, how the rule handles them, and the compiler's own notes on the rule (the Email Rules docs list them). When the rule has no questions and its conditions hold for nearly all of your recent mail (see breadth), or it is a grant rule whose conditions alone hold for over 20% of at least 20 emails (see conditions_breadth), the first warning says so."
15227
15661
  },
15228
15662
  "compiled_by": {
15229
15663
  "type": "string",
15230
15664
  "description": "An opaque name for the version of the rule compiler that produced the rule, such as rule-compiler-v1. Send it back as compiled_by when you save the rule."
15231
15665
  },
15666
+ "kind": {
15667
+ "description": "The kind it was compiled for. Send it with the tree to a test.",
15668
+ "type": "string",
15669
+ "enum": ["grant", "do_not_share"]
15670
+ },
15232
15671
  "breadth": {
15233
15672
  "description": "How many of your recent emails its conditions hold for, counted over your own mailboxes whatever scope you save it with, warning or not. Null when not counted in full: a rule with questions, headers-only access, no test of it possible as you, or a count that failed or ran out of time. Writes ignore it, so a compile answer (without include_sql) can be sent back unchanged.",
15234
15673
  "anyOf": [{
@@ -15248,6 +15687,25 @@ const operationManifest = [
15248
15687
  "required": ["checked", "matched"]
15249
15688
  }, { "type": "null" }]
15250
15689
  },
15690
+ "conditions_breadth": {
15691
+ "description": "For a grant rule with questions, breadth counted on its conditions alone: the emails its questions are asked about. Null for any other rule, or when not counted in full (as breadth).",
15692
+ "anyOf": [{
15693
+ "type": "object",
15694
+ "properties": {
15695
+ "checked": {
15696
+ "type": "integer",
15697
+ "minimum": 0,
15698
+ "description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes (for a grant rule, those you may share), the ones you can still read."
15699
+ },
15700
+ "matched": {
15701
+ "type": "integer",
15702
+ "minimum": 0,
15703
+ "description": "Of those, how many they hold for (for a do-not-share rule, one they cannot decide counts)."
15704
+ }
15705
+ },
15706
+ "required": ["checked", "matched"]
15707
+ }, { "type": "null" }]
15708
+ },
15251
15709
  "sql": {
15252
15710
  "description": "Present only when include_sql was true.",
15253
15711
  "type": "object",
@@ -15282,7 +15740,7 @@ const operationManifest = [
15282
15740
  "binaryResponse": false,
15283
15741
  "bodyRequired": true,
15284
15742
  "command": "create-email-rule",
15285
- "description": "Saves a rule as version 1 from a compile response or a tree you wrote, checked against the column contract. It starts in observe (recorded, nothing granted or blocked) unless state is draft, or active for a do_not_share rule. You are its author, and it never reaches mail you cannot read. evaluation_scope is own_mailboxes unless you name author or selected (scope_selection names only what you can read). expectations are judged in expectations_check. kind do_not_share blocks sharing what it matches; a key cannot list it (details.reason rule_blocks_sharing). 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.",
15743
+ "description": "Saves a rule as version 1 from a compile response or a tree you wrote, checked against the column contract. It starts in observe (recorded, nothing granted or blocked) unless state is draft, or active for a do_not_share rule. You are its author, and it never reaches mail you cannot read. evaluation_scope is own_mailboxes unless you name author or selected (scope_selection names only what you can read). expectations are judged in expectations_check. kind do_not_share blocks sharing what it matches; a key cannot list it (details.reason rule_blocks_sharing). Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
15286
15744
  "hasJsonBody": true,
15287
15745
  "method": "POST",
15288
15746
  "operationId": "createEmailRule",
@@ -15539,7 +15997,7 @@ const operationManifest = [
15539
15997
  }
15540
15998
  },
15541
15999
  "warnings": {
15542
- "description": "The compile response's warnings. Stored as sent.",
16000
+ "description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
15543
16001
  "maxItems": 10,
15544
16002
  "type": "array",
15545
16003
  "items": {
@@ -15572,6 +16030,25 @@ const operationManifest = [
15572
16030
  },
15573
16031
  "required": ["checked", "matched"]
15574
16032
  }, { "type": "null" }]
16033
+ },
16034
+ "conditions_breadth": {
16035
+ "description": "Ignored.",
16036
+ "anyOf": [{
16037
+ "type": "object",
16038
+ "properties": {
16039
+ "checked": {
16040
+ "type": "integer",
16041
+ "minimum": 0,
16042
+ "description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes (for a grant rule, those you may share), the ones you can still read."
16043
+ },
16044
+ "matched": {
16045
+ "type": "integer",
16046
+ "minimum": 0,
16047
+ "description": "Of those, how many they hold for (for a do-not-share rule, one they cannot decide counts)."
16048
+ }
16049
+ },
16050
+ "required": ["checked", "matched"]
16051
+ }, { "type": "null" }]
15575
16052
  }
15576
16053
  },
15577
16054
  "required": [
@@ -15995,6 +16472,10 @@ const operationManifest = [
15995
16472
  "endpoints",
15996
16473
  "shares_ended"
15997
16474
  ]
16475
+ },
16476
+ "notice": {
16477
+ "description": "After a write that saved a version of an active rule keys or webhooks read without checking it first: what it changes, and how to have the next one checked.",
16478
+ "type": "string"
15998
16479
  }
15999
16480
  },
16000
16481
  "required": [
@@ -16018,7 +16499,7 @@ const operationManifest = [
16018
16499
  "binaryResponse": false,
16019
16500
  "bodyRequired": true,
16020
16501
  "command": "create-email-rule-request",
16021
- "description": "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 or shared until they accept, and they may change the rule first. A message (up to 500 characters, fixed once sent) tells them why you ask. At most 5 pending requests to one member and 50 in all. With members:read the answer says whether they can accept it under their role (target_can_accept, target_warning); POST /v1/email-rule-requests/target-check checks first. 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.",
16502
+ "description": "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 or shared until they accept, and they may change the rule first. A message (up to 500 characters, fixed once sent) tells them why you ask. At most 5 pending requests to one member and 50 in all. With members:read the answer says whether they can accept it under their role (target_can_accept, target_warning); POST /v1/email-rule-requests/target-check checks first. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
16022
16503
  "hasJsonBody": true,
16023
16504
  "method": "POST",
16024
16505
  "operationId": "createEmailRuleRequest",
@@ -16114,7 +16595,7 @@ const operationManifest = [
16114
16595
  }
16115
16596
  },
16116
16597
  "warnings": {
16117
- "description": "The compile response's warnings. Stored as sent.",
16598
+ "description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
16118
16599
  "maxItems": 10,
16119
16600
  "type": "array",
16120
16601
  "items": {
@@ -16147,6 +16628,30 @@ const operationManifest = [
16147
16628
  },
16148
16629
  "required": ["checked", "matched"]
16149
16630
  }, { "type": "null" }]
16631
+ },
16632
+ "conditions_breadth": {
16633
+ "description": "Ignored.",
16634
+ "anyOf": [{
16635
+ "type": "object",
16636
+ "properties": {
16637
+ "checked": {
16638
+ "type": "integer",
16639
+ "minimum": 0,
16640
+ "description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes (for a grant rule, those you may share), the ones you can still read."
16641
+ },
16642
+ "matched": {
16643
+ "type": "integer",
16644
+ "minimum": 0,
16645
+ "description": "Of those, how many they hold for (for a do-not-share rule, one they cannot decide counts)."
16646
+ }
16647
+ },
16648
+ "required": ["checked", "matched"]
16649
+ }, { "type": "null" }]
16650
+ },
16651
+ "kind": {
16652
+ "description": "Only grant.",
16653
+ "type": "string",
16654
+ "const": "grant"
16150
16655
  }
16151
16656
  },
16152
16657
  "required": [
@@ -16212,7 +16717,16 @@ const operationManifest = [
16212
16717
  "warnings": {
16213
16718
  "type": "array",
16214
16719
  "items": { "type": "string" },
16215
- "description": "As the member who asked sent them, normally from their compile. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
16720
+ "description": "As the member who asked sent them, normally from their compile, then every compiler note on the rule's tree and words they lack. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
16721
+ },
16722
+ "server_explanation": {
16723
+ "description": "What the rule as asked actually does: Primitive's own reading of the request's tree, never the words of the member who asked or of a model. Null when the tree no longer reads as one.",
16724
+ "type": ["string", "null"]
16725
+ },
16726
+ "server_notes": {
16727
+ "description": "Primitive's own notes on the rule as asked, worked out from its tree and description each time the request is read, and to the member asked while pending, how to test it on look-alikes. Unlike warnings, never written by the member who asked, though a note can quote their words or tree values.",
16728
+ "type": "array",
16729
+ "items": { "type": "string" }
16216
16730
  },
16217
16731
  "compiled_by": { "type": "string" },
16218
16732
  "vocabulary": { "type": "string" },
@@ -16309,7 +16823,7 @@ const operationManifest = [
16309
16823
  "type": ["boolean", "null"]
16310
16824
  },
16311
16825
  "notice": {
16312
- "description": "For the member asked, while pending: what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
16826
+ "description": "For the member asked, while pending: what the rule actually does (server_explanation), Primitive's warnings, then what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
16313
16827
  "type": ["string", "null"]
16314
16828
  },
16315
16829
  "target_can_accept": {
@@ -16353,7 +16867,7 @@ const operationManifest = [
16353
16867
  "binaryResponse": false,
16354
16868
  "bodyRequired": false,
16355
16869
  "command": "decline-email-rule-request",
16356
- "description": "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.",
16870
+ "description": "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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
16357
16871
  "hasJsonBody": true,
16358
16872
  "method": "POST",
16359
16873
  "operationId": "declineEmailRuleRequest",
@@ -16441,7 +16955,16 @@ const operationManifest = [
16441
16955
  "warnings": {
16442
16956
  "type": "array",
16443
16957
  "items": { "type": "string" },
16444
- "description": "As the member who asked sent them, normally from their compile. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
16958
+ "description": "As the member who asked sent them, normally from their compile, then every compiler note on the rule's tree and words they lack. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
16959
+ },
16960
+ "server_explanation": {
16961
+ "description": "What the rule as asked actually does: Primitive's own reading of the request's tree, never the words of the member who asked or of a model. Null when the tree no longer reads as one.",
16962
+ "type": ["string", "null"]
16963
+ },
16964
+ "server_notes": {
16965
+ "description": "Primitive's own notes on the rule as asked, worked out from its tree and description each time the request is read, and to the member asked while pending, how to test it on look-alikes. Unlike warnings, never written by the member who asked, though a note can quote their words or tree values.",
16966
+ "type": "array",
16967
+ "items": { "type": "string" }
16445
16968
  },
16446
16969
  "compiled_by": { "type": "string" },
16447
16970
  "vocabulary": { "type": "string" },
@@ -16538,7 +17061,7 @@ const operationManifest = [
16538
17061
  "type": ["boolean", "null"]
16539
17062
  },
16540
17063
  "notice": {
16541
- "description": "For the member asked, while pending: what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
17064
+ "description": "For the member asked, while pending: what the rule actually does (server_explanation), Primitive's warnings, then what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
16542
17065
  "type": ["string", "null"]
16543
17066
  }
16544
17067
  },
@@ -16574,7 +17097,7 @@ const operationManifest = [
16574
17097
  "binaryResponse": false,
16575
17098
  "bodyRequired": false,
16576
17099
  "command": "delete-email-rule",
16577
- "description": "Deletes a rule with its versions, its decisions and the access it granted. A share of it ends (end_reason rule_deleted), and the member who shared can still list what it handed over. The answer lists the shares it ended (ended_shares) and the unrevoked keys that still list it, which now read nothing through it (keys, other_keys; left out when they could not be read). The author or a reader of all the organization's mail may delete it; while it is shared, 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.",
17100
+ "description": "Deletes a rule with its versions, its decisions and the access it granted. A share of it ends (end_reason rule_deleted), and the member who shared can still list what it handed over. The answer lists the shares it ended (ended_shares) and the unrevoked keys that still list it, which now read nothing through it (keys, other_keys; left out when they could not be read). The author or a reader of all the organization's mail may delete it; while it is shared, only the author or someone who manages members from the dashboard. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
16578
17101
  "hasJsonBody": false,
16579
17102
  "method": "DELETE",
16580
17103
  "operationId": "deleteEmailRule",
@@ -16639,7 +17162,7 @@ const operationManifest = [
16639
17162
  "binaryResponse": false,
16640
17163
  "bodyRequired": false,
16641
17164
  "command": "delete-email-rule-request",
16642
- "description": "Deletes a request you withdrew, for everyone who could see it. 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.",
17165
+ "description": "Deletes a request you withdrew, for everyone who could see it. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
16643
17166
  "hasJsonBody": false,
16644
17167
  "method": "DELETE",
16645
17168
  "operationId": "deleteEmailRuleRequest",
@@ -16706,7 +17229,7 @@ const operationManifest = [
16706
17229
  "binaryResponse": false,
16707
17230
  "bodyRequired": true,
16708
17231
  "command": "generate-look-alikes",
16709
- "description": "Writes made-up emails that come close to what a grant rule describes, and reports what the rule decides for each, as test-sample would. Most should not match (expected no_match): business near misses from its senders and topic (kind other: an all-clear, a reply with nothing new, a related document, another subject) and private mail (a personal medical bill, pay for named people, a personal purchase, personal banking or tax). By default a third, rounded down, are near cases it should match (expected match, kind other). failed means the rule decided one against expected. Nothing is stored and no mail is read. Keep them, with their expected, with add_expectation_samples, or for a request with the accept's expectation_samples. Limited to 20 an hour per member. 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.",
17232
+ "description": "Writes made-up emails that come close to what a grant rule describes, and reports what the rule decides for each, as test-sample would. Most should not match (expected no_match): business near misses from its senders and topic (kind other: an all-clear, a reply with nothing new, a related document, another subject) and private mail (a personal medical bill, pay for named people, a personal purchase, personal banking or tax). By default a third, rounded down, are near cases it should match (expected match, kind other). failed means the rule decided one against expected. Nothing is stored and no mail is read. Keep them, with their expected, with add_expectation_samples, or for a request with the accept's expectation_samples. Limited to 20 an hour per member. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
16710
17233
  "hasJsonBody": true,
16711
17234
  "method": "POST",
16712
17235
  "operationId": "generateLookAlikes",
@@ -16858,7 +17381,16 @@ const operationManifest = [
16858
17381
  "type": ["integer", "null"],
16859
17382
  "exclusiveMinimum": 0
16860
17383
  },
16861
- "vocabulary": { "type": "string" }
17384
+ "vocabulary": { "type": "string" },
17385
+ "kind": {
17386
+ "description": "The kind it was tested as.",
17387
+ "type": "string",
17388
+ "enum": ["grant", "do_not_share"]
17389
+ },
17390
+ "note": {
17391
+ "description": "Present when a tree was sent without kind, so it was tested as grant.",
17392
+ "type": "string"
17393
+ }
16862
17394
  },
16863
17395
  "required": [
16864
17396
  "id",
@@ -17026,7 +17558,7 @@ const operationManifest = [
17026
17558
  "binaryResponse": false,
17027
17559
  "bodyRequired": false,
17028
17560
  "command": "get-email-rule",
17029
- "description": "A rule, its scope (evaluation_scope, and scope_selection for a selected rule), its current version and its saved expectations. The current version's text (english, tree, explanation, assumptions, warnings) is under current, and current_version is its number. What the scope comes to for its author now is GET /email-rules/{id}/scope. The SQL the version renders to is included only when include_sql is true. 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.",
17561
+ "description": "A rule, its scope (evaluation_scope, and scope_selection for a selected rule), its current version and its saved expectations. The current version's text (english, tree, explanation, assumptions, warnings) is under current, and current_version is its number. What the scope comes to for its author now is GET /email-rules/{id}/scope. The SQL the version renders to is included only when include_sql is true. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
17030
17562
  "hasJsonBody": false,
17031
17563
  "method": "GET",
17032
17564
  "operationId": "getEmailRule",
@@ -17384,7 +17916,7 @@ const operationManifest = [
17384
17916
  "binaryResponse": false,
17385
17917
  "bodyRequired": false,
17386
17918
  "command": "get-email-rule-request",
17387
- "description": "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. To try it on an email that has not arrived, pass the request's tree to POST /v1/email-rules/test-sample with one you make up, or have look-alikes written (POST /v1/email-rules/look-alikes with request_id); neither stores anything. 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.",
17919
+ "description": "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. To try it on an email that has not arrived, pass the request's tree to POST /v1/email-rules/test-sample with one you make up, or have look-alikes written (POST /v1/email-rules/look-alikes with request_id); neither stores anything. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
17388
17920
  "hasJsonBody": false,
17389
17921
  "method": "GET",
17390
17922
  "operationId": "getEmailRuleRequest",
@@ -17457,7 +17989,16 @@ const operationManifest = [
17457
17989
  "warnings": {
17458
17990
  "type": "array",
17459
17991
  "items": { "type": "string" },
17460
- "description": "As the member who asked sent them, normally from their compile. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
17992
+ "description": "As the member who asked sent them, normally from their compile, then every compiler note on the rule's tree and words they lack. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
17993
+ },
17994
+ "server_explanation": {
17995
+ "description": "What the rule as asked actually does: Primitive's own reading of the request's tree, never the words of the member who asked or of a model. Null when the tree no longer reads as one.",
17996
+ "type": ["string", "null"]
17997
+ },
17998
+ "server_notes": {
17999
+ "description": "Primitive's own notes on the rule as asked, worked out from its tree and description each time the request is read, and to the member asked while pending, how to test it on look-alikes. Unlike warnings, never written by the member who asked, though a note can quote their words or tree values.",
18000
+ "type": "array",
18001
+ "items": { "type": "string" }
17461
18002
  },
17462
18003
  "compiled_by": { "type": "string" },
17463
18004
  "vocabulary": { "type": "string" },
@@ -17554,7 +18095,7 @@ const operationManifest = [
17554
18095
  "type": ["boolean", "null"]
17555
18096
  },
17556
18097
  "notice": {
17557
- "description": "For the member asked, while pending: what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
18098
+ "description": "For the member asked, while pending: what the rule actually does (server_explanation), Primitive's warnings, then what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
17558
18099
  "type": ["string", "null"]
17559
18100
  }
17560
18101
  },
@@ -17590,7 +18131,7 @@ const operationManifest = [
17590
18131
  "binaryResponse": false,
17591
18132
  "bodyRequired": false,
17592
18133
  "command": "get-email-rule-scope",
17593
- "description": "Whose mail the rule runs over, and what that comes to now: a rule never reaches further than what its author can read when it runs, so what a selected rule names and its author can no longer read stops matching. 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.",
18134
+ "description": "Whose mail the rule runs over, and what that comes to now: a rule never reaches further than what its author can read when it runs, so what a selected rule names and its author can no longer read stops matching. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
17594
18135
  "hasJsonBody": false,
17595
18136
  "method": "GET",
17596
18137
  "operationId": "getEmailRuleScope",
@@ -17723,7 +18264,7 @@ const operationManifest = [
17723
18264
  "binaryResponse": false,
17724
18265
  "bodyRequired": false,
17725
18266
  "command": "get-email-rule-share",
17726
- "description": "One share. 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.",
18267
+ "description": "One share. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
17727
18268
  "hasJsonBody": false,
17728
18269
  "method": "GET",
17729
18270
  "operationId": "getEmailRuleShare",
@@ -17906,7 +18447,7 @@ const operationManifest = [
17906
18447
  "binaryResponse": false,
17907
18448
  "bodyRequired": false,
17908
18449
  "command": "get-email-rule-vocabulary",
17909
- "description": "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.",
18450
+ "description": "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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
17910
18451
  "hasJsonBody": false,
17911
18452
  "method": "GET",
17912
18453
  "operationId": "getEmailRuleVocabulary",
@@ -18080,7 +18621,7 @@ const operationManifest = [
18080
18621
  "binaryResponse": false,
18081
18622
  "bodyRequired": false,
18082
18623
  "command": "list-email-rule-decisions",
18083
- "description": "What the rule decided for each email it was evaluated against, newest first: whether it matched, whether it nearly did, how each part decided and the answers to its questions, with which email it was (from_address, subject, received_at). Only decisions on emails the caller can read are listed. With matched, only matches (true) or only the rest (false). 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.",
18624
+ "description": "What the rule decided for each email it was evaluated against, newest first: whether it matched, whether it nearly did, how each part decided and the answers to its questions, with which email it was (from_address, subject, received_at). Only decisions on emails the caller can read are listed. With matched, only matches (true) or only the rest (false). Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
18084
18625
  "hasJsonBody": false,
18085
18626
  "method": "GET",
18086
18627
  "operationId": "listEmailRuleDecisions",
@@ -18236,7 +18777,7 @@ const operationManifest = [
18236
18777
  "binaryResponse": false,
18237
18778
  "bodyRequired": false,
18238
18779
  "command": "list-email-rule-requests",
18239
- "description": "Rule requests, newest first: those made to you (box incoming, the default), those you made (outgoing), or every one you can see (all). Pending ones by default; status decided lists accepted, declined and withdrawn ones, and any lists both. 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.",
18780
+ "description": "Rule requests, newest first: those made to you (box incoming, the default), those you made (outgoing), or every one you can see (all). Pending ones by default; status decided lists accepted, declined and withdrawn ones, and any lists both. 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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
18240
18781
  "hasJsonBody": false,
18241
18782
  "method": "GET",
18242
18783
  "operationId": "listEmailRuleRequests",
@@ -18347,7 +18888,16 @@ const operationManifest = [
18347
18888
  "warnings": {
18348
18889
  "type": "array",
18349
18890
  "items": { "type": "string" },
18350
- "description": "As the member who asked sent them, normally from their compile. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
18891
+ "description": "As the member who asked sent them, normally from their compile, then every compiler note on the rule's tree and words they lack. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
18892
+ },
18893
+ "server_explanation": {
18894
+ "description": "What the rule as asked actually does: Primitive's own reading of the request's tree, never the words of the member who asked or of a model. Null when the tree no longer reads as one.",
18895
+ "type": ["string", "null"]
18896
+ },
18897
+ "server_notes": {
18898
+ "description": "Primitive's own notes on the rule as asked, worked out from its tree and description each time the request is read, and to the member asked while pending, how to test it on look-alikes. Unlike warnings, never written by the member who asked, though a note can quote their words or tree values.",
18899
+ "type": "array",
18900
+ "items": { "type": "string" }
18351
18901
  },
18352
18902
  "compiled_by": { "type": "string" },
18353
18903
  "vocabulary": { "type": "string" },
@@ -18444,7 +18994,7 @@ const operationManifest = [
18444
18994
  "type": ["boolean", "null"]
18445
18995
  },
18446
18996
  "notice": {
18447
- "description": "For the member asked, while pending: what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
18997
+ "description": "For the member asked, while pending: what the rule actually does (server_explanation), Primitive's warnings, then what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
18448
18998
  "type": ["string", "null"]
18449
18999
  }
18450
19000
  },
@@ -18481,7 +19031,7 @@ const operationManifest = [
18481
19031
  "binaryResponse": false,
18482
19032
  "bodyRequired": false,
18483
19033
  "command": "list-email-rule-results",
18484
- "description": "What each rule you can see decided about this email (matched, not matched, or not run), in the words of the deciding version. A do_not_share rule that matched it blocks sharing while active; earlier shares stay. Only a caller who can read the email gets an answer. classification is every fact the classifier read, as rule conditions read it. At most 50 rules are listed, results first; not_listed counts the rest. Another member's rule that decided on your own mail is listed read_only (dashboard and CLI only); hidden counts deciding rules you cannot see. 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.",
19034
+ "description": "What each rule you can see decided about this email (matched, not matched, or not run), in the words of the deciding version. A do_not_share rule that matched it blocks sharing while active; earlier shares stay. Only a caller who can read the email gets an answer. classification is every fact the classifier read, as rule conditions read it. At most 50 rules are listed, results first; not_listed counts the rest. Another member's rule that decided on your own mail is listed read_only (dashboard and CLI only), with who receives what it shares (receivers) while it covers you; hidden counts deciding rules you cannot see. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
18485
19035
  "hasJsonBody": false,
18486
19036
  "method": "GET",
18487
19037
  "operationId": "listEmailRuleResults",
@@ -18734,6 +19284,157 @@ const operationManifest = [
18734
19284
  "name",
18735
19285
  "email"
18736
19286
  ]
19287
+ },
19288
+ "receivers": {
19289
+ "description": "With read_only: who receives what it shares; null unless it covers you now.",
19290
+ "anyOf": [{
19291
+ "type": "object",
19292
+ "properties": {
19293
+ "keys": {
19294
+ "type": "array",
19295
+ "items": {
19296
+ "type": "object",
19297
+ "properties": {
19298
+ "owner": { "anyOf": [{
19299
+ "type": "object",
19300
+ "properties": {
19301
+ "kind": {
19302
+ "type": "string",
19303
+ "const": "member"
19304
+ },
19305
+ "user_id": {
19306
+ "type": "string",
19307
+ "description": "The member's user id.",
19308
+ "format": "uuid"
19309
+ },
19310
+ "name": {
19311
+ "description": "Their name; null when they have none set.",
19312
+ "type": ["string", "null"]
19313
+ }
19314
+ },
19315
+ "required": [
19316
+ "kind",
19317
+ "user_id",
19318
+ "name"
19319
+ ]
19320
+ }, {
19321
+ "type": "object",
19322
+ "properties": { "kind": {
19323
+ "type": "string",
19324
+ "const": "organization",
19325
+ "description": "Held by no member: an organization key, or one whose holder has left."
19326
+ } },
19327
+ "required": ["kind"]
19328
+ }] },
19329
+ "count": {
19330
+ "type": "integer",
19331
+ "exclusiveMinimum": 0
19332
+ }
19333
+ },
19334
+ "required": ["owner", "count"]
19335
+ },
19336
+ "description": "API keys that work now (not revoked, expired or suspended) and hold mail:read, whose access lists the rule or its live share. Owner: who holds each, or the organization."
19337
+ },
19338
+ "webhooks": {
19339
+ "type": "array",
19340
+ "items": {
19341
+ "type": "object",
19342
+ "properties": {
19343
+ "owner": { "anyOf": [{
19344
+ "type": "object",
19345
+ "properties": {
19346
+ "kind": {
19347
+ "type": "string",
19348
+ "const": "member"
19349
+ },
19350
+ "user_id": {
19351
+ "type": "string",
19352
+ "description": "The member's user id.",
19353
+ "format": "uuid"
19354
+ },
19355
+ "name": {
19356
+ "description": "Their name; null when they have none set.",
19357
+ "type": ["string", "null"]
19358
+ }
19359
+ },
19360
+ "required": [
19361
+ "kind",
19362
+ "user_id",
19363
+ "name"
19364
+ ]
19365
+ }, {
19366
+ "type": "object",
19367
+ "properties": { "kind": {
19368
+ "type": "string",
19369
+ "const": "organization",
19370
+ "description": "Held by no member: an organization key, or one whose holder has left."
19371
+ } },
19372
+ "required": ["kind"]
19373
+ }] },
19374
+ "count": {
19375
+ "type": "integer",
19376
+ "exclusiveMinimum": 0
19377
+ },
19378
+ "hosts": {
19379
+ "description": "Distinct sites they deliver to (a host's registrable domain, or a tunnel, preview or function service alone), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
19380
+ "type": "array",
19381
+ "items": { "type": "string" }
19382
+ },
19383
+ "hosts_not_listed": {
19384
+ "description": "Hosts past those listed.",
19385
+ "type": "integer",
19386
+ "minimum": 0
19387
+ }
19388
+ },
19389
+ "required": ["owner", "count"]
19390
+ },
19391
+ "description": "Webhooks taking received mail, bounces or reports that are sent what it matches: those of the key delivery acts as, when it lists the rule or its live share (owner: its holder, or the organization), and those of the member it is shared with (owner: that member)."
19392
+ },
19393
+ "shares": {
19394
+ "type": "array",
19395
+ "items": {
19396
+ "type": "object",
19397
+ "properties": {
19398
+ "beneficiary": {
19399
+ "type": "object",
19400
+ "properties": {
19401
+ "kind": {
19402
+ "type": "string",
19403
+ "const": "member"
19404
+ },
19405
+ "user_id": {
19406
+ "type": "string",
19407
+ "description": "The member's user id.",
19408
+ "format": "uuid"
19409
+ },
19410
+ "name": {
19411
+ "description": "Their name; null when they have none set.",
19412
+ "type": ["string", "null"]
19413
+ }
19414
+ },
19415
+ "required": [
19416
+ "kind",
19417
+ "user_id",
19418
+ "name"
19419
+ ]
19420
+ },
19421
+ "count": {
19422
+ "type": "integer",
19423
+ "exclusiveMinimum": 0
19424
+ }
19425
+ },
19426
+ "required": ["beneficiary", "count"]
19427
+ },
19428
+ "description": "The rule's live share (at most one), by its member, if they can read it and it is among their newest 20 shares."
19429
+ }
19430
+ },
19431
+ "required": [
19432
+ "keys",
19433
+ "webhooks",
19434
+ "shares"
19435
+ ],
19436
+ "description": "Who receives what the rule shares now, by person and count; empty unless it is an active grant rule."
19437
+ }, { "type": "null" }]
18737
19438
  }
18738
19439
  },
18739
19440
  "required": [
@@ -18817,7 +19518,7 @@ const operationManifest = [
18817
19518
  "binaryResponse": false,
18818
19519
  "bodyRequired": false,
18819
19520
  "command": "list-email-rule-scope-options",
18820
- "description": "How much the caller can read, and the inboxes and domains the caller can read, which is what they may name when a rule runs over selected inboxes and domains. For a caller who reads the whole organization, addresses lists the inboxes known as someone's (member addresses, members' verified work emails at the organization's domains, agents' addresses and inboxes with shared access), not every address that receives mail: may_name_unlisted says when an address that is not listed, such as an inbox nobody has claimed, may be named too. 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.",
19521
+ "description": "How much the caller can read, and the inboxes and domains the caller can read, which is what they may name when a rule runs over selected inboxes and domains. For a caller who reads the whole organization, addresses lists the inboxes known as someone's (member addresses, members' verified work emails at the organization's domains, agents' addresses and inboxes with shared access), not every address that receives mail: may_name_unlisted says when an address that is not listed, such as an inbox nobody has claimed, may be named too. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
18821
19522
  "hasJsonBody": false,
18822
19523
  "method": "GET",
18823
19524
  "operationId": "listEmailRuleScopeOptions",
@@ -18927,6 +19628,34 @@ const operationManifest = [
18927
19628
  "items": {
18928
19629
  "type": "object",
18929
19630
  "properties": {
19631
+ "imported": {
19632
+ "type": ["object", "null"],
19633
+ "properties": {
19634
+ "from": {
19635
+ "type": "string",
19636
+ "const": "google_workspace"
19637
+ },
19638
+ "method": {
19639
+ "type": "string",
19640
+ "const": "primitive_direct"
19641
+ },
19642
+ "verification": {
19643
+ "type": "string",
19644
+ "const": "provider_fetched"
19645
+ },
19646
+ "at": {
19647
+ "type": "string",
19648
+ "format": "date-time"
19649
+ }
19650
+ },
19651
+ "required": [
19652
+ "from",
19653
+ "method",
19654
+ "verification",
19655
+ "at"
19656
+ ],
19657
+ "default": null
19658
+ },
18930
19659
  "delivery_report": {
18931
19660
  "type": ["object", "null"],
18932
19661
  "properties": {
@@ -19164,6 +19893,7 @@ const operationManifest = [
19164
19893
  }
19165
19894
  },
19166
19895
  "required": [
19896
+ "imported",
19167
19897
  "id",
19168
19898
  "message_id",
19169
19899
  "domain_id",
@@ -19202,7 +19932,7 @@ const operationManifest = [
19202
19932
  "binaryResponse": false,
19203
19933
  "bodyRequired": false,
19204
19934
  "command": "list-email-rule-shares",
19205
- "description": "Lists rules shared with you, rules you share, or every share you can see. A share is visible to its two people 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.",
19935
+ "description": "Lists rules shared with you, rules you share, or every share you can see. A share is visible to its two people and the organization's owners and admins. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
19206
19936
  "hasJsonBody": false,
19207
19937
  "method": "GET",
19208
19938
  "operationId": "listEmailRuleShares",
@@ -19424,7 +20154,7 @@ const operationManifest = [
19424
20154
  "binaryResponse": false,
19425
20155
  "bodyRequired": false,
19426
20156
  "command": "list-email-rule-versions",
19427
- "description": "A rule's versions as they were written: what each one's conditions and questions were, so a decision can be read against the version that made it. Without versions, every version newest first, a page at a time (meta.cursor). With versions, only those named, oldest first; numbers that are not versions of the rule are left out. 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.",
20157
+ "description": "A rule's versions as they were written: what each one's conditions and questions were, so a decision can be read against the version that made it. Without versions, every version newest first, a page at a time (meta.cursor). With versions, only those named, oldest first; numbers that are not versions of the rule are left out. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
19428
20158
  "hasJsonBody": false,
19429
20159
  "method": "GET",
19430
20160
  "operationId": "listEmailRuleVersions",
@@ -19562,7 +20292,7 @@ const operationManifest = [
19562
20292
  "binaryResponse": false,
19563
20293
  "bodyRequired": false,
19564
20294
  "command": "list-email-rules",
19565
- "description": "The rules the caller can see, newest first: their own, or every member's rules for a caller who reads the whole organization's mail. Each carries its scope (evaluation_scope, and scope_selection for a selected rule) and current_version, but not the version's text: read that under current from GET /email-rules/{id}. With matched_email_id, only the rules that matched that email. 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.",
20295
+ "description": "The rules the caller can see, newest first: their own, or every member's rules for a caller who reads the whole organization's mail. Each carries its scope (evaluation_scope, and scope_selection for a selected rule) and current_version, but not the version's text: read that under current from GET /email-rules/{id}. With matched_email_id, only the rules that matched that email. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
19566
20296
  "hasJsonBody": false,
19567
20297
  "method": "GET",
19568
20298
  "operationId": "listEmailRules",
@@ -19930,7 +20660,7 @@ const operationManifest = [
19930
20660
  "binaryResponse": false,
19931
20661
  "bodyRequired": true,
19932
20662
  "command": "test-email-rule",
19933
- "description": "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 of how each top-level condition and question decided. Test an unsaved tree, or a saved rule by rule_id (its current version, as its author). It reads only mail its author can read and its scope covers. Without email_ids it tests the newest emails, at most 200 and none older than 30 days, plus any expected ones. Unclassified emails over 2 hours old are classified first unless classify_missing is false. It records no decision and grants nothing, and stops at about 90 seconds. 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.",
20663
+ "description": "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 of how each top-level condition and question decided. Test an unsaved tree, or a saved rule by rule_id (its current version, as its author). It reads only mail its author can read and its scope covers. A rule you see only because it covers your own mailboxes runs as you, over only those, from the dashboard or the Primitive CLI. Without email_ids it tests the newest emails, at most 200 and none older than 30 days, plus any expected ones. Unclassified emails over 2 hours old are classified first unless classify_missing is false. It records no decision and grants nothing, and stops at about 90 seconds. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
19934
20664
  "hasJsonBody": true,
19935
20665
  "method": "POST",
19936
20666
  "operationId": "testEmailRule",
@@ -20016,7 +20746,7 @@ const operationManifest = [
20016
20746
  "description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
20017
20747
  },
20018
20748
  "rule_id": {
20019
- "description": "A saved rule you can see. Its current version is tested, with its author's access.",
20749
+ "description": "A saved rule you can see. Its current version is tested, with its author's access; one you see only because it covers your mailboxes, with yours, over only those (dashboard or Primitive CLI only).",
20020
20750
  "type": "string",
20021
20751
  "format": "uuid"
20022
20752
  },
@@ -20183,7 +20913,16 @@ const operationManifest = [
20183
20913
  "type": ["integer", "null"],
20184
20914
  "exclusiveMinimum": 0
20185
20915
  },
20186
- "vocabulary": { "type": "string" }
20916
+ "vocabulary": { "type": "string" },
20917
+ "kind": {
20918
+ "description": "The kind it was tested as.",
20919
+ "type": "string",
20920
+ "enum": ["grant", "do_not_share"]
20921
+ },
20922
+ "note": {
20923
+ "description": "Present when a tree was sent without kind, so it was tested as grant.",
20924
+ "type": "string"
20925
+ }
20187
20926
  },
20188
20927
  "required": [
20189
20928
  "id",
@@ -20708,7 +21447,7 @@ const operationManifest = [
20708
21447
  "binaryResponse": false,
20709
21448
  "bodyRequired": true,
20710
21449
  "command": "test-email-rule-on-sample",
20711
- "description": "Reports what a rule would decide for an email you describe (sender, recipients, subject, plain text, attachment types; optionally automated, from a mailing list, and a spam score), classified and decided as received mail would be. A rule reading a spam score you gave none for decides on none (unset_columns). Nothing is stored. Test an unsaved tree or a saved rule by rule_id. The answer includes what the classifier read. 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.",
21450
+ "description": "Reports what a rule would decide for an email you describe (sender, recipients, subject, plain text, attachment types; optionally automated, from a mailing list, and a spam score), classified and decided as received mail would be. A rule reading a spam score you gave none for decides on none (unset_columns). Nothing is stored. Test an unsaved tree or a saved rule by rule_id. The answer includes what the classifier read. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
20712
21451
  "hasJsonBody": true,
20713
21452
  "method": "POST",
20714
21453
  "operationId": "testEmailRuleOnSample",
@@ -20906,7 +21645,16 @@ const operationManifest = [
20906
21645
  "type": ["integer", "null"],
20907
21646
  "exclusiveMinimum": 0
20908
21647
  },
20909
- "vocabulary": { "type": "string" }
21648
+ "vocabulary": { "type": "string" },
21649
+ "kind": {
21650
+ "description": "The kind it was tested as.",
21651
+ "type": "string",
21652
+ "enum": ["grant", "do_not_share"]
21653
+ },
21654
+ "note": {
21655
+ "description": "Present when a tree was sent without kind, so it was tested as grant.",
21656
+ "type": "string"
21657
+ }
20910
21658
  },
20911
21659
  "required": [
20912
21660
  "id",
@@ -21055,7 +21803,7 @@ const operationManifest = [
21055
21803
  "binaryResponse": false,
21056
21804
  "bodyRequired": true,
21057
21805
  "command": "update-email-rule",
21058
- "description": "Renames the rule, saves a new version (english and tree together; earlier versions stay) or restores one (restore_version), changes its state (draft is off; observe; active), its scope (evaluation_scope, with scope_selection when selected) or its saved expectations (judged in expectations_check). Anyone but its author who sees it may only set state draft, and while it is shared only if they manage members from the dashboard. A scope change saves a new version; a shared rule keeps its scope, and a kind never changes. A saved version takes effect at once. if_version refuses a write once a version was saved since you read it; if_revision, once anything changed. Without if_expectations_pass a version is saved even when its expectations fail. 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.",
21806
+ "description": "Renames the rule, saves a new version (english and tree together; earlier versions stay) or restores one (restore_version), changes its state (draft is off; observe; active), its scope (evaluation_scope, with scope_selection when selected) or its saved expectations (judged in expectations_check). Anyone but its author who sees it may only set state draft, and while it is shared only if they manage members from the dashboard. A scope change saves a new version; a shared rule keeps its scope, and a kind never changes. A saved version takes effect at once. if_version refuses a write once a version was saved since you read it; if_revision, once anything changed. Without if_expectations_pass a version is saved even when its expectations fail, except on an active rule keys or webhooks read: that write is checked first unless if_expectations_pass is false. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
21059
21807
  "hasJsonBody": true,
21060
21808
  "method": "PATCH",
21061
21809
  "operationId": "updateEmailRule",
@@ -21142,7 +21890,7 @@ const operationManifest = [
21142
21890
  }
21143
21891
  },
21144
21892
  "warnings": {
21145
- "description": "The compile response's warnings. Stored as sent.",
21893
+ "description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
21146
21894
  "maxItems": 10,
21147
21895
  "type": "array",
21148
21896
  "items": {
@@ -21176,6 +21924,30 @@ const operationManifest = [
21176
21924
  "required": ["checked", "matched"]
21177
21925
  }, { "type": "null" }]
21178
21926
  },
21927
+ "conditions_breadth": {
21928
+ "description": "Ignored.",
21929
+ "anyOf": [{
21930
+ "type": "object",
21931
+ "properties": {
21932
+ "checked": {
21933
+ "type": "integer",
21934
+ "minimum": 0,
21935
+ "description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes (for a grant rule, those you may share), the ones you can still read."
21936
+ },
21937
+ "matched": {
21938
+ "type": "integer",
21939
+ "minimum": 0,
21940
+ "description": "Of those, how many they hold for (for a do-not-share rule, one they cannot decide counts)."
21941
+ }
21942
+ },
21943
+ "required": ["checked", "matched"]
21944
+ }, { "type": "null" }]
21945
+ },
21946
+ "kind": {
21947
+ "description": "Must be the rule's own (400 kind_mismatch).",
21948
+ "type": "string",
21949
+ "enum": ["grant", "do_not_share"]
21950
+ },
21179
21951
  "evaluation_scope": {
21180
21952
  "type": "string",
21181
21953
  "enum": [
@@ -21458,7 +22230,7 @@ const operationManifest = [
21458
22230
  "maximum": 2147483647
21459
22231
  },
21460
22232
  "if_expectations_pass": {
21461
- "description": "true: judge the rule as this write leaves it (new tree, restored version, new scope, or the version it activates) against the expectations it leaves, as POST /email-rules/test would, before saving; it can take as long as a test. Failed: 409 expectations_failed; on emails the rule cannot read: 409 expectations_unreadable; undecided: 409 expectations_undecided (each with details.expectations_check); none to judge: 400 no_expectations. Refused writes save nothing; a pass saves unless the rule moved meanwhile (409 email_rule_conflict). Only writes that save a version or activate the rule are judged.",
22233
+ "description": "true: judge the rule as this write leaves it (new tree, restored version, new scope, or the version it activates) against the expectations it leaves, as POST /email-rules/test would, before saving; it can take as long as a test. Failed: 409 expectations_failed; on emails the rule cannot read: 409 expectations_unreadable; undecided: 409 expectations_undecided (each with details.expectations_check); none to judge: 400 no_expectations. Refused writes save nothing; a pass saves unless the rule moved meanwhile (409 email_rule_conflict). Only writes that save a version or activate the rule are judged. Omitted: judged as with true when the write saves a version or changes the scope of an active rule that API keys or webhooks read and that has expectations. false: never judged first.",
21462
22234
  "type": "boolean"
21463
22235
  },
21464
22236
  "restore_version": {
@@ -21884,6 +22656,10 @@ const operationManifest = [
21884
22656
  "endpoints",
21885
22657
  "shares_ended"
21886
22658
  ]
22659
+ },
22660
+ "notice": {
22661
+ "description": "After a write that saved a version of an active rule keys or webhooks read without checking it first: what it changes, and how to have the next one checked.",
22662
+ "type": "string"
21887
22663
  }
21888
22664
  },
21889
22665
  "required": [
@@ -21907,7 +22683,7 @@ const operationManifest = [
21907
22683
  "binaryResponse": false,
21908
22684
  "bodyRequired": false,
21909
22685
  "command": "withdraw-email-rule-request",
21910
- "description": "Withdraws a pending request you made. 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.",
22686
+ "description": "Withdraws a pending request you made. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
21911
22687
  "hasJsonBody": false,
21912
22688
  "method": "POST",
21913
22689
  "operationId": "withdrawEmailRuleRequest",
@@ -21986,7 +22762,16 @@ const operationManifest = [
21986
22762
  "warnings": {
21987
22763
  "type": "array",
21988
22764
  "items": { "type": "string" },
21989
- "description": "As the member who asked sent them, normally from their compile. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
22765
+ "description": "As the member who asked sent them, normally from their compile, then every compiler note on the rule's tree and words they lack. The compiler's note that the rule matches nearly everything, in its own wording, counted that member's recent mail: anyone else reads it naming them."
22766
+ },
22767
+ "server_explanation": {
22768
+ "description": "What the rule as asked actually does: Primitive's own reading of the request's tree, never the words of the member who asked or of a model. Null when the tree no longer reads as one.",
22769
+ "type": ["string", "null"]
22770
+ },
22771
+ "server_notes": {
22772
+ "description": "Primitive's own notes on the rule as asked, worked out from its tree and description each time the request is read, and to the member asked while pending, how to test it on look-alikes. Unlike warnings, never written by the member who asked, though a note can quote their words or tree values.",
22773
+ "type": "array",
22774
+ "items": { "type": "string" }
21990
22775
  },
21991
22776
  "compiled_by": { "type": "string" },
21992
22777
  "vocabulary": { "type": "string" },
@@ -22083,7 +22868,7 @@ const operationManifest = [
22083
22868
  "type": ["boolean", "null"]
22084
22869
  },
22085
22870
  "notice": {
22086
- "description": "For the member asked, while pending: what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
22871
+ "description": "For the member asked, while pending: what the rule actually does (server_explanation), Primitive's warnings, then what accepting would share. For the member who asked, once accepted with changes: that the request is not what is shared. Else null.",
22087
22872
  "type": ["string", "null"]
22088
22873
  }
22089
22874
  },
@@ -22595,6 +23380,35 @@ const operationManifest = [
22595
23380
  },
22596
23381
  "description": "Attachment metadata for this message, each item as its own detail read reports it: `parsed.attachments` on `/emails/{id}` for inbound, `attachments` on `/sent-emails/{id}` for outbound, in the same order. Empty when there are none or an inbound message has no parsed content. No bytes or download URLs; download a part with `/emails/{id}/attachments/{part_index}` or `/sent-emails/{id}/attachments/{part_index}`."
22597
23382
  },
23383
+ "imported": {
23384
+ "type": ["object", "null"],
23385
+ "description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
23386
+ "required": [
23387
+ "from",
23388
+ "method",
23389
+ "verification",
23390
+ "at"
23391
+ ],
23392
+ "properties": {
23393
+ "from": {
23394
+ "type": "string",
23395
+ "enum": ["google_workspace"]
23396
+ },
23397
+ "method": {
23398
+ "type": "string",
23399
+ "enum": ["primitive_direct"]
23400
+ },
23401
+ "verification": {
23402
+ "type": "string",
23403
+ "enum": ["provider_fetched"]
23404
+ },
23405
+ "at": {
23406
+ "type": "string",
23407
+ "format": "date-time",
23408
+ "description": "When Primitive acquired this historical message."
23409
+ }
23410
+ }
23411
+ },
22598
23412
  "copies": {
22599
23413
  "type": "array",
22600
23414
  "items": {
@@ -23458,6 +24272,35 @@ const operationManifest = [
23458
24272
  }
23459
24273
  }
23460
24274
  },
24275
+ "imported": {
24276
+ "type": ["object", "null"],
24277
+ "description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
24278
+ "required": [
24279
+ "from",
24280
+ "method",
24281
+ "verification",
24282
+ "at"
24283
+ ],
24284
+ "properties": {
24285
+ "from": {
24286
+ "type": "string",
24287
+ "enum": ["google_workspace"]
24288
+ },
24289
+ "method": {
24290
+ "type": "string",
24291
+ "enum": ["primitive_direct"]
24292
+ },
24293
+ "verification": {
24294
+ "type": "string",
24295
+ "enum": ["provider_fetched"]
24296
+ },
24297
+ "at": {
24298
+ "type": "string",
24299
+ "format": "date-time",
24300
+ "description": "When Primitive acquired this historical message."
24301
+ }
24302
+ }
24303
+ },
23461
24304
  "snippet": {
23462
24305
  "type": ["string", "null"],
23463
24306
  "maxLength": 200,
@@ -23487,6 +24330,7 @@ const operationManifest = [
23487
24330
  "from_verified",
23488
24331
  "from_header_email",
23489
24332
  "from_name",
24333
+ "imported",
23490
24334
  "snippet"
23491
24335
  ]
23492
24336
  },
@@ -23547,6 +24391,7 @@ const operationManifest = [
23547
24391
  "type": "object",
23548
24392
  "description": "What an inbound email says, as plain text, with the fields that identify it.",
23549
24393
  "required": [
24394
+ "imported",
23550
24395
  "id",
23551
24396
  "thread_id",
23552
24397
  "received_at",
@@ -23567,6 +24412,35 @@ const operationManifest = [
23567
24412
  "attachments"
23568
24413
  ],
23569
24414
  "properties": {
24415
+ "imported": {
24416
+ "type": ["object", "null"],
24417
+ "description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
24418
+ "required": [
24419
+ "from",
24420
+ "method",
24421
+ "verification",
24422
+ "at"
24423
+ ],
24424
+ "properties": {
24425
+ "from": {
24426
+ "type": "string",
24427
+ "enum": ["google_workspace"]
24428
+ },
24429
+ "method": {
24430
+ "type": "string",
24431
+ "enum": ["primitive_direct"]
24432
+ },
24433
+ "verification": {
24434
+ "type": "string",
24435
+ "enum": ["provider_fetched"]
24436
+ },
24437
+ "at": {
24438
+ "type": "string",
24439
+ "format": "date-time",
24440
+ "description": "When Primitive acquired this historical message."
24441
+ }
24442
+ }
24443
+ },
23570
24444
  "id": {
23571
24445
  "type": "string",
23572
24446
  "format": "uuid",
@@ -24371,6 +25245,35 @@ const operationManifest = [
24371
25245
  "format": "uuid",
24372
25246
  "description": "With `group=message`: the send of this message, when you can read it (under a connected agent key, only its own sends)."
24373
25247
  },
25248
+ "imported": {
25249
+ "type": ["object", "null"],
25250
+ "description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
25251
+ "required": [
25252
+ "from",
25253
+ "method",
25254
+ "verification",
25255
+ "at"
25256
+ ],
25257
+ "properties": {
25258
+ "from": {
25259
+ "type": "string",
25260
+ "enum": ["google_workspace"]
25261
+ },
25262
+ "method": {
25263
+ "type": "string",
25264
+ "enum": ["primitive_direct"]
25265
+ },
25266
+ "verification": {
25267
+ "type": "string",
25268
+ "enum": ["provider_fetched"]
25269
+ },
25270
+ "at": {
25271
+ "type": "string",
25272
+ "format": "date-time",
25273
+ "description": "When Primitive acquired this historical message."
25274
+ }
25275
+ }
25276
+ },
24374
25277
  "snippet": {
24375
25278
  "type": ["string", "null"],
24376
25279
  "maxLength": 200,
@@ -24393,6 +25296,7 @@ const operationManifest = [
24393
25296
  "automated_reasons",
24394
25297
  "from_verified",
24395
25298
  "from_header_email",
25299
+ "imported",
24396
25300
  "snippet"
24397
25301
  ]
24398
25302
  }
@@ -25032,6 +25936,35 @@ const operationManifest = [
25032
25936
  "format": "uuid",
25033
25937
  "description": "With `group=message`: the send of this message, when you can read it (under a connected agent key, only its own sends)."
25034
25938
  },
25939
+ "imported": {
25940
+ "type": ["object", "null"],
25941
+ "description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
25942
+ "required": [
25943
+ "from",
25944
+ "method",
25945
+ "verification",
25946
+ "at"
25947
+ ],
25948
+ "properties": {
25949
+ "from": {
25950
+ "type": "string",
25951
+ "enum": ["google_workspace"]
25952
+ },
25953
+ "method": {
25954
+ "type": "string",
25955
+ "enum": ["primitive_direct"]
25956
+ },
25957
+ "verification": {
25958
+ "type": "string",
25959
+ "enum": ["provider_fetched"]
25960
+ },
25961
+ "at": {
25962
+ "type": "string",
25963
+ "format": "date-time",
25964
+ "description": "When Primitive acquired this historical message."
25965
+ }
25966
+ }
25967
+ },
25035
25968
  "snippet": {
25036
25969
  "type": ["string", "null"],
25037
25970
  "maxLength": 200,
@@ -25054,6 +25987,7 @@ const operationManifest = [
25054
25987
  "automated_reasons",
25055
25988
  "from_verified",
25056
25989
  "from_header_email",
25990
+ "imported",
25057
25991
  "snippet"
25058
25992
  ]
25059
25993
  }, {
@@ -25512,7 +26446,7 @@ const operationManifest = [
25512
26446
  }
25513
26447
  }
25514
26448
  },
25515
- "responseSchema": {
26449
+ "responseSchema": { "allOf": [{
25516
26450
  "type": "object",
25517
26451
  "properties": {
25518
26452
  "recipient": {
@@ -25778,7 +26712,28 @@ const operationManifest = [
25778
26712
  "failure_count",
25779
26713
  "consecutive_fails"
25780
26714
  ]
25781
- },
26715
+ }, {
26716
+ "type": "object",
26717
+ "properties": { "warnings": {
26718
+ "description": "For a webhook (kind http). same_path_as_another_endpoint: another webhook you can see, on and not deleted, sends to the same scheme, host and path with any query string, so each email both receive is delivered twice; endpoint_id names it (at most 5, newest first). The URL is never echoed. Empty when none; absent when it could not be checked (a caller who may not read endpoints, or a failed read). Other codes may be added.",
26719
+ "type": "array",
26720
+ "items": {
26721
+ "type": "object",
26722
+ "properties": {
26723
+ "code": { "type": "string" },
26724
+ "message": { "type": "string" },
26725
+ "endpoint_id": {
26726
+ "description": "The other webhook a same_path_as_another_endpoint warning names.",
26727
+ "type": "string",
26728
+ "format": "uuid",
26729
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
26730
+ }
26731
+ },
26732
+ "required": ["code", "message"],
26733
+ "additionalProperties": {}
26734
+ }
26735
+ } }
26736
+ }] },
25782
26737
  "sdkName": "createEndpoint",
25783
26738
  "summary": "Create a webhook endpoint",
25784
26739
  "tag": "Endpoints",
@@ -26627,8 +27582,8 @@ const operationManifest = [
26627
27582
  "description": "HTTP status code returned by the endpoint"
26628
27583
  },
26629
27584
  "body": {
26630
- "type": "string",
26631
- "description": "Response body (truncated to 1000 characters)"
27585
+ "description": "The receiver response text, only with organization-wide mail.raw:read. Null without that access because a receiver can echo a raw download link.",
27586
+ "type": ["string", "null"]
26632
27587
  },
26633
27588
  "signature": {
26634
27589
  "type": "string",
@@ -38441,7 +39396,7 @@ const operationManifest = [
38441
39396
  "binaryResponse": false,
38442
39397
  "bodyRequired": false,
38443
39398
  "command": "get-relay-auto-join",
38444
- "description": "Whether someone who proves an address on the organization's mail relay domain with Google Workspace joins automatically, and with what access. `option` is null when auto-join is off and an invitation is required; `options` lists the choices. Answers 404 `feature_disabled` unless the organization has mail relay.",
39399
+ "description": "Whether someone who proves an address on the organization's mail relay domain with Google Workspace joins automatically. Auto-joined people have no mail access until an owner or admin assigns a role. `option` is null when auto-join is off and an invitation is required; legacy mail-grant settings read as `no_access`. `options` lists the choices. Answers 404 `feature_disabled` unless the organization has mail relay.",
38445
39400
  "hasJsonBody": false,
38446
39401
  "method": "GET",
38447
39402
  "operationId": "getRelayAutoJoin",
@@ -39250,7 +40205,7 @@ const operationManifest = [
39250
40205
  "binaryResponse": false,
39251
40206
  "bodyRequired": true,
39252
40207
  "command": "set-relay-auto-join",
39253
- "description": "`option` is a choice's id from the GET, or null to require an invitation (turning it off needs only members:manage). Choosing an option answers 404 `feature_disabled` unless the organization has mail relay, 400 `validation_error` for an id that is not one of the choices, 403 `grant_forbidden` unless the caller is an owner or admin who can assign roles and send invitations and covers the role the option gives, 409 `role_key_taken` when a custom role already holds that role's key, and 409 `role_assignment_unavailable` when the organization cannot be given that role yet. Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `relay_auto_join.write` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs members:manage, and roles:assign to turn it on. API keys are refused.",
40208
+ "description": "`option` is a choice's id from the GET, or null to require an invitation (turning it off needs only members:manage). Auto-joined people have no mail access until an owner or admin assigns a role; legacy mail-grant choices cannot be selected. Choosing an option answers 404 `feature_disabled` unless the organization has mail relay, 400 `validation_error` for an id outside the current catalog, 403 `grant_forbidden` without owner or admin assignment authority, and 409 `role_assignment_unavailable` when the restricted role cannot be assigned yet. Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `relay_auto_join.write` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs members:manage, and roles:assign to turn it on. API keys are refused.",
39254
40209
  "hasJsonBody": true,
39255
40210
  "method": "PUT",
39256
40211
  "operationId": "setRelayAutoJoin",
@@ -52645,18 +53600,19 @@ function emptyEmailListHint(input) {
52645
53600
  }
52646
53601
  // src/oclif/endpoint-event-types.ts
52647
53602
  const EVENT_TYPES_FLAG_OPERATIONS = /* @__PURE__ */ new Set(["createEndpoint", "updateEndpoint"]);
52648
- const EVENT_TYPES_FLAG_DESCRIPTION = "Event types this endpoint subscribes to, comma separated or repeated (sets rules.event_types). Omitting the subscription means every event type except the opt-in sent_email.* and email_rule_request.* events, which an endpoint receives only when it lists them; sent_email.* and email_rule_request.* each expand to all four. Rule request events can be listed only when the webhook is created, signed in as yourself; such a webhook is yours and always a route target. Keep email.received in the list if the endpoint also handles inbound mail. On update, the endpoint's other rules are kept.";
53603
+ const EVENT_TYPES_FLAG_DESCRIPTION = "Event types this endpoint subscribes to, comma separated or repeated (sets rules.event_types). Omitting the subscription means every event type except the opt-in sent_email.*, email_rule_request.* and email_rule_objection.* events, which an endpoint receives only when it lists them; each of those shorthands expands to all four. Rule request and objection events can be listed only when the webhook is created, signed in as yourself; such a webhook is yours and always a route target. Keep email.received in the list if the endpoint also handles inbound mail. On update, the endpoint's other rules are kept.";
52649
53604
  /** Shorthands the CLI expands, since the server would store them as literals that match nothing. */
52650
53605
  const WILDCARDS = {
52651
53606
  "sent_email.*": SENT_EMAIL_EVENT_TYPES,
52652
- "email_rule_request.*": EMAIL_RULE_REQUEST_EVENT_TYPES
53607
+ "email_rule_request.*": EMAIL_RULE_REQUEST_EVENT_TYPES,
53608
+ "email_rule_objection.*": EMAIL_RULE_OBJECTION_EVENT_TYPES
52653
53609
  };
52654
53610
  const KNOWN_EVENT_TYPES = new Set(WEBHOOK_EVENT_TYPES);
52655
53611
  var EventTypesFlagError = class extends Error {};
52656
53612
  /**
52657
53613
  * Turn the raw `--event-types` values into the list to store: split on
52658
- * commas, trim, expand `sent_email.*` and `email_rule_request.*`, and drop duplicates while keeping the
52659
- * order the caller gave.
53614
+ * commas, trim, expand the shorthands in WILDCARDS, and drop duplicates while
53615
+ * keeping the order the caller gave.
52660
53616
  */
52661
53617
  function parseEventTypesFlag(values) {
52662
53618
  const out = [];
@@ -52671,7 +53627,7 @@ function parseEventTypesFlag(values) {
52671
53627
  out.push(entry);
52672
53628
  }
52673
53629
  }
52674
- if (out.length === 0) throw new EventTypesFlagError("--event-types needs at least one event type. To receive every event type except the opt-in sent_email.* and email_rule_request.* events, omit the subscription instead.");
53630
+ if (out.length === 0) throw new EventTypesFlagError("--event-types needs at least one event type. To receive every event type except the opt-in sent_email.*, email_rule_request.* and email_rule_objection.* events, omit the subscription instead.");
52675
53631
  if (out.length > 50) throw new EventTypesFlagError(`--event-types accepts at most 50 event types (got ${out.length}).`);
52676
53632
  return out;
52677
53633
  }
@@ -54574,7 +55530,7 @@ function savedConnectedProfiles(configDir, exclude) {
54574
55530
  */
54575
55531
  async function otherProfiles(configDir, session, current) {
54576
55532
  if (session) try {
54577
- const { connectedProfilesForSession } = await import("./machine-session-CI8tnGzz.js").then((n) => n.s);
55533
+ const { connectedProfilesForSession } = await import("./machine-session-DkXYR62a.js").then((n) => n.s);
54578
55534
  return {
54579
55535
  inSession: true,
54580
55536
  profiles: connectedProfilesForSession(configDir, session, current)
@@ -54648,24 +55604,25 @@ async function explainPendingMailNotFound(configDir, emailId, write = (line) =>
54648
55604
  if (outcome.kind === "dropped") write(`Dropped the pending notice for ${id} from profile ${current.profile} after ${outcome.reads} consecutive not_found reads; the email is no longer visible to this profile.\n`);
54649
55605
  } catch {}
54650
55606
  }
54651
- const RULE_REQUEST_WEBHOOK_CREATE_HINT = "Hint: a webhook for rule request events is made by the person it is for, signed in as themself: after `primitive login`, run this without --api-key, PRIMITIVE_API_KEY or PRIMITIVE_AGENT_PROFILE set, or create it in the dashboard. An API key, another app or an agent cannot make one. If you are already signed in as yourself, try again. It is a route target whatever your access, so it never takes a domain's or the organization's default slot.";
54652
- const RULE_REQUEST_WEBHOOK_HTTP_HINT = "Hint: rule request events go only to an http webhook (kind http).";
54653
- const RULE_REQUEST_WEBHOOK_SUBSCRIBE_HINT = "Hint: rule request events go only to a webhook made for them. If this webhook does not list them yet, it cannot be given them: create a new one with `--event-types 'email_rule_request.*'`, signed in as yourself. If it does, only its maker, signed in as themself, can change it.";
54654
- const RULE_REQUEST_WEBHOOK_KEY_HINT = "Hint: a webhook for rule request events is made by the person it is for, signed in as themself, and stays theirs: it cannot be given to an API key.";
54655
- const RULE_REQUEST_WEBHOOK_CHANGE_HINT = "Hint: only the person who made a webhook for rule request events, signed in as themself (not with an API key, another app or an agent), can change it. It can be deleted as any other webhook can.";
54656
- const RULE_REQUEST_WEBHOOK_DEFAULT_HINT = "Hint: a webhook for rule request events is always a route target. Leave out --no-is-route-target, --takeover and --no-takeover (is_route_target: false and takeover in a raw body).";
54657
- const RULE_REQUEST_EVENT_PREFIX = "email_rule_request.";
55607
+ const RULE_REQUEST_WEBHOOK_CREATE_HINT = "Hint: a webhook for rule request or objection events is made by the person it is for, signed in as themself: after `primitive login`, run this without --api-key, PRIMITIVE_API_KEY or PRIMITIVE_AGENT_PROFILE set, or create it in the dashboard. An API key, another app or an agent cannot make one. If you are already signed in as yourself, try again. It is a route target whatever your access, so it never takes a domain's or the organization's default slot.";
55608
+ const RULE_REQUEST_WEBHOOK_HTTP_HINT = "Hint: rule request and objection events go only to an http webhook (kind http).";
55609
+ const RULE_REQUEST_WEBHOOK_SUBSCRIBE_HINT = "Hint: rule request and objection events go only to a webhook made for them. If this webhook does not list them yet, it cannot be given them: create a new one with `--event-types` naming them (such as 'email_rule_request.*' or 'email_rule_objection.*'), signed in as yourself. If it does, only its maker, signed in as themself, can change it.";
55610
+ const RULE_REQUEST_WEBHOOK_KEY_HINT = "Hint: a webhook for rule request or objection events is made by the person it is for, signed in as themself, and stays theirs: it cannot be given to an API key.";
55611
+ const RULE_REQUEST_WEBHOOK_CHANGE_HINT = "Hint: only the person who made a webhook for rule request or objection events, signed in as themself (not with an API key, another app or an agent), can change it. It can be deleted as any other webhook can.";
55612
+ const RULE_REQUEST_WEBHOOK_DEFAULT_HINT = "Hint: a webhook for rule request or objection events is always a route target. Leave out --no-is-route-target, --takeover and --no-takeover (is_route_target: false and takeover in a raw body).";
55613
+ /** The event families, of those this CLI lists, that the API keeps to a webhook its person made for them, matched by prefix as the API matches them. */
55614
+ const MEMBER_EVENT_PREFIXES = ["email_rule_request.", "email_rule_objection."];
54658
55615
  function record(value) {
54659
55616
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
54660
55617
  }
54661
55618
  /**
54662
- * Whether a create or update body lists any rule request event. Matched by
54663
- * prefix, as the API matches it, so a raw body's literal
54664
- * `email_rule_request.*` counts too.
55619
+ * Whether a create or update body lists any rule request or objection
55620
+ * event. Matched by prefix, as the API matches it, so a raw body's
55621
+ * literal `email_rule_request.*` counts too.
54665
55622
  */
54666
55623
  function listsRuleRequestEvents(body) {
54667
55624
  const types = record(record(body)?.rules)?.event_types;
54668
- return Array.isArray(types) && types.some((t) => typeof t === "string" && t.startsWith(RULE_REQUEST_EVENT_PREFIX));
55625
+ return Array.isArray(types) && types.some((t) => typeof t === "string" && MEMBER_EVENT_PREFIXES.some((prefix) => t.startsWith(prefix)));
54669
55626
  }
54670
55627
  function refusalReason(payload) {
54671
55628
  const top = record(payload);
@@ -55971,7 +56928,7 @@ function createOperationCommand(operation) {
55971
56928
  ...tail ? { pastFlag: "--since" } : query.cursor !== void 0 ? { pastFlag: "--cursor" } : {},
55972
56929
  nextCursor: tail ? null : more,
55973
56930
  caller: tail || more ? null : await readCallerMailFor(auth, apiClient.client)
55974
- }) : emptyRuleListHint(operation.sdkName, query) ?? EMPTY_RESULT_HINTS[operation.sdkName];
56931
+ }) : emptyRuleListHint(operation.sdkName, query) ?? emptyDeliveriesHint(operation.sdkName, query) ?? EMPTY_RESULT_HINTS[operation.sdkName];
55975
56932
  if (hint && jsonOutput) summary.push(hint);
55976
56933
  else if (hint) process.stderr.write(`${hint}\n`);
55977
56934
  }
@@ -56078,6 +57035,20 @@ function emptyRuleListHint(sdkName, query) {
56078
57035
  return said("objections", box && status ? "pending objections you made" : box ? "objections you made" : status ? "pending objections" : null, [...box ? ["--box all"] : [], ...status ? ["--status any"] : []]);
56079
57036
  }
56080
57037
  }
57038
+ /**
57039
+ * An empty delivery list narrowed by a filter (--endpoint-id, --status,
57040
+ * --event-type and the rest) names the filters given, in place of the general
57041
+ * hint, which reads as if nothing was ever delivered, and keeps its point that
57042
+ * test fires are not logged. Undefined for any other list, or when no filter
57043
+ * was given.
57044
+ */
57045
+ function emptyDeliveriesHint(sdkName, query) {
57046
+ if (sdkName !== "listDeliveries") return void 0;
57047
+ const flags = listFilters(query).map((name) => `--${parameterFlagName(sdkName, name)}`);
57048
+ if (flags.length === 0) return void 0;
57049
+ if (query.cursor !== void 0) return "(no results) No more deliveries match these filters.";
57050
+ return `(no results) No deliveries match ${flags.length === 1 ? flags[0] : `${flags.slice(0, -1).join(", ")} and ${flags[flags.length - 1]}`}. Test fires from \`primitive endpoints test\` are not logged here; real deliveries are, when an event fans out to the endpoint. Leave out ${flags.length === 1 ? flags[0] : "a filter"} to list more.`;
57051
+ }
56081
57052
  function canonicalizeCliReferences(description) {
56082
57053
  return description.replaceAll("`primitive emails:latest`", "`primitive emails latest`").replaceAll("`primitive describe emails:get-email | jq '.responseSchema.properties'`", "`primitive describe emails:get | jq '.responseSchema.properties'`");
56083
57054
  }