@samva/cli 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/AGENTS.md +27 -3
  2. package/README.md +10 -3
  3. package/dist/bin.mjs +1513 -339
  4. package/package.json +7 -7
package/dist/bin.mjs CHANGED
@@ -13982,7 +13982,7 @@ var layer12 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE
13982
13982
  // package.json
13983
13983
  var package_default = {
13984
13984
  name: "@samva/cli",
13985
- version: "0.8.0",
13985
+ version: "0.10.0",
13986
13986
  description: "Samva CLI \u2014 email and platform operations from your terminal",
13987
13987
  keywords: [
13988
13988
  "cli",
@@ -14037,16 +14037,16 @@ var package_default = {
14037
14037
  "@types/node": "catalog:",
14038
14038
  "better-auth": "catalog:",
14039
14039
  effect: "catalog:effect",
14040
- samva: "workspace:0.11.0",
14040
+ samva: "workspace:0.13.0",
14041
14041
  typescript: "catalog:",
14042
14042
  vite: "~8.3.0",
14043
14043
  vitest: "catalog:"
14044
14044
  },
14045
14045
  optionalDependencies: {
14046
- "@samva/cli-darwin-arm64": "workspace:0.8.0",
14047
- "@samva/cli-darwin-x64": "workspace:0.8.0",
14048
- "@samva/cli-linux-arm64": "workspace:0.8.0",
14049
- "@samva/cli-linux-x64": "workspace:0.8.0"
14046
+ "@samva/cli-darwin-arm64": "workspace:0.10.0",
14047
+ "@samva/cli-darwin-x64": "workspace:0.10.0",
14048
+ "@samva/cli-linux-arm64": "workspace:0.10.0",
14049
+ "@samva/cli-linux-x64": "workspace:0.10.0"
14050
14050
  },
14051
14051
  engines: {
14052
14052
  node: ">=18"
@@ -43621,6 +43621,121 @@ var DIAGNOSTIC_CODES = codes2({
43621
43621
  channelOnly: true
43622
43622
  }
43623
43623
  });
43624
+ // ../sdk/dist/inline-attachments-B56eS0MF.js
43625
+ var SDK_VERSION = "0.13.0";
43626
+ var CLIENT_ATTRIBUTION_HEADER = "x-samva-client";
43627
+ var clientAttribution = (surface) => `${surface}/${SDK_VERSION}`;
43628
+ var MediaUploadError = class extends Error {
43629
+ _tag = "MediaUploadError";
43630
+ filename;
43631
+ mediaId;
43632
+ status;
43633
+ cause;
43634
+ constructor(input) {
43635
+ super(input.status === undefined ? `Uploading attachment "${input.filename}" (${input.mediaId}) failed before storage answered` : `Uploading attachment "${input.filename}" (${input.mediaId}) failed with storage status ${input.status}`, { cause: input.cause });
43636
+ this.name = "MediaUploadError";
43637
+ this.filename = input.filename;
43638
+ this.mediaId = input.mediaId;
43639
+ this.status = input.status;
43640
+ this.cause = input.cause;
43641
+ }
43642
+ };
43643
+ var isRecord = (value) => typeof value === "object" && value !== null;
43644
+ var attachmentsOf = (payload) => {
43645
+ const email = payload.email;
43646
+ if (!isRecord(email))
43647
+ return [];
43648
+ const attachments = email.attachments;
43649
+ return Array.isArray(attachments) ? attachments : [];
43650
+ };
43651
+ var decodedBase64Bytes = (content) => {
43652
+ const length = content.length;
43653
+ if (length === 0)
43654
+ return 0;
43655
+ let padding = 0;
43656
+ if (content.endsWith("=="))
43657
+ padding = 2;
43658
+ else if (content.endsWith("="))
43659
+ padding = 1;
43660
+ return Math.floor(length * 3 / 4) - padding;
43661
+ };
43662
+ var base64ToBytes = (content) => {
43663
+ let binary;
43664
+ try {
43665
+ binary = atob(content);
43666
+ } catch {
43667
+ return;
43668
+ }
43669
+ const bytes = new Uint8Array(binary.length);
43670
+ for (let index = 0;index < binary.length; index += 1)
43671
+ bytes[index] = binary.charCodeAt(index);
43672
+ return bytes;
43673
+ };
43674
+ var planInlineUploads = (payload) => {
43675
+ const inline = [];
43676
+ for (const [index, entry] of attachmentsOf(payload).entries()) {
43677
+ if (!isRecord(entry))
43678
+ continue;
43679
+ const attachment = entry;
43680
+ if (typeof attachment.content !== "string")
43681
+ continue;
43682
+ if (attachment.mediaId !== undefined)
43683
+ return [];
43684
+ inline.push({
43685
+ index,
43686
+ filename: typeof attachment.filename === "string" ? attachment.filename : "attachment",
43687
+ contentType: typeof attachment.contentType === "string" ? attachment.contentType : "application/octet-stream",
43688
+ content: attachment.content,
43689
+ sizeBytes: typeof attachment.size === "number" ? attachment.size : decodedBase64Bytes(attachment.content)
43690
+ });
43691
+ }
43692
+ let remaining = inline.reduce((total, upload) => total + upload.sizeBytes, 0);
43693
+ if (remaining <= 4194304)
43694
+ return [];
43695
+ const chosen = [];
43696
+ const largestFirst = [...inline].sort((left, right) => right.sizeBytes - left.sizeBytes || left.index - right.index);
43697
+ for (const { content, ...upload } of largestFirst) {
43698
+ if (remaining <= 4194304)
43699
+ break;
43700
+ const bytes = base64ToBytes(content);
43701
+ if (bytes === undefined)
43702
+ return [];
43703
+ chosen.push({
43704
+ ...upload,
43705
+ bytes
43706
+ });
43707
+ remaining -= upload.sizeBytes;
43708
+ }
43709
+ return chosen;
43710
+ };
43711
+ var mediaCreateBody = (upload) => ({
43712
+ filename: upload.filename,
43713
+ contentType: upload.contentType,
43714
+ sizeBytes: upload.sizeBytes,
43715
+ purpose: "attachment"
43716
+ });
43717
+ var uploadContentType = (headers) => Object.entries(headers).find(([name]) => name.toLowerCase() === "content-type")?.[1];
43718
+ var withUploadedAttachments = (payload, uploaded) => {
43719
+ const email = payload.email;
43720
+ const attachments = email.attachments.map((entry, index) => {
43721
+ const replacement = uploaded.get(index);
43722
+ if (replacement === undefined)
43723
+ return entry;
43724
+ const { content: _content, ...rest } = entry;
43725
+ return {
43726
+ ...rest,
43727
+ mediaId: replacement.mediaId
43728
+ };
43729
+ });
43730
+ return {
43731
+ ...payload,
43732
+ email: {
43733
+ ...email,
43734
+ attachments
43735
+ }
43736
+ };
43737
+ };
43738
+
43624
43739
  // ../sdk/dist/normalize-B79uJIeb.js
43625
43740
  function toRecipientArray(recipient) {
43626
43741
  return Array.isArray(recipient) ? recipient : [recipient];
@@ -43690,11 +43805,6 @@ function buildMessagesSendPayload(input) {
43690
43805
  };
43691
43806
  }
43692
43807
 
43693
- // ../sdk/dist/client-attribution-Ct2FKITg.js
43694
- var SDK_VERSION = "0.11.0";
43695
- var CLIENT_ATTRIBUTION_HEADER = "x-samva-client";
43696
- var clientAttribution = (surface) => `${surface}/${SDK_VERSION}`;
43697
-
43698
43808
  // ../../node_modules/.bun/effect@4.0.0/node_modules/effect/dist/Random.js
43699
43809
  var Random2 = Random;
43700
43810
  var randomWith = (f) => withFiber2((fiber) => succeed6(f(fiber.getRef(Random2))));
@@ -43946,6 +44056,7 @@ var baseUrl = () => {
43946
44056
 
43947
44057
  // ../../node_modules/.bun/effect@4.0.0/node_modules/effect/dist/http/HttpClientRequest.js
43948
44058
  var TypeId40 = "~effect/http/HttpClientRequest";
44059
+ var isHttpClientRequest = (u) => hasProperty(u, TypeId40);
43949
44060
  var Proto13 = {
43950
44061
  [TypeId40]: TypeId40,
43951
44062
  ...BaseProto,
@@ -44044,6 +44155,7 @@ var setHash = /* @__PURE__ */ dual(2, (self, hash) => makeWith(self.method, self
44044
44155
  var setBody = /* @__PURE__ */ dual(2, (self, body) => {
44045
44156
  return makeWith(self.method, self.url, self.urlParams, self.hash, updateHeaders(self.headers, body), body);
44046
44157
  });
44158
+ var bodyUint8Array = /* @__PURE__ */ dual((args) => isHttpClientRequest(args[0]), (self, body, contentType) => setBody(self, uint8Array(body, contentType)));
44047
44159
  var bodyFormData = /* @__PURE__ */ dual(2, (self, body) => setBody(self, formData(body)));
44048
44160
  function toUrl(self) {
44049
44161
  const r = make32(self.url, self.urlParams, getOrUndefined(self.hash));
@@ -46053,7 +46165,7 @@ var fetch2 = /* @__PURE__ */ make34((request, url, signal, fiber) => {
46053
46165
  });
46054
46166
  var layer15 = /* @__PURE__ */ layerMergedContext(/* @__PURE__ */ succeed6(fetch2));
46055
46167
 
46056
- // ../sdk/dist/client-8YXjfsVc.js
46168
+ // ../sdk/dist/client-DYPNDvVU.js
46057
46169
  var Sensitive = (schema) => RedactedFromValue(schema);
46058
46170
  var SensitiveString = Sensitive(String4);
46059
46171
  var ABSOLUTE_ISO_INSTANT_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|([+-])(\d{2}):(\d{2}))$/;
@@ -46290,6 +46402,12 @@ var CampaignFooterRequiredError = class extends TaggedError3()("CampaignFooterRe
46290
46402
  };
46291
46403
  var ExternalServiceError = class extends TaggedError3()("ExternalServiceError", Struct({ message: String4 })) {
46292
46404
  };
46405
+ var SenderNotReadyError = class extends TaggedError3()("SenderNotReadyError", Struct({
46406
+ message: String4,
46407
+ sender: String4,
46408
+ retryAfterSeconds: optionalKey2(Union2([Finite.check(isFinite4().annotate({ expected: "a finite number" })), Null2]))
46409
+ })) {
46410
+ };
46293
46411
  var CampaignRecipientId = String4.check(isPattern2(/* @__PURE__ */ new RegExp("^crcpt_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
46294
46412
  expected: "a string matching the RegExp ^crcpt_[0-9a-hjkmnp-tv-z]{16,24}$",
46295
46413
  identifier: "CampaignRecipientId"
@@ -46327,11 +46445,11 @@ var ContactPreferences = Struct({
46327
46445
  }), Null2]))
46328
46446
  }), Null2]))
46329
46447
  }).annotate({ identifier: "ContactPreferences" });
46330
- var UnknownRecord = Record(String4, JsonValue).annotate({ identifier: "UnknownRecord" });
46331
46448
  var BulkUpdateResult = Struct({
46332
46449
  updated: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
46333
46450
  failed: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
46334
46451
  }).annotate({ identifier: "BulkUpdateResult" });
