primcli 3.0.0-preview.8 → 3.0.0-preview.9

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-DNbrLjEF.js";
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-DqcHvqvW.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";
@@ -602,7 +602,7 @@ const operationManifest = [
602
602
  "binaryResponse": false,
603
603
  "bodyRequired": true,
604
604
  "command": "update-account",
605
- "description": "Update the mutable account settings (such as display name and notification preferences) for the authenticated organization.",
605
+ "description": "Update the organization's spam threshold (spam_threshold) and whether an email's content is discarded once a webhook confirms receipt (discard_content_on_webhook_confirmed), the opt-in POST /emails/{id}/discard-content needs.",
606
606
  "hasJsonBody": true,
607
607
  "method": "PATCH",
608
608
  "operationId": "updateAccount",
@@ -7128,12 +7128,12 @@ const operationManifest = [
7128
7128
  },
7129
7129
  "hold": {
7130
7130
  "type": "object",
7131
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
7131
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
7132
7132
  "required": ["reason", "since"],
7133
7133
  "properties": {
7134
7134
  "reason": {
7135
7135
  "type": "string",
7136
- "description": "Open: credential_reuse_hold."
7136
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
7137
7137
  },
7138
7138
  "since": {
7139
7139
  "type": ["string", "null"],
@@ -10698,7 +10698,7 @@ const operationManifest = [
10698
10698
  "id": { "type": "string" },
10699
10699
  "label": {
10700
10700
  "type": "string",
10701
- "description": "A webhook's URL, a pull subscription's name (or pull when it has none), a route's or filter's pattern, or a wake schedule's command and the address it wakes (command to address). A Function trigger's label is function: look it up by id."
10701
+ "description": "A webhook's scheme and host, followed by \"/... (path and query hidden)\" when its URL has more (GET /v1/endpoints/{id} has the whole URL), a pull subscription's name (or pull when it has none), a route's or filter's pattern, or a wake schedule's command and the address it wakes (command to address). A Function trigger's label is function: look it up by id."
10702
10702
  },
10703
10703
  "org_owned": {
10704
10704
  "type": "boolean",
@@ -12947,6 +12947,458 @@ const operationManifest = [
12947
12947
  "tag": "Domains",
12948
12948
  "tagCommand": "domains"
12949
12949
  },
12950
+ {
12951
+ "binaryResponse": false,
12952
+ "bodyRequired": false,
12953
+ "command": "get-email-rule-covering-me",
12954
+ "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.",
12955
+ "hasJsonBody": false,
12956
+ "method": "GET",
12957
+ "operationId": "getEmailRuleCoveringMe",
12958
+ "path": "/email-rules/covering-me/{id}",
12959
+ "pathParams": [{
12960
+ "description": "The rule id.",
12961
+ "enum": null,
12962
+ "name": "id",
12963
+ "required": true,
12964
+ "type": "string"
12965
+ }],
12966
+ "queryParams": [],
12967
+ "headerParams": [],
12968
+ "permissions": ["mail:read"],
12969
+ "access": null,
12970
+ "requestSchema": null,
12971
+ "responseSchema": {
12972
+ "type": "object",
12973
+ "properties": {
12974
+ "id": {
12975
+ "type": "string",
12976
+ "format": "uuid"
12977
+ },
12978
+ "name": {
12979
+ "description": "Null when covers_now is false: its name now may describe something else.",
12980
+ "type": ["string", "null"]
12981
+ },
12982
+ "state": {
12983
+ "type": "string",
12984
+ "enum": [
12985
+ "draft",
12986
+ "observe",
12987
+ "active"
12988
+ ],
12989
+ "description": "draft: it decides nothing. observe: it decides and records, and shares nothing. active: it decides and, for a grant rule, shares what it matches."
12990
+ },
12991
+ "kind": {
12992
+ "type": "string",
12993
+ "enum": ["grant", "do_not_share"],
12994
+ "description": "grant: what it matches can be shared. do_not_share: it blocks sharing what it matches."
12995
+ },
12996
+ "author": {
12997
+ "type": "object",
12998
+ "properties": {
12999
+ "user_id": {
13000
+ "type": "string",
13001
+ "format": "uuid"
13002
+ },
13003
+ "name": {
13004
+ "description": "Their name; null when they have none set.",
13005
+ "type": ["string", "null"]
13006
+ },
13007
+ "email": {
13008
+ "description": "Sign-in email; null unless you can list member emails or this is you.",
13009
+ "type": ["string", "null"]
13010
+ }
13011
+ },
13012
+ "required": [
13013
+ "user_id",
13014
+ "name",
13015
+ "email"
13016
+ ]
13017
+ },
13018
+ "is_author": {
13019
+ "type": "boolean",
13020
+ "description": "Whether you wrote it."
13021
+ },
13022
+ "covers": {
13023
+ "description": "Null when it no longer covers your mailboxes and you see it because it decided on your mail.",
13024
+ "anyOf": [{
13025
+ "type": "object",
13026
+ "properties": {
13027
+ "addresses": {
13028
+ "type": "array",
13029
+ "items": { "type": "string" },
13030
+ "description": "Your own mailboxes (your member mailbox and your personal agents' addresses) it reaches now, lowercase."
13031
+ },
13032
+ "via": {
13033
+ "type": "string",
13034
+ "enum": [
13035
+ "author_reach",
13036
+ "selected",
13037
+ "own_mailboxes"
13038
+ ],
13039
+ "description": "author_reach: it runs over everything its author can read, which includes these. selected: it names these mailboxes or their domain. own_mailboxes: it is your own rule over your own mail."
13040
+ }
13041
+ },
13042
+ "required": ["addresses", "via"]
13043
+ }, { "type": "null" }]
13044
+ },
13045
+ "current_version": {
13046
+ "type": ["integer", "null"],
13047
+ "exclusiveMinimum": 0,
13048
+ "description": "Null when covers_now is false."
13049
+ },
13050
+ "created_at": {
13051
+ "type": "string",
13052
+ "format": "date-time"
13053
+ },
13054
+ "covers_now": {
13055
+ "type": "boolean",
13056
+ "description": "Whether it covers one of your own mailboxes now. False for a rule you see only because it decided on mail at your own mailbox before."
13057
+ },
13058
+ "current": {
13059
+ "description": "Its current version: what it asks of each email. When covers_now is false, the newest version that decided on your mail instead.",
13060
+ "anyOf": [{
13061
+ "type": "object",
13062
+ "properties": {
13063
+ "version": {
13064
+ "type": "integer",
13065
+ "exclusiveMinimum": 0
13066
+ },
13067
+ "english": {
13068
+ "type": "string",
13069
+ "description": "What its author asked for, in their words."
13070
+ },
13071
+ "tree": {
13072
+ "type": "object",
13073
+ "properties": {
13074
+ "version": {
13075
+ "type": "number",
13076
+ "const": 1
13077
+ },
13078
+ "vocabulary": {
13079
+ "type": "string",
13080
+ "description": "Vocabulary version, such as v1."
13081
+ },
13082
+ "when": {
13083
+ "type": "object",
13084
+ "propertyNames": { "type": "string" },
13085
+ "additionalProperties": {},
13086
+ "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
13087
+ },
13088
+ "questions": {
13089
+ "type": "array",
13090
+ "items": { "type": "string" },
13091
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
13092
+ }
13093
+ },
13094
+ "required": [
13095
+ "version",
13096
+ "vocabulary",
13097
+ "when",
13098
+ "questions"
13099
+ ]
13100
+ },
13101
+ "explanation": {
13102
+ "type": "string",
13103
+ "description": "What the rule matches, as compiled."
13104
+ },
13105
+ "assumptions": {
13106
+ "type": "array",
13107
+ "items": { "type": "string" }
13108
+ },
13109
+ "compiled_by": { "type": "string" },
13110
+ "vocabulary": { "type": "string" },
13111
+ "created_at": {
13112
+ "type": "string",
13113
+ "format": "date-time"
13114
+ }
13115
+ },
13116
+ "required": [
13117
+ "version",
13118
+ "english",
13119
+ "tree",
13120
+ "explanation",
13121
+ "assumptions",
13122
+ "compiled_by",
13123
+ "vocabulary",
13124
+ "created_at"
13125
+ ]
13126
+ }, { "type": "null" }]
13127
+ },
13128
+ "note": {
13129
+ "description": "Present when covers_now is false: what is withheld, and why.",
13130
+ "type": "string"
13131
+ }
13132
+ },
13133
+ "required": [
13134
+ "id",
13135
+ "name",
13136
+ "state",
13137
+ "kind",
13138
+ "author",
13139
+ "is_author",
13140
+ "covers",
13141
+ "current_version",
13142
+ "created_at",
13143
+ "covers_now",
13144
+ "current"
13145
+ ]
13146
+ },
13147
+ "sdkName": "getEmailRuleCoveringMe",
13148
+ "summary": "Get a rule over your mail",
13149
+ "tag": "Email Rule Oversight",
13150
+ "tagCommand": "email-rule-oversight"
13151
+ },
13152
+ {
13153
+ "binaryResponse": false,
13154
+ "bodyRequired": false,
13155
+ "command": "list-email-rule-decisions-on-my-mail",
13156
+ "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.",
13157
+ "hasJsonBody": false,
13158
+ "method": "GET",
13159
+ "operationId": "listEmailRuleDecisionsOnMyMail",
13160
+ "path": "/email-rules/covering-me/{id}/decisions",
13161
+ "pathParams": [{
13162
+ "description": "The rule id.",
13163
+ "enum": null,
13164
+ "name": "id",
13165
+ "required": true,
13166
+ "type": "string"
13167
+ }],
13168
+ "queryParams": [
13169
+ {
13170
+ "default": 50,
13171
+ "description": "Decisions per page, from 1 to 100; defaults to 50.",
13172
+ "enum": null,
13173
+ "maximum": 100,
13174
+ "minimum": 1,
13175
+ "name": "limit",
13176
+ "required": false,
13177
+ "type": "integer"
13178
+ },
13179
+ {
13180
+ "description": "meta.cursor from the preceding page. Omit for the first page.",
13181
+ "enum": null,
13182
+ "name": "cursor",
13183
+ "required": false,
13184
+ "type": "string"
13185
+ },
13186
+ {
13187
+ "description": "true for matches only, false for the rest.",
13188
+ "enum": ["true", "false"],
13189
+ "name": "matched",
13190
+ "required": false,
13191
+ "type": "string"
13192
+ }
13193
+ ],
13194
+ "headerParams": [],
13195
+ "permissions": ["mail:read"],
13196
+ "access": null,
13197
+ "requestSchema": null,
13198
+ "responseSchema": {
13199
+ "type": "array",
13200
+ "items": {
13201
+ "type": "object",
13202
+ "properties": {
13203
+ "id": {
13204
+ "type": "string",
13205
+ "format": "uuid"
13206
+ },
13207
+ "email_id": {
13208
+ "type": "string",
13209
+ "format": "uuid"
13210
+ },
13211
+ "rule_version": {
13212
+ "type": "integer",
13213
+ "exclusiveMinimum": 0
13214
+ },
13215
+ "classification_id": {
13216
+ "type": "string",
13217
+ "format": "uuid"
13218
+ },
13219
+ "matched": { "type": "boolean" },
13220
+ "near_miss": {
13221
+ "type": "boolean",
13222
+ "description": "Not matched, but nearly. False when detail_withheld is true."
13223
+ },
13224
+ "parts": {
13225
+ "type": "array",
13226
+ "items": {},
13227
+ "description": "How each top-level part of the rule decided."
13228
+ },
13229
+ "question_answers": {
13230
+ "type": "array",
13231
+ "items": {},
13232
+ "description": "The answers to the rule's own questions, when they were asked."
13233
+ },
13234
+ "detail_withheld": {
13235
+ "description": "Present, as true, when the email's content cannot be read: matched still says what the rule decided, and parts and question_answers are empty.",
13236
+ "type": "boolean",
13237
+ "const": true
13238
+ },
13239
+ "created_at": {
13240
+ "type": "string",
13241
+ "format": "date-time"
13242
+ },
13243
+ "from_address": {
13244
+ "description": "The email's sender address, as GET /v1/emails/{id} shows it.",
13245
+ "type": ["string", "null"]
13246
+ },
13247
+ "subject": { "type": ["string", "null"] },
13248
+ "received_at": {
13249
+ "type": ["string", "null"],
13250
+ "format": "date-time",
13251
+ "description": "When the email arrived. Null, with the other two, when you are not shown the email (it awaits sender authentication)."
13252
+ }
13253
+ },
13254
+ "required": [
13255
+ "id",
13256
+ "email_id",
13257
+ "rule_version",
13258
+ "classification_id",
13259
+ "matched",
13260
+ "near_miss",
13261
+ "parts",
13262
+ "question_answers",
13263
+ "created_at",
13264
+ "from_address",
13265
+ "subject",
13266
+ "received_at"
13267
+ ]
13268
+ }
13269
+ },
13270
+ "sdkName": "listEmailRuleDecisionsOnMyMail",
13271
+ "summary": "List what a rule decided about your mail",
13272
+ "tag": "Email Rule Oversight",
13273
+ "tagCommand": "email-rule-oversight"
13274
+ },
13275
+ {
13276
+ "binaryResponse": false,
13277
+ "bodyRequired": false,
13278
+ "command": "list-email-rules-covering-me",
13279
+ "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.",
13280
+ "hasJsonBody": false,
13281
+ "method": "GET",
13282
+ "operationId": "listEmailRulesCoveringMe",
13283
+ "path": "/email-rules/covering-me",
13284
+ "pathParams": [],
13285
+ "queryParams": [{
13286
+ "default": 50,
13287
+ "description": "Rules per page, from 1 to 100; defaults to 50.",
13288
+ "enum": null,
13289
+ "maximum": 100,
13290
+ "minimum": 1,
13291
+ "name": "limit",
13292
+ "required": false,
13293
+ "type": "integer"
13294
+ }, {
13295
+ "description": "meta.cursor from the preceding page. Omit for the first page.",
13296
+ "enum": null,
13297
+ "name": "cursor",
13298
+ "required": false,
13299
+ "type": "string"
13300
+ }],
13301
+ "headerParams": [],
13302
+ "permissions": ["mail:read"],
13303
+ "access": null,
13304
+ "requestSchema": null,
13305
+ "responseSchema": {
13306
+ "type": "array",
13307
+ "items": {
13308
+ "type": "object",
13309
+ "properties": {
13310
+ "id": {
13311
+ "type": "string",
13312
+ "format": "uuid"
13313
+ },
13314
+ "name": { "type": "string" },
13315
+ "state": {
13316
+ "type": "string",
13317
+ "enum": [
13318
+ "draft",
13319
+ "observe",
13320
+ "active"
13321
+ ],
13322
+ "description": "draft: it decides nothing. observe: it decides and records, and shares nothing. active: it decides and, for a grant rule, shares what it matches."
13323
+ },
13324
+ "kind": {
13325
+ "type": "string",
13326
+ "enum": ["grant", "do_not_share"],
13327
+ "description": "grant: what it matches can be shared. do_not_share: it blocks sharing what it matches."
13328
+ },
13329
+ "author": {
13330
+ "type": "object",
13331
+ "properties": {
13332
+ "user_id": {
13333
+ "type": "string",
13334
+ "format": "uuid"
13335
+ },
13336
+ "name": {
13337
+ "description": "Their name; null when they have none set.",
13338
+ "type": ["string", "null"]
13339
+ },
13340
+ "email": {
13341
+ "description": "Sign-in email; null unless you can list member emails or this is you.",
13342
+ "type": ["string", "null"]
13343
+ }
13344
+ },
13345
+ "required": [
13346
+ "user_id",
13347
+ "name",
13348
+ "email"
13349
+ ]
13350
+ },
13351
+ "is_author": {
13352
+ "type": "boolean",
13353
+ "description": "Whether you wrote it."
13354
+ },
13355
+ "covers": {
13356
+ "type": "object",
13357
+ "properties": {
13358
+ "addresses": {
13359
+ "type": "array",
13360
+ "items": { "type": "string" },
13361
+ "description": "Your own mailboxes (your member mailbox and your personal agents' addresses) it reaches now, lowercase."
13362
+ },
13363
+ "via": {
13364
+ "type": "string",
13365
+ "enum": [
13366
+ "author_reach",
13367
+ "selected",
13368
+ "own_mailboxes"
13369
+ ],
13370
+ "description": "author_reach: it runs over everything its author can read, which includes these. selected: it names these mailboxes or their domain. own_mailboxes: it is your own rule over your own mail."
13371
+ }
13372
+ },
13373
+ "required": ["addresses", "via"]
13374
+ },
13375
+ "current_version": {
13376
+ "type": ["integer", "null"],
13377
+ "exclusiveMinimum": 0
13378
+ },
13379
+ "created_at": {
13380
+ "type": "string",
13381
+ "format": "date-time"
13382
+ }
13383
+ },
13384
+ "required": [
13385
+ "id",
13386
+ "name",
13387
+ "state",
13388
+ "kind",
13389
+ "author",
13390
+ "is_author",
13391
+ "covers",
13392
+ "current_version",
13393
+ "created_at"
13394
+ ]
13395
+ }
13396
+ },
13397
+ "sdkName": "listEmailRulesCoveringMe",
13398
+ "summary": "List the rules over your mail",
13399
+ "tag": "Email Rule Oversight",
13400
+ "tagCommand": "email-rule-oversight"
13401
+ },
12950
13402
  {
12951
13403
  "binaryResponse": false,
12952
13404
  "bodyRequired": false,
@@ -13006,7 +13458,7 @@ const operationManifest = [
13006
13458
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
13007
13459
  },
13008
13460
  "questions": {
13009
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
13461
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
13010
13462
  "type": "array",
13011
13463
  "items": { "type": "string" }
13012
13464
  }
@@ -13219,7 +13671,7 @@ const operationManifest = [
13219
13671
  "questions": {
13220
13672
  "type": "array",
13221
13673
  "items": { "type": "string" },
13222
- "description": "Yes/no questions asked once the conditions match; all must be yes."
13674
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
13223
13675
  }
13224
13676
  },
13225
13677
  "required": [
@@ -13383,7 +13835,7 @@ const operationManifest = [
13383
13835
  "enum": ["grant", "do_not_share"]
13384
13836
  },
13385
13837
  "protection_note": {
13386
- "description": "On a do_not_share rule only: it protects nothing yet (not active), or a classifier fact narrows it.",
13838
+ "description": "On a do_not_share rule only: it protects nothing yet (not active), a classifier fact narrows it, or its several questions are alternatives.",
13387
13839
  "type": "string"
13388
13840
  },
13389
13841
  "evaluation_scope": {
@@ -13489,7 +13941,7 @@ const operationManifest = [
13489
13941
  "questions": {
13490
13942
  "type": "array",
13491
13943
  "items": { "type": "string" },
13492
- "description": "Yes/no questions asked once the conditions match; all must be yes."
13944
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
13493
13945
  }
13494
13946
  },
13495
13947
  "required": [
@@ -13819,7 +14271,7 @@ const operationManifest = [
13819
14271
  "binaryResponse": false,
13820
14272
  "bodyRequired": true,
13821
14273
  "command": "compile-email-rule",
13822
- "description": "Turns a plain-English description of which received emails to match into a rule tree over the published column contract, with a plain-English explanation of what it matches, the assumptions made, and warnings for anything the columns cannot express. Where the columns fall short the rule may carry up to five yes/no questions, asked about an email only after its conditions match. Nothing is saved. A rule with no questions has its conditions counted, read only, over the caller's recent classified mail (what a test of it covers by default): breadth is that count, and a warning says when it matches nearly all of it. The SQL the rule renders to is returned only when include_sql is true. kind do_not_share compiles a do-not-share rule for recall: conditions only as narrow as the description says, the judgement of what it describes put into questions, and with nothing a column decides for certain, conditions that hold for every 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.",
14274
+ "description": "Turns a plain-English description of which received emails to match into a rule tree over the published column contract, with a plain-English explanation of what it matches, the assumptions made, and warnings for anything the columns cannot express. Where the columns fall short the rule may carry up to five yes/no questions, asked about an email only after its conditions match; they read its subject, its new text and its attachments' file names, never what is inside an attachment, and warnings say when a question mentions attachments. Nothing is saved. A rule with no questions has its conditions counted, read only, over the caller's recent classified mail (what a test of it covers by default): breadth is that count, and a warning says when it matches nearly all of it. The SQL the rule renders to is returned only when include_sql is true. kind do_not_share compiles a do-not-share rule for recall: conditions only as narrow as the description says, the judgement of what it describes put into questions, and with nothing a column decides for certain, conditions that hold for every 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.",
13823
14275
  "hasJsonBody": true,
13824
14276
  "method": "POST",
13825
14277
  "operationId": "compileEmailRule",
@@ -13880,7 +14332,7 @@ const operationManifest = [
13880
14332
  "questions": {
13881
14333
  "type": "array",
13882
14334
  "items": { "type": "string" },
13883
- "description": "Yes/no questions asked once the conditions match; all must be yes."
14335
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
13884
14336
  }
13885
14337
  },
13886
14338
  "required": [
@@ -14189,7 +14641,7 @@ const operationManifest = [
14189
14641
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
14190
14642
  },
14191
14643
  "questions": {
14192
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
14644
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
14193
14645
  "type": "array",
14194
14646
  "items": { "type": "string" }
14195
14647
  }
@@ -14282,7 +14734,7 @@ const operationManifest = [
14282
14734
  "enum": ["grant", "do_not_share"]
14283
14735
  },
14284
14736
  "protection_note": {
14285
- "description": "On a do_not_share rule only: it protects nothing yet (not active), or a classifier fact narrows it.",
14737
+ "description": "On a do_not_share rule only: it protects nothing yet (not active), a classifier fact narrows it, or its several questions are alternatives.",
14286
14738
  "type": "string"
14287
14739
  },
14288
14740
  "evaluation_scope": {
@@ -14388,7 +14840,7 @@ const operationManifest = [
14388
14840
  "questions": {
14389
14841
  "type": "array",
14390
14842
  "items": { "type": "string" },
14391
- "description": "Yes/no questions asked once the conditions match; all must be yes."
14843
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
14392
14844
  }
14393
14845
  },
14394
14846
  "required": [
@@ -14764,7 +15216,7 @@ const operationManifest = [
14764
15216
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
14765
15217
  },
14766
15218
  "questions": {
14767
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
15219
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
14768
15220
  "type": "array",
14769
15221
  "items": { "type": "string" }
14770
15222
  }
@@ -14873,7 +15325,7 @@ const operationManifest = [
14873
15325
  "questions": {
14874
15326
  "type": "array",
14875
15327
  "items": { "type": "string" },
14876
- "description": "Yes/no questions asked once the conditions match; all must be yes."
15328
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
14877
15329
  }
14878
15330
  },
14879
15331
  "required": [
@@ -15102,7 +15554,7 @@ const operationManifest = [
15102
15554
  "questions": {
15103
15555
  "type": "array",
15104
15556
  "items": { "type": "string" },
15105
- "description": "Yes/no questions asked once the conditions match; all must be yes."
15557
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
15106
15558
  }
15107
15559
  },
15108
15560
  "required": [
@@ -15349,7 +15801,7 @@ const operationManifest = [
15349
15801
  "binaryResponse": false,
15350
15802
  "bodyRequired": false,
15351
15803
  "command": "end-email-rule-share",
15352
- "description": "Stops sharing. Either person on the share can do this, or an owner or admin who manages members. The share is kept, marked as ended. This needs no mail access and does not depend on the email rules feature. An owner or admin not on the share must use a dashboard session. Otherwise use your own session, or an OAuth or CLI token that acts with your full access: API keys and agent keys are refused.",
15804
+ "description": "Stops sharing; the rule itself is left unchanged, as the answer's note says. Either person on the share can do this, or an owner or admin who manages members. The share is kept, marked as ended. This needs no mail access and does not depend on the email rules feature. An owner or admin not on the share must use a dashboard session. Otherwise use your own session, or an OAuth or CLI token that acts with your full access: API keys and agent keys are refused.",
15353
15805
  "hasJsonBody": false,
15354
15806
  "method": "DELETE",
15355
15807
  "operationId": "endEmailRuleShare",
@@ -15368,8 +15820,13 @@ const operationManifest = [
15368
15820
  "requestSchema": null,
15369
15821
  "responseSchema": {
15370
15822
  "type": "object",
15371
- "properties": { "ended": { "type": "boolean" } },
15372
- "required": ["ended"]
15823
+ "properties": {
15824
+ "ended": { "type": "boolean" },
15825
+ "rule_id": { "type": "string" },
15826
+ "note": { "type": "string" }
15827
+ },
15828
+ "required": ["ended"],
15829
+ "additionalProperties": {}
15373
15830
  },
15374
15831
  "sdkName": "endEmailRuleShare",
15375
15832
  "summary": "End a rule share",
@@ -15380,7 +15837,7 @@ const operationManifest = [
15380
15837
  "binaryResponse": false,
15381
15838
  "bodyRequired": true,
15382
15839
  "command": "generate-look-alikes",
15383
- "description": "Writes made-up emails that come close to what a grant rule describes but are private (a personal medical bill, pay for named people, a personal purchase, personal banking or tax, or another near case), and reports what the rule decides for each, as test-sample would. failed means the rule matched it, so it would be shared. Nothing is stored and no mail is read. Keep the ones it must never match 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.",
15840
+ "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.",
15384
15841
  "hasJsonBody": true,
15385
15842
  "method": "POST",
15386
15843
  "operationId": "generateLookAlikes",
@@ -15417,7 +15874,7 @@ const operationManifest = [
15417
15874
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
15418
15875
  },
15419
15876
  "questions": {
15420
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
15877
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
15421
15878
  "type": "array",
15422
15879
  "items": { "type": "string" }
15423
15880
  }
@@ -15493,7 +15950,7 @@ const operationManifest = [
15493
15950
  "maximum": 8
15494
15951
  },
15495
15952
  "kinds": {
15496
- "description": "Which kinds, taken in turn; all by default, the private ones first.",
15953
+ "description": "Which kinds, taken in turn, all expected no_match; other is a business near miss. Left out, a default mix.",
15497
15954
  "minItems": 1,
15498
15955
  "maxItems": 5,
15499
15956
  "type": "array",
@@ -15509,7 +15966,7 @@ const operationManifest = [
15509
15966
  }
15510
15967
  },
15511
15968
  "to": {
15512
- "description": "The mailbox they arrive in; by default the rule author's (a request's target's) sign-in address when you may see it, else yours.",
15969
+ "description": "The mailbox they arrive in; by default the first address (alphabetically) a selected scope names that a made-up email can be sent to, preferring one the author still reads; else the rule author's (a request's target's) sign-in address when you may see it, else yours.",
15513
15970
  "type": "string",
15514
15971
  "maxLength": 254,
15515
15972
  "format": "email",
@@ -15555,9 +16012,14 @@ const operationManifest = [
15555
16012
  "other"
15556
16013
  ]
15557
16014
  },
16015
+ "expected": {
16016
+ "type": "string",
16017
+ "enum": ["match", "no_match"],
16018
+ "description": "match: a near case the rule should match; no_match: one it should not."
16019
+ },
15558
16020
  "why": {
15559
16021
  "type": "string",
15560
- "description": "Why the rule should not match it."
16022
+ "description": "Why the rule should, or should not, match it."
15561
16023
  },
15562
16024
  "email": {
15563
16025
  "type": "object",
@@ -15615,7 +16077,7 @@ const operationManifest = [
15615
16077
  "failed",
15616
16078
  "undecided"
15617
16079
  ],
15618
- "description": "failed: the rule matched it, so it would be shared. undecided: the rule reads a spam score, which it cannot carry, whatever it decided; or not matched on something it could not decide (not classified, a fact or answer missing, or not reached in time)."
16080
+ "description": "failed: the rule decided it against expected (shared one it should not, or missed one it should match). undecided: the rule reads a spam score, which it cannot carry, whatever it decided; or not matched on something it could not decide (not classified, a fact or answer missing, or not reached in time)."
15619
16081
  },
15620
16082
  "question_answers": {
15621
16083
  "type": "array",
@@ -15637,6 +16099,7 @@ const operationManifest = [
15637
16099
  },
15638
16100
  "required": [
15639
16101
  "kind",
16102
+ "expected",
15640
16103
  "why",
15641
16104
  "email",
15642
16105
  "outcome",
@@ -15663,7 +16126,7 @@ const operationManifest = [
15663
16126
  "dropped": {
15664
16127
  "type": "integer",
15665
16128
  "minimum": 0,
15666
- "description": "Asked for but not returned: not written, outside the sample bounds, or of a kind not asked for."
16129
+ "description": "Asked for but not returned: not written, outside the sample bounds, or of a kind and expected not asked for."
15667
16130
  }
15668
16131
  },
15669
16132
  "required": [
@@ -15686,7 +16149,7 @@ const operationManifest = [
15686
16149
  ]
15687
16150
  },
15688
16151
  "sdkName": "generateLookAlikes",
15689
- "summary": "Write look-alike emails a rule should not match",
16152
+ "summary": "Write look-alike emails a rule should or should not match",
15690
16153
  "tag": "Email Rules",
15691
16154
  "tagCommand": "email-rules"
15692
16155
  },
@@ -15739,7 +16202,7 @@ const operationManifest = [
15739
16202
  "enum": ["grant", "do_not_share"]
15740
16203
  },
15741
16204
  "protection_note": {
15742
- "description": "On a do_not_share rule only: it protects nothing yet (not active), or a classifier fact narrows it.",
16205
+ "description": "On a do_not_share rule only: it protects nothing yet (not active), a classifier fact narrows it, or its several questions are alternatives.",
15743
16206
  "type": "string"
15744
16207
  },
15745
16208
  "evaluation_scope": {
@@ -15845,7 +16308,7 @@ const operationManifest = [
15845
16308
  "questions": {
15846
16309
  "type": "array",
15847
16310
  "items": { "type": "string" },
15848
- "description": "Yes/no questions asked once the conditions match; all must be yes."
16311
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
15849
16312
  }
15850
16313
  },
15851
16314
  "required": [
@@ -16107,7 +16570,7 @@ const operationManifest = [
16107
16570
  "questions": {
16108
16571
  "type": "array",
16109
16572
  "items": { "type": "string" },
16110
- "description": "Yes/no questions asked once the conditions match; all must be yes."
16573
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
16111
16574
  }
16112
16575
  },
16113
16576
  "required": [
@@ -16814,7 +17277,7 @@ const operationManifest = [
16814
17277
  "matched": { "type": "boolean" },
16815
17278
  "near_miss": {
16816
17279
  "type": "boolean",
16817
- "description": "Not matched, but nearly: its questions did not all say yes, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false). Decisions recorded under the earlier definition counted an exclusion too."
17280
+ "description": "Not matched, but nearly: its conditions held and its questions did not match it, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false). Decisions recorded under the earlier definition counted an exclusion too."
16818
17281
  },
16819
17282
  "parts": {
16820
17283
  "type": "array",
@@ -16997,7 +17460,7 @@ const operationManifest = [
16997
17460
  "questions": {
16998
17461
  "type": "array",
16999
17462
  "items": { "type": "string" },
17000
- "description": "Yes/no questions asked once the conditions match; all must be yes."
17463
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
17001
17464
  }
17002
17465
  },
17003
17466
  "required": [
@@ -17149,7 +17612,7 @@ const operationManifest = [
17149
17612
  "binaryResponse": false,
17150
17613
  "bodyRequired": false,
17151
17614
  "command": "list-email-rule-results",
17152
- "description": "Every rule you can see and what it decided about this email (matched, not matched, or not run, with what is known), in the words of the version that decided. A matched do_not_share rule keeps rules from sharing the email while it is active; what was shared before then stays shared. Only a caller who can read the email gets an answer. classification is what the classifier read from the email, every fact as rule conditions read it, so you can see why a rule did or did not match. At most 50 rules are listed, those with a result first; hidden counts the rest. 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.",
17615
+ "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.",
17153
17616
  "hasJsonBody": false,
17154
17617
  "method": "GET",
17155
17618
  "operationId": "listEmailRuleResults",
@@ -17208,7 +17671,7 @@ const operationManifest = [
17208
17671
  "type": "string",
17209
17672
  "format": "uuid"
17210
17673
  },
17211
- "name": { "type": "string" },
17674
+ "name": { "type": ["string", "null"] },
17212
17675
  "state": {
17213
17676
  "type": "string",
17214
17677
  "enum": [
@@ -17232,7 +17695,7 @@ const operationManifest = [
17232
17695
  },
17233
17696
  "matched": { "type": "boolean" },
17234
17697
  "near_miss": {
17235
- "description": "Not matched, but nearly: its questions did not all say yes, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false). False when detail_withheld is true. Decisions recorded under the earlier definition counted an exclusion too.",
17698
+ "description": "Not matched, but nearly: its conditions held and its questions did not match it, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false). False when detail_withheld is true. Decisions recorded under the earlier definition counted an exclusion too.",
17236
17699
  "type": "boolean"
17237
17700
  },
17238
17701
  "parts": {
@@ -17298,7 +17761,7 @@ const operationManifest = [
17298
17761
  "questions": {
17299
17762
  "type": "array",
17300
17763
  "items": { "type": "string" },
17301
- "description": "Yes/no questions asked once the conditions match; all must be yes."
17764
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
17302
17765
  }
17303
17766
  },
17304
17767
  "required": [
@@ -17375,6 +17838,33 @@ const operationManifest = [
17375
17838
  "description": "On a do-not-share rule whose author is no longer a member of the organization: it blocks nothing now, whatever it decided. Absent otherwise.",
17376
17839
  "type": "boolean",
17377
17840
  "const": true
17841
+ },
17842
+ "read_only": {
17843
+ "description": "Another member's rule that decided on your own mail; dashboard and CLI only. name is null once it no longer covers you.",
17844
+ "type": "boolean",
17845
+ "const": true
17846
+ },
17847
+ "author": {
17848
+ "type": "object",
17849
+ "properties": {
17850
+ "user_id": {
17851
+ "type": "string",
17852
+ "format": "uuid"
17853
+ },
17854
+ "name": {
17855
+ "description": "Their name; null when they have none set.",
17856
+ "type": ["string", "null"]
17857
+ },
17858
+ "email": {
17859
+ "description": "Sign-in email; null unless you can list member emails or this is you.",
17860
+ "type": ["string", "null"]
17861
+ }
17862
+ },
17863
+ "required": [
17864
+ "user_id",
17865
+ "name",
17866
+ "email"
17867
+ ]
17378
17868
  }
17379
17869
  },
17380
17870
  "required": [
@@ -17385,12 +17875,17 @@ const operationManifest = [
17385
17875
  "not_run_reason"
17386
17876
  ]
17387
17877
  },
17388
- "description": "Every rule the caller can see: those that matched this email, then those that did not, then those that have not run on it; newest rule first within each."
17878
+ "description": "Rules you can see, and read_only ones: matched first, then not matched, then not run; newest first within each."
17389
17879
  },
17390
17880
  "hidden": {
17391
17881
  "type": "integer",
17392
17882
  "minimum": 0,
17393
- "description": "How many more rules the caller can see that are not listed."
17883
+ "description": "Rules that decided on this email that you cannot see."
17884
+ },
17885
+ "not_listed": {
17886
+ "description": "Rules you can see past the 50 listed.",
17887
+ "type": "integer",
17888
+ "minimum": 0
17394
17889
  },
17395
17890
  "classification": {
17396
17891
  "type": ["object", "null"],
@@ -18131,7 +18626,7 @@ const operationManifest = [
18131
18626
  "questions": {
18132
18627
  "type": "array",
18133
18628
  "items": { "type": "string" },
18134
- "description": "Yes/no questions asked once the conditions match; all must be yes."
18629
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
18135
18630
  }
18136
18631
  },
18137
18632
  "required": [
@@ -18258,7 +18753,7 @@ const operationManifest = [
18258
18753
  "enum": ["grant", "do_not_share"]
18259
18754
  },
18260
18755
  "protection_note": {
18261
- "description": "On a do_not_share rule only: it protects nothing yet (not active), or a classifier fact narrows it.",
18756
+ "description": "On a do_not_share rule only: it protects nothing yet (not active), a classifier fact narrows it, or its several questions are alternatives.",
18262
18757
  "type": "string"
18263
18758
  },
18264
18759
  "evaluation_scope": {
@@ -18603,7 +19098,7 @@ const operationManifest = [
18603
19098
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
18604
19099
  },
18605
19100
  "questions": {
18606
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
19101
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
18607
19102
  "type": "array",
18608
19103
  "items": { "type": "string" }
18609
19104
  }
@@ -18947,7 +19442,7 @@ const operationManifest = [
18947
19442
  "skipped",
18948
19443
  "not_found"
18949
19444
  ],
18950
- "description": "near_miss: Not matched, but nearly: its questions did not all say yes, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false). skipped: an email you can see that cannot be tested; skipped_reason says why. not_found: no such email, or not one the rule can read (or not settled, or awaiting sender authentication)."
19445
+ "description": "near_miss: Not matched, but nearly: its conditions held and its questions did not match it, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false). skipped: an email you can see that cannot be tested; skipped_reason says why. not_found: no such email, or not one the rule can read (or not settled, or awaiting sender authentication)."
18951
19446
  },
18952
19447
  "received_at": {
18953
19448
  "type": "string",
@@ -19381,7 +19876,7 @@ const operationManifest = [
19381
19876
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
19382
19877
  },
19383
19878
  "questions": {
19384
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
19879
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
19385
19880
  "type": "array",
19386
19881
  "items": { "type": "string" }
19387
19882
  }
@@ -19562,7 +20057,7 @@ const operationManifest = [
19562
20057
  "near_miss",
19563
20058
  "no_match"
19564
20059
  ],
19565
- "description": "near_miss: Not matched, but nearly: its questions did not all say yes, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false)."
20060
+ "description": "near_miss: Not matched, but nearly: its conditions held and its questions did not match it, or it needs several parts and exactly one failed while at least one part that held is not an exclusion (a top-level not, or is_false)."
19566
20061
  },
19567
20062
  "parts": {
19568
20063
  "type": "array",
@@ -19749,7 +20244,7 @@ const operationManifest = [
19749
20244
  "description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
19750
20245
  },
19751
20246
  "questions": {
19752
- "description": "Yes/no questions asked once the conditions match; all must be yes. Left out, none.",
20247
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes. Left out, none.",
19753
20248
  "type": "array",
19754
20249
  "items": { "type": "string" }
19755
20250
  }
@@ -20094,7 +20589,7 @@ const operationManifest = [
20094
20589
  "maximum": 2147483647
20095
20590
  },
20096
20591
  "if_expectations_pass": {
20097
- "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; undecided: 409 expectations_undecided (both 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.",
20592
+ "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.",
20098
20593
  "type": "boolean"
20099
20594
  },
20100
20595
  "restore_version": {
@@ -20128,7 +20623,7 @@ const operationManifest = [
20128
20623
  "enum": ["grant", "do_not_share"]
20129
20624
  },
20130
20625
  "protection_note": {
20131
- "description": "On a do_not_share rule only: it protects nothing yet (not active), or a classifier fact narrows it.",
20626
+ "description": "On a do_not_share rule only: it protects nothing yet (not active), a classifier fact narrows it, or its several questions are alternatives.",
20132
20627
  "type": "string"
20133
20628
  },
20134
20629
  "evaluation_scope": {
@@ -20234,7 +20729,7 @@ const operationManifest = [
20234
20729
  "questions": {
20235
20730
  "type": "array",
20236
20731
  "items": { "type": "string" },
20237
- "description": "Yes/no questions asked once the conditions match; all must be yes."
20732
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
20238
20733
  }
20239
20734
  },
20240
20735
  "required": [
@@ -20604,7 +21099,7 @@ const operationManifest = [
20604
21099
  "questions": {
20605
21100
  "type": "array",
20606
21101
  "items": { "type": "string" },
20607
- "description": "Yes/no questions asked once the conditions match; all must be yes."
21102
+ "description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
20608
21103
  }
20609
21104
  },
20610
21105
  "required": [
@@ -21258,12 +21753,12 @@ const operationManifest = [
21258
21753
  },
21259
21754
  "hold": {
21260
21755
  "type": "object",
21261
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
21756
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
21262
21757
  "required": ["reason", "since"],
21263
21758
  "properties": {
21264
21759
  "reason": {
21265
21760
  "type": "string",
21266
- "description": "Open: credential_reuse_hold."
21761
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
21267
21762
  },
21268
21763
  "since": {
21269
21764
  "type": ["string", "null"],
@@ -37002,7 +37497,7 @@ const operationManifest = [
37002
37497
  "binaryResponse": false,
37003
37498
  "bodyRequired": false,
37004
37499
  "command": "get-access-mode",
37005
- "description": "Whole-org or delegated mailbox access. Holders of roles:assign also get the preview of a switch (every item that needs a decision, each with the decision_options it takes, worded for what the switch does) and the decisions made, plus notices: member and group domain entries that delegated mode keeps off personal mailboxes, each with how many it leaves out. Notices are informational, never decided, and never hold the switch (notices_truncated past 500, notices_unavailable when they could not be read). In whole-org mode it also lists narrowed_agents: every live agent connection the switch narrows to an own-address key (personal agents of members, and shared agents), informational in the same way (narrowed_agents_truncated past 500, narrowed_agents_unavailable when they could not be read). Any person; API keys are refused.",
37500
+ "description": "Whole-org or delegated mailbox access. Holders of roles:assign also get the preview of a switch (every item that needs a decision, each with the decision_options it takes, worded for what the switch does) and the decisions made, plus notices: member and group domain entries that delegated mode keeps off personal mailboxes, each with how many it leaves out. Notices are informational, never decided, and never hold the switch (notices_truncated past 500, notices_unavailable when they could not be read). In whole-org mode it also lists narrowed_agents: every live agent connection the switch narrows to an own-address key (personal agents of members, and shared agents), informational in the same way (narrowed_agents_truncated past 500, narrowed_agents_unavailable when they could not be read). Needs members:read (owners, admins, members and roles that grant it); API keys are refused.",
37006
37501
  "hasJsonBody": false,
37007
37502
  "method": "GET",
37008
37503
  "operationId": "getAccessMode",
@@ -37264,7 +37759,7 @@ const operationManifest = [
37264
37759
  "binaryResponse": false,
37265
37760
  "bodyRequired": false,
37266
37761
  "command": "list-roles",
37267
- "description": "Every role in the organization (built-in, template copies and custom roles), with how many members and groups hold each, the templates not yet copied, and whether roles can be assigned now. `unassigned` describes role restricted on a member with no role_id, which is not a role and is never in `roles`. Any person (a session or OAuth token); API keys are refused.",
37762
+ "description": "Every role in the organization (built-in, template copies and custom roles), with how many members and groups hold each, the templates not yet copied, and whether roles can be assigned now. `unassigned` describes role restricted on a member with no role_id, which is not a role and is never in `roles`. Needs members:read (owners, admins, members and roles that grant it); API keys are refused.",
37268
37763
  "hasJsonBody": false,
37269
37764
  "method": "GET",
37270
37765
  "operationId": "listRoles",
@@ -39808,12 +40303,12 @@ const operationManifest = [
39808
40303
  },
39809
40304
  "hold": {
39810
40305
  "type": "object",
39811
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
40306
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
39812
40307
  "required": ["reason", "since"],
39813
40308
  "properties": {
39814
40309
  "reason": {
39815
40310
  "type": "string",
39816
- "description": "Open: credential_reuse_hold."
40311
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
39817
40312
  },
39818
40313
  "since": {
39819
40314
  "type": ["string", "null"],
@@ -40041,12 +40536,12 @@ const operationManifest = [
40041
40536
  },
40042
40537
  "hold": {
40043
40538
  "type": "object",
40044
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
40539
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
40045
40540
  "required": ["reason", "since"],
40046
40541
  "properties": {
40047
40542
  "reason": {
40048
40543
  "type": "string",
40049
- "description": "Open: credential_reuse_hold."
40544
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
40050
40545
  },
40051
40546
  "since": {
40052
40547
  "type": ["string", "null"],
@@ -40506,12 +41001,12 @@ const operationManifest = [
40506
41001
  },
40507
41002
  "hold": {
40508
41003
  "type": "object",
40509
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
41004
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
40510
41005
  "required": ["reason", "since"],
40511
41006
  "properties": {
40512
41007
  "reason": {
40513
41008
  "type": "string",
40514
- "description": "Open: credential_reuse_hold."
41009
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
40515
41010
  },
40516
41011
  "since": {
40517
41012
  "type": ["string", "null"],
@@ -40739,12 +41234,12 @@ const operationManifest = [
40739
41234
  },
40740
41235
  "hold": {
40741
41236
  "type": "object",
40742
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
41237
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
40743
41238
  "required": ["reason", "since"],
40744
41239
  "properties": {
40745
41240
  "reason": {
40746
41241
  "type": "string",
40747
- "description": "Open: credential_reuse_hold."
41242
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
40748
41243
  },
40749
41244
  "since": {
40750
41245
  "type": ["string", "null"],
@@ -41720,12 +42215,12 @@ const operationManifest = [
41720
42215
  },
41721
42216
  "hold": {
41722
42217
  "type": "object",
41723
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
42218
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
41724
42219
  "required": ["reason", "since"],
41725
42220
  "properties": {
41726
42221
  "reason": {
41727
42222
  "type": "string",
41728
- "description": "Open: credential_reuse_hold."
42223
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
41729
42224
  },
41730
42225
  "since": {
41731
42226
  "type": ["string", "null"],
@@ -41953,12 +42448,12 @@ const operationManifest = [
41953
42448
  },
41954
42449
  "hold": {
41955
42450
  "type": "object",
41956
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
42451
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
41957
42452
  "required": ["reason", "since"],
41958
42453
  "properties": {
41959
42454
  "reason": {
41960
42455
  "type": "string",
41961
- "description": "Open: credential_reuse_hold."
42456
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
41962
42457
  },
41963
42458
  "since": {
41964
42459
  "type": ["string", "null"],
@@ -42585,12 +43080,12 @@ const operationManifest = [
42585
43080
  },
42586
43081
  "hold": {
42587
43082
  "type": "object",
42588
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
43083
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
42589
43084
  "required": ["reason", "since"],
42590
43085
  "properties": {
42591
43086
  "reason": {
42592
43087
  "type": "string",
42593
- "description": "Open: credential_reuse_hold."
43088
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
42594
43089
  },
42595
43090
  "since": {
42596
43091
  "type": ["string", "null"],
@@ -43070,12 +43565,12 @@ const operationManifest = [
43070
43565
  },
43071
43566
  "hold": {
43072
43567
  "type": "object",
43073
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
43568
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
43074
43569
  "required": ["reason", "since"],
43075
43570
  "properties": {
43076
43571
  "reason": {
43077
43572
  "type": "string",
43078
- "description": "Open: credential_reuse_hold."
43573
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
43079
43574
  },
43080
43575
  "since": {
43081
43576
  "type": ["string", "null"],
@@ -43303,12 +43798,12 @@ const operationManifest = [
43303
43798
  },
43304
43799
  "hold": {
43305
43800
  "type": "object",
43306
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
43801
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
43307
43802
  "required": ["reason", "since"],
43308
43803
  "properties": {
43309
43804
  "reason": {
43310
43805
  "type": "string",
43311
- "description": "Open: credential_reuse_hold."
43806
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
43312
43807
  },
43313
43808
  "since": {
43314
43809
  "type": ["string", "null"],
@@ -44091,12 +44586,12 @@ const operationManifest = [
44091
44586
  },
44092
44587
  "hold": {
44093
44588
  "type": "object",
44094
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
44589
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
44095
44590
  "required": ["reason", "since"],
44096
44591
  "properties": {
44097
44592
  "reason": {
44098
44593
  "type": "string",
44099
- "description": "Open: credential_reuse_hold."
44594
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
44100
44595
  },
44101
44596
  "since": {
44102
44597
  "type": ["string", "null"],
@@ -44324,12 +44819,12 @@ const operationManifest = [
44324
44819
  },
44325
44820
  "hold": {
44326
44821
  "type": "object",
44327
- "description": "Only on a held scheduled send: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. Status stays scheduled.",
44822
+ "description": "Only on a scheduled send that is not going out yet; status stays scheduled. credential_reuse_hold: its OAuth grant was revoked after refresh token reuse, so it waits until released (POST /sent-emails/{id}/release) or canceled; canceled after 7 days. sending_ip_warmup_cap: your dedicated sending address is at today's warm-up limit or paused, so it goes out on its own within the hour after the limit resets at 00:00 UTC (fails with sending_ip_warmup_cap after 7 such holds); no release needed. On sent-email reads and conversation messages.",
44328
44823
  "required": ["reason", "since"],
44329
44824
  "properties": {
44330
44825
  "reason": {
44331
44826
  "type": "string",
44332
- "description": "Open: credential_reuse_hold."
44827
+ "description": "Open: credential_reuse_hold, sending_ip_warmup_cap."
44333
44828
  },
44334
44829
  "since": {
44335
44830
  "type": ["string", "null"],
@@ -48041,7 +48536,10 @@ const operationManifest = [
48041
48536
  "format": "uuid",
48042
48537
  "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)$"
48043
48538
  },
48044
- "endpoint_url": { "type": "string" },
48539
+ "endpoint_url": {
48540
+ "type": "string",
48541
+ "description": "Where it was sent: a webhook's scheme and host, followed by \"/... (path and query hidden)\" when its URL has more (GET /endpoints/{id} has the whole URL), function://<id> for a Function, or pull: for a pull subscription."
48542
+ },
48045
48543
  "status": { "type": "string" },
48046
48544
  "attempt_count": { "type": "integer" },
48047
48545
  "duration_ms": { "type": ["integer", "null"] },
@@ -48052,7 +48550,7 @@ const operationManifest = [
48052
48550
  "description": "The HTTP status the endpoint answered this attempt with: a webhook's own answer, or for a Function what its runtime answered, which is the platform's own error when the Function could not be run. Null when no answer came back (a network error, a timeout, an attempt refused or not sent) and on attempts recorded before this field."
48053
48551
  },
48054
48552
  "response_body": {
48055
- "description": "The first 2 KB of the body the endpoint answered this attempt with, so a handler that answers 200 and ignores a delivery can be seen doing so. It is whatever came back, which may echo what was sent. Null when no answer came back, and cleared when the message's content is discarded or the sent email is deleted. Withheld from a caller who cannot read message content, since an answer can echo what was sent.",
48553
+ "description": "The first 2 KB of the body the endpoint answered this attempt with, so a handler that answers 200 and ignores a delivery can be seen doing so. It is whatever came back, which may echo what was sent. Null when no answer came back, and cleared when the message's content is discarded or the sent email is deleted. Withheld from a caller who cannot read message content, since an answer can echo what was sent. Null for a redirect (3xx), whose body repeats its Location; otherwise the webhook URL's path and query are hidden wherever it repeats them.",
48056
48554
  "type": ["string", "null"]
48057
48555
  },
48058
48556
  "created_at": { "type": "string" },
@@ -48105,7 +48603,7 @@ const operationManifest = [
48105
48603
  "description": "The HTTP status the endpoint answered this attempt with: a webhook's own answer, or for a Function what its runtime answered, which is the platform's own error when the Function could not be run. Null when no answer came back (a network error, a timeout, an attempt refused or not sent) and on attempts recorded before this field."
48106
48604
  },
48107
48605
  "response_body": {
48108
- "description": "The first 2 KB of the body the endpoint answered this attempt with, so a handler that answers 200 and ignores a delivery can be seen doing so. It is whatever came back, which may echo what was sent. Null when no answer came back, and cleared when the message's content is discarded or the sent email is deleted. Withheld from a caller who cannot read message content, since an answer can echo what was sent.",
48606
+ "description": "The first 2 KB of the body the endpoint answered this attempt with, so a handler that answers 200 and ignores a delivery can be seen doing so. It is whatever came back, which may echo what was sent. Null when no answer came back, and cleared when the message's content is discarded or the sent email is deleted. Withheld from a caller who cannot read message content, since an answer can echo what was sent. Null for a redirect (3xx), whose body repeats its Location; otherwise the webhook URL's path and query are hidden wherever it repeats them.",
48109
48607
  "type": ["string", "null"]
48110
48608
  },
48111
48609
  "retry_scheduled": {
@@ -48262,7 +48760,10 @@ const operationManifest = [
48262
48760
  "type": "string",
48263
48761
  "format": "uuid"
48264
48762
  },
48265
- "endpoint_url": { "type": "string" },
48763
+ "endpoint_url": {
48764
+ "type": "string",
48765
+ "description": "Where it was sent: a webhook's scheme and host, followed by \"/... (path and query hidden)\" when its URL has more (GET /endpoints/{id} has the whole URL), function://<id> for a Function, or pull: for a pull subscription."
48766
+ },
48266
48767
  "status": {
48267
48768
  "type": "string",
48268
48769
  "enum": [
@@ -48315,7 +48816,7 @@ const operationManifest = [
48315
48816
  },
48316
48817
  "response_body": {
48317
48818
  "type": ["string", "null"],
48318
- "description": "The first 2 KB of the body the endpoint answered this attempt with, so a handler that answers 200 and ignores a delivery can be seen doing so. It is whatever came back, which may echo what was sent. Null when no answer came back, and cleared when the message's content is discarded or the sent email is deleted. Withheld from a caller who cannot read message content, since an answer can echo what was sent."
48819
+ "description": "The first 2 KB of the body the endpoint answered this attempt with, so a handler that answers 200 and ignores a delivery can be seen doing so. It is whatever came back, which may echo what was sent. Null when no answer came back, and cleared when the message's content is discarded or the sent email is deleted. Withheld from a caller who cannot read message content, since an answer can echo what was sent. Null for a redirect (3xx), whose body repeats its Location; otherwise the webhook URL's path and query are hidden wherever it repeats them."
48319
48820
  },
48320
48821
  "latest_attempt": {
48321
48822
  "type": "boolean",
@@ -49577,9 +50078,18 @@ function cutLabel(text, max) {
49577
50078
  return (/[\uD800-\uDBFF]$/.test(cut) ? cut.slice(0, -1) : cut).trimEnd();
49578
50079
  }
49579
50080
  /**
49580
- * A look-alike as a must-not-match sample: the email as written, labelled
49581
- * with its kind and why the rule should not match it ("medical: ..."), or
49582
- * the why alone when both do not fit a label.
50081
+ * Whether a look-alike is one the rule should match: its `expected` as the
50082
+ * API gives it. An answer without one (an older server) is must-not-match,
50083
+ * as every look-alike was.
50084
+ */
50085
+ function lookAlikeExpected(lookAlike) {
50086
+ return lookAlike.expected === "match" ? "match" : "no_match";
50087
+ }
50088
+ /**
50089
+ * A look-alike as a sample, keeping its `expected` (most must not match; a
50090
+ * near case the rule should take must match): the email as written,
50091
+ * labelled with its kind and why ("medical: ..."), or the why alone when
50092
+ * both do not fit a label.
49583
50093
  */
49584
50094
  function lookAlikeSample(lookAlike) {
49585
50095
  if (!isRecord$1(lookAlike) || !isRecord$1(lookAlike.email)) return null;
@@ -49588,7 +50098,7 @@ function lookAlikeSample(lookAlike) {
49588
50098
  const both = kind && why ? `${kind}: ${why}` : kind || why;
49589
50099
  const label = both.length <= SAMPLE_LABEL_MAX ? both : why.length <= SAMPLE_LABEL_MAX ? why : `${cutLabel(why, 197)}...`;
49590
50100
  return {
49591
- expected: "no_match",
50101
+ expected: lookAlikeExpected(lookAlike),
49592
50102
  ...label ? { label } : {},
49593
50103
  email: lookAlike.email
49594
50104
  };
@@ -49665,8 +50175,8 @@ const SAMPLE_KEYS = /* @__PURE__ */ new Set([
49665
50175
  /**
49666
50176
  * The samples a file holds: a JSON array of samples, as --samples-file
49667
50177
  * writes them, or a generate-look-alikes answer saved as the command printed
49668
- * it (with or without --json), whose look-alikes become must-not-match
49669
- * samples numbered as its report numbered them. Only a literal [] holds no
50178
+ * it (with or without --json), whose look-alikes become samples, each
50179
+ * keeping whether it must match, numbered as its report numbered them. Only a literal [] holds no
49670
50180
  * samples; an answer with none is refused, so it never empties a rule's.
49671
50181
  */
49672
50182
  function samplesFromJson(value, source) {
@@ -49794,19 +50304,25 @@ function expectSamples(flags) {
49794
50304
  function pickFlagHelp(flags) {
49795
50305
  return `Take only these samples from ${flags.map((flag) => `--${flag}`).join(" or ")}, by their numbers from 1 as generate-look-alikes printed them: --pick 2,4. A number the file does not hold is refused.`;
49796
50306
  }
49797
- /** What the rule decided for a look-alike, and what its status makes of it. */
49798
- function decidedLine(outcome, status) {
50307
+ /**
50308
+ * What the rule decided for a look-alike, and what its status makes of it,
50309
+ * against what it should do: leave it (`no_match`), or take it (`match`).
50310
+ */
50311
+ function decidedLine(outcome, status, expected) {
49799
50312
  if (outcome === "not_decided") return "The rule did not decide it: it was not reached in time, or deciding it failed.";
49800
- if (outcome === "matched") return status === "undecided" ? "The rule matched it, but it reads a spam score, which a look-alike does not carry, so this one is undecided." : "The rule matched it, so mail like it would be shared.";
50313
+ if (outcome === "matched") return status === "undecided" ? "The rule matched it, but it reads a spam score, which a look-alike does not carry, so this one is undecided." : expected === "match" ? "The rule matched it, as it should." : "The rule matched it, so mail like it would be shared.";
49801
50314
  const decided = outcome === "near_miss" ? "The rule nearly matched it, but did not" : "The rule did not match it";
49802
- return status === "undecided" ? `${decided}, on something it could not decide (its classification failed, a fact or a question's answer is missing, or it reads a spam score, which a look-alike does not carry), so this one is undecided.` : `${decided}.`;
50315
+ if (status === "undecided") return `${decided}, on something it could not decide (its classification failed, a fact or a question's answer is missing, or it reads a spam score, which a look-alike does not carry), so this one is undecided.`;
50316
+ if (expected === "no_match") return `${decided}.`;
50317
+ return `${decided}, ${outcome === "near_miss" ? "though" : "but"} it should: mail like it would be missed.`;
49803
50318
  }
49804
50319
  /**
49805
50320
  * The stderr report of generate-look-alikes: each look-alike numbered as the
49806
50321
  * samples file numbers it, with its status, kind, subject, sender, why the
49807
- * rule should not match it and what the rule decided; the counts; the
49808
- * answer's note; and how to save the ones you choose. With --samples-file it
49809
- * writes every look-alike there as a must-not-match sample, in that order.
50322
+ * rule should (or should not) match it and what the rule decided; the
50323
+ * counts; the answer's note; and how to save the ones you choose. With
50324
+ * --samples-file it writes every look-alike there as a sample keeping its
50325
+ * expected, in that order.
49810
50326
  */
49811
50327
  function lookAlikesReport(data, request) {
49812
50328
  const file = request.flags?.[LOOK_ALIKES_SAMPLES_FILE_FLAG];
@@ -49831,9 +50347,10 @@ function lookAlikesReport(data, request) {
49831
50347
  const status = typeof lookAlike.status === "string" ? lookAlike.status : "undecided";
49832
50348
  const kind = typeof lookAlike.kind === "string" ? lookAlike.kind : "other";
49833
50349
  const outcome = typeof lookAlike.outcome === "string" ? lookAlike.outcome : "not_decided";
50350
+ const expected = lookAlikeExpected(lookAlike);
49834
50351
  lines.push(`${index + 1}. ${status} ${kind} ${subject} from ${from}`);
49835
- if (typeof lookAlike.why === "string" && lookAlike.why.trim()) lines.push(` Why it should not match: ${lookAlike.why.trim()}`);
49836
- lines.push(` ${decidedLine(outcome, status)}`);
50352
+ if (typeof lookAlike.why === "string" && lookAlike.why.trim()) lines.push(` Why it should ${expected === "match" ? "" : "not "}match: ${lookAlike.why.trim()}`);
50353
+ lines.push(` ${decidedLine(outcome, status, expected)}`);
49837
50354
  });
49838
50355
  const counts = isRecord$1(data.counts) ? data.counts : {};
49839
50356
  const count = (key) => typeof counts[key] === "number" ? counts[key] : 0;
@@ -49841,9 +50358,12 @@ function lookAlikesReport(data, request) {
49841
50358
  lines.push(`Counts: ${count("passed")} passed, ${count("failed")} failed, ${count("undecided")} undecided${dropped > 0 ? `; ${dropped} asked for did not come back` : ""}.`);
49842
50359
  if (typeof data.note === "string" && data.note.trim()) lines.push(data.note.trim());
49843
50360
  const numbered = (status) => entries.map(({ lookAlike }, index) => lookAlike.status === status ? index + 1 : 0).filter((n) => n > 0);
49844
- const matched = numbered("failed");
50361
+ const wanted = (n) => entries[n - 1]?.sample.expected === "match";
50362
+ const failed = numbered("failed");
50363
+ const missed = failed.filter(wanted);
50364
+ const matched = failed.filter((n) => !wanted(n));
49845
50365
  const undecided = numbered("undecided");
49846
- const chosen = matched.length > 0 ? matched : undecided.length > 0 ? numbered("passed") : [];
50366
+ const chosen = failed.length > 0 ? failed : undecided.length > 0 ? numbered("passed") : [];
49847
50367
  const pick = chosen.length > 0 ? ` --pick ${chosen.join(",")}` : "";
49848
50368
  const body = isRecord$1(request.body) ? request.body : {};
49849
50369
  const ruleId = typeof body.rule_id === "string" ? body.rule_id : null;
@@ -49852,8 +50372,10 @@ function lookAlikesReport(data, request) {
49852
50372
  const save = ruleId ? `\`primitive email-rules update-email-rule ${ruleId} --${ADD_SAMPLES_FILE_FLAG} ${target}${pick}\`` : requestId ? `\`primitive email-rules accept-email-rule-request ${requestId} --${SAMPLES_FILE_FLAG} ${target}${pick}\` when the member the request asks accepts it` : `\`primitive email-rules create-email-rule ... --${SAMPLES_FILE_FLAG} ${target}${pick}\` when you save the rule`;
49853
50373
  const one = (count, single, many) => count === 1 ? single : many;
49854
50374
  const noneDecided = entries.length > 0 && undecided.length === entries.length ? `None of them was decided (each says why above), so saved as they are they may stay undecided; if the rule reads a spam score, give each email a spam_score${typeof file === "string" ? " in the file" : ""} first.` : "";
49855
- const which = matched.length > 0 ? `Keep ${one(matched.length, "the one it matched as an email", "the ones it matched as emails")} it must not match` : chosen.length > 0 ? `Keep ${one(chosen.length, "the one it did not match as an email", "the ones it did not match as emails")} it must not match (an undecided one may stay undecided as a sample)` : `Keep ${one(entries.length, "it as an email", "them as emails")} the rule must not match`;
49856
- const test = matched.length > 0 ? ` Test an edited rule on ${one(matched.length, "it", "them")} with \`primitive email-rules test-email-rule ${ruleId ? `--rule-id ${ruleId}` : "--body-file <body.json>"} --${EXPECT_SAMPLES_FILE_FLAG} ${target}${pick}\`.` : "";
50375
+ const keepMatched = `${one(matched.length, "the one it matched as an email", "the ones it matched as emails")} it must not match`;
50376
+ const keepMissed = `${one(missed.length, "the one it missed as an email", "the ones it missed as emails")} it must match`;
50377
+ const which = failed.length > 0 ? `Keep ${matched.length > 0 && missed.length > 0 ? `${keepMatched}, and ${keepMissed}` : matched.length > 0 ? keepMatched : keepMissed}` : chosen.length > 0 ? chosen.some(wanted) ? `Keep ${one(chosen.length, "the one", "the ones")} it decided as expected (each keeps whether it must match; an undecided one may stay undecided as a sample)` : `Keep ${one(chosen.length, "the one it did not match as an email", "the ones it did not match as emails")} it must not match (an undecided one may stay undecided as a sample)` : entries.some((_, index) => wanted(index + 1)) ? `Keep ${one(entries.length, "it as an email", "them as emails")} the rule must match or not, as each says` : `Keep ${one(entries.length, "it as an email", "them as emails")} the rule must not match`;
50378
+ const test = failed.length > 0 ? ` Test an edited rule on ${one(failed.length, "it", "them")} with \`primitive email-rules test-email-rule ${ruleId ? `--rule-id ${ruleId}` : "--body-file <body.json>"} --${EXPECT_SAMPLES_FILE_FLAG} ${target}${pick}\`.` : "";
49857
50379
  if (typeof file === "string") {
49858
50380
  const samples = entries.map((entry) => entry.sample);
49859
50381
  if (samples.length === 0) {
@@ -49885,7 +50407,7 @@ function lookAlikesReport(data, request) {
49885
50407
  };
49886
50408
  }
49887
50409
  const wrote = `Wrote ${one(samples.length, "the look-alike", `the ${samples.length} look-alikes`)} to ${file}, numbered as above.`;
49888
- lines.push(noneDecided ? `${wrote} ${noneDecided}` : `${wrote} ${which} with ${save}; --pick takes any of the numbers.${test}`);
50410
+ lines.push(noneDecided ? `${wrote} ${noneDecided}` : `${wrote} ${which}, with ${save}; --pick takes any of the numbers.${test}`);
49889
50411
  } else if (noneDecided) lines.push(noneDecided);
49890
50412
  else if (entries.length > 0) lines.push(`${which}: save the JSON printed above to a file and give it to ${save}; --pick takes any of the numbers above.${test}`);
49891
50413
  return { lines };
@@ -50562,8 +51084,8 @@ function readAgain(id) {
50562
51084
  * The hint for update-email-rule's refusals: an email_rule_conflict by its
50563
51085
  * details.reason (version_moved, revision_moved, expectations_moved,
50564
51086
  * rule_changed), and the expectations guard's expectations_failed,
50565
- * expectations_undecided and no_expectations. Nothing was saved in any of
50566
- * them.
51087
+ * expectations_undecided, expectations_unreadable and no_expectations.
51088
+ * Nothing was saved in any of them.
50567
51089
  */
50568
51090
  function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
50569
51091
  const id = typeof ruleId === "string" && ruleId ? ruleId : "<rule-id>";
@@ -50595,6 +51117,13 @@ function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
50595
51117
  const byReason = reason !== "none" && Object.hasOwn(UNDECIDED_NEXT_STEP, reason) ? UNDECIDED_NEXT_STEP[reason] : UNDECIDED_NEXT_STEP.none;
50596
51118
  return `Hint: the rule, as this write would leave it, was judged against its expectations before saving (if_expectations_pass), and nothing was saved.${which}${code === "expectations_failed" ? "" : samplesMayStay ? `${undecided.length > 0 ? ` ${byReason}` : ""} ${UNDECIDED_SAMPLES_NEXT_STEP} ${refusedSampleTest(body, id)}` : ` ${byReason}`} The command exits ${updateEmailRuleErrorExitCode(payload) ?? 1}.`;
50597
51119
  }
51120
+ if (code === "expectations_unreadable") {
51121
+ const unreadable = Array.isArray(details.unreadable) ? details.unreadable.filter((entry) => entry !== null && entry !== void 0 && entry !== "").map(String) : [];
51122
+ const one = unreadable.length === 1;
51123
+ const named = unreadable.length > 0 ? `: ${unreadable.join(", ")}` : "";
51124
+ const them = one ? "it" : "them";
51125
+ return `Hint: the rule, as this write would leave it, was judged against its expectations before saving (if_expectations_pass), and nothing was saved. ${one ? "An expectation names an email" : "Expectations name emails"} this rule cannot read (deleted, or outside its scope or its author's mail)${named}. Sending the write again will not decide ${them}: send --expectations-file without ${them}, or an evaluation_scope that reads ${them}. The command exits 1.`;
51126
+ }
50598
51127
  if (code === "no_expectations") return "Hint: nothing was saved. Give the rule expectations with --expectations-file or made-up emails with --expectation-samples-file or --add-expectation-samples-file (in this write or before it), or send the write without if_expectations_pass (--fail-on-expectations or --if-expectations-pass).";
50599
51128
  }
50600
51129
  /** The reasons a guard's undecided judgment can be decided by sending the write again. */
@@ -50631,13 +51160,14 @@ const UNDECIDED_NEXT_STEP = {
50631
51160
  };
50632
51161
  /**
50633
51162
  * update-email-rule's exit code for the expectations guard's refusals: 1 when
50634
- * one failed, or when they may not be decided by trying again (the rule
50635
- * cannot run as its author, or a made-up email is undecided for no reason
50636
- * the answer gives); 3 when trying again later can decide them.
51163
+ * one failed, or when they may not be decided by trying again (an expectation
51164
+ * names an email the rule cannot read, the rule cannot run as its author, or
51165
+ * a made-up email is undecided for no reason the answer gives); 3 when trying
51166
+ * again later can decide them.
50637
51167
  */
50638
51168
  function updateEmailRuleErrorExitCode(payload) {
50639
51169
  const code = isRecord(payload) ? payload.code : void 0;
50640
- if (code === "expectations_failed") return 1;
51170
+ if (code === "expectations_failed" || code === "expectations_unreadable") return 1;
50641
51171
  if (code !== "expectations_undecided") return void 0;
50642
51172
  const details = errorDetails(payload);
50643
51173
  if (details.reason === "author_unresolvable") return 1;
@@ -50687,7 +51217,7 @@ function listEmailRulesReport(data) {
50687
51217
  /** create-email-rule's --fail-on-expectations: the exit code follows the check made after saving. */
50688
51218
  const FAIL_ON_EXPECTATIONS_HELP = "Exit 1 when an expectation in the answer's expectations_check failed, and 3 when none failed but one is undecided or the expectations this write sent were not checked (test the rule to decide). A create does not judge made-up emails, so with some it exits 3. Without it the command exits 0 whatever the check says.";
50689
51219
  /** update-email-rule's --fail-on-expectations: the server refuses the write. */
50690
- const UPDATE_FAIL_ON_EXPECTATIONS_HELP = "Refuse the write unless the rule, as this write would leave it, passes its expectations. It sends if_expectations_pass (over any in --body-file or --raw-body), so the server judges a new version, a restored one, a new scope or turning the rule active before saving, on its emails by id and its made-up emails, and saves nothing when one failed (exit 1), one is undecided (exit 3, or 1 when the rule cannot run as its author or a made-up email is undecided for no reason the answer gives) or the rule has none (exit 1). It can take as long as a test of the rule; the command waits for it. Judging needs a credential that reads the mail's content. A write the server does not judge (one changing only expectations, say) is saved, and the exit code then follows the answer's expectations_check, as on create. With --json, a refused write's document holds the API's error alone; a saved write's holds the rule.";
51220
+ const UPDATE_FAIL_ON_EXPECTATIONS_HELP = "Refuse the write unless the rule, as this write would leave it, passes its expectations. It sends if_expectations_pass (over any in --body-file or --raw-body), so the server judges a new version, a restored one, a new scope or turning the rule active before saving, on its emails by id and its made-up emails, and saves nothing when one failed (exit 1), one names an email the rule cannot read (exit 1, since sending again never decides it), one is undecided (exit 3, or 1 when the rule cannot run as its author or a made-up email is undecided for no reason the answer gives) or the rule has none (exit 1). It can take as long as a test of the rule; the command waits for it. Judging needs a credential that reads the mail's content. A write the server does not judge (one changing only expectations, say) is saved, and the exit code then follows the answer's expectations_check, as on create. With --json, a refused write's document holds the API's error alone; a saved write's holds the rule.";
50691
51221
  /** What a samples file flag reads. */
50692
51222
  const SAMPLES_FILE_SHAPE = "A JSON file of made-up emails the rule must match or not: an array such as [{\"expected\": \"no_match\", \"label\": \"a personal bill\", \"email\": {...}}], with email as test-email-rule-on-sample takes it (text up to 4,000 characters, at most 10 each of to, cc and attachment_types), like the one generate-look-alikes --samples-file writes, or a generate-look-alikes answer saved as it printed it.";
50693
51223
  const EXPECTATION_FLAG_NOTE = "Replaces any expect in --body-file or --raw-body. The answer reports them in expectations (passed, counts, results) and the exit code follows it; see --help-full.";
@@ -50704,6 +51234,15 @@ function expectationsGuardBodyFields(flags) {
50704
51234
  value: true
50705
51235
  }];
50706
51236
  }
51237
+ /**
51238
+ * The stderr report of end-email-rule-share: the answer's note, which says
51239
+ * the rule itself is left as it was (ending a share does not turn it off)
51240
+ * and, to the member who shared, how to stop it.
51241
+ */
51242
+ function endEmailRuleShareReport(data) {
51243
+ const note = isRecord(data) && typeof data.note === "string" ? data.note.trim() : "";
51244
+ return { lines: note ? [note] : [] };
51245
+ }
50707
51246
  const EMAIL_RULE_OPERATION_EXTENSIONS = {
50708
51247
  testEmailRule: {
50709
51248
  flags: {
@@ -50773,12 +51312,12 @@ const EMAIL_RULE_OPERATION_EXTENSIONS = {
50773
51312
  report: writtenEmailRuleReport
50774
51313
  },
50775
51314
  generateLookAlikes: {
50776
- flags: { [LOOK_ALIKES_SAMPLES_FILE_FLAG]: Flags.string({ description: `Also write the look-alikes to this JSON file as made-up emails the rule must not match, a JSON array numbered from 1 in the order the report prints them. Save the ones you choose with create-email-rule --${SAMPLES_FILE_FLAG}, update-email-rule --${ADD_SAMPLES_FILE_FLAG} or, for a request, accept-email-rule-request --${SAMPLES_FILE_FLAG}, with --pick; test an edited rule on them with test-email-rule --${EXPECT_SAMPLES_FILE_FLAG}. Replaces the file if it exists, once the call succeeds; when no look-alikes came back it leaves the file as it was and exits 1.` }) },
51315
+ flags: { [LOOK_ALIKES_SAMPLES_FILE_FLAG]: Flags.string({ description: `Also write the look-alikes to this JSON file as made-up emails the rule must match or not (each keeps its expected: most must not match, and a near case it should take must match), a JSON array numbered from 1 in the order the report prints them. Save the ones you choose with create-email-rule --${SAMPLES_FILE_FLAG}, update-email-rule --${ADD_SAMPLES_FILE_FLAG} or, for a request, accept-email-rule-request --${SAMPLES_FILE_FLAG}, with --pick; test an edited rule on them with test-email-rule --${EXPECT_SAMPLES_FILE_FLAG}. Replaces the file if it exists, once the call succeeds; when no look-alikes came back it leaves the file as it was and exits 1. The numbered report is printed on stderr, and only without --json, which prints exactly one JSON document and nothing on stderr; the answer's look_alikes and this file hold the same emails in the same order, so with --json the file still gives the numbered set to --pick from.` }) },
50777
51316
  report: lookAlikesReport
50778
51317
  },
50779
51318
  acceptEmailRuleRequest: {
50780
51319
  flags: {
50781
- [SAMPLES_FILE_FLAG]: Flags.string({ description: `${SAMPLES_FILE_SHAPE} Sets expectation_samples (at most 20), over any in --body-file or --raw-body: they are kept on the rule this accept writes, such as the look-alikes of the request it must never match.` }),
51320
+ [SAMPLES_FILE_FLAG]: Flags.string({ description: `${SAMPLES_FILE_SHAPE} Sets expectation_samples (at most 20), over any in --body-file or --raw-body: they are kept on the rule this accept writes, such as the look-alikes of the request, each keeping whether it must match.` }),
50782
51321
  [PICK_FLAG]: Flags.string({ description: pickFlagHelp([SAMPLES_FILE_FLAG]) })
50783
51322
  },
50784
51323
  bodyFields: samplesBodyFields(false),
@@ -50788,6 +51327,10 @@ const EMAIL_RULE_OPERATION_EXTENSIONS = {
50788
51327
  flags: {},
50789
51328
  report: compileEmailRuleReport
50790
51329
  },
51330
+ endEmailRuleShare: {
51331
+ flags: {},
51332
+ report: endEmailRuleShareReport
51333
+ },
50791
51334
  getEmailRule: {
50792
51335
  flags: {},
50793
51336
  report: getEmailRuleReport
@@ -52926,7 +53469,7 @@ function savedConnectedProfiles(configDir, exclude) {
52926
53469
  */
52927
53470
  async function otherProfiles(configDir, session, current) {
52928
53471
  if (session) try {
52929
- const { connectedProfilesForSession } = await import("./machine-session-DNnNhhFr.js").then((n) => n.s);
53472
+ const { connectedProfilesForSession } = await import("./machine-session-Cre9Mt_2.js").then((n) => n.s);
52930
53473
  return {
52931
53474
  inSession: true,
52932
53475
  profiles: connectedProfilesForSession(configDir, session, current)
@@ -54321,7 +54864,7 @@ function createOperationCommand(operation) {
54321
54864
  ...tail ? { pastFlag: "--since" } : query.cursor !== void 0 ? { pastFlag: "--cursor" } : {},
54322
54865
  nextCursor: tail ? null : more,
54323
54866
  caller: tail || more ? null : await readCallerMailFor(auth, apiClient.client)
54324
- }) : EMPTY_RESULT_HINTS[operation.sdkName];
54867
+ }) : emptyRuleListHint(operation.sdkName, query) ?? EMPTY_RESULT_HINTS[operation.sdkName];
54325
54868
  if (hint && jsonOutput) summary.push(hint);
54326
54869
  else if (hint) process.stderr.write(`${hint}\n`);
54327
54870
  }
@@ -54398,6 +54941,30 @@ const EMPTY_RESULT_HINTS = {
54398
54941
  listFilters: "(no results) No filter rules configured.",
54399
54942
  listFunctions: "(no results) No Functions configured yet. Start with `primitive functions templates`, then `primitive functions init --template <template>` and `primitive functions deploy --name <name> --file <bundle>`."
54400
54943
  };
54944
+ /**
54945
+ * An empty rule request or share list, read by the filters the call left at
54946
+ * their defaults: each list shows only part of what you can see by default
54947
+ * (pending requests made to you; live shares made with you), so an empty
54948
+ * answer says which flags widen it. Undefined for any other list, when every
54949
+ * filter was given, or on a later page (--cursor), which is empty only past
54950
+ * the end.
54951
+ */
54952
+ function emptyRuleListHint(sdkName, query) {
54953
+ if (query.cursor !== void 0) return void 0;
54954
+ const unset = (name) => query[name] === void 0;
54955
+ const said = (noun, phrase, flags) => phrase === null ? void 0 : `(no results) No ${noun} match. By default this lists only ${phrase}: add \`${flags.join(" ")}\` to widen it.`;
54956
+ if (sdkName === "listEmailRuleRequests") {
54957
+ const box = unset("box");
54958
+ const status = unset("status");
54959
+ return said("requests", box && status ? "pending requests made to you" : box ? "requests made to you" : status ? "pending requests" : null, [...box ? ["--box all"] : [], ...status ? ["--status any"] : []]);
54960
+ }
54961
+ if (sdkName === "listEmailRuleShares") {
54962
+ const box = unset("box");
54963
+ const live = unset("live");
54964
+ return said("shares", box && live ? "live shares made with you" : box ? "shares made with you" : live ? "live shares" : null, [...box ? ["--box all"] : [], ...live ? ["--live any"] : []]);
54965
+ }
54966
+ if (sdkName === "listGivenEmailRuleShares") return said("shares", unset("live") ? "live shares of your mail" : null, ["--live any"]);
54967
+ }
54401
54968
  function canonicalizeCliReferences(description) {
54402
54969
  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'`");
54403
54970
  }