46452
+ var UnknownRecord = Record(String4, JsonValue).annotate({ identifier: "UnknownRecord" });
46335
46453
  var CustomFieldDefinitionId = String4.check(isPattern2(/* @__PURE__ */ new RegExp("^cfield_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
46336
46454
  expected: "a string matching the RegExp ^cfield_[0-9a-hjkmnp-tv-z]{16,24}$",
46337
46455
  identifier: "CustomFieldDefinitionId"
@@ -46381,6 +46499,25 @@ var EmailChannelError = class extends TaggedError3()("EmailChannelError", Struct
46381
46499
  statusCode: optionalKey2(Union2([Finite.check(isFinite4().annotate({ expected: "a finite number" })), Null2]))
46382
46500
  })) {
46383
46501
  };
46502
+ var CustomTrackingCertificate = Struct({
46503
+ reason: Struct({
46504
+ code: Union2([
46505
+ Literal2("initializing"),
46506
+ Literal2("awaiting-hostname"),
46507
+ Literal2("awaiting-dcv"),
46508
+ Literal2("issuing"),
46509
+ Literal2("caa-blocked"),
46510
+ Literal2("validation-error"),
46511
+ Literal2("timed-out"),
46512
+ Literal2("verifying-route"),
46513
+ Literal2("ready"),
46514
+ Literal2("provider-unreachable")
46515
+ ]),
46516
+ message: String4
46517
+ }),
46518
+ lastCheckedAt: Union2([String4, Null2]),
46519
+ nextCheckAt: Union2([String4, Null2])
46520
+ }).annotate({ identifier: "CustomTrackingCertificate" });
46384
46521
  var CustomTrackingDnsRecord = Struct({
46385
46522
  name: String4,
46386
46523
  type: String4,
@@ -46567,6 +46704,36 @@ var ExtensionRun = Struct({
46567
46704
  error: Union2([String4, Null2]),
46568
46705
  logs: ArraySchema(String4)
46569
46706
  }).annotate({ identifier: "ExtensionRun" });
46707
+ var ExtensionPermissionDiff = Struct({
46708
+ added: ArraySchema(Union2([
46709
+ Literal2("permission:read"),
46710
+ Literal2("permission:update"),
46711
+ Literal2("permission:send"),
46712
+ Literal2("permission:quarantine.read"),
46713
+ Literal2("event:mailbox.message.received"),
46714
+ Literal2("event:mailbox.message.sent"),
46715
+ Literal2("event:mailbox.action.pending_approval"),
46716
+ Literal2("event:mailbox.message.quarantined"),
46717
+ Literal2("event:mailbox.message.released"),
46718
+ Literal2("event:mailbox.message.discarded")
46719
+ ])),
46720
+ removed: ArraySchema(Union2([
46721
+ Literal2("permission:read"),
46722
+ Literal2("permission:update"),
46723
+ Literal2("permission:send"),
46724
+ Literal2("permission:quarantine.read"),
46725
+ Literal2("event:mailbox.message.received"),
46726
+ Literal2("event:mailbox.message.sent"),
46727
+ Literal2("event:mailbox.action.pending_approval"),
46728
+ Literal2("event:mailbox.message.quarantined"),
46729
+ Literal2("event:mailbox.message.released"),
46730
+ Literal2("event:mailbox.message.discarded")
46731
+ ]))
46732
+ }).annotate({ identifier: "ExtensionPermissionDiff" });
46733
+ var UserId = String4.check(isPattern2(/* @__PURE__ */ new RegExp("^user_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
46734
+ expected: "a string matching the RegExp ^user_[0-9a-hjkmnp-tv-z]{16,24}$",
46735
+ identifier: "UserId"
46736
+ })).pipe(brand("UserId"));
46570
46737
  var ExtensionBundle = Struct({
46571
46738
  sha256: String4,
46572
46739
  sizeBytes: Finite.check(isInt().annotate({ expected: "an integer" }))
@@ -46617,6 +46784,39 @@ var MailboxPolicyId = String4.check(isPattern2(/* @__PURE__ */ new RegExp("^mbxp
46617
46784
  expected: "a string matching the RegExp ^mbxpol_[0-9a-hjkmnp-tv-z]{16,24}$",
46618
46785
  identifier: "MailboxPolicyId"
46619
46786
  })).pipe(brand("MailboxPolicyId"));
46787
+ var OnboardingReviewRequiredError = class extends TaggedError3()("OnboardingReviewRequiredError", Struct({
46788
+ message: String4,
46789
+ code: Union2([
46790
+ Literal2("review_required"),
46791
+ Literal2("review_in_progress"),
46792
+ Literal2("information_required"),
46793
+ Literal2("review_rejected"),
46794
+ Literal2("identity_review_required"),
46795
+ Literal2("identity_review_rejected"),
46796
+ Literal2("identity_changed")
46797
+ ]),
46798
+ decision: Union2([
46799
+ Literal2("undecided"),
46800
+ Literal2("approved"),
46801
+ Literal2("rejected")
46802
+ ]),
46803
+ stage: Union2([
46804
+ Literal2("collecting"),
46805
+ Literal2("automated_review"),
46806
+ Literal2("manual_review"),
46807
+ Literal2("information_requested"),
46808
+ Literal2("complete")
46809
+ ]),
46810
+ nextAction: Union2([
46811
+ Literal2("wait_for_review"),
46812
+ Literal2("provide_information"),
46813
+ Literal2("verify_sending_identity"),
46814
+ Literal2("reapply"),
46815
+ Literal2("contact_support")
46816
+ ]),
46817
+ identityId: optionalKey2(Union2([String4, Null2]))
46818
+ })) {
46819
+ };
46620
46820
  var MailboxAgentActivity = Struct({
46621
46821
  actions: Struct({
46622
46822
  byType: ArraySchema(Struct({
@@ -46690,10 +46890,6 @@ var MailboxGrantId = String4.check(isPattern2(/* @__PURE__ */ new RegExp("^mbxac
46690
46890
  expected: "a string matching the RegExp ^mbxacl_[0-9a-hjkmnp-tv-z]{16,24}$",
46691
46891
  identifier: "MailboxGrantId"
46692
46892
  })).pipe(brand("MailboxGrantId"));
46693
- var UserId = String4.check(isPattern2(/* @__PURE__ */ new RegExp("^user_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
46694
- expected: "a string matching the RegExp ^user_[0-9a-hjkmnp-tv-z]{16,24}$",
46695
- identifier: "UserId"
46696
- })).pipe(brand("UserId"));
46697
46893
  var MailboxGrantRole = Union2([
46698
46894
  Literal2("admin"),
46699
46895
  Literal2("collaborator"),
@@ -46800,39 +46996,6 @@ var EmailSender = Union2([Struct({
46800
46996
  email: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
46801
46997
  name: optionalKey2(Union2([String4, Null2]))
46802
46998
  }), Null2]).annotate({ identifier: "EmailSender" });
46803
- var OnboardingReviewRequiredError = class extends TaggedError3()("OnboardingReviewRequiredError", Struct({
46804
- message: String4,
46805
- code: Union2([
46806
- Literal2("review_required"),
46807
- Literal2("review_in_progress"),
46808
- Literal2("information_required"),
46809
- Literal2("review_rejected"),
46810
- Literal2("identity_review_required"),
46811
- Literal2("identity_review_rejected"),
46812
- Literal2("identity_changed")
46813
- ]),
46814
- decision: Union2([
46815
- Literal2("undecided"),
46816
- Literal2("approved"),
46817
- Literal2("rejected")
46818
- ]),
46819
- stage: Union2([
46820
- Literal2("collecting"),
46821
- Literal2("automated_review"),
46822
- Literal2("manual_review"),
46823
- Literal2("information_requested"),
46824
- Literal2("complete")
46825
- ]),
46826
- nextAction: Union2([
46827
- Literal2("wait_for_review"),
46828
- Literal2("provide_information"),
46829
- Literal2("verify_sending_identity"),
46830
- Literal2("reapply"),
46831
- Literal2("contact_support")
46832
- ]),
46833
- identityId: optionalKey2(Union2([String4, Null2]))
46834
- })) {
46835
- };
46836
46999
  var DeliveryUnavailableError = class extends TaggedError3()("DeliveryUnavailableError", Struct({
46837
47000
  message: String4,
46838
47001
  retryAfterSeconds: Finite.check(isFinite4().annotate({ expected: "a finite number" }))
@@ -47300,7 +47463,7 @@ var BrandFooter = Struct({
47300
47463
  }).annotate({ identifier: "BrandFooter" });
47301
47464
  var EmailAttachment = Struct({
47302
47465
  filename: String4,
47303
- content: optionalKey2(Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$", "u")).annotate({ expected: "a string matching the RegExp ^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$" })), Null2])),
47466
+ content: optionalKey2(Union2([String4, Null2])),
47304
47467
  mediaId: optionalKey2(Union2([MediaId, Null2])),
47305
47468
  contentType: String4,
47306
47469
  size: Finite.check(isInt().annotate({ expected: "an integer" })).check(isLessThanOrEqualTo3(26214400).annotate({ expected: "a value less than or equal to 26214400" })).check(isGreaterThan2(0).annotate({ expected: "a value greater than 0" }))
@@ -47727,6 +47890,49 @@ var BlockLogPage = Struct({
47727
47890
  })),
47728
47891
  nextCursor: Union2([String4, Null2])
47729
47892
  }).annotate({ identifier: "BlockLogPage" });
47893
+ var ReceivingStatus = Struct({
47894
+ domain: String4,
47895
+ receivingHost: String4,
47896
+ sending: Struct({
47897
+ satisfied: Boolean3,
47898
+ phase: Union2([
47899
+ Literal2("dns-setup"),
47900
+ Literal2("provisioning"),
47901
+ Literal2("verifying"),
47902
+ Literal2("ready"),
47903
+ Literal2("degraded"),
47904
+ Literal2("failed")
47905
+ ])
47906
+ }),
47907
+ destination: Struct({
47908
+ satisfied: Boolean3,
47909
+ endpointId: Union2([WebhookEndpointId, Null2]),
47910
+ forwardingRules: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
47911
+ mailboxes: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
47912
+ }),
47913
+ receiving: Struct({
47914
+ satisfied: Boolean3,
47915
+ catchAll: Boolean3
47916
+ }),
47917
+ mx: Struct({
47918
+ satisfied: Boolean3,
47919
+ state: Union2([
47920
+ Literal2("pointing-here"),
47921
+ Literal2("elsewhere"),
47922
+ Literal2("missing"),
47923
+ Literal2("unknown")
47924
+ ]),
47925
+ expected: Struct({
47926
+ exchange: String4,
47927
+ priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
47928
+ }),
47929
+ current: ArraySchema(Struct({
47930
+ exchange: String4,
47931
+ priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
47932
+ }))
47933
+ }),
47934
+ ready: Boolean3
47935
+ }).annotate({ identifier: "ReceivingStatus" });
47730
47936
  var WebhookEndpoint = Struct({
47731
47937
  id: WebhookEndpointId,
47732
47938
  name: String4,
@@ -47879,6 +48085,7 @@ var CustomTrackingStatus = Struct({
47879
48085
  hostname: String4,
47880
48086
  region: String4,
47881
48087
  sslStatus: Union2([String4, Null2]),
48088
+ certificate: Union2([CustomTrackingCertificate, Null2]),
47882
48089
  dnsRecords: Struct({
47883
48090
  tracking: Union2([CustomTrackingDnsRecord, Null2]),
47884
48091
  dcvDelegation: Union2([CustomTrackingDnsRecord, Null2])
@@ -47967,10 +48174,11 @@ var ForwardingRuleList = Struct({ items: ArraySchema(Struct({
47967
48174
  id: EmailForwardingRuleId,
47968
48175
  name: String4,
47969
48176
  description: Union2([String4, Null2]),
48177
+ domainId: Union2([EmailDomainId, Null2]),
47970
48178
  sourcePattern: Union2([String4, Null2]),
47971
48179
  forwardTo: ArraySchema(String4),
47972
48180
  preserveHeaders: Boolean3,
47973
- priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
48181
+ priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(2147483647).annotate({ expected: "a value less than or equal to 2147483647" })),
47974
48182
  isActive: Boolean3,
47975
48183
  forwardCount: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
47976
48184
  failureCount: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
@@ -48071,6 +48279,22 @@ var ExtensionVersionRef = Struct({
48071
48279
  id: ExtensionVersionId,
48072
48280
  version: String4
48073
48281
  }).annotate({ identifier: "ExtensionVersionRef" });
48282
+ Struct({
48283
+ version: optionalKey2(Union2([Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}(?:-[0-9A-Za-z.-]{1,64})?$", "u")).annotate({ expected: "a string matching the RegExp ^\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}(?:-[0-9A-Za-z.-]{1,64})?$" })), ExtensionVersionId]), Null2])),
48284
+ acceptPermissions: optionalKey2(Union2([ArraySchema(Union2([
48285
+ Literal2("permission:read"),
48286
+ Literal2("permission:update"),
48287
+ Literal2("permission:send"),
48288
+ Literal2("permission:quarantine.read"),
48289
+ Literal2("event:mailbox.message.received"),
48290
+ Literal2("event:mailbox.message.sent"),
48291
+ Literal2("event:mailbox.action.pending_approval"),
48292
+ Literal2("event:mailbox.message.quarantined"),
48293
+ Literal2("event:mailbox.message.released"),
48294
+ Literal2("event:mailbox.message.discarded")
48295
+ ])), Null2])),
48296
+ dryRun: optionalKey2(Union2([Boolean3, Null2]))
48297
+ }).annotate({ identifier: "UpgradeExtensionPayload" });
48074
48298
  var ExtensionRunList = Struct({ items: ArraySchema(ExtensionRunSummary) }).annotate({ identifier: "ExtensionRunList" });
48075
48299
  var ExtensionVersion = Struct({
48076
48300
  id: ExtensionVersionId,
@@ -49334,6 +49558,17 @@ var ExtensionInstallation = Struct({
49334
49558
  updatedAt: String4,
49335
49559
  disabledAt: Union2([String4, Null2])
49336
49560
  }).annotate({ identifier: "ExtensionInstallation" });
49561
+ var ExtensionVersionChange = Struct({
49562
+ id: String4,
49563
+ organizationId: OrganizationId,
49564
+ installationId: ExtensionInstallationId,
49565
+ extensionId: ExtensionId,
49566
+ fromVersion: ExtensionVersionRef,
49567
+ toVersion: ExtensionVersionRef,
49568
+ permissionDiff: ExtensionPermissionDiff,
49569
+ changedBy: UserId,
49570
+ changedAt: String4
49571
+ }).annotate({ identifier: "ExtensionVersionChange" });
49337
49572
  var Extension = Struct({
49338
49573
  id: ExtensionId,
49339
49574
  name: String4,
@@ -49599,6 +49834,14 @@ var InstallExtensionResponse = Struct({
49599
49834
  webhookSecret: SensitiveString
49600
49835
  }), Null2])
49601
49836
  }).annotate({ identifier: "InstallExtensionResponse" });
49837
+ var UpgradeExtensionResponse = Struct({
49838
+ installation: ExtensionInstallation,
49839
+ fromVersion: ExtensionVersionRef,
49840
+ toVersion: ExtensionVersionRef,
49841
+ permissionDiff: ExtensionPermissionDiff,
49842
+ dryRun: Boolean3,
49843
+ versionChange: Union2([ExtensionVersionChange, Null2])
49844
+ }).annotate({ identifier: "UpgradeExtensionResponse" });
49602
49845
  var ExtensionPage = Struct({
49603
49846
  items: ArraySchema(Extension),
49604
49847
  nextCursor: Union2([String4, Null2])
@@ -50190,6 +50433,7 @@ var CampaignsScheduleRun422 = Union2([
50190
50433
  ]);
50191
50434
  var CampaignsScheduleRun500 = InternalError;
50192
50435
  var CampaignsScheduleRun502 = ExternalServiceError;
50436
+ var CampaignsScheduleRun503 = SenderNotReadyError;
50193
50437
  var CampaignsScheduleRun504 = GatewayTimeoutError;
50194
50438
  var CampaignsGetRunPathParams = Struct({
50195
50439
  id: CampaignId,
@@ -50486,8 +50730,6 @@ var ContactGroupsRemoveMembers422 = ValidationError;
50486
50730
  var ContactGroupsRemoveMembers500 = InternalError;
50487
50731
  var ContactGroupsRemoveMembers504 = GatewayTimeoutError;
50488
50732
  var ContactGroupsPreviewRequestJson = Struct({ criteria: Struct({
50489
- contactTypes: optionalKey2(Union2([ArraySchema(String4), Null2])),
50490
- capabilities: optionalKey2(Union2([ArraySchema(String4), Null2])),
50491
50733
  tags: optionalKey2(Union2([ArraySchema(String4), Null2])),
50492
50734
  channels: optionalKey2(Union2([ArraySchema(String4), Null2])),
50493
50735
  match: optionalKey2(Union2([Union2([Literal2("all"), Literal2("any")]), Null2])),
@@ -50502,7 +50744,6 @@ var ContactGroupsPreview200 = Struct({
50502
50744
  sample: ArraySchema(Struct({
50503
50745
  id: ContactId,
50504
50746
  name: String4,
50505
- type: String4,
50506
50747
  status: String4
50507
50748
  }))
50508
50749
  });
@@ -50697,16 +50938,23 @@ var ContactsBulkDelete504 = GatewayTimeoutError;
50697
50938
  var ContactsBulkImportRequestJson = Struct({
50698
50939
  contacts: ArraySchema(Struct({
50699
50940
  name: String4,
50700
- email: optionalKey2(Union2([String4, Null2])),
50701
- phone: optionalKey2(Union2([String4, Null2])),
50941
+ displayName: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
50942
+ avatar: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
50943
+ identities: optionalKey2(Union2([ArraySchema(ContactIdentityInput), Null2])),
50944
+ profile: optionalKey2(Union2([Union2([ContactProfile, Null2]), Null2])),
50945
+ preferences: optionalKey2(Union2([Union2([ContactPreferences, Null2]), Null2])),
50702
50946
  tags: optionalKey2(Union2([ArraySchema(String4), Null2])),
50703
- firstName: optionalKey2(Union2([String4, Null2])),
50704
- lastName: optionalKey2(Union2([String4, Null2])),
50705
- company: optionalKey2(Union2([String4, Null2])),
50706
- jobTitle: optionalKey2(Union2([String4, Null2])),
50707
- customFields: optionalKey2(Union2([UnknownRecord, Null2]))
50947
+ status: optionalKey2(Union2([Union2([
50948
+ Literal2("active"),
50949
+ Literal2("paused"),
50950
+ Literal2("blocked"),
50951
+ Literal2("archived")
50952
+ ]), Null2])),
50953
+ statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
50954
+ externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
50955
+ metadata: optionalKey2(Union2([Union2([JsonObject, Null2]), Null2]))
50708
50956
  })),
50709
- upsertByEmail: optionalKey2(Union2([Boolean3, Null2]))
50957
+ onConflict: optionalKey2(Union2([Union2([Literal2("skip"), Literal2("update")]), Null2]))
50710
50958
  });
50711
50959
  var ContactsBulkImport200 = Struct({
50712
50960
  total: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
@@ -51367,6 +51615,16 @@ var EmailCompleteCustomTrackingDomainConnect403 = ForbiddenError;
51367
51615
  var EmailCompleteCustomTrackingDomainConnect422 = ValidationError;
51368
51616
  var EmailCompleteCustomTrackingDomainConnect500 = InternalError;
51369
51617
  var EmailCompleteCustomTrackingDomainConnect504 = GatewayTimeoutError;
51618
+ var EmailRecheckCustomTrackingPathParams = Struct({ id: EmailDomainId });
51619
+ var EmailRecheckCustomTracking200 = CustomTrackingStatus;
51620
+ var EmailRecheckCustomTracking401 = UnauthorizedError;
51621
+ var EmailRecheckCustomTracking403 = ForbiddenError;
51622
+ var EmailRecheckCustomTracking404 = ResourceNotFoundError;
51623
+ var EmailRecheckCustomTracking409 = ConflictError;
51624
+ var EmailRecheckCustomTracking422 = ValidationError;
51625
+ var EmailRecheckCustomTracking500 = InternalError;
51626
+ var EmailRecheckCustomTracking502 = EmailChannelError;
51627
+ var EmailRecheckCustomTracking504 = GatewayTimeoutError;
51370
51628
  var EmailSetDefaultDomainPathParams = Struct({ id: EmailDomainId });
51371
51629
  var EmailSetDefaultDomain200 = SuccessResult;
51372
51630
  var EmailSetDefaultDomain401 = UnauthorizedError;
@@ -51436,7 +51694,7 @@ var EmailCompleteDomainConnect500 = InternalError;
51436
51694
  var EmailCompleteDomainConnect502 = EmailChannelError;
51437
51695
  var EmailCompleteDomainConnect504 = GatewayTimeoutError;
51438
51696
  var EmailEnableCatchAllPathParams = Struct({ id: EmailDomainId });
51439
- var EmailEnableCatchAllRequestJson = Struct({ endpointId: WebhookEndpointId });
51697
+ var EmailEnableCatchAllRequestJson = Struct({ endpointId: optionalKey2(Union2([WebhookEndpointId, Null2])) });
51440
51698
  var EmailEnableCatchAll201 = Struct({ success: Literal2(true) });
51441
51699
  var EmailEnableCatchAll401 = UnauthorizedError;
51442
51700
  var EmailEnableCatchAll403 = ForbiddenError;
@@ -51462,6 +51720,14 @@ var EmailEnableReceiving404 = ResourceNotFoundError;
51462
51720
  var EmailEnableReceiving422 = ValidationError;
51463
51721
  var EmailEnableReceiving500 = InternalError;
51464
51722
  var EmailEnableReceiving504 = GatewayTimeoutError;
51723
+ var EmailGetReceivingStatusPathParams = Struct({ id: EmailDomainId });
51724
+ var EmailGetReceivingStatus200 = ReceivingStatus;
51725
+ var EmailGetReceivingStatus401 = UnauthorizedError;
51726
+ var EmailGetReceivingStatus403 = ForbiddenError;
51727
+ var EmailGetReceivingStatus404 = ResourceNotFoundError;
51728
+ var EmailGetReceivingStatus422 = ValidationError;
51729
+ var EmailGetReceivingStatus500 = InternalError;
51730
+ var EmailGetReceivingStatus504 = GatewayTimeoutError;
51465
51731
  var EmailDetectRegistrarPathParams = Struct({ id: EmailDomainId });
51466
51732
  var EmailDetectRegistrarRequestJson = Struct({ domain: String4 });
51467
51733
  var EmailDetectRegistrar200 = Struct({
@@ -51607,7 +51873,7 @@ var EmailCreateForwardingRuleRequestJson = Struct({
51607
51873
  preserveHeaders: optionalKey2(Union2([Boolean3, Null2])),
51608
51874
  appendNote: optionalKey2(Union2([String4, Null2])),
51609
51875
  conditions: optionalKey2(Union2([ForwardingConditions, Null2])),
51610
- priority: optionalKey2(Union2([Finite.check(isFinite4().annotate({ expected: "a finite number" })), Null2])),
51876
+ priority: optionalKey2(Union2([Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(2147483647).annotate({ expected: "a value less than or equal to 2147483647" })), Null2])),
51611
51877
  isActive: optionalKey2(Union2([Boolean3, Null2])),
51612
51878
  metadata: optionalKey2(Union2([Union2([Record(String4, JsonValue), Null2]), Null2]))
51613
51879
  });
@@ -51615,7 +51881,7 @@ var EmailCreateForwardingRule201 = Struct({
51615
51881
  id: EmailForwardingRuleId,
51616
51882
  name: String4,
51617
51883
  forwardTo: ArraySchema(String4),
51618
- priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
51884
+ priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(2147483647).annotate({ expected: "a value less than or equal to 2147483647" })),
51619
51885
  isActive: Boolean3,
51620
51886
  createdAt: String4
51621
51887
  });
@@ -51644,7 +51910,7 @@ var EmailUpdateForwardingRuleRequestJson = Struct({
51644
51910
  preserveHeaders: optionalKey2(Union2([Boolean3, Null2])),
51645
51911
  appendNote: optionalKey2(Union2([String4, Null2])),
51646
51912
  conditions: optionalKey2(Union2([Union2([ForwardingConditions, Null2]), Null2])),
51647
- priority: optionalKey2(Union2([Finite.check(isFinite4().annotate({ expected: "a finite number" })), Null2])),
51913
+ priority: optionalKey2(Union2([Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(2147483647).annotate({ expected: "a value less than or equal to 2147483647" })), Null2])),
51648
51914
  isActive: optionalKey2(Union2([Boolean3, Null2])),
51649
51915
  metadata: optionalKey2(Union2([Union2([Record(String4, JsonValue), Null2]), Null2]))
51650
51916
  });
@@ -51652,7 +51918,7 @@ var EmailUpdateForwardingRule200 = Struct({
51652
51918
  id: EmailForwardingRuleId,
51653
51919
  name: String4,
51654
51920
  forwardTo: ArraySchema(String4),
51655
- priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
51921
+ priority: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(2147483647).annotate({ expected: "a value less than or equal to 2147483647" })),
51656
51922
  isActive: Boolean3,
51657
51923
  updatedAt: String4
51658
51924
  });
@@ -51998,6 +52264,31 @@ var ExtensionInstallationsGetRun404 = ResourceNotFoundError;
51998
52264
  var ExtensionInstallationsGetRun422 = ValidationError;
51999
52265
  var ExtensionInstallationsGetRun500 = InternalError;
52000
52266
  var ExtensionInstallationsGetRun504 = GatewayTimeoutError;
52267
+ var ExtensionInstallationsUpgradePathParams = Struct({ id: ExtensionInstallationId });
52268
+ var ExtensionInstallationsUpgradeRequestJson = Struct({
52269
+ version: optionalKey2(Union2([Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}(?:-[0-9A-Za-z.-]{1,64})?$", "u")).annotate({ expected: "a string matching the RegExp ^\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}(?:-[0-9A-Za-z.-]{1,64})?$" })), ExtensionVersionId]), Null2])),
52270
+ acceptPermissions: optionalKey2(Union2([ArraySchema(Union2([
52271
+ Literal2("permission:read"),
52272
+ Literal2("permission:update"),
52273
+ Literal2("permission:send"),
52274
+ Literal2("permission:quarantine.read"),
52275
+ Literal2("event:mailbox.message.received"),
52276
+ Literal2("event:mailbox.message.sent"),
52277
+ Literal2("event:mailbox.action.pending_approval"),
52278
+ Literal2("event:mailbox.message.quarantined"),
52279
+ Literal2("event:mailbox.message.released"),
52280
+ Literal2("event:mailbox.message.discarded")
52281
+ ])), Null2])),
52282
+ dryRun: optionalKey2(Union2([Boolean3, Null2]))
52283
+ });
52284
+ var ExtensionInstallationsUpgrade200 = UpgradeExtensionResponse;
52285
+ var ExtensionInstallationsUpgrade401 = UnauthorizedError;
52286
+ var ExtensionInstallationsUpgrade403 = ForbiddenError;
52287
+ var ExtensionInstallationsUpgrade404 = ResourceNotFoundError;
52288
+ var ExtensionInstallationsUpgrade409 = ConflictError;
52289
+ var ExtensionInstallationsUpgrade422 = ValidationError;
52290
+ var ExtensionInstallationsUpgrade500 = InternalError;
52291
+ var ExtensionInstallationsUpgrade504 = GatewayTimeoutError;
52001
52292
  var ExtensionsListQuery = Struct({
52002
52293
  limit: optionalKey2(Union2([String4, Null2])),
52003
52294
  cursor: optionalKey2(Union2([Cursor, Null2])),
@@ -52188,12 +52479,14 @@ var MailboxesApproveActionPathParams = Struct({
52188
52479
  var MailboxesApproveAction200 = MailboxAction;
52189
52480
  var MailboxesApproveAction401 = UnauthorizedError;
52190
52481
  var MailboxesApproveAction402 = PaymentRequiredError;
52191
- var MailboxesApproveAction403 = ForbiddenError;
52482
+ var MailboxesApproveAction403 = Union2([ForbiddenError, OnboardingReviewRequiredError]);
52192
52483
  var MailboxesApproveAction404 = ResourceNotFoundError;
52193
52484
  var MailboxesApproveAction409 = ConflictError;
52194
52485
  var MailboxesApproveAction422 = ValidationError;
52486
+ var MailboxesApproveAction429 = RateLimitedError;
52195
52487
  var MailboxesApproveAction500 = InternalError;
52196
52488
  var MailboxesApproveAction502 = BillingProviderError;
52489
+ var MailboxesApproveAction503 = SenderNotReadyError;
52197
52490
  var MailboxesApproveAction504 = GatewayTimeoutError;
52198
52491
  var MailboxesDenyActionPathParams = Struct({
52199
52492
  id: MailboxId,
@@ -52304,12 +52597,14 @@ var MailboxesSendDraftHeaders = Struct({ "idempotency-key": optionalKey2(Union2(
52304
52597
  var MailboxesSendDraft200 = MailboxSendReceipt;
52305
52598
  var MailboxesSendDraft401 = UnauthorizedError;
52306
52599
  var MailboxesSendDraft402 = PaymentRequiredError;
52307
- var MailboxesSendDraft403 = ForbiddenError;
52600
+ var MailboxesSendDraft403 = Union2([ForbiddenError, OnboardingReviewRequiredError]);
52308
52601
  var MailboxesSendDraft404 = ResourceNotFoundError;
52309
52602
  var MailboxesSendDraft409 = ConflictError;
52310
52603
  var MailboxesSendDraft422 = ValidationError;
52604
+ var MailboxesSendDraft429 = RateLimitedError;
52311
52605
  var MailboxesSendDraft500 = InternalError;
52312
52606
  var MailboxesSendDraft502 = BillingProviderError;
52607
+ var MailboxesSendDraft503 = SenderNotReadyError;
52313
52608
  var MailboxesSendDraft504 = GatewayTimeoutError;
52314
52609
  var MailboxesListEventsPathParams = Struct({ id: MailboxId });
52315
52610
  var MailboxesListEventsQuery = Struct({
@@ -52464,12 +52759,14 @@ var MailboxesSendMessageRequestJson = Struct({
52464
52759
  var MailboxesSendMessage200 = MailboxSendReceipt;
52465
52760
  var MailboxesSendMessage401 = UnauthorizedError;
52466
52761
  var MailboxesSendMessage402 = PaymentRequiredError;
52467
- var MailboxesSendMessage403 = ForbiddenError;
52762
+ var MailboxesSendMessage403 = Union2([ForbiddenError, OnboardingReviewRequiredError]);
52468
52763
  var MailboxesSendMessage404 = ResourceNotFoundError;
52469
52764
  var MailboxesSendMessage409 = ConflictError;
52470
52765
  var MailboxesSendMessage422 = ValidationError;
52766
+ var MailboxesSendMessage429 = RateLimitedError;
52471
52767
  var MailboxesSendMessage500 = InternalError;
52472
52768
  var MailboxesSendMessage502 = BillingProviderError;
52769
+ var MailboxesSendMessage503 = SenderNotReadyError;
52473
52770
  var MailboxesSendMessage504 = GatewayTimeoutError;
52474
52771
  var MailboxesGetMessagePathParams = Struct({
52475
52772
  id: MailboxId,
@@ -52523,12 +52820,14 @@ var MailboxesForwardRequestJson = Struct({
52523
52820
  var MailboxesForward200 = MailboxSendReceipt;
52524
52821
  var MailboxesForward401 = UnauthorizedError;
52525
52822
  var MailboxesForward402 = PaymentRequiredError;
52526
- var MailboxesForward403 = ForbiddenError;
52823
+ var MailboxesForward403 = Union2([ForbiddenError, OnboardingReviewRequiredError]);
52527
52824
  var MailboxesForward404 = ResourceNotFoundError;
52528
52825
  var MailboxesForward409 = ConflictError;
52529
52826
  var MailboxesForward422 = ValidationError;
52827
+ var MailboxesForward429 = RateLimitedError;
52530
52828
  var MailboxesForward500 = InternalError;
52531
52829
  var MailboxesForward502 = BillingProviderError;
52830
+ var MailboxesForward503 = SenderNotReadyError;
52532
52831
  var MailboxesForward504 = GatewayTimeoutError;
52533
52832
  var MailboxesGetMessageRawPathParams = Struct({
52534
52833
  id: MailboxId,
@@ -52568,12 +52867,14 @@ var MailboxesReplyRequestJson = Struct({
52568
52867
  var MailboxesReply200 = MailboxSendReceipt;
52569
52868
  var MailboxesReply401 = UnauthorizedError;
52570
52869
  var MailboxesReply402 = PaymentRequiredError;
52571
- var MailboxesReply403 = ForbiddenError;
52870
+ var MailboxesReply403 = Union2([ForbiddenError, OnboardingReviewRequiredError]);
52572
52871
  var MailboxesReply404 = ResourceNotFoundError;
52573
52872
  var MailboxesReply409 = ConflictError;
52574
52873
  var MailboxesReply422 = ValidationError;
52874
+ var MailboxesReply429 = RateLimitedError;
52575
52875
  var MailboxesReply500 = InternalError;
52576
52876
  var MailboxesReply502 = BillingProviderError;
52877
+ var MailboxesReply503 = SenderNotReadyError;
52577
52878
  var MailboxesReply504 = GatewayTimeoutError;
52578
52879
  var MailboxesReplyAllPathParams = Struct({
52579
52880
  id: MailboxId,
@@ -52590,12 +52891,14 @@ var MailboxesReplyAllRequestJson = Struct({
52590
52891
  var MailboxesReplyAll200 = MailboxSendReceipt;
52591
52892
  var MailboxesReplyAll401 = UnauthorizedError;
52592
52893
  var MailboxesReplyAll402 = PaymentRequiredError;
52593
- var MailboxesReplyAll403 = ForbiddenError;
52894
+ var MailboxesReplyAll403 = Union2([ForbiddenError, OnboardingReviewRequiredError]);
52594
52895
  var MailboxesReplyAll404 = ResourceNotFoundError;
52595
52896
  var MailboxesReplyAll409 = ConflictError;
52596
52897
  var MailboxesReplyAll422 = ValidationError;
52898
+ var MailboxesReplyAll429 = RateLimitedError;
52597
52899
  var MailboxesReplyAll500 = InternalError;
52598
52900
  var MailboxesReplyAll502 = BillingProviderError;
52901
+ var MailboxesReplyAll503 = SenderNotReadyError;
52599
52902
  var MailboxesReplyAll504 = GatewayTimeoutError;
52600
52903
  var MailboxesPausePathParams = Struct({ id: MailboxId });
52601
52904
  var MailboxesPause200 = Mailbox;
@@ -52946,7 +53249,7 @@ var MessagesSend422 = ValidationError;
52946
53249
  var MessagesSend429 = RateLimitedError;
52947
53250
  var MessagesSend500 = InternalError;
52948
53251
  var MessagesSend502 = Union2([BillingProviderError, ExternalServiceError]);
52949
- var MessagesSend503 = DeliveryUnavailableError;
53252
+ var MessagesSend503 = Union2([SenderNotReadyError, DeliveryUnavailableError]);
52950
53253
  var MessagesSend504 = GatewayTimeoutError;
52951
53254
  var MessagesGetPathParams = Struct({ id: MessageId });
52952
53255
  var MessagesGet200 = Message;
@@ -53248,6 +53551,7 @@ var ScheduledMessagesResume409 = ConflictError;
53248
53551
  var ScheduledMessagesResume422 = ValidationError;
53249
53552
  var ScheduledMessagesResume500 = InternalError;
53250
53553
  var ScheduledMessagesResume502 = ExternalServiceError;
53554
+ var ScheduledMessagesResume503 = SenderNotReadyError;
53251
53555
  var ScheduledMessagesResume504 = GatewayTimeoutError;
53252
53556
  var MessagesValidateEmailRequestJson = Struct({
53253
53557
  conversationId: optionalKey2(Union2([Union2([ConversationId, Null2]), Null2])),
@@ -53265,6 +53569,7 @@ var MessagesValidateEmail403 = ForbiddenError;
53265
53569
  var MessagesValidateEmail404 = ResourceNotFoundError;
53266
53570
  var MessagesValidateEmail422 = ValidationError;
53267
53571
  var MessagesValidateEmail500 = InternalError;
53572
+ var MessagesValidateEmail503 = SenderNotReadyError;
53268
53573
  var MessagesValidateEmail504 = GatewayTimeoutError;
53269
53574
  var NamespacesListQuery = Struct({
53270
53575
  limit: optionalKey2(Union2([String4, Null2])),
@@ -55764,6 +56069,7 @@ var CampaignsGroup = class extends make38("Campaigns").add(get5("campaignsList",
55764
56069
  CampaignsScheduleRun422.pipe(status(422)),
55765
56070
  CampaignsScheduleRun500,
55766
56071
  CampaignsScheduleRun502.pipe(status(502)),
56072
+ CampaignsScheduleRun503.pipe(status(503)),
55767
56073
  CampaignsScheduleRun504.pipe(status(504))
55768
56074
  ]
55769
56075
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "campaigns.scheduleRun").annotate(Summary, "Schedule a campaign run").annotate(Description, "Schedules an email campaign run at the absolute ISO-8601 instant in scheduledFor, or immediately when omitted. The optional idempotencyKey is scoped to the organization and replays return the original run. An email campaign must carry the brand footer: it is refused with CampaignFooterRequiredError when its footer is off and its template renders no BrandFooter, and with BrandAddressRequiredError when a brand that signs it off has no postal address."), get5("campaignsGetRun", "/v1/campaigns/:id/runs/:runId", {
@@ -56109,7 +56415,7 @@ var ContactsGroup = class extends make38("Contacts").add(get5("contactsList", "/
56109
56415
  ContactsBulkImport502.pipe(status(502)),
56110
56416
  ContactsBulkImport504.pipe(status(504))
56111
56417
  ]
56112
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "contacts.bulkImport").annotate(Summary, "Bulk import contacts").annotate(Description, "Creates or updates contacts in bulk from a list, returning per-entry results with created, updated, skipped, and error counts."), post("contactsBulkUpdateStatus", "/v1/contacts/bulk-update-status", {
56418
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "contacts.bulkImport").annotate(Summary, "Bulk import contacts").annotate(Description, 'Creates contacts in bulk from a list of entries shaped like a create request, returning per-entry results with created, updated, skipped, and error counts. An entry whose identities match an existing contact is skipped, or updates it with `onConflict: "update"`.'), post("contactsBulkUpdateStatus", "/v1/contacts/bulk-update-status", {
56113
56419
  payload: ContactsBulkUpdateStatusRequestJson,
56114
56420
  success: ContactsBulkUpdateStatus200,
56115
56421
  error: [
@@ -56589,7 +56895,20 @@ var EmailGroup = class extends make38("Email").add(get5("emailListBlocks", "/v1/
56589
56895
  EmailCompleteCustomTrackingDomainConnect500,
56590
56896
  EmailCompleteCustomTrackingDomainConnect504.pipe(status(504))
56591
56897
  ]
56592
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.completeCustomTrackingDomainConnect").annotate(Summary, "Complete an automatic Custom Tracking Domain return").annotate(Description, "Validates the signed state returned by the DNS provider, then checks the tracking host again. Returning here never marks the host ready or changes which tracking host email uses."), post("emailSetDefaultDomain", "/v1/email/domains/:id/default", {
56898
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.completeCustomTrackingDomainConnect").annotate(Summary, "Complete an automatic Custom Tracking Domain return").annotate(Description, "Validates the signed state returned by the DNS provider, then checks the tracking host again. Returning here never marks the host ready or changes which tracking host email uses."), post("emailRecheckCustomTracking", "/v1/email/domains/:id/custom-tracking/recheck", {
56899
+ params: EmailRecheckCustomTrackingPathParams,
56900
+ success: EmailRecheckCustomTracking200,
56901
+ error: [
56902
+ EmailRecheckCustomTracking401.pipe(status(401)),
56903
+ EmailRecheckCustomTracking403.pipe(status(403)),
56904
+ EmailRecheckCustomTracking404.pipe(status(404)),
56905
+ EmailRecheckCustomTracking409.pipe(status(409)),
56906
+ EmailRecheckCustomTracking422.pipe(status(422)),
56907
+ EmailRecheckCustomTracking500,
56908
+ EmailRecheckCustomTracking502.pipe(status(502)),
56909
+ EmailRecheckCustomTracking504.pipe(status(504))
56910
+ ]
56911
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.recheckCustomTracking").annotate(Summary, "Recheck a custom tracking domain's certificate").annotate(Description, "Checks the hostname's certificate now instead of waiting for the next scheduled check, and returns the refreshed state. Samva checks a hostname at most once every 30 seconds; a recheck inside that window returns the state from the last check. Returns a conflict when custom tracking is disabled or being torn down."), post("emailSetDefaultDomain", "/v1/email/domains/:id/default", {
56593
56912
  params: EmailSetDefaultDomainPathParams,
56594
56913
  success: EmailSetDefaultDomain200,
56595
56914
  error: [
@@ -56661,7 +56980,7 @@ var EmailGroup = class extends make38("Email").add(get5("emailListBlocks", "/v1/
56661
56980
  EmailBuildDomainConnectApplyUrl502.pipe(status(502)),
56662
56981
  EmailBuildDomainConnectApplyUrl504.pipe(status(504))
56663
56982
  ]
56664
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.buildDomainConnectApplyUrl").annotate(Summary, "Build a one-click DNS apply URL").annotate(Description, "Builds the signed Domain Connect apply URL for the selected sending-only or sending-and-receiving service. Manual DNS remains available for either mode."), post("emailCompleteDomainConnect", "/v1/email/domains/:id/domain-connect/complete", {
56983
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.buildDomainConnectApplyUrl").annotate(Summary, "Build a one-click DNS apply URL").annotate(Description, "Builds the signed Domain Connect apply URL for the selected sending-only or sending-and-receiving service. The sending-and-receiving service writes the apex inbound MX, so it is refused until the domain's receiving is enabled. Manual DNS remains available for either mode."), post("emailCompleteDomainConnect", "/v1/email/domains/:id/domain-connect/complete", {
56665
56984
  params: EmailCompleteDomainConnectPathParams,
56666
56985
  payload: EmailCompleteDomainConnectRequestJson,
56667
56986
  success: EmailCompleteDomainConnect200,
@@ -56687,7 +57006,7 @@ var EmailGroup = class extends make38("Email").add(get5("emailListBlocks", "/v1/
56687
57006
  EmailEnableCatchAll502.pipe(status(502)),
56688
57007
  EmailEnableCatchAll504.pipe(status(504))
56689
57008
  ]
56690
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.enableCatchAll").annotate(Summary, "Enable catch-all receiving").annotate(Description, "Enables catch-all inbound receiving for a domain. `endpointId` is one of the organization's webhook endpoints; every address on the domain delivers `message.received` to it. Responds with 201."), post("emailEnableReceiving", "/v1/email/domains/:id/enable-receiving", {
57009
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.enableCatchAll").annotate(Summary, "Enable catch-all receiving").annotate(Description, "Enables catch-all inbound receiving for a verified domain. `endpointId` is one of the organization's webhook endpoints; every address on the domain delivers `message.received` to it. Omit it to deliver through forwarding rules alone, which needs at least one active forwarding rule covering the domain. Mail that matches neither a rule nor an endpoint is rejected as an unknown recipient. Responds with 201."), post("emailEnableReceiving", "/v1/email/domains/:id/enable-receiving", {
56691
57010
  params: EmailEnableReceivingPathParams,
56692
57011
  payload: EmailEnableReceivingRequestJson,
56693
57012
  success: EmailEnableReceiving200,
@@ -56699,7 +57018,18 @@ var EmailGroup = class extends make38("Email").add(get5("emailListBlocks", "/v1/
56699
57018
  EmailEnableReceiving500,
56700
57019
  EmailEnableReceiving504.pipe(status(504))
56701
57020
  ]
56702
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.enableReceiving").annotate(Summary, "Enable inbound email for a domain").annotate(Description, "Enables inbound receiving for a verified domain and returns the recipient addresses it accepts. Set `catchAll` to route every address on the domain; that requires a webhook endpoint, supplied as `endpointId` or already configured on the domain."), post("emailDetectRegistrar", "/v1/email/domains/:id/registrar", {
57021
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.enableReceiving").annotate(Summary, "Enable inbound email for a domain").annotate(Description, "Enables inbound receiving for a verified domain and returns the recipient addresses it accepts. Set `catchAll` to route every address on the domain; that needs a destination: a webhook endpoint, supplied as `endpointId` or already configured on the domain, or at least one active forwarding rule that covers the domain. Mail that matches neither is rejected, never accepted and dropped."), get5("emailGetReceivingStatus", "/v1/email/domains/:id/receiving-status", {
57022
+ params: EmailGetReceivingStatusPathParams,
57023
+ success: EmailGetReceivingStatus200,
57024
+ error: [
57025
+ EmailGetReceivingStatus401.pipe(status(401)),
57026
+ EmailGetReceivingStatus403.pipe(status(403)),
57027
+ EmailGetReceivingStatus404.pipe(status(404)),
57028
+ EmailGetReceivingStatus422.pipe(status(422)),
57029
+ EmailGetReceivingStatus500,
57030
+ EmailGetReceivingStatus504.pipe(status(504))
57031
+ ]
57032
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.getReceivingStatus").annotate(Summary, "Get receiving setup status").annotate(Description, "Reports each prerequisite for receiving a domain's mail at Samva, in order: sending verified, a destination (a webhook endpoint or an active forwarding rule), receiving enabled, and the inbound MX record. The MX answer is a live DNS lookup that names the current target when mail is routed elsewhere."), post("emailDetectRegistrar", "/v1/email/domains/:id/registrar", {
56703
57033
  params: EmailDetectRegistrarPathParams,
56704
57034
  payload: EmailDetectRegistrarRequestJson,
56705
57035
  success: EmailDetectRegistrar200,
@@ -56847,7 +57177,7 @@ var EmailGroup = class extends make38("Email").add(get5("emailListBlocks", "/v1/
56847
57177
  EmailListForwardingRules500,
56848
57178
  EmailListForwardingRules504.pipe(status(504))
56849
57179
  ]
56850
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listForwardingRules").annotate(Summary, "List forwarding rules").annotate(Description, "Returns every inbound email forwarding rule, highest priority first, optionally filtered by domain and active state. An organization holds at most 100, so the list is never paged."), post("emailCreateForwardingRule", "/v1/email/forwarding", {
57180
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listForwardingRules").annotate(Summary, "List forwarding rules").annotate(Description, "Returns every inbound email forwarding rule in the order inbound mail is matched against them: highest priority first, then an exact address before a wildcard pattern at equal priority, then oldest first. The first rule that matches is the one that forwards. Filtering by domain returns that domain's rules and the rules that apply to every domain (domainId null). An organization holds at most 100, so the list is never paged."), post("emailCreateForwardingRule", "/v1/email/forwarding", {
56851
57181
  payload: EmailCreateForwardingRuleRequestJson,
56852
57182
  success: EmailCreateForwardingRule201.pipe(status(201)),
56853
57183
  error: [
@@ -56859,7 +57189,7 @@ var EmailGroup = class extends make38("Email").add(get5("emailListBlocks", "/v1/
56859
57189
  EmailCreateForwardingRule500,
56860
57190
  EmailCreateForwardingRule504.pipe(status(504))
56861
57191
  ]
56862
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.createForwardingRule").annotate(Summary, "Create a forwarding rule").annotate(Description, "Creates an inbound email forwarding rule and returns it. Responds with 201. An organization holds at most 100 forwarding rules."), del("emailDeleteForwardingRule", "/v1/email/forwarding/:id", {
57192
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.createForwardingRule").annotate(Summary, "Create a forwarding rule").annotate(Description, "Creates an inbound email forwarding rule and returns it. Responds with 201. Priority is a non-negative integer, default 0; higher priority rules are tried first, and at equal priority an exact address outranks a wildcard pattern. An organization holds at most 100 forwarding rules."), del("emailDeleteForwardingRule", "/v1/email/forwarding/:id", {
56863
57193
  params: EmailDeleteForwardingRulePathParams,
56864
57194
  success: EmailDeleteForwardingRule200,
56865
57195
  error: [
@@ -57167,7 +57497,20 @@ var ExtensionInstallationsGroup = class extends make38("Extension installations"
57167
57497
  ExtensionInstallationsGetRun500,
57168
57498
  ExtensionInstallationsGetRun504.pipe(status(504))
57169
57499
  ]
57170
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "extensionInstallations.getRun").annotate(Summary, "Get a hosted run").annotate(Description, "Returns one retained run with the lines its handler logged: at most 50 lines of 500 characters.")).annotate(Description, "Extension versions installed into the organization, each acting as its own principal") {
57500
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "extensionInstallations.getRun").annotate(Summary, "Get a hosted run").annotate(Description, "Returns one retained run with the lines its handler logged: at most 50 lines of 500 characters."), post("extensionInstallationsUpgrade", "/v1/extension-installations/:id/upgrade", {
57501
+ params: ExtensionInstallationsUpgradePathParams,
57502
+ payload: ExtensionInstallationsUpgradeRequestJson,
57503
+ success: ExtensionInstallationsUpgrade200,
57504
+ error: [
57505
+ ExtensionInstallationsUpgrade401.pipe(status(401)),
57506
+ ExtensionInstallationsUpgrade403.pipe(status(403)),
57507
+ ExtensionInstallationsUpgrade404.pipe(status(404)),
57508
+ ExtensionInstallationsUpgrade409.pipe(status(409)),
57509
+ ExtensionInstallationsUpgrade422.pipe(status(422)),
57510
+ ExtensionInstallationsUpgrade500,
57511
+ ExtensionInstallationsUpgrade504.pipe(status(504))
57512
+ ]
57513
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "extensionInstallations.upgrade").annotate(Summary, "Upgrade or roll back an installation").annotate(Description, "Changes the pinned version in place. Omit version for the latest publication, or name a version string or id, including an older version to roll back. Preview with dryRun; changing requires acceptPermissions to list exactly the added permission: and event: grants. Only a person can upgrade. Credentials, owner, scope, send mode, and status stay attached to the installation.")).annotate(Description, "Extension versions installed into the organization, each acting as its own principal") {
57171
57514
  };
57172
57515
  var ExtensionsGroup = class extends make38("Extensions").add(get5("extensionsList", "/v1/extensions", {
57173
57516
  query: ExtensionsListQuery,
@@ -57321,8 +57664,10 @@ var MailboxesGroup = class extends make38("Mailboxes").add(get5("mailboxesList",
57321
57664
  MailboxesApproveAction404.pipe(status(404)),
57322
57665
  MailboxesApproveAction409.pipe(status(409)),
57323
57666
  MailboxesApproveAction422.pipe(status(422)),
57667
+ MailboxesApproveAction429.pipe(status(429)),
57324
57668
  MailboxesApproveAction500,
57325
57669
  MailboxesApproveAction502.pipe(status(502)),
57670
+ MailboxesApproveAction503.pipe(status(503)),
57326
57671
  MailboxesApproveAction504.pipe(status(504))
57327
57672
  ]
57328
57673
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.approveAction").annotate(Summary, "Approve a mailbox action").annotate(Description, "Approves an action waiting for approval, executes it, and returns the executed action. Only a person signed in or through OAuth may approve, and never the one who proposed it."), post("mailboxesDenyAction", "/v1/mailboxes/:id/actions/:actionId/deny", {
@@ -57420,8 +57765,10 @@ var MailboxesGroup = class extends make38("Mailboxes").add(get5("mailboxesList",
57420
57765
  MailboxesSendDraft404.pipe(status(404)),
57421
57766
  MailboxesSendDraft409.pipe(status(409)),
57422
57767
  MailboxesSendDraft422.pipe(status(422)),
57768
+ MailboxesSendDraft429.pipe(status(429)),
57423
57769
  MailboxesSendDraft500,
57424
57770
  MailboxesSendDraft502.pipe(status(502)),
57771
+ MailboxesSendDraft503.pipe(status(503)),
57425
57772
  MailboxesSendDraft504.pipe(status(504))
57426
57773
  ]
57427
57774
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.sendDraft").annotate(Summary, "Send a draft").annotate(Description, "Sends one of the caller's drafts: a reply draft in its thread, any other draft as a new conversation. A draft needs recipients, a subject, and a body."), get5("mailboxesListEvents", "/v1/mailboxes/:id/events", {
@@ -57556,8 +57903,10 @@ var MailboxesGroup = class extends make38("Mailboxes").add(get5("mailboxesList",
57556
57903
  MailboxesSendMessage404.pipe(status(404)),
57557
57904
  MailboxesSendMessage409.pipe(status(409)),
57558
57905
  MailboxesSendMessage422.pipe(status(422)),
57906
+ MailboxesSendMessage429.pipe(status(429)),
57559
57907
  MailboxesSendMessage500,
57560
57908
  MailboxesSendMessage502.pipe(status(502)),
57909
+ MailboxesSendMessage503.pipe(status(503)),
57561
57910
  MailboxesSendMessage504.pipe(status(504))
57562
57911
  ]
57563
57912
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.sendMessage").annotate(Summary, "Send a new message").annotate(Description, "Starts a new conversation from the mailbox's default From address. `status` is `sent`, or `pending_approval` when the caller's grant or a mailbox policy holds sends for a person's approval; a policy that denies sends refuses it with 403."), get5("mailboxesGetMessage", "/v1/mailboxes/:id/messages/:messageId", {
@@ -57607,8 +57956,10 @@ var MailboxesGroup = class extends make38("Mailboxes").add(get5("mailboxesList",
57607
57956
  MailboxesForward404.pipe(status(404)),
57608
57957
  MailboxesForward409.pipe(status(409)),
57609
57958
  MailboxesForward422.pipe(status(422)),
57959
+ MailboxesForward429.pipe(status(429)),
57610
57960
  MailboxesForward500,
57611
57961
  MailboxesForward502.pipe(status(502)),
57962
+ MailboxesForward503.pipe(status(503)),
57612
57963
  MailboxesForward504.pipe(status(504))
57613
57964
  ]
57614
57965
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.forward").annotate(Summary, "Forward a message").annotate(Description, "Forwards the message to new recipients as a new conversation, with the original quoted below the caller's text and its attachments attached ahead of any the caller adds. The combined attachments must fit the email attachment limits."), get5("mailboxesGetMessageRaw", "/v1/mailboxes/:id/messages/:messageId/raw", {
@@ -57646,8 +57997,10 @@ var MailboxesGroup = class extends make38("Mailboxes").add(get5("mailboxesList",
57646
57997
  MailboxesReply404.pipe(status(404)),
57647
57998
  MailboxesReply409.pipe(status(409)),
57648
57999
  MailboxesReply422.pipe(status(422)),
58000
+ MailboxesReply429.pipe(status(429)),
57649
58001
  MailboxesReply500,
57650
58002
  MailboxesReply502.pipe(status(502)),
58003
+ MailboxesReply503.pipe(status(503)),
57651
58004
  MailboxesReply504.pipe(status(504))
57652
58005
  ]
57653
58006
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.reply").annotate(Summary, "Reply to a message").annotate(Description, "Replies to the message's Reply-To address, or its sender, in the same thread. The server sets the recipients, subject, and threading headers."), post("mailboxesReplyAll", "/v1/mailboxes/:id/messages/:messageId/reply-all", {
@@ -57662,8 +58015,10 @@ var MailboxesGroup = class extends make38("Mailboxes").add(get5("mailboxesList",
57662
58015
  MailboxesReplyAll404.pipe(status(404)),
57663
58016
  MailboxesReplyAll409.pipe(status(409)),
57664
58017
  MailboxesReplyAll422.pipe(status(422)),
58018
+ MailboxesReplyAll429.pipe(status(429)),
57665
58019
  MailboxesReplyAll500,
57666
58020
  MailboxesReplyAll502.pipe(status(502)),
58021
+ MailboxesReplyAll503.pipe(status(503)),
57667
58022
  MailboxesReplyAll504.pipe(status(504))
57668
58023
  ]
57669
58024
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.replyAll").annotate(Summary, "Reply to all recipients of a message").annotate(Description, "Replies to the sender and every other recipient of the message except the mailbox itself, in the same thread."), post("mailboxesPause", "/v1/mailboxes/:id/pause", {
@@ -57900,7 +58255,7 @@ var MediaGroup = class extends make38("Media").add(post("mediaCreate", "/v1/medi
57900
58255
  MediaCreate500,
57901
58256
  MediaCreate504.pipe(status(504))
57902
58257
  ]
57903
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "media.create").annotate(Summary, "Create a media object").annotate(Description, "Creates the media object in the pending state and returns it with the upload instruction \u2014 URL, method, and headers \u2014 for putting its bytes into storage."), get5("mediaGetById", "/v1/media/:id", {
58258
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "media.create").annotate(Summary, "Create a media object").annotate(Description, "Creates the media object in the pending state and returns it with the upload instruction \u2014 URL, method, and headers \u2014 for putting its bytes into storage. Requires `messages:create`, or `email:send` for `attachment` media."), get5("mediaGetById", "/v1/media/:id", {
57904
58259
  params: MediaGetByIdPathParams,
57905
58260
  success: MediaGetById200,
57906
58261
  error: [
@@ -57933,7 +58288,7 @@ var MediaGroup = class extends make38("Media").add(post("mediaCreate", "/v1/medi
57933
58288
  MediaComplete500,
57934
58289
  MediaComplete504.pipe(status(504))
57935
58290
  ]
57936
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "media.complete").annotate(Summary, "Complete a media upload").annotate(Description, "Verifies the uploaded object exists in storage, marks the media object ready, and returns it with a download URL."), get5("mediaDownloadUrl", "/v1/media/:id/url", {
58291
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "media.complete").annotate(Summary, "Complete a media upload").annotate(Description, "Verifies the uploaded object exists in storage, marks the media object ready, and returns it with a download URL. Requires the permission that creating the media object did."), get5("mediaDownloadUrl", "/v1/media/:id/url", {
57937
58292
  params: MediaDownloadUrlPathParams,
57938
58293
  success: MediaDownloadUrl200,
57939
58294
  error: [
@@ -58062,6 +58417,7 @@ var MessagesGroup = class extends make38("Messages").add(get5("messagesList", "/
58062
58417
  MessagesValidateEmail404.pipe(status(404)),
58063
58418
  MessagesValidateEmail422.pipe(status(422)),
58064
58419
  MessagesValidateEmail500,
58420
+ MessagesValidateEmail503.pipe(status(503)),
58065
58421
  MessagesValidateEmail504.pipe(status(504))
58066
58422
  ]
58067
58423
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "messages.validateEmail").annotate(Summary, "Validate an email message").annotate(Description, "Resolves recipients, sender, and inline or published-template content without sending anything, creating contacts or messages, or counting toward your quota.")).annotate(Description, "Send messages and read their delivery state and timeline.") {
@@ -58123,6 +58479,7 @@ var ScheduledMessagesGroup = class extends make38("Scheduled Messages").add(get5
58123
58479
  ScheduledMessagesResume422.pipe(status(422)),
58124
58480
  ScheduledMessagesResume500,
58125
58481
  ScheduledMessagesResume502.pipe(status(502)),
58482
+ ScheduledMessagesResume503.pipe(status(503)),
58126
58483
  ScheduledMessagesResume504.pipe(status(504))
58127
58484
  ]
58128
58485
  }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "scheduledMessages.resume").annotate(Summary, "Resume a review-paused scheduled message").annotate(Description, "Explicitly resumes a scheduled message after onboarding review clearance. An overdue message requires either send_now or a new future scheduledFor value.")).annotate(Description, "One-off scheduled message timers") {
@@ -58171,7 +58528,7 @@ var NamespacesGroup = class extends make38("Namespaces").add(get5("namespacesLis
58171
58528
  NamespacesRemove500,
58172
58529
  NamespacesRemove504.pipe(status(504))
58173
58530
  ]
58174
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.remove").annotate(Summary, "Delete a namespace").annotate(Description, "Deletes an empty namespace. A namespace that still holds mailboxes or API keys conflicts: remove or move them first."), patch("namespacesUpdate", "/v1/namespaces/:id", {
58531
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.remove").annotate(Summary, "Delete a namespace").annotate(Description, "Deletes an empty namespace. A namespace that still holds mailboxes, API keys, or webhook endpoints conflicts: remove them first."), patch("namespacesUpdate", "/v1/namespaces/:id", {
58175
58532
  params: NamespacesUpdatePathParams,
58176
58533
  payload: NamespacesUpdateRequestJson,
58177
58534
  success: NamespacesUpdate200,
@@ -58933,7 +59290,18 @@ var make39 = (config) => gen2(function* () {
58933
59290
  for (const [name, value] of Object.entries(config.headers ?? {}))
58934
59291
  if (value !== undefined)
58935
59292
  headers[name] = value;
59293
+ const storage = yield* HttpClient;
59294
+ const putUpload = (input) => storage.execute(make33(input.method)(input.url).pipe(bodyUint8Array(input.bytes, uploadContentType(input.headers)), setHeaders(input.headers))).pipe(mapError2((cause) => new MediaUploadError({
59295
+ filename: input.filename,
59296
+ mediaId: input.mediaId,
59297
+ cause
59298
+ })), flatMap3((response) => response.status >= 200 && response.status < 300 ? void_3 : fail6(new MediaUploadError({
59299
+ filename: input.filename,
59300
+ mediaId: input.mediaId,
59301
+ status: response.status
59302
+ }))));
58936
59303
  return Service3.of({
59304
+ putUpload,
58937
59305
  raw,
58938
59306
  operation: (name) => flat[name],
58939
59307
  connection: {
@@ -58949,7 +59317,7 @@ var layer16 = (config) => effect(Service3, make39(config));
58949
59317
  var layerFetch = (config) => layer16(config).pipe(provide2(layer15));
58950
59318
  var raw2 = map7(Service3, (client) => client.raw);
58951
59319
 
58952
- // ../sdk/dist/categories-DvsHUJtX.js
59320
+ // ../sdk/dist/categories-Bcwq5jPV.js
58953
59321
  var SamvaErrorMetadata = {
58954
59322
  AnalyticsQueryError: {
58955
59323
  categories: [],
@@ -59015,6 +59383,10 @@ var SamvaErrorMetadata = {
59015
59383
  categories: ["notFound"],
59016
59384
  retryable: false
59017
59385
  },
59386
+ SenderNotReadyError: {
59387
+ categories: ["transient"],
59388
+ retryable: true
59389
+ },
59018
59390
  UnauthorizedError: {
59019
59391
  categories: ["auth"],
59020
59392
  retryable: false
@@ -59110,7 +59482,7 @@ var generateIdempotencyKey = gen2(function* () {
59110
59482
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
59111
59483
  });
59112
59484
 
59113
- // ../sdk/dist/operation-BuyvAsZ1.js
59485
+ // ../sdk/dist/operation-B_Ty1LG-.js
59114
59486
  var SDK_OPERATION_CALLS = {
59115
59487
  brandsList: { kind: "none" },
59116
59488
  brandsCreate: { kind: "payload" },
@@ -59308,6 +59680,10 @@ var SDK_OPERATION_CALLS = {
59308
59680
  kind: "pathPayload",
59309
59681
  paths: ["id"]
59310
59682
  },
59683
+ emailGetReceivingStatus: {
59684
+ kind: "path",
59685
+ paths: ["id"]
59686
+ },
59311
59687
  emailEnableCustomTracking: {
59312
59688
  kind: "pathPayload",
59313
59689
  paths: ["id"]
@@ -59316,6 +59692,10 @@ var SDK_OPERATION_CALLS = {
59316
59692
  kind: "path",
59317
59693
  paths: ["id"]
59318
59694
  },
59695
+ emailRecheckCustomTracking: {
59696
+ kind: "path",
59697
+ paths: ["id"]
59698
+ },
59319
59699
  emailGetCustomTrackingDomainConnect: {
59320
59700
  kind: "path",
59321
59701
  paths: ["id"]
@@ -60032,6 +60412,10 @@ var SDK_OPERATION_CALLS = {
60032
60412
  },
60033
60413
  extensionInstallationsList: { kind: "params" },
60034
60414
  extensionInstallationsInstall: { kind: "payload" },
60415
+ extensionInstallationsUpgrade: {
60416
+ kind: "pathPayload",
60417
+ paths: ["id"]
60418
+ },
60035
60419
  extensionInstallationsGet: {
60036
60420
  kind: "path",
60037
60421
  paths: ["id"]
@@ -60208,11 +60592,35 @@ var make40 = (operationName) => {
60208
60592
  }
60209
60593
  return operation;
60210
60594
  };
60595
+ var uploadOversizedAttachments = (client, payload) => gen2(function* () {
60596
+ const plan = planInlineUploads(payload);
60597
+ if (plan.length === 0)
60598
+ return payload;
60599
+ const uploaded = /* @__PURE__ */ new Map;
60600
+ for (const upload of plan) {
60601
+ const created = yield* rawOperation(client, "mediaCreate")({ payload: mediaCreateBody(upload) });
60602
+ yield* client.putUpload({
60603
+ filename: upload.filename,
60604
+ mediaId: created.id,
60605
+ url: created.upload.url,
60606
+ method: created.upload.method,
60607
+ headers: created.upload.headers,
60608
+ bytes: upload.bytes
60609
+ });
60610
+ yield* rawOperation(client, "mediaComplete")({ params: { id: created.id } });
60611
+ uploaded.set(upload.index, {
60612
+ mediaId: created.id,
60613
+ upload
60614
+ });
60615
+ }
60616
+ return withUploadedAttachments(payload, uploaded);
60617
+ });
60211
60618
  var sendPayload = (payload, options) => gen2(function* () {
60212
60619
  const client = yield* Service3;
60213
60620
  const idempotencyKey = options?.idempotencyKey ?? (yield* generateIdempotencyKey);
60621
+ const prepared = yield* uploadOversizedAttachments(client, payload);
60214
60622
  return yield* withRetry(rawOperation(client, "messagesSend")({
60215
- payload: stripUndefined(payload),
60623
+ payload: stripUndefined(prepared),
60216
60624
  headers: { "idempotency-key": idempotencyKey }
60217
60625
  }));
60218
60626
  });
@@ -60357,8 +60765,10 @@ var getDomainConnect = make40("emailGetDomainConnect");
60357
60765
  var buildDomainConnectApplyUrl = make40("emailBuildDomainConnectApplyUrl");
60358
60766
  var completeDomainConnect = make40("emailCompleteDomainConnect");
60359
60767
  var enableReceiving = make40("emailEnableReceiving");
60768
+ var getReceivingStatus = make40("emailGetReceivingStatus");
60360
60769
  var enableCustomTracking = make40("emailEnableCustomTracking");
60361
60770
  var getCustomTracking = make40("emailGetCustomTracking");
60771
+ var recheckCustomTracking = make40("emailRecheckCustomTracking");
60362
60772
  var getCustomTrackingDomainConnect = make40("emailGetCustomTrackingDomainConnect");
60363
60773
  var buildCustomTrackingDomainConnectApplyUrl = make40("emailBuildCustomTrackingDomainConnectApplyUrl");
60364
60774
  var completeCustomTrackingDomainConnect = make40("emailCompleteCustomTrackingDomainConnect");
@@ -60403,6 +60813,7 @@ var getForwardingLog = make40("emailGetForwardingLog");
60403
60813
  // ../sdk/dist/effect/extension-installations.js
60404
60814
  var list9 = make40("extensionInstallationsList");
60405
60815
  var install = make40("extensionInstallationsInstall");
60816
+ var upgrade = make40("extensionInstallationsUpgrade");
60406
60817
  var get11 = make40("extensionInstallationsGet");
60407
60818
  var uninstall = make40("extensionInstallationsUninstall");
60408
60819
  var disable = make40("extensionInstallationsDisable");
@@ -60420,7 +60831,7 @@ var getVersion = make40("extensionsGetVersion");
60420
60831
  // ../sdk/dist/effect/feedback.js
60421
60832
  var send2 = make40("feedbackSend");
60422
60833
 
60423
- // ../sdk/dist/mailbox-events-CcWm8lO4.js
60834
+ // ../sdk/dist/mailbox-events-CsbF35vH.js
60424
60835
  var MAILBOX_EVENT_STREAM_PATH = "/v1/mailboxes/events";
60425
60836
  var MailboxEventStreamCloseCode = {
60426
60837
  invalidFrame: 4400,
@@ -60470,8 +60881,10 @@ var RETRY_MAX_MILLIS = 30000;
60470
60881
  var RETRY_AFTER_MAX_MILLIS = 300000;
60471
60882
  var REFUSAL_BODY_LIMIT = 65536;
60472
60883
  var DIAGNOSE_TIMEOUT_MILLIS = 1e4;
60473
- var MAILBOX_EVENT_STREAM_IDLE_MILLIS = 90000;
60474
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
60884
+ var MAILBOX_EVENT_STREAM_PING_FRAME = '{"kind":"ping"}';
60885
+ var MAILBOX_EVENT_STREAM_PING_MILLIS = 30000;
60886
+ var MAILBOX_EVENT_STREAM_IDLE_MILLIS = 3 * MAILBOX_EVENT_STREAM_PING_MILLIS;
60887
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
60475
60888
  var frameText = (raw) => {
60476
60889
  if (typeof raw === "string")
60477
60890
  return raw;
@@ -60488,14 +60901,16 @@ var decodeFrame = (raw) => {
60488
60901
  } catch {
60489
60902
  return;
60490
60903
  }
60491
- if (!isRecord(parsed) || typeof parsed.cursor !== "string")
60904
+ if (isRecord2(parsed) && parsed.kind === "pong")
60905
+ return { kind: "pong" };
60906
+ if (!isRecord2(parsed) || typeof parsed.cursor !== "string")
60492
60907
  return;
60493
- if (parsed.kind === "live" || parsed.kind === "heartbeat")
60908
+ if (parsed.kind === "live" || parsed.kind === "progress")
60494
60909
  return {
60495
60910
  kind: parsed.kind,
60496
60911
  cursor: parsed.cursor
60497
60912
  };
60498
- if (parsed.kind !== "event" || typeof parsed.id !== "string" || !isRecord(parsed.event))
60913
+ if (parsed.kind !== "event" || typeof parsed.id !== "string" || !isRecord2(parsed.event))
60499
60914
  return;
60500
60915
  const { type, timestamp, data } = parsed.event;
60501
60916
  if (typeof type !== "string" || typeof timestamp !== "string")
@@ -60593,7 +61008,7 @@ var closeOutcome = (closeCode) => {
60593
61008
  }
60594
61009
  };
60595
61010
  var fieldsOf = (value) => {
60596
- if (!isRecord(value))
61011
+ if (!isRecord2(value))
60597
61012
  return;
60598
61013
  const fields = {};
60599
61014
  for (const [path, messages] of Object.entries(value))
@@ -60602,7 +61017,7 @@ var fieldsOf = (value) => {
60602
61017
  return fields;
60603
61018
  };
60604
61019
  var refusalOutcome = (refusal) => {
60605
- const body = isRecord(refusal.body) ? refusal.body : {};
61020
+ const body = isRecord2(refusal.body) ? refusal.body : {};
60606
61021
  const serverTag = typeof body._tag === "string" ? body._tag : undefined;
60607
61022
  const known = serverTag !== undefined && REFUSAL_TAGS.has(serverTag);
60608
61023
  const _tag = known ? serverTag : REFUSAL_TAG_BY_STATUS[refusal.status] ?? "StreamRefusedError";
@@ -60831,6 +61246,7 @@ var MailboxEventStream = class {
60831
61246
  let opened = false;
60832
61247
  let settled = false;
60833
61248
  let idleTimer;
61249
+ let pingTimer;
60834
61250
  const armIdle = () => {
60835
61251
  clearTimeout(idleTimer);
60836
61252
  idleTimer = setTimeout(() => {
@@ -60846,6 +61262,7 @@ var MailboxEventStream = class {
60846
61262
  return;
60847
61263
  settled = true;
60848
61264
  clearTimeout(idleTimer);
61265
+ clearInterval(pingTimer);
60849
61266
  this.#stop.signal.removeEventListener("abort", onStop);
60850
61267
  if (this.#socket === socket)
60851
61268
  this.#socket = undefined;
@@ -60868,6 +61285,10 @@ var MailboxEventStream = class {
60868
61285
  armIdle();
60869
61286
  socket.addEventListener("open", () => {
60870
61287
  opened = true;
61288
+ pingTimer = setInterval(() => {
61289
+ if (socket.readyState === OPEN)
61290
+ socket.send(MAILBOX_EVENT_STREAM_PING_FRAME);
61291
+ }, MAILBOX_EVENT_STREAM_PING_MILLIS);
60871
61292
  });
60872
61293
  socket.addEventListener("message", (message) => {
60873
61294
  if (this.#ended)
@@ -60884,13 +61305,15 @@ var MailboxEventStream = class {
60884
61305
  socket.close(1000);
60885
61306
  return;
60886
61307
  }
61308
+ if (frame.kind === "pong")
61309
+ return;
60887
61310
  if (frame.kind === "event") {
60888
61311
  this.#queue.push({
60889
61312
  cursor: frame.cursor,
60890
61313
  id: frame.id,
60891
61314
  type: frame.event.type,
60892
61315
  timestamp: frame.event.timestamp,
60893
- data: isRecord(frame.event.data) ? frame.event.data : {}
61316
+ data: isRecord2(frame.event.data) ? frame.event.data : {}
60894
61317
  });
60895
61318
  this.#wake();
60896
61319
  return;
@@ -60994,7 +61417,7 @@ var readRefusalBody = async (response) => {
60994
61417
  }
60995
61418
  };
60996
61419
 
60997
- // ../sdk/dist/mailboxes-4gJMAJh4.js
61420
+ // ../sdk/dist/mailboxes-D3Kx7elM.js
60998
61421
  var toStreamError = (cause) => cause instanceof MailboxEventStreamError ? cause : new MailboxEventStreamError({
60999
61422
  _tag: "StreamDisconnectedError",
61000
61423
  message: String(cause)
@@ -61279,6 +61702,7 @@ var apiStatuses = {
61279
61702
  BillingProviderError: 502,
61280
61703
  DeliveryUnavailableError: 503,
61281
61704
  ServiceUnavailableError: 503,
61705
+ SenderNotReadyError: 503,
61282
61706
  EmailChannelError: 502,
61283
61707
  SmsChannelError: 502,
61284
61708
  WhatsAppChannelError: 502,
@@ -61316,6 +61740,9 @@ var apiErrorGuidance = (error) => {
61316
61740
  case "ServiceUnavailableError":
61317
61741
  next = typeof details.retryAfterSeconds === "number" ? `Wait ${details.retryAfterSeconds} seconds before retrying.` : "Wait a moment before retrying.";
61318
61742
  break;
61743
+ case "SenderNotReadyError":
61744
+ next = typeof details.retryAfterSeconds === "number" ? `Wait ${details.retryAfterSeconds} seconds before retrying.` : "Wait for the sending identity to be ready before retrying.";
61745
+ break;
61319
61746
  case "CursorExpiredError":
61320
61747
  next = "Read current state from the API, then retry without the cursor.";
61321
61748
  break;
@@ -61412,7 +61839,7 @@ var commandTree = {
61412
61839
  check: {},
61413
61840
  remove: {},
61414
61841
  "rotate-dkim": {},
61415
- "custom-tracking": { enable: {}, status: {}, disable: {} }
61842
+ "custom-tracking": { enable: {}, status: {}, recheck: {}, disable: {} }
61416
61843
  },
61417
61844
  senders: { list: {}, add: {}, check: {}, remove: {} }
61418
61845
  },
@@ -61462,10 +61889,16 @@ var commandTree = {
61462
61889
  events: {},
61463
61890
  list: {},
61464
61891
  create: {},
61892
+ get: {},
61893
+ update: {},
61894
+ pause: {},
61895
+ resume: {},
61896
+ remove: {},
61465
61897
  threads: {},
61466
61898
  read: {},
61467
61899
  send: {},
61468
61900
  reply: {},
61901
+ actions: { list: {}, approve: {}, deny: {} },
61469
61902
  quarantine: { list: {}, release: {}, discard: {} }
61470
61903
  },
61471
61904
  extensions: {
@@ -63282,7 +63715,10 @@ var printCustomTracking = (data) => gen2(function* () {
63282
63715
  ["Host", custom.hostname],
63283
63716
  ["Region", custom.region],
63284
63717
  ["Certificate", custom.sslStatus ?? "pending"],
63285
- ["CAA blocked", custom.caaBlocked ? "yes" : "no"]
63718
+ ["CAA blocked", custom.caaBlocked ? "yes" : "no"],
63719
+ ["Reason", custom.certificate?.reason.message],
63720
+ ["Last checked", custom.certificate?.lastCheckedAt],
63721
+ ["Next check", custom.certificate?.nextCheckAt]
63286
63722
  ]);
63287
63723
  yield* log(`
63288
63724
  Create these DNS records:`);
@@ -63334,6 +63770,16 @@ var customStatus = make29("status", {
63334
63770
  return yield* printJson(data);
63335
63771
  yield* printCustomTracking(data);
63336
63772
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
63773
+ var customRecheck = make29("recheck", {
63774
+ id: String10("id").pipe(withDescription4("Domain id to recheck")),
63775
+ json: jsonFlag
63776
+ }).pipe(withDescription3("Check a domain's custom tracking certificate now instead of waiting for the next scheduled check"), withExamples([{ command: "samva email domains custom-tracking recheck dom_abc123" }]), withHandler(({ id, json }) => gen2(function* () {
63777
+ const client = yield* getClientProvider;
63778
+ const data = yield* recheckCustomTracking({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not recheck custom tracking", error)));
63779
+ if (json)
63780
+ return yield* printJson(data);
63781
+ yield* printCustomTracking(data);
63782
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
63337
63783
  var customDisable = make29("disable", {
63338
63784
  id: String10("id").pipe(withDescription4("Domain id to disable custom tracking for")),
63339
63785
  dryRun: Boolean6("dry-run").pipe(withDescription2("Print the teardown plan without calling the API"), withDefault5(false)),
@@ -63358,50 +63804,106 @@ var customDisable = make29("disable", {
63358
63804
  return yield* printJson(data);
63359
63805
  yield* log(`Disabled custom tracking for ${id}.`);
63360
63806
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
63361
- var customTracking = make29("custom-tracking").pipe(withDescription3("Manage a domain's custom tracking (custom open/click subdomain)"), withExamples([{ command: "samva email domains custom-tracking enable dom_abc123" }]), withSubcommands([customEnable, customStatus, customDisable]));
63807
+ var customTracking = make29("custom-tracking").pipe(withDescription3("Manage a domain's custom tracking (custom open/click subdomain)"), withExamples([{ command: "samva email domains custom-tracking enable dom_abc123" }]), withSubcommands([customEnable, customStatus, customRecheck, customDisable]));
63362
63808
  var domainsCommand = make29("domains").pipe(withDescription3("Manage email sending domains"), withExamples([
63363
63809
  { command: "samva email domains list", description: "List configured domains" }
63364
63810
  ]), withSubcommands([list21, add2, check2, rotateDkim, remove16, customTracking]));
63365
63811
 
63366
63812
  // src/commands/email/receiving.ts
63813
+ var destinationLabel = (destination) => {
63814
+ const parts = [
63815
+ destination.endpointId === null ? [] : [`webhook ${destination.endpointId}`],
63816
+ destination.forwardingRules === 0 ? [] : [
63817
+ `${destination.forwardingRules} forwarding rule${destination.forwardingRules === 1 ? "" : "s"}`
63818
+ ],
63819
+ destination.mailboxes === 0 ? [] : [`${destination.mailboxes} mailbox${destination.mailboxes === 1 ? "" : "es"}`]
63820
+ ].flat();
63821
+ return parts.length === 0 ? "none (add a webhook endpoint or a forwarding rule)" : parts.join(", ");
63822
+ };
63823
+ var mxLabel = (mx) => {
63824
+ switch (mx.state) {
63825
+ case "pointing-here":
63826
+ return `points at ${mx.expected.exchange}`;
63827
+ case "elsewhere":
63828
+ return `routes mail to ${mx.current[0]?.exchange ?? "another provider"}; set it to ${mx.expected.exchange}`;
63829
+ case "missing":
63830
+ return `no MX record; add ${mx.expected.exchange}`;
63831
+ default:
63832
+ return "could not be looked up; try again";
63833
+ }
63834
+ };
63367
63835
  var status2 = make29("status", {
63368
63836
  domainId: String10("domain-id").pipe(withDescription4("Sending domain id")),
63369
63837
  json: jsonFlag
63370
- }).pipe(withDescription3("Get a domain's receiving prerequisite status"), withExamples([{ command: "samva email receiving status dom_abc123 --json" }]), withHandler(({ domainId, json }) => gen2(function* () {
63838
+ }).pipe(withDescription3("Report each prerequisite for receiving a domain's mail at Samva, in order, with a live MX lookup"), withExamples([{ command: "samva email receiving status dom_abc123 --json" }]), withHandler(({ domainId, json }) => gen2(function* () {
63371
63839
  const client = yield* getClientProvider;
63372
- const data = yield* getDomainVerification({ id: domainId }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get receiving status", error)));
63840
+ const data = yield* getReceivingStatus({ id: domainId }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get receiving status", error)));
63373
63841
  if (json)
63374
63842
  return yield* printJson(data);
63843
+ const mark = (satisfied) => satisfied ? "done" : "todo";
63375
63844
  yield* printFields([
63376
63845
  ["Domain", data.domain],
63377
- ["Phase", data.phase]
63846
+ ["1. Sending", `${mark(data.sending.satisfied)} (${data.sending.phase})`],
63847
+ [
63848
+ "2. Destination",
63849
+ `${mark(data.destination.satisfied)} ${destinationLabel(data.destination)}`
63850
+ ],
63851
+ [
63852
+ "3. Receiving",
63853
+ `${mark(data.receiving.satisfied)}${data.receiving.catchAll ? " (catch-all)" : ""}`
63854
+ ],
63855
+ [`4. Inbound MX`, `${mark(data.mx.satisfied)} ${data.receivingHost} ${mxLabel(data.mx)}`],
63856
+ ["Ready", data.ready ? "yes" : "no"]
63378
63857
  ]);
63379
63858
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
63380
63859
  var enable2 = make29("enable", {
63381
63860
  domainId: String10("domain-id").pipe(withDescription4("Sending domain id")),
63382
63861
  domain: String9("domain").pipe(withDescription2("Verified domain name")),
63383
- address: String9("address").pipe(withDescription2("Recipient address to receive (repeatable)"), atLeast2(1)),
63384
- catchAll: Boolean6("catch-all").pipe(withDescription2("Also receive unmatched addresses"), withDefault5(false)),
63862
+ address: String9("address").pipe(withDescription2("Exact recipient address to receive (repeatable)"), atLeast2(0)),
63863
+ catchAll: Boolean6("catch-all").pipe(withDescription2("Receive every address on the domain. Needs --endpoint or an active forwarding rule that covers the domain"), withDefault5(false)),
63864
+ endpoint: String9("endpoint").pipe(withDescription2("Webhook endpoint id that receives message.received for a catch-all domain"), optional4),
63385
63865
  dryRun: Boolean6("dry-run").pipe(withDescription2("Print the provider setup request without calling the API"), withDefault5(false)),
63386
63866
  json: jsonFlag
63387
- }).pipe(withDescription3("Enable inbound receiving for a verified domain"), withExamples([
63867
+ }).pipe(withDescription3("Enable inbound receiving for a verified domain. Receiving needs somewhere to deliver: exact addresses are accepted, and a catch-all needs a webhook endpoint or a forwarding rule"), withExamples([
63868
+ {
63869
+ command: "samva email receiving enable dom_abc123 --domain example.com --catch-all --endpoint wep_abc123"
63870
+ },
63871
+ {
63872
+ command: "samva email receiving enable dom_abc123 --domain example.com --catch-all"
63873
+ },
63388
63874
  {
63389
63875
  command: "samva email receiving enable dom_abc123 --domain example.com --address replies@example.com --dry-run"
63390
63876
  },
63391
63877
  {
63392
63878
  command: "samva email receiving enable dom_abc123 --domain example.com --address replies@example.com"
63393
63879
  }
63394
- ]), withHandler(({ domainId, domain, address, catchAll, dryRun, json }) => gen2(function* () {
63395
- const request = { domain, catchAll, addresses: [...address] };
63880
+ ]), withHandler(({ domainId, domain, address, catchAll, endpoint, dryRun, json }) => gen2(function* () {
63881
+ if (address.length === 0 && !catchAll) {
63882
+ return yield* new SamvaCliError({
63883
+ message: "Pass --address for each exact recipient, or --catch-all for the whole domain."
63884
+ });
63885
+ }
63886
+ const endpointId = getOrUndefined(endpoint);
63887
+ if (endpointId !== undefined && !catchAll) {
63888
+ return yield* new SamvaCliError({
63889
+ message: "--endpoint names the catch-all webhook, so it needs --catch-all."
63890
+ });
63891
+ }
63892
+ const request = {
63893
+ domain,
63894
+ catchAll,
63895
+ addresses: [...address],
63896
+ ...endpointId === undefined ? {} : { endpointId }
63897
+ };
63396
63898
  if (dryRun)
63397
- return yield* json ? printJson({ dryRun: true, action: "email.receiving.enable", domainId, request }) : log(`[dry-run] Would enable receiving for ${domain} (${address.join(", ")}).`);
63899
+ return yield* json ? printJson({ dryRun: true, action: "email.receiving.enable", domainId, request }) : log(`[dry-run] Would enable receiving for ${domain} (${catchAll ? "catch-all" : address.join(", ")}).`);
63398
63900
  const client = yield* getClientProvider;
63399
63901
  const data = yield* enableReceiving({ id: domainId, ...request }).pipe(client.provide, mapError2((error) => toCliApiError("Could not enable receiving", error)));
63400
63902
  if (json)
63401
63903
  return yield* printJson(data);
63402
63904
  yield* printFields([["Recipients", data.recipients.join(", ")]]);
63403
63905
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
63404
- var receivingCommand = make29("receiving").pipe(withDescription3("Configure inbound email receiving"), withExamples([{ command: "samva email receiving status dom_abc123" }]), withSubcommands([status2, enable2]));
63906
+ var receivingCommand = make29("receiving").pipe(withDescription3("Move a domain's inbound email to Samva and check what is left to do"), withExamples([{ command: "samva email receiving status dom_abc123" }]), withSubcommands([status2, enable2]));
63405
63907
 
63406
63908
  // src/commands/email/review.ts
63407
63909
  var readStatus = gen2(function* () {
@@ -63446,8 +63948,117 @@ var reapply = make29("reapply", { json: jsonFlag }).pipe(withDescription3("Resub
63446
63948
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
63447
63949
  var reviewCommand = make29("review").pipe(withDescription3("Inspect or resubmit email onboarding review"), withSubcommands([status3, reapply]));
63448
63950
 
63951
+ // src/lib/attachments.ts
63952
+ import { readFile as readFile3, stat as stat3 } from "fs/promises";
63953
+ import { basename, extname } from "path";
63954
+
63955
+ // ../core/src/messages/attachment-budget.ts
63956
+ var EMAIL_ATTACHMENT_BUDGET = {
63957
+ maxCount: 10,
63958
+ maxItemBytes: 25 * 1024 * 1024,
63959
+ maxAggregateBytes: 25 * 1024 * 1024,
63960
+ maxInlineBytes: 4 * 1024 * 1024
63961
+ };
63962
+ var emailAttachmentBudgetViolation = (attachments) => {
63963
+ if (attachments.length > EMAIL_ATTACHMENT_BUDGET.maxCount)
63964
+ return "count";
63965
+ let aggregateBytes = 0;
63966
+ for (const attachment of attachments) {
63967
+ if (!Number.isSafeInteger(attachment.size) || attachment.size <= 0 || attachment.size > EMAIL_ATTACHMENT_BUDGET.maxItemBytes) {
63968
+ return "itemBytes";
63969
+ }
63970
+ aggregateBytes += attachment.size;
63971
+ if (aggregateBytes > EMAIL_ATTACHMENT_BUDGET.maxAggregateBytes)
63972
+ return "aggregateBytes";
63973
+ }
63974
+ return null;
63975
+ };
63976
+ var emailAttachmentBudgetMessage = (violation) => {
63977
+ switch (violation) {
63978
+ case "count":
63979
+ return `Email supports at most ${EMAIL_ATTACHMENT_BUDGET.maxCount} attachments`;
63980
+ case "itemBytes":
63981
+ return `Each email attachment must be between 1 byte and ${EMAIL_ATTACHMENT_BUDGET.maxItemBytes} bytes`;
63982
+ case "aggregateBytes":
63983
+ return `Email attachments must total at most ${EMAIL_ATTACHMENT_BUDGET.maxAggregateBytes} bytes`;
63984
+ }
63985
+ };
63986
+ var emailInlineAttachmentBytes = (attachments) => attachments.reduce((total, attachment) => attachment.content === undefined ? total : total + attachment.size, 0);
63987
+ var EMAIL_INLINE_ATTACHMENT_MESSAGE = `Inline attachment content must total at most ${EMAIL_ATTACHMENT_BUDGET.maxInlineBytes} bytes. Upload larger files with POST /v1/media and send their mediaId instead of content.`;
63988
+
63989
+ // src/lib/attachments.ts
63990
+ var CONTENT_TYPE_BY_EXTENSION = {
63991
+ ".csv": "text/csv",
63992
+ ".doc": "application/msword",
63993
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
63994
+ ".gif": "image/gif",
63995
+ ".htm": "text/html",
63996
+ ".html": "text/html",
63997
+ ".ics": "text/calendar",
63998
+ ".jpeg": "image/jpeg",
63999
+ ".jpg": "image/jpeg",
64000
+ ".json": "application/json",
64001
+ ".md": "text/markdown",
64002
+ ".mp3": "audio/mpeg",
64003
+ ".mp4": "video/mp4",
64004
+ ".pdf": "application/pdf",
64005
+ ".png": "image/png",
64006
+ ".ppt": "application/vnd.ms-powerpoint",
64007
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
64008
+ ".svg": "image/svg+xml",
64009
+ ".txt": "text/plain",
64010
+ ".webp": "image/webp",
64011
+ ".xls": "application/vnd.ms-excel",
64012
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
64013
+ ".xml": "application/xml",
64014
+ ".zip": "application/zip"
64015
+ };
64016
+ var contentTypeForPath = (path) => CONTENT_TYPE_BY_EXTENSION[extname(path).toLowerCase()] ?? "application/octet-stream";
64017
+ var attachmentError = (code, message) => new CliUsageError({ code, message });
64018
+ var describeCause = (cause) => cause instanceof Error ? cause.message : String(cause);
64019
+ var unreadable = (path) => (cause) => attachmentError("attachment_unreadable", `Cannot read --attach ${path}: ${describeCause(cause)}`);
64020
+ var checkAttachmentBudget = (files) => gen2(function* () {
64021
+ for (const file of files) {
64022
+ if (file.size === 0) {
64023
+ return yield* attachmentError("attachment_empty", `--attach ${file.path} is empty; an attachment must be at least 1 byte.`);
64024
+ }
64025
+ if (file.size > EMAIL_ATTACHMENT_BUDGET.maxItemBytes) {
64026
+ return yield* attachmentError("attachment_too_large", `--attach ${file.path} is ${file.size} bytes; each attachment must be at most ${EMAIL_ATTACHMENT_BUDGET.maxItemBytes} bytes.`);
64027
+ }
64028
+ }
64029
+ const violation = emailAttachmentBudgetViolation(files);
64030
+ if (violation !== null) {
64031
+ const total = files.reduce((sum, file) => sum + file.size, 0);
64032
+ return yield* attachmentError(`attachment_budget_${violation}`, `${emailAttachmentBudgetMessage(violation)} (got ${files.length} files, ${total} bytes).`);
64033
+ }
64034
+ });
64035
+ var readAttachments = (paths) => gen2(function* () {
64036
+ const sizes = yield* forEach2(paths, (path) => tryPromise2({
64037
+ try: async () => ({ path, size: (await stat3(path)).size }),
64038
+ catch: unreadable(path)
64039
+ }));
64040
+ yield* checkAttachmentBudget(sizes);
64041
+ const files = yield* forEach2(paths, (path) => tryPromise2({
64042
+ try: async () => ({
64043
+ path,
64044
+ filename: basename(path),
64045
+ contentType: contentTypeForPath(path),
64046
+ bytes: await readFile3(path)
64047
+ }),
64048
+ catch: unreadable(path)
64049
+ }));
64050
+ yield* checkAttachmentBudget(files.map((file) => ({ path: file.path, size: file.bytes.length })));
64051
+ return files;
64052
+ });
64053
+ var toSendAttachments = (files) => files.map((file) => ({
64054
+ filename: file.filename,
64055
+ contentType: file.contentType,
64056
+ size: file.bytes.length,
64057
+ content: Buffer.from(file.bytes).toString("base64")
64058
+ }));
64059
+
63449
64060
  // src/lib/stdin.ts
63450
- import { readFile as readFile3 } from "fs";
64061
+ import { readFile as readFile4 } from "fs";
63451
64062
  import { isatty as isatty2 } from "tty";
63452
64063
  import { promisify } from "util";
63453
64064
  var readStdinUtf8 = gen2(function* () {
@@ -63457,7 +64068,7 @@ var readStdinUtf8 = gen2(function* () {
63457
64068
  });
63458
64069
  }
63459
64070
  return yield* tryPromise2({
63460
- try: () => promisify(readFile3)(0, "utf8"),
64071
+ try: () => promisify(readFile4)(0, "utf8"),
63461
64072
  catch: () => new SamvaCliError({ message: "Could not read stdin." })
63462
64073
  });
63463
64074
  });
@@ -63768,6 +64379,7 @@ var replyToAddressFlag = String9("reply-to").pipe(withDescription2("Reply-To hea
63768
64379
  var idempotencyKeyFlag2 = String9("idempotency-key").pipe(withDescription2("Key (1-255 characters) so identical retries return the original email"), optional4);
63769
64380
  var trackOpensFlag2 = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for this send; recipient opt-out still wins"), optional4);
63770
64381
  var trackClicksFlag2 = Literals3("track-clicks", ["on", "off"]).pipe(withDescription2("Override click tracking for this send; recipient opt-out still wins"), optional4);
64382
+ var attachFlag = String9("attach").pipe(withDescription2("File to attach (repeatable); small files travel inline, larger ones upload through media first"), atLeast2(0));
63771
64383
  var dryRunFlag2 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
63772
64384
  var bodySourceName = (input) => {
63773
64385
  if (input.templateRefValue)
@@ -63804,6 +64416,7 @@ var send3 = make29("send", {
63804
64416
  idempotencyKey: idempotencyKeyFlag2,
63805
64417
  trackOpens: trackOpensFlag2,
63806
64418
  trackClicks: trackClicksFlag2,
64419
+ attach: attachFlag,
63807
64420
  dryRun: dryRunFlag2,
63808
64421
  wait: Boolean6("wait").pipe(withDescription2("Wait for delivered/read or a terminal delivery failure"), withDefault5(false)),
63809
64422
  timeout: timeoutFlag,
@@ -63832,6 +64445,10 @@ var send3 = make29("send", {
63832
64445
  {
63833
64446
  command: "samva email send --to you@example.com --subject Hi --text Hello --idempotency-key welcome-email-ada",
63834
64447
  description: "Retry a send safely with an idempotency key"
64448
+ },
64449
+ {
64450
+ command: "samva email send --to you@example.com --subject Report --text Attached --attach ./report.pdf --attach ./data.csv",
64451
+ description: "Attach files; those past the 4 MiB inline limit upload through media automatically"
63835
64452
  }
63836
64453
  ]), withHandler(({
63837
64454
  to,
@@ -63852,6 +64469,7 @@ var send3 = make29("send", {
63852
64469
  idempotencyKey,
63853
64470
  trackOpens,
63854
64471
  trackClicks,
64472
+ attach,
63855
64473
  dryRun,
63856
64474
  wait,
63857
64475
  timeout,
@@ -63923,6 +64541,7 @@ var send3 = make29("send", {
63923
64541
  message: "Choose exactly one body source: --html, --text, or a template (--template-id/--template-slug)."
63924
64542
  });
63925
64543
  }
64544
+ const attachmentFiles = yield* readAttachments(attach);
63926
64545
  const request = {
63927
64546
  to: [...to],
63928
64547
  ...ccValue ? { cc: [{ email: ccValue }] } : {},
@@ -63969,7 +64588,16 @@ var send3 = make29("send", {
63969
64588
  return yield* printJson({
63970
64589
  dryRun: true,
63971
64590
  bodySource: source,
63972
- request,
64591
+ request: {
64592
+ ...request,
64593
+ ...attachmentFiles.length === 0 ? {} : {
64594
+ attachments: attachmentFiles.map((file) => ({
64595
+ filename: file.filename,
64596
+ contentType: file.contentType,
64597
+ size: file.bytes.length
64598
+ }))
64599
+ }
64600
+ },
63973
64601
  idempotencyKey: idempotencyKeyValue
63974
64602
  });
63975
64603
  }
@@ -63985,6 +64613,10 @@ var send3 = make29("send", {
63985
64613
  ...request.inReplyToMessageId ? [["Reply to", request.inReplyToMessageId]] : [],
63986
64614
  ...request.replyTo ? [["Reply-To", request.replyTo]] : [],
63987
64615
  ...idempotencyKeyValue ? [["Idempotency key", idempotencyKeyValue]] : [],
64616
+ ...attachmentFiles.map((file) => [
64617
+ "Attachment",
64618
+ `${file.filename} (${file.contentType}, ${file.bytes.length} bytes)`
64619
+ ]),
63988
64620
  ...request.tracking ? [
63989
64621
  ["Track opens", request.tracking.opens],
63990
64622
  ["Track clicks", request.tracking.clicks]
@@ -64008,7 +64640,8 @@ ${truncateForDisplay(JSON.stringify(request.templateData, null, 2))}`);
64008
64640
  return;
64009
64641
  }
64010
64642
  const client = yield* getClientProvider;
64011
- const data = yield* send(request, sendOptions).pipe(client.provide, mapError2((error) => toCliApiError("Failed to send email", error)));
64643
+ const attachments = toSendAttachments(attachmentFiles);
64644
+ const data = yield* send({ ...request, ...attachments.length === 0 ? {} : { attachments } }, sendOptions).pipe(client.provide, mapError2((error) => toCliApiError("Failed to send email", error)));
64012
64645
  const finalMessage = waitDuration === undefined ? data : yield* waitForMessage(data, waitDuration);
64013
64646
  const projection = projectMessage(finalMessage);
64014
64647
  const outcome = wait ? lifecycleOf(finalMessage) : undefined;
@@ -64783,8 +65416,6 @@ var CONTACT_STATUS_VALUES = ["active", "paused", "blocked", "archived"];
64783
65416
  var contactStatusSchema = Literals(CONTACT_STATUS_VALUES);
64784
65417
  var ACTOR_STATUS_VALUES = ["active", "disabled", "archived"];
64785
65418
  var actorStatusSchema = Literals(ACTOR_STATUS_VALUES);
64786
- var ACCESS_LEVEL_VALUES = ["public", "authenticated", "vip", "internal"];
64787
- var accessLevelSchema = Literals(ACCESS_LEVEL_VALUES);
64788
65419
  var CONTACT_GROUP_TYPE_VALUES = ["static", "dynamic", "smart"];
64789
65420
  var contactGroupTypeSchema = Literals(CONTACT_GROUP_TYPE_VALUES);
64790
65421
  var CUSTOM_FIELD_TYPE_VALUES = ["text", "number", "boolean", "date", "select"];
@@ -65240,6 +65871,33 @@ var IanaTimezone2 = String4.check(makeFilter2(isIanaTimezone, {
65240
65871
  })).annotate({ identifier: "IanaTimezone" });
65241
65872
 
65242
65873
  // ../core/src/mailboxes/mailbox.ts
65874
+ var mailboxEventTypes = [
65875
+ "mailbox.created",
65876
+ "address.attached",
65877
+ "email.received",
65878
+ "email.released",
65879
+ "email.sent",
65880
+ "thread.created",
65881
+ "thread.updated",
65882
+ "draft.created",
65883
+ "draft.updated",
65884
+ "action.proposed",
65885
+ "action.policy_decided",
65886
+ "action.approval_requested",
65887
+ "action.approval_resolved",
65888
+ "action.executed",
65889
+ "action.failed"
65890
+ ];
65891
+ var mailboxActionScopes = [
65892
+ "sendMessage",
65893
+ "reply",
65894
+ "updateDraft",
65895
+ "createNote",
65896
+ "assignThread",
65897
+ "changeThreadState",
65898
+ "call",
65899
+ "extensionRequest"
65900
+ ];
65243
65901
  var mailboxActorKinds = [
65244
65902
  "user",
65245
65903
  "apiKey",
@@ -65248,6 +65906,27 @@ var mailboxActorKinds = [
65248
65906
  "samvaAgent",
65249
65907
  "system"
65250
65908
  ];
65909
+ var mailboxActionSources = [
65910
+ "humanUi",
65911
+ "externalApi",
65912
+ "aiSdkTool",
65913
+ "extension",
65914
+ "externalAgent",
65915
+ "samvaManagedAgent",
65916
+ "system"
65917
+ ];
65918
+ var mailboxActionStates = [
65919
+ "proposed",
65920
+ "allowed",
65921
+ "approvalRequired",
65922
+ "policyDenied",
65923
+ "approved",
65924
+ "approvalDenied",
65925
+ "executing",
65926
+ "executed",
65927
+ "failed"
65928
+ ];
65929
+ var mailboxApproverKinds = ["user", "samvaAgent", "system"];
65251
65930
  var mailboxPermissions = [
65252
65931
  "mailbox:read",
65253
65932
  "mailbox:configure",
@@ -65277,7 +65956,6 @@ var extensionRuntimes = ["hosted", "webhook"];
65277
65956
  var ExtensionRuntime = Literals(extensionRuntimes);
65278
65957
  var ExtensionPermission = Literals(mailboxKeyActions);
65279
65958
  var EXTENSION_BUNDLE_MAX_BYTES = 1024 * 1024;
65280
- var EXTENSION_TOOL_REQUEST_MAX_BYTES = 6 * 1024 * 1024;
65281
65959
  var uniqueValues = (values) => new Set(values).size === values.length;
65282
65960
  var ExtensionName = String4.check(isPattern2(/^[a-z][a-z0-9-]{1,62}[a-z0-9]$/u, {
65283
65961
  message: "An extension name is 3-64 lowercase letters, digits, and hyphens"
@@ -65380,6 +66058,38 @@ var InstallExtensionResponse2 = Struct({
65380
66058
  webhookSecret: SensitiveString2
65381
66059
  }))
65382
66060
  }).annotate({ identifier: "InstallExtensionResponse" });
66061
+ var ExtensionUpgradeGrant = Literals([
66062
+ ...mailboxKeyActions.map((permission) => `permission:${permission}`),
66063
+ ...MAILBOX_WEBHOOK_EVENT_TYPE_VALUES.map((event) => `event:${event}`)
66064
+ ]);
66065
+ var ExtensionPermissionDiff2 = Struct({
66066
+ added: ArraySchema(ExtensionUpgradeGrant),
66067
+ removed: ArraySchema(ExtensionUpgradeGrant)
66068
+ }).annotate({ identifier: "ExtensionPermissionDiff" });
66069
+ var ExtensionVersionChange2 = Struct({
66070
+ id: String4,
66071
+ organizationId: OrganizationId2,
66072
+ installationId: ExtensionInstallationId2,
66073
+ extensionId: ExtensionId2,
66074
+ fromVersion: ExtensionVersionRef2,
66075
+ toVersion: ExtensionVersionRef2,
66076
+ permissionDiff: ExtensionPermissionDiff2,
66077
+ changedBy: UserId2,
66078
+ changedAt: DateFromString
66079
+ }).annotate({ identifier: "ExtensionVersionChange" });
66080
+ var UpgradeExtensionPayload = Struct({
66081
+ version: optional2(Union2([ExtensionVersionString, ExtensionVersionId2])),
66082
+ acceptPermissions: optional2(ArraySchema(ExtensionUpgradeGrant).check(makeFilter2(uniqueValues, { message: "Each accepted grant is listed once" }))),
66083
+ dryRun: optional2(Boolean3)
66084
+ }).annotate({ identifier: "UpgradeExtensionPayload" });
66085
+ var UpgradeExtensionResponse2 = Struct({
66086
+ installation: ExtensionInstallation2,
66087
+ fromVersion: ExtensionVersionRef2,
66088
+ toVersion: ExtensionVersionRef2,
66089
+ permissionDiff: ExtensionPermissionDiff2,
66090
+ dryRun: Boolean3,
66091
+ versionChange: NullOr(ExtensionVersionChange2)
66092
+ }).annotate({ identifier: "UpgradeExtensionResponse" });
65383
66093
  var ExtensionRunOutcome = Literals([
65384
66094
  "succeeded",
65385
66095
  "failed",
@@ -65640,10 +66350,14 @@ var initExtension = (dir, manifest) => gen2(function* () {
65640
66350
  "src/extension.ts": `import { defineExtension } from "@samva/mailbox";
65641
66351
 
65642
66352
  export default defineExtension({
65643
- manifest: ${JSON.stringify(manifest, null, 2)},
66353
+ manifest: ${JSON.stringify(manifest, null, 2).replaceAll(`
66354
+ `, `
66355
+ `)},
65644
66356
  on: {
65645
66357
  "mailbox.message.received": async (event, { samva, log }) => {
65646
- await samva.messages.reply(event.data.mailboxId, event.data.message.id, { text: "Thanks for your message. We received it." });
66358
+ await samva.messages.reply(event.data.mailboxId, event.data.message.id, {
66359
+ text: "Thanks for your message. We received it.",
66360
+ });
65647
66361
  log("Acknowledged", event.data.message.id);
65648
66362
  },
65649
66363
  },
@@ -65672,6 +66386,10 @@ var undecodedStatus = (error) => isHttpClientError(error) ? error.response?.stat
65672
66386
  var GATED_NEXT = "Mailboxes are not enabled for this organization (the `mailbox` launch flag is off). Mailbox commands work once it is enabled.";
65673
66387
  var personOnlyNext = (action) => {
65674
66388
  switch (action) {
66389
+ case "approve":
66390
+ return "Approving an action needs a person signed in with `samva login`, different from its proposer; an API key cannot approve.";
66391
+ case "deny":
66392
+ return "Denying an action needs a person signed in with `samva login`, different from its proposer; an API key cannot deny.";
65675
66393
  case "release":
65676
66394
  return "Releasing a held message needs a person signed in with `samva login`; an API key cannot release.";
65677
66395
  case "discard":
@@ -65691,7 +66409,7 @@ var mailboxApiError = (prefix, error, options = {}) => {
65691
66409
  api: { reason: "FlagDisabledError", status: 404, details: {}, next: GATED_NEXT }
65692
66410
  });
65693
66411
  const failure = toCliApiError(prefix, error);
65694
- if (options.personOnly !== undefined && failure.api?.status === 403)
66412
+ if (options.personOnly !== undefined && failure.api?.reason === "ForbiddenError")
65695
66413
  return new SamvaCliError({
65696
66414
  message: failure.message,
65697
66415
  api: { ...failure.api, next: personOnlyNext(options.personOnly) }
@@ -65739,26 +66457,98 @@ var ActivityRangeQuery = {
65739
66457
  }))
65740
66458
  };
65741
66459
 
65742
- // src/commands/extensions-api.ts
65743
- var printInstallationSummary = (item) => printFields([
65744
- ["Installation", item.id],
65745
- ["Extension", item.name],
65746
- ["Version", item.version.version],
66460
+ // src/commands/extensions-output.ts
66461
+ var printManifest = (item) => printFields([
66462
+ ["Extension", `${item.name}@${item.version}`],
66463
+ ["Display name", item.displayName],
66464
+ ["Description", item.description === null ? "None" : item.description],
65747
66465
  ["Runtime", item.runtime],
65748
- ["Status", item.status]
66466
+ ["Events", item.events.join(", ")],
66467
+ ["Permissions", item.permissions.join(", ")]
65749
66468
  ]);
65750
- var printInstallation = (item) => printFields([
65751
- ["Installation", item.id],
65752
- ["Extension", item.name],
65753
- ["Version", item.version.version],
66469
+ var printExtension = (item) => gen2(function* () {
66470
+ yield* log(`${item.displayName} (${item.name})`);
66471
+ yield* printFields([
66472
+ ["Extension ID", item.id],
66473
+ ["Description", item.description ?? "None"],
66474
+ ["Runtime", item.runtime],
66475
+ ["Latest version", `${item.latestVersion.version} (${item.latestVersion.id})`],
66476
+ ["Created", item.createdAt],
66477
+ ["Updated", item.updatedAt]
66478
+ ]);
66479
+ });
66480
+ var printVersionSummary = (item) => printFields([
66481
+ ["Version", `${item.version} (${item.id})`],
65754
66482
  ["Runtime", item.runtime],
65755
- ["Status", item.status],
65756
- ["Permissions", item.permissions.join(", ")],
65757
- ["Send mode", item.sendMode],
65758
- ["Mailboxes", item.scope.mailboxIds?.join(", ") ?? "All accessible mailboxes"],
65759
- ["Namespace", item.scope.namespaceId],
65760
- ["Webhook", item.webhook?.url]
66483
+ ["Published", item.publishedAt],
66484
+ ["Bundle", item.bundle === null ? "None" : `${item.bundle.sizeBytes} bytes`],
66485
+ ["SHA256", item.bundle?.sha256]
65761
66486
  ]);
66487
+ var printVersion = (item) => gen2(function* () {
66488
+ yield* printVersionSummary(item);
66489
+ yield* log("Manifest");
66490
+ yield* printManifest(item.manifest);
66491
+ });
66492
+ var printInstallationSummary = (item) => gen2(function* () {
66493
+ yield* log(`${item.displayName} (${item.name}) \u2014 ${item.status}`);
66494
+ yield* printFields([
66495
+ ["Installation", item.id],
66496
+ ["Extension ID", item.extensionId],
66497
+ ["Version", `${item.version.version} (${item.version.id})`],
66498
+ ["Runtime", item.runtime],
66499
+ ["Created", item.createdAt]
66500
+ ]);
66501
+ });
66502
+ var printInstallation = (item) => gen2(function* () {
66503
+ yield* printInstallationSummary(item);
66504
+ yield* log("Access and delivery");
66505
+ yield* printFields([
66506
+ ["Events", item.events.join(", ") || "None"],
66507
+ ["Permissions", item.permissions.join(", ") || "None"],
66508
+ ["Send mode", item.sendMode],
66509
+ [
66510
+ "Mailboxes",
66511
+ item.scope.mailboxIds === null ? "All accessible mailboxes" : item.scope.mailboxIds.join(", ") || "None"
66512
+ ],
66513
+ ["Namespace", item.scope.namespaceId ?? "All namespaces"],
66514
+ ["Webhook", item.webhook?.url ?? "None"],
66515
+ ["Webhook endpoint", item.webhook?.endpointId],
66516
+ ["Updated", item.updatedAt],
66517
+ ["Disabled", item.disabledAt ?? "No"]
66518
+ ]);
66519
+ });
66520
+ var printRunSummary = (item) => gen2(function* () {
66521
+ yield* log(`${item.id}: ${item.outcome}`);
66522
+ yield* printFields([
66523
+ ["Event", item.eventId],
66524
+ ["Type", item.eventType],
66525
+ ["Attempt", item.attempt],
66526
+ ["Started", item.startedAt],
66527
+ ["Duration (ms)", item.durationMs],
66528
+ ["Error", item.error ?? "None"]
66529
+ ]);
66530
+ });
66531
+ var printUpgrade = (result) => gen2(function* () {
66532
+ yield* log(result.dryRun ? "Upgrade preview; no changes made. Installation details below show its current state." : result.versionChange === null ? "Installation already uses the selected version; no changes made." : "Installation upgraded.");
66533
+ yield* printFields([
66534
+ ["From version", `${result.fromVersion.version} (${result.fromVersion.id})`],
66535
+ ["To version", `${result.toVersion.version} (${result.toVersion.id})`],
66536
+ ["Added grants", result.permissionDiff.added.join(", ") || "None"],
66537
+ ["Removed grants", result.permissionDiff.removed.join(", ") || "None"]
66538
+ ]);
66539
+ yield* printInstallation(result.installation);
66540
+ if (result.versionChange !== null) {
66541
+ yield* log("Version change");
66542
+ yield* printFields([
66543
+ ["Change ID", result.versionChange.id],
66544
+ ["Organization", result.versionChange.organizationId],
66545
+ ["Changed by", result.versionChange.changedBy],
66546
+ ["Changed at", result.versionChange.changedAt]
66547
+ ]);
66548
+ }
66549
+ });
66550
+
66551
+ // src/commands/extensions-api.ts
65762
66552
  var pageFlags = {
65763
66553
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
65764
66554
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
@@ -65818,13 +66608,7 @@ var list24 = make29("list", { ...pageFlags, json: jsonFlag }).pipe(withDescripti
65818
66608
  flags,
65819
66609
  empty: "No extensions found.",
65820
66610
  fetch: (query) => list10(query).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list extensions", e))),
65821
- print: (item) => printFields([
65822
- ["ID", item.id],
65823
- ["Name", item.name],
65824
- ["Display name", item.displayName],
65825
- ["Runtime", item.runtime],
65826
- ["Version", item.latestVersion.version]
65827
- ])
66611
+ print: printExtension
65828
66612
  });
65829
66613
  })));
65830
66614
  var versions = make29("versions", {
@@ -65837,35 +66621,19 @@ var versions = make29("versions", {
65837
66621
  flags,
65838
66622
  empty: "No versions found.",
65839
66623
  fetch: (query) => listVersions({ id: extension, ...query }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list versions", e))),
65840
- print: (item) => printFields([
65841
- ["ID", item.id],
65842
- ["Version", item.version],
65843
- ["Runtime", item.runtime],
65844
- ["Published", item.publishedAt],
65845
- ["Size", item.bundle?.sizeBytes],
65846
- ["SHA256", item.bundle?.sha256]
65847
- ])
66624
+ print: printVersionSummary
65848
66625
  });
65849
66626
  })));
65850
66627
  var version2 = make29("version", {
65851
66628
  extension: extensionArgument,
65852
66629
  version: String10("version"),
65853
66630
  json: jsonFlag
65854
- }).pipe(withDescription3("Show one published version with its manifest, by version or id"), withExamples([{ command: "samva extensions version auto-reply 1.0.0 --json" }]), withHandler(({ extension, version, json }) => gen2(function* () {
66631
+ }).pipe(withDescription3("Show one published version with its manifest, by version or id"), withExamples([{ command: "samva extensions version auto-reply 1.0.0 --json" }]), withHandler(({ extension, version: selectedVersion, json }) => gen2(function* () {
65855
66632
  const client = yield* getClientProvider;
65856
- const data = yield* getVersion({ id: extension, versionId: version }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read version", e)));
66633
+ const data = yield* getVersion({ id: extension, versionId: selectedVersion }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read version", e)));
65857
66634
  if (json)
65858
66635
  return yield* printJson(data);
65859
- yield* printFields([
65860
- ["ID", data.id],
65861
- ["Version", data.version],
65862
- ["Runtime", data.runtime],
65863
- ["Published", data.publishedAt],
65864
- ["Events", data.manifest.events.join(", ")],
65865
- ["Permissions", data.manifest.permissions.join(", ")],
65866
- ["Size", data.bundle?.sizeBytes],
65867
- ["SHA256", data.bundle?.sha256]
65868
- ]);
66636
+ yield* printVersion(data);
65869
66637
  })));
65870
66638
  var install2 = make29("install", {
65871
66639
  extension: extensionArgument,
@@ -65880,11 +66648,20 @@ var install2 = make29("install", {
65880
66648
  {
65881
66649
  command: "samva extensions install auto-reply --mailbox mbx_1234567890123456 --permission read --permission send --send-mode approval"
65882
66650
  }
65883
- ]), withHandler(({ extension, version, mailbox, namespace, permission, sendMode, webhookUrl, json }) => gen2(function* () {
66651
+ ]), withHandler(({
66652
+ extension,
66653
+ version: selectedVersion,
66654
+ mailbox,
66655
+ namespace,
66656
+ permission,
66657
+ sendMode,
66658
+ webhookUrl,
66659
+ json
66660
+ }) => gen2(function* () {
65884
66661
  const client = yield* getClientProvider;
65885
66662
  const data = yield* install({
65886
66663
  extension,
65887
- ...isSome2(version) ? { version: version.value } : {},
66664
+ ...isSome2(selectedVersion) ? { version: selectedVersion.value } : {},
65888
66665
  ...mailbox.length ? { mailboxIds: mailbox } : {},
65889
66666
  ...isSome2(namespace) ? { namespaceId: namespace.value } : {},
65890
66667
  ...permission.length ? { permissions: permission } : {},
@@ -65925,6 +66702,37 @@ var installation = make29("installation", {
65925
66702
  return yield* printJson(data);
65926
66703
  yield* printInstallation(data);
65927
66704
  })));
66705
+ var upgrade2 = make29("upgrade", {
66706
+ id: installationArgument,
66707
+ version: String9("version").pipe(withSchema2(Union2([ExtensionVersionString, ExtensionVersionId2])), withDescription2("Published version or version ID; defaults to the latest published version"), optional4),
66708
+ acceptPermissions: Literals3("accept-permissions", ExtensionUpgradeGrant.literals).pipe(withDescription2("Acknowledge one added permission:<name> or event:<type> grant; repeat for each"), atLeast2(0)),
66709
+ dryRun: Boolean6("dry-run").pipe(withDescription2("Ask the API for a preview without changing the installation"), withDefault5(false)),
66710
+ yes: Boolean6("yes").pipe(withDescription2("Skip confirmation"), withDefault5(false)),
66711
+ json: jsonFlag
66712
+ }).pipe(withDescription3("Upgrade an installation using a person signed in with samva login"), withExamples([
66713
+ { command: "samva extensions upgrade exti_1234567890123456 --dry-run --json" },
66714
+ {
66715
+ command: "samva extensions upgrade exti_1234567890123456 --version 2.0.0 --accept-permissions permission:send --accept-permissions event:mailbox.message.sent --yes"
66716
+ }
66717
+ ]), withHandler(({ id, version: selectedVersion, acceptPermissions, dryRun, yes, json }) => gen2(function* () {
66718
+ if (!dryRun)
66719
+ yield* confirmDestructive({
66720
+ yes,
66721
+ json,
66722
+ message: `Upgrade ${id} to ${getOrElse(selectedVersion, () => "the latest published version")}?`,
66723
+ nonInteractiveMessage: "Upgrade changes the installation's version and grants. Preview with --dry-run, then pass --yes to confirm and --accept-permissions for every added grant."
66724
+ });
66725
+ const client = yield* getClientProvider;
66726
+ const data = yield* upgrade({
66727
+ id,
66728
+ ...isSome2(selectedVersion) ? { version: selectedVersion.value } : {},
66729
+ ...acceptPermissions.length ? { acceptPermissions } : {},
66730
+ ...dryRun ? { dryRun: true } : {}
66731
+ }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not upgrade extension", e, { personOnly: "manage" })));
66732
+ if (json)
66733
+ return yield* printJson(data);
66734
+ yield* printUpgrade(data);
66735
+ })));
65928
66736
  var uninstall2 = make29("uninstall", {
65929
66737
  id: installationArgument,
65930
66738
  yes: Boolean6("yes").pipe(withDefault5(false)),
@@ -65960,15 +66768,7 @@ var runs = make29("runs", { id: installationArgument, json: jsonFlag }).pipe(wit
65960
66768
  if (!data.items.length)
65961
66769
  return yield* log("No runs found.");
65962
66770
  for (const item of data.items)
65963
- yield* printFields([
65964
- ["Run", item.id],
65965
- ["Event", item.eventId],
65966
- ["Type", item.eventType],
65967
- ["Attempt", item.attempt],
65968
- ["Outcome", item.outcome],
65969
- ["Duration (ms)", item.durationMs],
65970
- ["Error", item.error]
65971
- ]);
66771
+ yield* printRunSummary(item);
65972
66772
  })));
65973
66773
  var run6 = make29("run", {
65974
66774
  id: installationArgument,
@@ -65976,23 +66776,15 @@ var run6 = make29("run", {
65976
66776
  json: jsonFlag
65977
66777
  }).pipe(withDescription3("Show one hosted run with the lines its handler logged"), withExamples([
65978
66778
  { command: "samva extensions run exti_1234567890123456 0b6c1e1a-run-id --json" }
65979
- ]), withHandler(({ id, run, json }) => gen2(function* () {
66779
+ ]), withHandler(({ id, run: runId, json }) => gen2(function* () {
65980
66780
  const client = yield* getClientProvider;
65981
- const data = yield* getRun2({ id, runId: run }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read run", e)));
66781
+ const data = yield* getRun2({ id, runId }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read run", e)));
65982
66782
  if (json)
65983
66783
  return yield* printJson(data);
65984
- yield* printFields([
65985
- ["Run", data.id],
65986
- ["Event", data.eventId],
65987
- ["Type", data.eventType],
65988
- ["Attempt", data.attempt],
65989
- ["Outcome", data.outcome],
65990
- ["Duration (ms)", data.durationMs],
65991
- ["Error", data.error]
65992
- ]);
65993
- if (data.logs.length)
65994
- yield* log(truncateForDisplay(data.logs.join(`
65995
- `)));
66784
+ yield* printRunSummary(data);
66785
+ yield* log("Logs");
66786
+ yield* log(data.logs.length ? data.logs.join(`
66787
+ `) : "None");
65996
66788
  })));
65997
66789
  var extensionApiCommands = [
65998
66790
  list24,
@@ -66001,6 +66793,7 @@ var extensionApiCommands = [
66001
66793
  install2,
66002
66794
  installations,
66003
66795
  installation,
66796
+ upgrade2,
66004
66797
  uninstall2,
66005
66798
  setStatus("disable"),
66006
66799
  setStatus("enable"),
@@ -66008,6 +66801,66 @@ var extensionApiCommands = [
66008
66801
  run6
66009
66802
  ];
66010
66803
 
66804
+ // ../sdk/dist/effect/mailboxes.js
66805
+ var exports_mailboxes = {};
66806
+ __export(exports_mailboxes, {
66807
+ MailboxEventStreamError: () => MailboxEventStreamError,
66808
+ addThreadLabels: () => addThreadLabels,
66809
+ approveAction: () => approveAction,
66810
+ create: () => create8,
66811
+ createDraft: () => createDraft,
66812
+ createGrant: () => createGrant,
66813
+ createLabel: () => createLabel,
66814
+ createNote: () => createNote,
66815
+ createPolicy: () => createPolicy,
66816
+ deleteDraft: () => deleteDraft,
66817
+ deleteLabel: () => deleteLabel,
66818
+ deleteNote: () => deleteNote,
66819
+ deletePolicy: () => deletePolicy,
66820
+ denyAction: () => denyAction,
66821
+ discardMessage: () => discardMessage,
66822
+ events: () => events,
66823
+ forward: () => forward,
66824
+ get: () => get13,
66825
+ getAgentActivity: () => getAgentActivity,
66826
+ getDraft: () => getDraft,
66827
+ getMessage: () => getMessage,
66828
+ getMessageAttachment: () => getMessageAttachment,
66829
+ getMessageRaw: () => getMessageRaw,
66830
+ getPolicy: () => getPolicy,
66831
+ getThread: () => getThread,
66832
+ getThreadContent: () => getThreadContent,
66833
+ list: () => list11,
66834
+ listActions: () => listActions,
66835
+ listDrafts: () => listDrafts,
66836
+ listEvents: () => listEvents,
66837
+ listFolders: () => listFolders,
66838
+ listGrants: () => listGrants,
66839
+ listLabels: () => listLabels,
66840
+ listPolicies: () => listPolicies,
66841
+ listQuarantine: () => listQuarantine,
66842
+ listThreadMessages: () => listThreadMessages,
66843
+ listThreadNotes: () => listThreadNotes,
66844
+ listThreads: () => listThreads,
66845
+ pause: () => pause,
66846
+ releaseMessage: () => releaseMessage,
66847
+ remove: () => remove9,
66848
+ removeThreadLabels: () => removeThreadLabels,
66849
+ reply: () => reply,
66850
+ replyAll: () => replyAll,
66851
+ resume: () => resume,
66852
+ revokeGrant: () => revokeGrant,
66853
+ sendDraft: () => sendDraft,
66854
+ sendMessage: () => sendMessage2,
66855
+ update: () => update9,
66856
+ updateDraft: () => updateDraft,
66857
+ updateGrant: () => updateGrant,
66858
+ updateLabel: () => updateLabel,
66859
+ updateNote: () => updateNote,
66860
+ updatePolicy: () => updatePolicy,
66861
+ updateThread: () => updateThread
66862
+ });
66863
+
66011
66864
  // src/commands/mailboxes-events.ts
66012
66865
  var NORMAL_CLOSE = 1000;
66013
66866
  var refusalNext = (failure) => {
@@ -66163,8 +67016,12 @@ var init = make29("init", {
66163
67016
  const data = yield* initExtension(dir, manifest);
66164
67017
  if (json)
66165
67018
  yield* printJson(data);
66166
- else
66167
- yield* log(`Created ${name} in ${data.directory}. Run bun install, then samva extensions dev.`);
67019
+ else {
67020
+ yield* log(`Created ${name} in ${data.directory}.`);
67021
+ yield* printManifest(data.manifest);
67022
+ yield* printFields([["Files", data.files.join(", ")]]);
67023
+ yield* log("Run bun install in that directory, then samva extensions dev.");
67024
+ }
66168
67025
  })));
66169
67026
  var build2 = make29("build", {
66170
67027
  ...projectFlags,
@@ -66173,14 +67030,14 @@ var build2 = make29("build", {
66173
67030
  const { bundle: _bundle, ...data } = yield* buildExtension(dir, entry, out);
66174
67031
  if (json)
66175
67032
  yield* printJson(data);
66176
- else
67033
+ else {
67034
+ yield* printManifest(data.manifest);
66177
67035
  yield* printFields([
66178
- ["Extension", `${data.manifest.name}@${data.manifest.version}`],
66179
- ["Runtime", data.manifest.runtime],
66180
67036
  ["Size", `${data.sizeBytes} bytes`],
66181
67037
  ["SHA256", data.sha256],
66182
67038
  ["Output", data.output]
66183
67039
  ]);
67040
+ }
66184
67041
  })));
66185
67042
  var publish3 = make29("publish", projectFlags).pipe(withDescription3("Build and publish an immutable extension version as a person signed in with samva login"), withExamples([{ command: "samva extensions publish . --json" }]), withHandler(({ dir, entry, json }) => gen2(function* () {
66186
67043
  const built = yield* buildExtension(dir, entry);
@@ -66191,8 +67048,11 @@ var publish3 = make29("publish", projectFlags).pipe(withDescription3("Build and
66191
67048
  }).pipe(client.provide, mapError2((error) => mailboxApiError("Could not publish extension", error, { personOnly: "publish" })));
66192
67049
  if (json)
66193
67050
  yield* printJson(data);
66194
- else
66195
- yield* log(`Published ${data.extension.name}@${data.version.version} (${data.version.id}).`);
67051
+ else {
67052
+ yield* log(`Published ${data.extension.name}@${data.version.version}.`);
67053
+ yield* printExtension(data.extension);
67054
+ yield* printVersion(data.version);
67055
+ }
66196
67056
  })));
66197
67057
  var dev = make29("dev", {
66198
67058
  ...projectFlags,
@@ -66217,9 +67077,9 @@ var dev = make29("dev", {
66217
67077
  };
66218
67078
  const stopped = new AbortController;
66219
67079
  const client = createSamvaClient({
66220
- fetch: (input, init) => globalThis.fetch(input, {
66221
- ...init,
66222
- signal: init?.signal === undefined || init.signal === null ? stopped.signal : AbortSignal.any([init.signal, stopped.signal])
67080
+ fetch: (input, requestInit) => globalThis.fetch(input, {
67081
+ ...requestInit,
67082
+ signal: requestInit?.signal === undefined || requestInit.signal === null ? stopped.signal : AbortSignal.any([requestInit.signal, stopped.signal])
66223
67083
  }),
66224
67084
  baseUrl: config.baseUrl,
66225
67085
  headers
@@ -66244,7 +67104,8 @@ var dev = make29("dev", {
66244
67104
  const data = { eventId: event.id, cursor: event.cursor, ...result };
66245
67105
  const text = mode === "jsonl" ? JSON.stringify(resultEnvelope("extensions.dev", data)) : [
66246
67106
  ...result.logs,
66247
- `${event.id}: ${result.ok ? "succeeded" : `failed: ${result.error}`}`
67107
+ `${event.id}: ${result.ok ? "succeeded" : `failed: ${result.error}`}`,
67108
+ `Cursor ${event.cursor}`
66248
67109
  ].join(`
66249
67110
  `);
66250
67111
  yield* writeOutput(process.stdout, `${text}
@@ -68952,67 +69813,6 @@ var logoutCommand = make29("logout").pipe(withDescription3("Sign out and remove
68952
69813
  yield* clearCredentials;
68953
69814
  yield* printResult({ action: "logout" }, "Logged out.");
68954
69815
  })));
68955
- // ../core/src/shared/excess-properties.ts
68956
- var rejectExcessProperties = (schema) => {
68957
- const declared = new Set(Object.keys(schema.fields));
68958
- return flip3(flip3(schema).check(makeFilter2((input, ast) => {
68959
- if (!isObject(input))
68960
- return;
68961
- const issues = [];
68962
- for (const key of Reflect.ownKeys(input)) {
68963
- if (declared.has(key))
68964
- continue;
68965
- issues.push({ path: [key], issue: new UnexpectedKey(ast, input[key]) });
68966
- }
68967
- return issues;
68968
- })));
68969
- };
68970
-
68971
- // ../core/src/messages/attachment-budget.ts
68972
- var EMAIL_ATTACHMENT_BUDGET = {
68973
- maxCount: 10,
68974
- maxItemBytes: 25 * 1024 * 1024,
68975
- maxAggregateBytes: 25 * 1024 * 1024
68976
- };
68977
- var emailAttachmentBudgetViolation = (attachments) => {
68978
- if (attachments.length > EMAIL_ATTACHMENT_BUDGET.maxCount)
68979
- return "count";
68980
- let aggregateBytes = 0;
68981
- for (const attachment of attachments) {
68982
- if (!Number.isSafeInteger(attachment.size) || attachment.size <= 0 || attachment.size > EMAIL_ATTACHMENT_BUDGET.maxItemBytes) {
68983
- return "itemBytes";
68984
- }
68985
- aggregateBytes += attachment.size;
68986
- if (aggregateBytes > EMAIL_ATTACHMENT_BUDGET.maxAggregateBytes)
68987
- return "aggregateBytes";
68988
- }
68989
- return null;
68990
- };
68991
-
68992
- // ../core/src/messages/email-attachment.ts
68993
- var EmailAttachment2 = Struct({
68994
- filename: String4,
68995
- content: optional2(String4.check(isBase64())),
68996
- mediaId: optional2(MediaId2),
68997
- contentType: String4,
68998
- size: Finite.check(isInt(), isGreaterThan2(0), isLessThanOrEqualTo3(EMAIL_ATTACHMENT_BUDGET.maxItemBytes))
68999
- }).check(makeFilter2((attachment) => {
69000
- const hasInlineContent = attachment.content !== undefined;
69001
- const hasOwnedMedia = attachment.mediaId !== undefined;
69002
- if (hasInlineContent === hasOwnedMedia)
69003
- return false;
69004
- if (!hasInlineContent)
69005
- return true;
69006
- const decoded = decode(attachment.content);
69007
- return isSuccess2(decoded) && decoded.success.byteLength === attachment.size;
69008
- }, {
69009
- message: "Email attachment requires exactly one of content or mediaId, and inline content must match its declared size"
69010
- })).annotate({
69011
- identifier: "EmailAttachment"
69012
- }).pipe(rejectExcessProperties);
69013
- var EmailAttachments2 = ArraySchema(EmailAttachment2).check(isMaxLength(EMAIL_ATTACHMENT_BUDGET.maxCount), makeFilter2((attachments) => emailAttachmentBudgetViolation(attachments) === null, {
69014
- message: `Email attachments must total at most ${EMAIL_ATTACHMENT_BUDGET.maxAggregateBytes} bytes`
69015
- }));
69016
69816
 
69017
69817
  // ../core/src/mailboxes/resource.ts
69018
69818
  var MailboxActorKind = Literals(mailboxActorKinds);
@@ -69133,6 +69933,116 @@ var UpdateMailboxPayload = Struct({
69133
69933
  }))
69134
69934
  }).annotate({ identifier: "UpdateMailboxPayload" });
69135
69935
 
69936
+ // ../core/src/mailboxes/action-event-policy.ts
69937
+ var MailboxActionType = Literals(mailboxActionScopes);
69938
+ var MailboxActionSource = Literals(mailboxActionSources);
69939
+ var MailboxActionState = Literals(mailboxActionStates);
69940
+ var MailboxPolicyOutcome = Union2([
69941
+ Struct({ outcome: Literal2("allow") }),
69942
+ Struct({
69943
+ outcome: Literal2("requireApproval"),
69944
+ approverKinds: ArraySchema(Literals(mailboxApproverKinds)),
69945
+ reason: String4
69946
+ }),
69947
+ Struct({ outcome: Literal2("deny"), reason: String4 })
69948
+ ]);
69949
+ var MailboxPolicyDecisionSchema = Struct({
69950
+ policyId: NullOr(MailboxPolicyId2),
69951
+ actionId: MailboxActionId2,
69952
+ outcome: MailboxPolicyOutcome,
69953
+ decidedAt: DateFromString
69954
+ });
69955
+ var MailboxActionRecord = Struct({
69956
+ id: MailboxActionId2,
69957
+ mailboxId: MailboxId2,
69958
+ threadId: optional2(MailboxThreadId2),
69959
+ conversationId: optional2(ConversationId2),
69960
+ draftId: optional2(MailboxDraftId2),
69961
+ type: MailboxActionType,
69962
+ source: MailboxActionSource,
69963
+ state: MailboxActionState,
69964
+ proposedBy: MailboxActorRef,
69965
+ policyDecision: optional2(MailboxPolicyDecisionSchema),
69966
+ payload: Record(String4, Unknown2),
69967
+ createdAt: DateFromString,
69968
+ updatedAt: DateFromString
69969
+ });
69970
+ var MailboxEventType = Literals(mailboxEventTypes);
69971
+ var MailboxActionProposalResponse = Union2([
69972
+ Struct({ status: Literal2("accepted"), action: MailboxActionRecord }),
69973
+ Struct({
69974
+ status: Literal2("approvalRequired"),
69975
+ action: MailboxActionRecord,
69976
+ reason: String4
69977
+ }),
69978
+ Struct({
69979
+ status: Literal2("denied"),
69980
+ action: MailboxActionRecord,
69981
+ reason: String4
69982
+ })
69983
+ ]);
69984
+ var MailboxActionDecision2 = Struct({
69985
+ outcome: Literals(["allow", "requireApproval", "deny"]),
69986
+ reason: NullOr(String4),
69987
+ policyId: NullOr(MailboxPolicyId2),
69988
+ decidedAt: DateFromString
69989
+ }).annotate({ identifier: "MailboxActionDecision" });
69990
+ var MailboxAction2 = Struct({
69991
+ id: MailboxActionId2,
69992
+ type: MailboxActionType,
69993
+ state: MailboxActionState,
69994
+ source: MailboxActionSource,
69995
+ proposedBy: MailboxActorRef,
69996
+ threadId: NullOr(MailboxThreadId2),
69997
+ draftId: NullOr(MailboxDraftId2),
69998
+ decision: NullOr(MailboxActionDecision2),
69999
+ createdAt: DateFromString,
70000
+ updatedAt: DateFromString
70001
+ }).annotate({ identifier: "MailboxAction" });
70002
+ var MailboxEvent2 = Struct({
70003
+ id: MailboxEventId2,
70004
+ type: MailboxEventType,
70005
+ threadId: NullOr(MailboxThreadId2),
70006
+ actionId: NullOr(MailboxActionId2),
70007
+ actor: MailboxActorRef,
70008
+ payload: Record(String4, Unknown2),
70009
+ occurredAt: DateFromString
70010
+ }).annotate({ identifier: "MailboxEvent" });
70011
+ // ../core/src/shared/excess-properties.ts
70012
+ var rejectExcessProperties = (schema) => {
70013
+ const declared = new Set(Object.keys(schema.fields));
70014
+ return flip3(flip3(schema).check(makeFilter2((input, ast) => {
70015
+ if (!isObject(input))
70016
+ return;
70017
+ const issues = [];
70018
+ for (const key of Reflect.ownKeys(input)) {
70019
+ if (declared.has(key))
70020
+ continue;
70021
+ issues.push({ path: [key], issue: new UnexpectedKey(ast, input[key]) });
70022
+ }
70023
+ return issues;
70024
+ })));
70025
+ };
70026
+
70027
+ // ../core/src/messages/email-attachment.ts
70028
+ var EmailAttachment2 = Struct({
70029
+ filename: String4,
70030
+ content: optional2(String4),
70031
+ mediaId: optional2(MediaId2),
70032
+ contentType: String4,
70033
+ size: Finite.check(isInt(), isGreaterThan2(0), isLessThanOrEqualTo3(EMAIL_ATTACHMENT_BUDGET.maxItemBytes))
70034
+ }).check(makeFilter2((attachment) => attachment.content === undefined !== (attachment.mediaId === undefined), { message: "Email attachment requires exactly one of content or mediaId" }), makeFilter2((attachment) => {
70035
+ if (attachment.content === undefined)
70036
+ return true;
70037
+ const decoded = decode(attachment.content);
70038
+ return isSuccess2(decoded) && decoded.success.byteLength === attachment.size;
70039
+ }, { message: "Inline content must be Base64 that decodes to exactly its declared size" })).annotate({
70040
+ identifier: "EmailAttachment"
70041
+ }).pipe(rejectExcessProperties);
70042
+ var EmailAttachments2 = ArraySchema(EmailAttachment2).check(isMaxLength(EMAIL_ATTACHMENT_BUDGET.maxCount), makeFilter2((attachments) => emailAttachmentBudgetViolation(attachments) === null, {
70043
+ message: `Email attachments must total at most ${EMAIL_ATTACHMENT_BUDGET.maxAggregateBytes} bytes`
70044
+ }), makeFilter2((attachments) => emailInlineAttachmentBytes(attachments) <= EMAIL_ATTACHMENT_BUDGET.maxInlineBytes, { message: EMAIL_INLINE_ATTACHMENT_MESSAGE }));
70045
+
69136
70046
  // ../core/src/mailboxes/thread.ts
69137
70047
  var CssTrustedEmailBody = String4.pipe(brand("CssTrustedEmailBody"));
69138
70048
  var MailboxMessageAttachmentSchema = Struct({
@@ -69324,6 +70234,143 @@ var MailboxThreadLabels = Struct({
69324
70234
  labels: NonEmptyArray(MailboxLabelId2)
69325
70235
  }).annotate({ identifier: "MailboxThreadLabels" });
69326
70236
 
70237
+ // src/lib/mailbox-output.ts
70238
+ var present = (value) => value === null ? "none" : value === "" ? '""' : value;
70239
+ var actor = (value) => `${value.displayName == null ? "" : `${value.displayName} \u2014 `}${value.kind} ${value.id}`;
70240
+ var identity2 = (address, name, attributed) => `${name === undefined || name === null ? "" : `${name} <`}${address}${name === undefined || name === null ? "" : ">"}${attributed === undefined ? "" : attributed === null ? "; actor: none" : `; actor: ${actor(attributed)}`}`;
70241
+ var printMailboxSummary = (data) => gen2(function* () {
70242
+ yield* log(`${data.displayName} (${data.slug}) \u2014 ${data.status}`);
70243
+ yield* printFields([
70244
+ ["ID", data.id],
70245
+ ["Primary address", present(data.primaryAddress)],
70246
+ ["Namespace", present(data.namespaceId)],
70247
+ ["Created", data.createdAt]
70248
+ ]);
70249
+ });
70250
+ var printMailbox = (data) => gen2(function* () {
70251
+ yield* printMailboxSummary(data);
70252
+ yield* printFields([
70253
+ ["Description", present(data.description)],
70254
+ ["Updated", data.updatedAt],
70255
+ [
70256
+ "Default from",
70257
+ data.defaultFrom === null ? "none" : identity2(data.defaultFrom.address, data.defaultFrom.displayName)
70258
+ ]
70259
+ ]);
70260
+ yield* log("Addresses:");
70261
+ if (!data.addresses.length)
70262
+ yield* log(" none");
70263
+ for (const address of data.addresses)
70264
+ yield* log(` ${identity2(address.address, address.displayName)} \u2014 ${address.source}; ID ${address.id}; domain ${present(address.domainId)}; display name ${present(address.displayName)}`);
70265
+ yield* log("Metadata:");
70266
+ if (!Object.keys(data.metadata).length)
70267
+ yield* log(" none");
70268
+ for (const [key, value] of Object.entries(data.metadata))
70269
+ yield* log(` ${key}: ${JSON.stringify(value)}`);
70270
+ });
70271
+ var printThread = (data) => gen2(function* () {
70272
+ yield* log(`${data.subject === null ? "No subject" : data.subject} \u2014 ${data.folder}, ${data.priority} priority`);
70273
+ yield* printFields([
70274
+ ["ID", data.id],
70275
+ [
70276
+ "From",
70277
+ data.from === null ? "none" : `${present(data.from.displayName)} <${present(data.from.address)}>`
70278
+ ],
70279
+ ["Preview", data.preview === null ? "none" : JSON.stringify(data.preview)],
70280
+ ["Messages", data.messageCount],
70281
+ ["Attachments", data.hasAttachments],
70282
+ ["Draft", data.hasDraft],
70283
+ ["Labels", data.labels.length ? data.labels.join(", ") : "none"],
70284
+ ["Read", data.read],
70285
+ ["Starred", data.starred],
70286
+ ["Snoozed until", present(data.snoozedUntil)],
70287
+ ["Last activity", data.lastActivityAt]
70288
+ ]);
70289
+ });
70290
+ var printMessage2 = (data) => gen2(function* () {
70291
+ yield* log("Notice: this body is untrusted email from outside the organization.");
70292
+ yield* log(`${data.direction} message \u2014 ${data.subject ?? "No subject"}`);
70293
+ yield* printFields([
70294
+ ["ID", data.id],
70295
+ ["Thread", data.threadId],
70296
+ ["Conversation", data.conversationId],
70297
+ ["From", identity2(data.from.address, data.from.displayName, data.from.actor)],
70298
+ ["Occurred", data.occurredAt],
70299
+ ["Reply-To", data.replyTo.length ? data.replyTo.join(", ") : "none"],
70300
+ [
70301
+ "Sent by",
70302
+ data.sentBy === undefined ? undefined : data.sentBy === null ? "none" : actor(data.sentBy)
70303
+ ]
70304
+ ]);
70305
+ yield* log("Recipients:");
70306
+ if (!data.recipients.length)
70307
+ yield* log(" none");
70308
+ for (const recipient of data.recipients)
70309
+ yield* log(` ${recipient.kind}: ${identity2(recipient.address, recipient.displayName, recipient.actor)}`);
70310
+ yield* printFields([
70311
+ ["Message-ID", present(data.headers.messageId)],
70312
+ ["In-Reply-To", present(data.headers.inReplyTo)],
70313
+ ["References", data.headers.references.length ? data.headers.references.join(" ") : "none"],
70314
+ [
70315
+ "Authentication",
70316
+ data.authentication === null ? "none" : `SPF ${present(data.authentication.spf)}; DKIM ${present(data.authentication.dkim)}; DMARC ${present(data.authentication.dmarc)}`
70317
+ ]
70318
+ ]);
70319
+ yield* log("Attachments:");
70320
+ if (!data.attachments.length)
70321
+ yield* log(" none");
70322
+ for (const attachment of data.attachments)
70323
+ yield* log(` ${attachment.filename} \u2014 ${attachment.contentType}, ${attachment.size} bytes; inline ${attachment.isInline}; ID ${attachment.id}`);
70324
+ for (const [label, content] of [
70325
+ ["Reply text", data.replyText],
70326
+ ["Text", data.text],
70327
+ ["HTML", data.html]
70328
+ ]) {
70329
+ if (content !== undefined) {
70330
+ yield* log(`${label}:`);
70331
+ yield* log(content);
70332
+ }
70333
+ }
70334
+ });
70335
+ var printReceipt = (data) => gen2(function* () {
70336
+ yield* log(`Send ${data.status}${data.waitReason === null ? "" : ` \u2014 waiting: ${data.waitReason}`}`);
70337
+ yield* printFields([
70338
+ ["Message", present(data.messageId)],
70339
+ ["Thread", data.threadId],
70340
+ ["Action", data.actionId],
70341
+ ["Wait reason", present(data.waitReason)],
70342
+ ["Review expected at", present(data.reviewExpectedAt)],
70343
+ ["Skipped", skippedRecipientsLine(data) ?? "none"],
70344
+ ["Created", data.createdAt]
70345
+ ]);
70346
+ });
70347
+ var printAction = (data) => gen2(function* () {
70348
+ yield* log(`${data.type} \u2014 ${data.state}`);
70349
+ yield* printFields([
70350
+ ["Action", data.id],
70351
+ ["Source", data.source],
70352
+ ["Proposed by", actor(data.proposedBy)],
70353
+ ["Thread", present(data.threadId)],
70354
+ ["Draft", present(data.draftId)],
70355
+ ["Created", data.createdAt],
70356
+ ["Updated", data.updatedAt]
70357
+ ]);
70358
+ yield* log(data.decision === null ? "Decision: none" : `Decision: ${data.decision.outcome}; reason ${present(data.decision.reason)}; policy ${present(data.decision.policyId)}; decided ${data.decision.decidedAt}`);
70359
+ });
70360
+ var printHeldMessage = (data) => gen2(function* () {
70361
+ yield* log(`${data.subject === null ? "No subject" : data.subject} \u2014 ${data.disposition}, ${data.reason} (${data.source})`);
70362
+ yield* printFields([
70363
+ ["Message", data.id],
70364
+ ["From", identity2(data.from.address, data.from.name)],
70365
+ ["Sender name", present(data.from.name)],
70366
+ ["Received at", data.receivedAt],
70367
+ ["Held at", data.heldAt],
70368
+ ["Released at", present(data.releasedAt)],
70369
+ ["Thread", present(data.threadId)],
70370
+ ["Discarded at", present(data.discardedAt)]
70371
+ ]);
70372
+ });
70373
+
69327
70374
  // src/commands/mailboxes.ts
69328
70375
  var mailboxFlag = String9("mailbox").pipe(withDescription2("Mailbox ID"), withSchema2(MailboxId2));
69329
70376
  var messageIdArgument = String10("message-id").pipe(withSchema3(MessageId2));
@@ -69410,11 +70457,7 @@ var list25 = make29("list", {
69410
70457
  before: getOrUndefined(before)
69411
70458
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list mailboxes", e))),
69412
70459
  empty: "No mailboxes found.",
69413
- human: (item) => printFields([
69414
- ["ID", item.id],
69415
- ["Slug", item.slug],
69416
- ["Name", item.displayName]
69417
- ])
70460
+ human: printMailboxSummary
69418
70461
  });
69419
70462
  })));
69420
70463
  var create17 = make29("create", {
@@ -69446,13 +70489,164 @@ var create17 = make29("create", {
69446
70489
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not create mailbox", e)));
69447
70490
  if (json)
69448
70491
  return yield* printJson(data);
69449
- yield* printFields([
69450
- ["ID", data.id],
69451
- ["Name", data.displayName],
69452
- ["Address", data.primaryAddress],
69453
- ["Status", data.status]
69454
- ]);
70492
+ yield* printMailbox(data);
70493
+ })));
70494
+ var mailboxIdArgument = String10("mailbox-id").pipe(withSchema3(MailboxId2));
70495
+ var get23 = make29("get", { id: mailboxIdArgument, json: jsonFlag }).pipe(withDescription3("Inspect a mailbox's addresses, sending identity, and settings"), withHandler(({ id, json }) => gen2(function* () {
70496
+ const client = yield* getClientProvider;
70497
+ const result = yield* get13({ id }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read mailbox", e)));
70498
+ yield* json ? printJson(result) : printMailbox(result);
69455
70499
  })));
70500
+ var update16 = make29("update", {
70501
+ id: mailboxIdArgument,
70502
+ data: String9("data").pipe(withDescription2("JSON patch or @file: displayName, defaultFrom, metadata (null deletes a metadata key)")),
70503
+ dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
70504
+ json: jsonFlag
70505
+ }).pipe(withDescription3("Update mailbox settings from JSON"), withExamples([
70506
+ {
70507
+ command: `samva mailboxes update mbx_1234567890123456 --data '{"displayName":"Support","defaultFrom":{"address":"support@example.com"}}'`
70508
+ }
70509
+ ]), withHandler(({ id, data, dryRun, json }) => gen2(function* () {
70510
+ let source = data;
70511
+ if (data.startsWith("@")) {
70512
+ const path = data.slice(1);
70513
+ if (!path)
70514
+ return yield* new CliUsageError({
70515
+ code: "missing_data_file",
70516
+ message: "--data @ requires a file path."
70517
+ });
70518
+ const fs = yield* FileSystem;
70519
+ source = yield* fs.readFileString(path).pipe(mapError2(() => new CliUsageError({
70520
+ code: "data_file_unreadable",
70521
+ message: `Could not read mailbox update data from ${path}.`
70522
+ })));
70523
+ }
70524
+ const raw = yield* try_3({
70525
+ try: () => JSON.parse(source),
70526
+ catch: () => new CliUsageError({
70527
+ code: "mailbox_update_invalid",
70528
+ message: "--data must be valid JSON."
70529
+ })
70530
+ });
70531
+ const payload = yield* decodeUnknownEffect2(UpdateMailboxPayload)(raw, {
70532
+ onExcessProperty: "error"
70533
+ }).pipe(mapError2((e) => new CliUsageError({
70534
+ code: "mailbox_update_invalid",
70535
+ message: `--data must match the mailbox update schema: ${String(e)}`
70536
+ })));
70537
+ if (!Object.keys(payload).length)
70538
+ return yield* new CliUsageError({
70539
+ code: "mailbox_update_empty",
70540
+ message: "--data must name at least one of displayName, defaultFrom, or metadata."
70541
+ });
70542
+ if (dryRun)
70543
+ return yield* json ? printJson({ dryRun: true, action: "mailboxes.update", id, request: payload }) : printFields([
70544
+ ["Dry run", true],
70545
+ ["Mailbox", id],
70546
+ ["Patch", JSON.stringify(payload)]
70547
+ ]);
70548
+ const client = yield* getClientProvider;
70549
+ const result = yield* update9({ id, ...payload }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not update mailbox", e)));
70550
+ yield* json ? printJson(result) : printMailbox(result);
70551
+ })));
70552
+ var lifecycle = (verb) => make29(verb, {
70553
+ id: mailboxIdArgument,
70554
+ dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
70555
+ json: jsonFlag
70556
+ }).pipe(withDescription3(verb === "pause" ? "Pause sending and inbound delivery; mail arriving while paused is not backfilled" : "Resume mailbox delivery"), withHandler(({ id, dryRun, json }) => gen2(function* () {
70557
+ if (dryRun)
70558
+ return yield* json ? printJson({ dryRun: true, action: `mailboxes.${verb}`, id }) : log(`[dry-run] Would ${verb} mailbox ${id}.`);
70559
+ const client = yield* getClientProvider;
70560
+ const result = yield* exports_mailboxes[verb]({ id }).pipe(client.provide, mapError2((e) => mailboxApiError(`Could not ${verb} mailbox`, e)));
70561
+ yield* json ? printJson(result) : printMailbox(result);
70562
+ })));
70563
+ var actionsList = make29("list", {
70564
+ mailbox: mailboxFlag,
70565
+ ...pageFlags2,
70566
+ state: Literals3("state", MailboxActionState.literals).pipe(optional4),
70567
+ after: instantFlag("after", "Only actions created after this ISO 8601 instant"),
70568
+ before: instantFlag("before", "Only actions created before this ISO 8601 instant"),
70569
+ json: jsonFlag
70570
+ }).pipe(withDescription3("List mailbox actions and their policy decisions"), withHandler(({ mailbox, limit, cursor, all, state, after, before, json }) => gen2(function* () {
70571
+ const client = yield* getClientProvider;
70572
+ yield* followPages({
70573
+ all,
70574
+ json,
70575
+ cursor,
70576
+ page: (pageCursor) => listActions({
70577
+ id: mailbox,
70578
+ limit: pageLimit(limit),
70579
+ cursor: pageCursor,
70580
+ state: getOrUndefined(state),
70581
+ after: getOrUndefined(after),
70582
+ before: getOrUndefined(before)
70583
+ }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list actions", e))),
70584
+ empty: "No mailbox actions found.",
70585
+ human: printAction
70586
+ });
70587
+ })));
70588
+ var actionDecision = (verb) => make29(verb, {
70589
+ actionId: String10("action-id").pipe(withSchema3(MailboxActionId2)),
70590
+ mailbox: mailboxFlag,
70591
+ ...verb === "deny" ? {
70592
+ reason: optional6("reason").pipe(withDescription2("Denial reason; defaults to Denied by reviewer."))
70593
+ } : {},
70594
+ dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
70595
+ yes: Boolean6("yes").pipe(withDefault5(false)),
70596
+ json: jsonFlag
70597
+ }).pipe(withDescription3(`${verb === "approve" ? "Approve and execute" : "Deny"} an action as a signed-in person other than its proposer`), withHandler(({ actionId, mailbox, reason, dryRun, yes, json }) => gen2(function* () {
70598
+ const denialReason = reason === undefined ? undefined : getOrElse(reason, () => "Denied by reviewer.");
70599
+ if (dryRun)
70600
+ return yield* json ? printJson({
70601
+ dryRun: true,
70602
+ action: `mailboxes.actions.${verb}`,
70603
+ id: mailbox,
70604
+ actionId,
70605
+ ...verb === "deny" ? { reason: denialReason } : {}
70606
+ }) : printJson({
70607
+ dryRun: true,
70608
+ action: verb,
70609
+ mailbox,
70610
+ actionId,
70611
+ ...verb === "deny" ? { reason: denialReason } : {}
70612
+ });
70613
+ yield* confirmDestructive({
70614
+ yes,
70615
+ json,
70616
+ message: `${verb === "approve" ? "Approve and execute" : "Deny"} mailbox action ${actionId}?`,
70617
+ nonInteractiveMessage: `Action ${verb} requires --yes in non-interactive mode. Preview with --dry-run.`
70618
+ });
70619
+ const client = yield* getClientProvider;
70620
+ const result = yield* (verb === "approve" ? approveAction({ id: mailbox, actionId }) : denyAction({
70621
+ id: mailbox,
70622
+ actionId,
70623
+ reason: denialReason ?? "Denied by reviewer."
70624
+ })).pipe(client.provide, mapError2((e) => mailboxApiError(`Could not ${verb} action`, e, { personOnly: verb })));
70625
+ yield* json ? printJson(result) : printAction(result);
70626
+ })));
70627
+ var remove18 = make29("remove", {
70628
+ id: String10("mailbox-id").pipe(withSchema3(MailboxId2)),
70629
+ dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
70630
+ yes: Boolean6("yes").pipe(withDefault5(false)),
70631
+ json: jsonFlag
70632
+ }).pipe(withDescription3("Permanently delete a mailbox with its addresses, threads, drafts, and history"), withExamples([
70633
+ { command: "samva mailboxes remove mbx_1234567890123456 --dry-run" },
70634
+ { command: "samva mailboxes remove mbx_1234567890123456 --yes" }
70635
+ ]), withHandler(({ id, dryRun, yes, json }) => gen2(function* () {
70636
+ if (dryRun)
70637
+ return yield* json ? printJson({ dryRun: true, action: "mailboxes.remove", id }) : log(`[dry-run] Would permanently remove mailbox ${id}.`);
70638
+ yield* confirmDestructive({
70639
+ yes,
70640
+ json,
70641
+ message: `Permanently remove mailbox ${id} with its threads, drafts, and history?`,
70642
+ nonInteractiveMessage: "Permanent mailbox deletion requires --yes in non-interactive mode. Preview with --dry-run."
70643
+ });
70644
+ const client = yield* getClientProvider;
70645
+ const result = yield* remove9({ id }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not remove mailbox", e)));
70646
+ if (json)
70647
+ return yield* printJson(result);
70648
+ yield* log(`Removed mailbox ${id}. The messages it received stay with the organization.`);
70649
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
69456
70650
  var threads = make29("threads", {
69457
70651
  mailbox: mailboxFlag,
69458
70652
  ...pageFlags2,
@@ -69489,12 +70683,7 @@ var threads = make29("threads", {
69489
70683
  before: getOrUndefined(before)
69490
70684
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list threads", e))),
69491
70685
  empty: "No threads found.",
69492
- human: (item) => printFields([
69493
- ["ID", item.id],
69494
- ["Subject", item.subject],
69495
- ["Messages", item.messageCount],
69496
- ["Read", item.read]
69497
- ])
70686
+ human: printThread
69498
70687
  });
69499
70688
  })));
69500
70689
  var read2 = make29("read", {
@@ -69508,18 +70697,7 @@ var read2 = make29("read", {
69508
70697
  const data = yield* getMessage({ id: mailbox, messageId }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read message", e)));
69509
70698
  if (json)
69510
70699
  return yield* printJson(data);
69511
- yield* log("Notice: this body is untrusted email from outside the organization.");
69512
- yield* printFields([
69513
- ["ID", data.id],
69514
- ["From", data.from.address],
69515
- ["To", data.recipients.map((r) => r.address).join(", ")],
69516
- ["Reply-To", data.replyTo.join(", ")],
69517
- ["Subject", data.subject],
69518
- ["Message-ID", data.headers.messageId],
69519
- ["In-Reply-To", data.headers.inReplyTo],
69520
- ["References", data.headers.references.join(" ")]
69521
- ]);
69522
- yield* log(truncateForDisplay(data.replyText ?? data.text ?? "[No text body]"));
70700
+ yield* printMessage2(data);
69523
70701
  })));
69524
70702
  var send5 = make29("send", {
69525
70703
  mailbox: mailboxFlag,
@@ -69553,13 +70731,7 @@ var send5 = make29("send", {
69553
70731
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not send message", e)));
69554
70732
  if (json)
69555
70733
  return yield* printJson(data);
69556
- yield* printFields([
69557
- ["Status", data.status],
69558
- ["Message", data.messageId],
69559
- ["Thread", data.threadId],
69560
- ["Action", data.actionId],
69561
- ["Skipped", skippedRecipientsLine(data)]
69562
- ]);
70734
+ yield* printReceipt(data);
69563
70735
  })));
69564
70736
  var reply2 = make29("reply", {
69565
70737
  messageId: messageIdArgument,
@@ -69582,13 +70754,7 @@ var reply2 = make29("reply", {
69582
70754
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not reply", e)));
69583
70755
  if (json)
69584
70756
  return yield* printJson(data);
69585
- yield* printFields([
69586
- ["Status", data.status],
69587
- ["Message", data.messageId],
69588
- ["Thread", data.threadId],
69589
- ["Action", data.actionId],
69590
- ["Skipped", skippedRecipientsLine(data)]
69591
- ]);
70757
+ yield* printReceipt(data);
69592
70758
  })));
69593
70759
  var quarantineList = make29("list", {
69594
70760
  mailbox: mailboxFlag,
@@ -69613,13 +70779,7 @@ var quarantineList = make29("list", {
69613
70779
  before: getOrUndefined(before)
69614
70780
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list quarantine", e))),
69615
70781
  empty: "No quarantined messages found.",
69616
- human: (item) => printFields([
69617
- ["Message", item.id],
69618
- ["From", item.from.address],
69619
- ["Subject", item.subject],
69620
- ["Disposition", item.disposition],
69621
- ["Reason", item.reason]
69622
- ])
70782
+ human: printHeldMessage
69623
70783
  });
69624
70784
  })));
69625
70785
  var release2 = make29("release", {
@@ -69635,13 +70795,11 @@ var release2 = make29("release", {
69635
70795
  const data = yield* releaseMessage({ id: mailbox, messageId }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not release message", e, { personOnly: "release" })));
69636
70796
  if (json)
69637
70797
  return yield* printJson(data);
69638
- yield* printFields([
69639
- ["Message", data.id],
69640
- ["Released", data.releasedAt],
69641
- ["Thread", data.threadId]
69642
- ]);
70798
+ yield* printHeldMessage(data);
69643
70799
  })));
69644
70800
  var discard = make29("discard", {
70801
+ dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
70802
+ yes: Boolean6("yes").pipe(withDefault5(false)),
69645
70803
  messageId: messageIdArgument,
69646
70804
  mailbox: mailboxFlag,
69647
70805
  json: jsonFlag
@@ -69649,20 +70807,36 @@ var discard = make29("discard", {
69649
70807
  {
69650
70808
  command: "samva mailboxes quarantine discard msg_1234567890123456 --mailbox mbx_1234567890123456"
69651
70809
  }
69652
- ]), withHandler(({ messageId, mailbox, json }) => gen2(function* () {
70810
+ ]), withHandler(({ messageId, mailbox, dryRun, yes, json }) => gen2(function* () {
70811
+ if (dryRun)
70812
+ return yield* json ? printJson({
70813
+ dryRun: true,
70814
+ action: "mailboxes.quarantine.discard",
70815
+ id: mailbox,
70816
+ messageId
70817
+ }) : log(`[dry-run] Would permanently discard held message ${messageId}.`);
70818
+ yield* confirmDestructive({
70819
+ yes,
70820
+ json,
70821
+ message: `Permanently discard held message ${messageId}?`,
70822
+ nonInteractiveMessage: "Discarding held mail requires --yes in non-interactive mode. Preview with --dry-run."
70823
+ });
69653
70824
  const client = yield* getClientProvider;
69654
70825
  const data = yield* discardMessage({ id: mailbox, messageId }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not discard message", e, { personOnly: "discard" })));
69655
70826
  if (json)
69656
70827
  return yield* printJson(data);
69657
- yield* printFields([
69658
- ["Message", data.id],
69659
- ["Discarded", data.discardedAt]
69660
- ]);
70828
+ yield* printHeldMessage(data);
69661
70829
  })));
69662
70830
  var mailboxesCommand = make29("mailboxes").pipe(withDescription3("Mailbox reading and governed sending"), withSubcommands([
69663
70831
  mailboxesEventsCommand,
69664
70832
  list25,
69665
70833
  create17,
70834
+ get23,
70835
+ update16,
70836
+ lifecycle("pause"),
70837
+ lifecycle("resume"),
70838
+ make29("actions").pipe(withSubcommands([actionsList, actionDecision("approve"), actionDecision("deny")])),
70839
+ remove18,
69666
70840
  threads,
69667
70841
  read2,
69668
70842
  send5,
@@ -69857,7 +71031,7 @@ var use2 = make29("use", { name: String10("name") }).pipe(withDescription3("Sele
69857
71031
  yield* writeConfig({ ...config, activeProfile: name });
69858
71032
  yield* printResult({ action: "profile.use", name }, `Active profile set to ${name}.`);
69859
71033
  })));
69860
- var remove18 = make29("delete", {
71034
+ var remove19 = make29("delete", {
69861
71035
  name: String10("name"),
69862
71036
  yes: Boolean6("yes").pipe(withDefault5(false))
69863
71037
  }).pipe(withDescription3("Delete a profile and its OS-keyring credential"), withHandler(fnUntraced2(function* ({ name, yes }) {
@@ -69882,7 +71056,7 @@ var remove18 = make29("delete", {
69882
71056
  yield* (yield* Service5).clear(name);
69883
71057
  yield* printResult({ action: "profile.delete", name }, `Deleted profile ${name}.`);
69884
71058
  })));
69885
- var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list27, show, create18, use2, remove18]));
71059
+ var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list27, show, create18, use2, remove19]));
69886
71060
 
69887
71061
  // src/commands/scheduled.ts
69888
71062
  var SCHEDULED_STATUSES = [
@@ -70162,7 +71336,7 @@ var list28 = make29("list", {
70162
71336
  if (data.nextCursor !== null)
70163
71337
  yield* printFields([["Next cursor", data.nextCursor]]);
70164
71338
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
70165
- var get23 = make29("get", { id: String10("id"), json: jsonFlag }).pipe(withDescription3("Show a scheduled message by id"), withExamples([{ command: "samva scheduled-messages get sched_abc123" }]), withHandler(({ id, json }) => gen2(function* () {
71339
+ var get24 = make29("get", { id: String10("id"), json: jsonFlag }).pipe(withDescription3("Show a scheduled message by id"), withExamples([{ command: "samva scheduled-messages get sched_abc123" }]), withHandler(({ id, json }) => gen2(function* () {
70166
71340
  const client = yield* getClientProvider;
70167
71341
  const data = yield* get18({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not fetch scheduled message", error)));
70168
71342
  if (json)
@@ -70245,11 +71419,11 @@ var scheduledMessagesCommand = make29("scheduled-messages").pipe(withDescription
70245
71419
  description: "Schedule an email"
70246
71420
  },
70247
71421
  { command: "samva scheduled-messages list", description: "List scheduled messages" }
70248
- ]), withSubcommands([create19, list28, get23, cancel2, resume3]));
71422
+ ]), withSubcommands([create19, list28, get24, cancel2, resume3]));
70249
71423
 
70250
71424
  // src/commands/templates.ts
70251
71425
  import { constants as constants2 } from "fs";
70252
- import { access as access3, stat as stat4 } from "fs/promises";
71426
+ import { access as access3, stat as stat5 } from "fs/promises";
70253
71427
  import { dirname as dirname5, resolve as resolve16 } from "path";
70254
71428
  import { pathToFileURL as pathToFileURL5 } from "url";
70255
71429
 
@@ -71539,7 +72713,7 @@ import { resolve as resolve13 } from "path";
71539
72713
 
71540
72714
  // src/commands/templates/snapshot-browser.ts
71541
72715
  import { existsSync } from "fs";
71542
- import { copyFile as copyFile3, mkdir as mkdir4, mkdtemp as mkdtemp2, readFile as readFile4, rm as rm2, stat as stat3, writeFile as writeFile5 } from "fs/promises";
72716
+ import { copyFile as copyFile3, mkdir as mkdir4, mkdtemp as mkdtemp2, readFile as readFile5, rm as rm2, stat as stat4, writeFile as writeFile5 } from "fs/promises";
71543
72717
  import { tmpdir as tmpdir2 } from "os";
71544
72718
  import { join as join4 } from "path";
71545
72719
  import { pathToFileURL as pathToFileURL4 } from "url";
@@ -71653,7 +72827,7 @@ var runProcess = async (command, args, until) => {
71653
72827
  stderr += text;
71654
72828
  });
71655
72829
  const deadline = Date.now() + RUN_TIMEOUT_MS;
71656
- const produced = async () => until.stdoutIncludes !== undefined && stdout.includes(until.stdoutIncludes) || until.file !== undefined && existsSync(until.file) && (await stat3(until.file)).size > 0;
72830
+ const produced = async () => until.stdoutIncludes !== undefined && stdout.includes(until.stdoutIncludes) || until.file !== undefined && existsSync(until.file) && (await stat4(until.file)).size > 0;
71657
72831
  const state = { exited: false };
71658
72832
  child.exited.then(() => {
71659
72833
  state.exited = true;
@@ -71679,7 +72853,7 @@ var chromeLauncher = (binary, run = runProcess) => ({
71679
72853
  const profile = await mkdtemp2(join4(tmpdir2(), "samva-chrome-"));
71680
72854
  try {
71681
72855
  for (const request of requests) {
71682
- const source = await readFile4(request.htmlPath, "utf8");
72856
+ const source = await readFile5(request.htmlPath, "utf8");
71683
72857
  const measured = request.htmlPath.replace(/\.html$/, `.${request.viewport}.${request.scheme}.html`);
71684
72858
  await writeFile5(measured, withMeasurement(source));
71685
72859
  const measure = await run(binary, chromeMeasureArgs({
@@ -72397,7 +73571,7 @@ var typesCommand = make29("types", {
72397
73571
  })));
72398
73572
 
72399
73573
  // src/commands/templates/workspace.ts
72400
- import { basename, resolve as resolve15 } from "path";
73574
+ import { basename as basename2, resolve as resolve15 } from "path";
72401
73575
  var templateIdArgument = String10("template-id").pipe(withDescription4("Template whose project workspace to act on"));
72402
73576
  var revisionFlag = String9("revision").pipe(withDescription2("Workspace revision this call is fenced to; a workspace that moved refuses the call"));
72403
73577
  var idempotencyKeyFlag4 = String9("idempotency-key").pipe(withDescription2("Key so an identical retry returns the original result rather than repeating it"));
@@ -72490,7 +73664,7 @@ var addAsset = make29("add-asset", {
72490
73664
  const view = yield* putWorkspaceAsset({
72491
73665
  id,
72492
73666
  expectedRevision: revision,
72493
- path: getOrElse(path, () => `assets/${basename(source)}`),
73667
+ path: getOrElse(path, () => `assets/${basename2(source)}`),
72494
73668
  contentBase64: Buffer.from(bytes).toString("base64"),
72495
73669
  replace,
72496
73670
  idempotencyKey
@@ -72663,7 +73837,7 @@ var typecheckProject = (tsconfig) => tryPromise2({
72663
73837
  });
72664
73838
  var validateTemplatesDir = (dir) => tryPromise2({
72665
73839
  try: async () => {
72666
- const info = await stat4(dir);
73840
+ const info = await stat5(dir);
72667
73841
  if (!info.isDirectory()) {
72668
73842
  return Promise.reject(new SamvaCliError({ message: `${dir} is not a directory.` }));
72669
73843
  }
@@ -73251,7 +74425,7 @@ var list29 = make29("list", {
73251
74425
  if (data.nextCursor !== null)
73252
74426
  yield* printFields([["Next cursor", data.nextCursor]]);
73253
74427
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
73254
- var get24 = make29("get", { id: idArgument, json: jsonFlag }).pipe(withDescription3("Get a customer webhook"), withExamples([{ command: "samva webhooks get wep_abc123 --json" }]), withHandler(({ id, json }) => gen2(function* () {
74428
+ var get25 = make29("get", { id: idArgument, json: jsonFlag }).pipe(withDescription3("Get a customer webhook"), withExamples([{ command: "samva webhooks get wep_abc123 --json" }]), withHandler(({ id, json }) => gen2(function* () {
73255
74429
  const client = yield* getClientProvider;
73256
74430
  const data = yield* get19({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get webhook", error)));
73257
74431
  if (json)
@@ -73375,12 +74549,12 @@ var rotate2 = make29("rotate-secret", {
73375
74549
  yield* log(secret);
73376
74550
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
73377
74551
  var create20 = make29("create", {
73378
- data: String9("data").pipe(withDescription2("Webhook JSON: name, url, events, and optional retry settings")),
74552
+ data: String9("data").pipe(withDescription2("Webhook JSON: name, url, eventTypes, and optional retry settings")),
73379
74553
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
73380
74554
  json: jsonFlag
73381
74555
  }).pipe(withDescription3("Create a customer webhook from JSON"), withExamples([
73382
74556
  {
73383
- command: `samva webhooks create --data '{"name":"delivery","url":"https://example.com/hook","events":["message.delivered"]}' --dry-run`
74557
+ command: `samva webhooks create --data '{"name":"delivery","url":"https://example.com/hook","eventTypes":["message.delivered"]}' --dry-run`
73384
74558
  }
73385
74559
  ]), withHandler(({ data, dryRun, json }) => gen2(function* () {
73386
74560
  const payload = yield* decodePayload2(data, "--data", CreateWebhookPayload);
@@ -73392,7 +74566,7 @@ var create20 = make29("create", {
73392
74566
  return yield* printJson(result);
73393
74567
  yield* printJson(result);
73394
74568
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
73395
- var update16 = make29("update", {
74569
+ var update17 = make29("update", {
73396
74570
  id: idArgument,
73397
74571
  data: String9("data").pipe(withDescription2("JSON object of webhook fields to update")),
73398
74572
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
@@ -73411,7 +74585,7 @@ var update16 = make29("update", {
73411
74585
  return yield* printJson(result);
73412
74586
  yield* printJson(result);
73413
74587
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
73414
- var remove19 = make29("remove", {
74588
+ var remove20 = make29("remove", {
73415
74589
  id: idArgument,
73416
74590
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
73417
74591
  yes: Boolean6("yes").pipe(withDefault5(false)),
@@ -73434,7 +74608,7 @@ var remove19 = make29("remove", {
73434
74608
  return yield* printJson(result);
73435
74609
  yield* log(`Removed webhook ${id}.`);
73436
74610
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
73437
- var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, and recover customer webhooks"), withExamples([{ command: "samva webhooks list --json" }]), withSubcommands([list29, get24, create20, update16, test2, logs, stats, retry5, rotate2, remove19]));
74611
+ var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, and recover customer webhooks"), withExamples([{ command: "samva webhooks list --json" }]), withSubcommands([list29, get25, create20, update17, test2, logs, stats, retry5, rotate2, remove20]));
73438
74612
 
73439
74613
  // src/lib/root-commands.ts
73440
74614
  var rootCommands = [