@samva/cli 0.15.0 → 0.17.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 (3) hide show
  1. package/AGENTS.md +23 -7
  2. package/dist/bin.mjs +1407 -323
  3. package/package.json +7 -7
package/dist/bin.mjs CHANGED
@@ -14106,7 +14106,7 @@ var layer12 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE
14106
14106
  // package.json
14107
14107
  var package_default = {
14108
14108
  name: "@samva/cli",
14109
- version: "0.15.0",
14109
+ version: "0.17.0",
14110
14110
  description: "Samva CLI \u2014 email and platform operations from your terminal",
14111
14111
  keywords: [
14112
14112
  "cli",
@@ -14162,16 +14162,16 @@ var package_default = {
14162
14162
  "@types/node": "catalog:",
14163
14163
  "better-auth": "catalog:",
14164
14164
  effect: "catalog:effect",
14165
- samva: "workspace:0.19.0",
14165
+ samva: "workspace:0.20.0",
14166
14166
  typescript: "catalog:",
14167
14167
  vite: "~8.3.0",
14168
14168
  vitest: "catalog:"
14169
14169
  },
14170
14170
  optionalDependencies: {
14171
- "@samva/cli-darwin-arm64": "workspace:0.15.0",
14172
- "@samva/cli-darwin-x64": "workspace:0.15.0",
14173
- "@samva/cli-linux-arm64": "workspace:0.15.0",
14174
- "@samva/cli-linux-x64": "workspace:0.15.0"
14171
+ "@samva/cli-darwin-arm64": "workspace:0.17.0",
14172
+ "@samva/cli-darwin-x64": "workspace:0.17.0",
14173
+ "@samva/cli-linux-arm64": "workspace:0.17.0",
14174
+ "@samva/cli-linux-x64": "workspace:0.17.0"
14175
14175
  },
14176
14176
  engines: {
14177
14177
  node: ">=18"
@@ -19353,6 +19353,7 @@ var Literals4 = (name, choices) => Literals2(argumentKind, name, choices);
19353
19353
  var optional5 = (arg) => optional3(arg);
19354
19354
  var withDescription4 = /* @__PURE__ */ dual(2, (self, description) => withDescription(self, description));
19355
19355
  var withDefault6 = withDefault4;
19356
+ var atLeast3 = /* @__PURE__ */ dual(2, (self, min) => atLeast(self, min));
19356
19357
  var withSchema3 = /* @__PURE__ */ dual(2, (self, schema) => withSchema(self, schema));
19357
19358
  var filterMap3 = /* @__PURE__ */ dual(3, (self, f, onNone) => filterMap2(self, f, onNone));
19358
19359
 
@@ -20513,6 +20514,9 @@ var CAMPAIGN_RECIPIENT_SKIPPED_REASON_VALUES = [
20513
20514
  "unsubscribed",
20514
20515
  "blocked",
20515
20516
  "suppressed",
20517
+ "opted_out",
20518
+ "consent_required",
20519
+ "unreachable",
20516
20520
  "no_identity",
20517
20521
  "inactive",
20518
20522
  "run_cancelled",
@@ -20746,6 +20750,56 @@ var categorize = (errorClass, meta) => {
20746
20750
  return errorClass;
20747
20751
  };
20748
20752
 
20753
+ // ../core/src/shared/json.ts
20754
+ var JsonObject = Record(String4, Json2).annotate({
20755
+ identifier: "JsonObject"
20756
+ });
20757
+ var UnknownRecord = Record(String4, Unknown2).annotate({
20758
+ identifier: "UnknownRecord"
20759
+ });
20760
+ var decodeJsonString = decodeSync(fromJsonString2(Json2));
20761
+
20762
+ // ../core/src/templates/variable-values.ts
20763
+ var TemplateVariableValues = JsonObject;
20764
+
20765
+ // ../core/src/mailboxes/chat.ts
20766
+ var MailboxChatChannel = Literals(["whatsapp", "sms"]);
20767
+ var mailboxChatContentFields = {
20768
+ text: optional2(String4.check(isMinLength(1))),
20769
+ templateId: optional2(TemplateId),
20770
+ templateData: optional2(TemplateVariableValues)
20771
+ };
20772
+ var exactlyOneChatContent = makeFilter2((payload) => payload.text === undefined !== (payload.templateId === undefined) && (payload.templateId === undefined || payload.channel === "whatsapp") && (payload.templateData === undefined || payload.templateId !== undefined), {
20773
+ message: "Set exactly one of `text` or `templateId`; a template (with its `templateData`) sends on WhatsApp only."
20774
+ });
20775
+ var MailboxChatTemplate = Struct({
20776
+ templateId: TemplateId,
20777
+ templateChannelVariantId: TemplateChannelVariantId,
20778
+ templateData: NullOr(TemplateVariableValues)
20779
+ }).annotate({ identifier: "MailboxChatTemplate" });
20780
+
20781
+ class WhatsAppServiceWindowClosedError extends TaggedError3()("WhatsAppServiceWindowClosedError", {
20782
+ message: String4,
20783
+ closedAt: NullOr(String4)
20784
+ }, { httpApiStatus: 422 }) {
20785
+ }
20786
+ categorize(WhatsAppServiceWindowClosedError, { categories: ["validation"], retryable: false });
20787
+ var MailboxWhatsAppTemplateOption = Struct({
20788
+ templateId: TemplateId,
20789
+ slug: String4,
20790
+ name: String4,
20791
+ providerName: NullOr(String4),
20792
+ language: NullOr(String4),
20793
+ category: NullOr(String4),
20794
+ sendable: Boolean3,
20795
+ reason: NullOr(String4),
20796
+ inputSchema: NullOr(JsonObject)
20797
+ }).annotate({ identifier: "MailboxWhatsAppTemplateOption" });
20798
+ var MailboxWhatsAppTemplateOptions = Struct({
20799
+ endpointId: MailboxEndpointId,
20800
+ items: ArraySchema(MailboxWhatsAppTemplateOption)
20801
+ }).annotate({ identifier: "MailboxWhatsAppTemplateOptions" });
20802
+
20749
20803
  // ../core/src/shared/errors.ts
20750
20804
  class ResourceNotFoundError extends TaggedError3()("ResourceNotFoundError", {
20751
20805
  resource: String4,
@@ -20965,6 +21019,31 @@ class UnknownStatusError extends TaggedError3()("UnknownStatusError", {
20965
21019
  }
20966
21020
  }
20967
21021
 
21022
+ // ../core/src/mailboxes/endpoint-binding.ts
21023
+ var MailboxEmailEndpointBinding = Struct({
21024
+ channel: Literal2("email"),
21025
+ source: Literals(["samvaHosted", "verifiedDomain"]),
21026
+ localPart: String4,
21027
+ domain: String4,
21028
+ domainId: optional2(String4),
21029
+ subdomain: optional2(String4)
21030
+ }).annotate({ identifier: "MailboxEmailEndpointBinding" });
21031
+ var MailboxWhatsAppEndpointBinding = Struct({
21032
+ channel: Literal2("whatsapp"),
21033
+ businessAccountId: WhatsAppBusinessAccountId
21034
+ }).annotate({ identifier: "MailboxWhatsAppEndpointBinding" });
21035
+ var MailboxSmsEndpointBinding = Struct({
21036
+ channel: Literal2("sms"),
21037
+ phoneNumberId: SmsPhoneNumberId
21038
+ }).annotate({ identifier: "MailboxSmsEndpointBinding" });
21039
+ var MailboxEndpointBinding = Union2([
21040
+ MailboxEmailEndpointBinding,
21041
+ MailboxWhatsAppEndpointBinding,
21042
+ MailboxSmsEndpointBinding
21043
+ ]).annotate({
21044
+ identifier: "MailboxEndpointBinding"
21045
+ });
21046
+
20968
21047
  // ../core/src/mailboxes/mailbox.ts
20969
21048
  var mailboxChannels = ["email", "whatsapp", "sms"];
20970
21049
  var mailboxEventTypes = [
@@ -21065,10 +21144,6 @@ var MailboxChannel = Literals(mailboxChannels).annotate({
21065
21144
  identifier: "MailboxChannel",
21066
21145
  description: "The channel an endpoint, thread, or message belongs to."
21067
21146
  });
21068
-
21069
- class MailboxChannelUnsupportedError extends TaggedError3()("MailboxChannelUnsupportedError", { message: String4, channel: String4 }, { httpApiStatus: 422 }) {
21070
- }
21071
- categorize(MailboxChannelUnsupportedError, { categories: ["validation"], retryable: false });
21072
21147
  var endpointFields = {
21073
21148
  id: MailboxEndpointId,
21074
21149
  address: String4,
@@ -21081,7 +21156,21 @@ var MailboxEmailEndpoint = Struct({
21081
21156
  source: Literals(["samvaHosted", "verifiedDomain"]),
21082
21157
  domainId: NullOr(String4)
21083
21158
  }).annotate({ identifier: "MailboxEmailEndpoint" });
21084
- var MailboxEndpoint = Union2([MailboxEmailEndpoint]).annotate({
21159
+ var MailboxWhatsAppEndpoint = Struct({
21160
+ ...endpointFields,
21161
+ channel: Literal2("whatsapp"),
21162
+ businessAccountId: WhatsAppBusinessAccountId
21163
+ }).annotate({ identifier: "MailboxWhatsAppEndpoint" });
21164
+ var MailboxSmsEndpoint = Struct({
21165
+ ...endpointFields,
21166
+ channel: Literal2("sms"),
21167
+ phoneNumberId: SmsPhoneNumberId
21168
+ }).annotate({ identifier: "MailboxSmsEndpoint" });
21169
+ var MailboxEndpoint = Union2([
21170
+ MailboxEmailEndpoint,
21171
+ MailboxWhatsAppEndpoint,
21172
+ MailboxSmsEndpoint
21173
+ ]).annotate({
21085
21174
  identifier: "MailboxEndpoint"
21086
21175
  });
21087
21176
  var MailboxSendMode = Literals(mailboxSendModes).annotate({
@@ -21198,7 +21287,7 @@ var MailboxSendAttachment = Struct({
21198
21287
  })
21199
21288
  ])
21200
21289
  });
21201
- var MailboxSendIntent = Struct({
21290
+ var MailboxEmailSendIntent = Struct({
21202
21291
  channel: Literal2("email"),
21203
21292
  draftRevision: PositiveInt,
21204
21293
  from: String4,
@@ -21216,7 +21305,26 @@ var MailboxSendIntent = Struct({
21216
21305
  inReplyToMessageId: NullOr(MessageId)
21217
21306
  }).check(makeFilter2((intent) => intent.text !== null || intent.html !== null, {
21218
21307
  message: "A send intent requires text or html"
21219
- })).annotate({ identifier: "MailboxSendIntent" });
21308
+ })).annotate({ identifier: "MailboxEmailSendIntent" });
21309
+ var MailboxChatSendIntent = Struct({
21310
+ channel: MailboxChatChannel,
21311
+ draftRevision: PositiveInt,
21312
+ endpointId: MailboxEndpointId,
21313
+ sender: Union2([MailboxWhatsAppEndpointBinding, MailboxSmsEndpointBinding]),
21314
+ from: String4,
21315
+ to: String4,
21316
+ text: NullOr(String4),
21317
+ template: NullOr(MailboxChatTemplate),
21318
+ threadId: NullOr(MailboxThreadId),
21319
+ conversationId: NullOr(ConversationId),
21320
+ inReplyToMessageId: NullOr(MessageId)
21321
+ }).check(makeFilter2((intent) => intent.sender.channel === intent.channel && intent.text === null !== (intent.template === null) && (intent.template === null || intent.channel === "whatsapp"), {
21322
+ message: "A chat send intent carries text or a WhatsApp template, from an endpoint on its channel"
21323
+ })).annotate({ identifier: "MailboxChatSendIntent" });
21324
+ var MailboxSendIntent = Union2([
21325
+ MailboxEmailSendIntent,
21326
+ MailboxChatSendIntent
21327
+ ]).annotate({ identifier: "MailboxSendIntent" });
21220
21328
  var authorityFields = {
21221
21329
  actor: MailboxActorRef,
21222
21330
  installationId: NullOr(ExtensionInstallationId)
@@ -21277,10 +21385,10 @@ var SendMailboxEmailPayload = Struct({
21277
21385
  ...BodyFields
21278
21386
  }).annotate({ identifier: "SendMailboxEmailPayload" });
21279
21387
  var SendMailboxChatPayload = Struct({
21280
- channel: Literals(["whatsapp", "sms"]),
21388
+ channel: MailboxChatChannel,
21281
21389
  to: String4,
21282
- text: String4.check(isMinLength(1))
21283
- }).annotate({ identifier: "SendMailboxChatPayload" });
21390
+ ...mailboxChatContentFields
21391
+ }).check(exactlyOneChatContent).annotate({ identifier: "SendMailboxChatPayload" });
21284
21392
  var SendMailboxMessagePayload = Union2([
21285
21393
  SendMailboxEmailPayload,
21286
21394
  SendMailboxChatPayload
@@ -21292,9 +21400,9 @@ var ReplyMailboxEmailPayload = Struct({
21292
21400
  ...BodyFields
21293
21401
  }).annotate({ identifier: "ReplyMailboxEmailPayload" });
21294
21402
  var ReplyMailboxChatPayload = Struct({
21295
- channel: Literals(["whatsapp", "sms"]),
21296
- text: String4.check(isMinLength(1))
21297
- }).annotate({ identifier: "ReplyMailboxChatPayload" });
21403
+ channel: MailboxChatChannel,
21404
+ ...mailboxChatContentFields
21405
+ }).check(exactlyOneChatContent).annotate({ identifier: "ReplyMailboxChatPayload" });
21298
21406
  var ReplyMailboxMessagePayload = Union2([
21299
21407
  ReplyMailboxEmailPayload,
21300
21408
  ReplyMailboxChatPayload
@@ -21337,10 +21445,14 @@ var MailboxSendReceipt = Struct({
21337
21445
  return hasIdentity;
21338
21446
  return receipt.state === "uncertain" || !hasIdentity;
21339
21447
  }, { message: "A public message identity requires canonical acceptance" })).annotate({ identifier: "MailboxSendReceipt" });
21340
- var MailboxSendSnapshot = Struct({
21341
- ...MailboxSendIntent.fields,
21448
+ var MailboxEmailSendSnapshot = Struct({
21449
+ ...MailboxEmailSendIntent.fields,
21342
21450
  attachments: EmailAttachments
21343
- }).annotate({ identifier: "MailboxSendSnapshot" });
21451
+ }).annotate({ identifier: "MailboxEmailSendSnapshot" });
21452
+ var MailboxSendSnapshot = Union2([
21453
+ MailboxEmailSendSnapshot,
21454
+ MailboxChatSendIntent
21455
+ ]).annotate({ identifier: "MailboxSendSnapshot" });
21344
21456
 
21345
21457
  class MailboxSendConflictError extends TaggedError3()("MailboxSendConflictError", {
21346
21458
  message: String4,
@@ -21368,7 +21480,7 @@ var CreateMailboxEmailDraftPayload = Struct({
21368
21480
  inReplyToMessageId: optional2(MessageId)
21369
21481
  }).annotate({ identifier: "CreateMailboxEmailDraftPayload" });
21370
21482
  var CreateMailboxChatDraftPayload = Struct({
21371
- channel: Literals(["whatsapp", "sms"]),
21483
+ channel: MailboxChatChannel,
21372
21484
  to: optional2(String4),
21373
21485
  text: optional2(String4),
21374
21486
  inReplyToMessageId: optional2(MessageId)
@@ -23641,7 +23753,7 @@ var TemplateId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new R
23641
23753
  expected: "a string matching the RegExp ^tmpl_[0-9a-hjkmnp-tv-z]{16,24}$",
23642
23754
  identifier: "TemplateId"
23643
23755
  })).pipe(brand("TemplateId"));
23644
- var JsonObject = /* @__PURE__ */ Record(String4, JsonValue).annotate({ identifier: "JsonObject" });
23756
+ var JsonObject2 = /* @__PURE__ */ Record(String4, JsonValue).annotate({ identifier: "JsonObject" });
23645
23757
  var RenderLocale = /* @__PURE__ */ String4.check(isMaxCodePoints(64).annotate({
23646
23758
  expected: "a string with at most 64 code points",
23647
23759
  identifier: "RenderLocale"
@@ -23829,11 +23941,6 @@ var MailboxEndpointId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ *
23829
23941
  expected: "a string matching the RegExp ^mbxep_[0-9a-hjkmnp-tv-z]{16,24}$",
23830
23942
  identifier: "MailboxEndpointId"
23831
23943
  })).pipe(brand("MailboxEndpointId"));
23832
- var MailboxChannelUnsupportedError2 = class extends TaggedError3()("MailboxChannelUnsupportedError", Struct({
23833
- message: String4,
23834
- channel: String4
23835
- })) {
23836
- };
23837
23944
  var MailboxMetadataPatch2 = /* @__PURE__ */ Record(String4, Union2([String4.check(isMaxCodePoints(512).annotate({ expected: "a string with at most 512 code points" })).check(isMaxLength(512).annotate({ expected: "a value with a length of at most 512" })), Null2])).check(isPropertyNames(String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(64).annotate({ expected: "a string with at most 64 code points" }))).annotate({
23838
23945
  expected: "an object with property names matching the schema",
23839
23946
  identifier: "MailboxMetadataPatch"
@@ -23990,6 +24097,16 @@ var DeliveryUnavailableError = class extends TaggedError3()("DeliveryUnavailable
23990
24097
  })) {
23991
24098
  };
23992
24099
  var IanaTimezone = /* @__PURE__ */ String4.annotate({ identifier: "IanaTimezone" });
24100
+ var NamespaceMetadata = /* @__PURE__ */ Record(String4, String4).annotate({
24101
+ description: "Your own labels for the namespace, such as the id of your customer it serves. Samva stores them and never reads them.",
24102
+ identifier: "NamespaceMetadata"
24103
+ });
24104
+ var NamespaceResourceType = /* @__PURE__ */ Union2([
24105
+ Literal2("domain"),
24106
+ Literal2("sender"),
24107
+ Literal2("contact"),
24108
+ Literal2("template")
24109
+ ]).annotate({ identifier: "NamespaceResourceType" });
23993
24110
  var OperationResource = /* @__PURE__ */ Struct({
23994
24111
  type: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(80).annotate({ expected: "a string with at most 80 code points" })).check(isMaxLength(80).annotate({ expected: "a value with a length of at most 80" })),
23995
24112
  id: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
@@ -23998,6 +24115,22 @@ var TemplateFromDefault = /* @__PURE__ */ Struct({
23998
24115
  email: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
23999
24116
  name: optionalKey2(Union2([String4, Null2]))
24000
24117
  }).annotate({ identifier: "TemplateFromDefault" });
24118
+ var TestWebhookPayload = /* @__PURE__ */ Struct({ data: optionalKey2(Union2([Record(String4, JsonValue), Null2])) }).annotate({ identifier: "TestWebhookPayload" });
24119
+ var ApiKeyMailboxAccess = /* @__PURE__ */ Struct({
24120
+ permissions: TupleWithRest(Tuple2([Union2([
24121
+ Literal2("read"),
24122
+ Literal2("update"),
24123
+ Literal2("send"),
24124
+ Literal2("quarantine.read")
24125
+ ])]), [Union2([
24126
+ Literal2("read"),
24127
+ Literal2("update"),
24128
+ Literal2("send"),
24129
+ Literal2("quarantine.read")
24130
+ ])]).annotate({ description: "`read` reads mailboxes, threads, and messages; `update` changes thread state, labels, drafts, and notes; `send` sends and replies; `quarantine.read` reads quarantined mail." }),
24131
+ mailboxIds: optionalKey2(Union2([TupleWithRest(Tuple2([MailboxId2]), [MailboxId2]), Null2]).annotate({ description: "The mailboxes the key may act on. Omit to reach every mailbox the owner can." })),
24132
+ sendMode: optionalKey2(Union2([MailboxSendMode2, Null2]).annotate({ description: "Defaults to `send`. With `approval`, each send waits until a person other than the key approves it." }))
24133
+ }).annotate({ identifier: "ApiKeyMailboxAccess" });
24001
24134
  var CreateTemplatePayload = /* @__PURE__ */ Struct({
24002
24135
  name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(200).annotate({ expected: "a string with at most 200 code points" })).check(isMaxLength(200).annotate({ expected: "a value with a length of at most 200" })),
24003
24136
  projectName: optionalKey2(Union2([String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(200).annotate({ expected: "a string with at most 200 code points" })).check(isMaxLength(200).annotate({ expected: "a value with a length of at most 200" })), Null2])),
@@ -24015,24 +24148,9 @@ var CreateTemplatePayload = /* @__PURE__ */ Struct({
24015
24148
  Literal2("alert")
24016
24149
  ]), Null2]), Null2])),
24017
24150
  isActive: optionalKey2(Union2([Boolean3, Null2])),
24151
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the new template project belongs to; the project and every entry added to it share it. Omit for organization level. A namespace-scoped key always creates in its own namespace." })),
24018
24152
  idempotencyKey: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
24019
24153
  }).annotate({ identifier: "CreateTemplatePayload" });
24020
- var TestWebhookPayload = /* @__PURE__ */ Struct({ data: optionalKey2(Union2([Record(String4, JsonValue), Null2])) }).annotate({ identifier: "TestWebhookPayload" });
24021
- var ApiKeyMailboxAccess = /* @__PURE__ */ Struct({
24022
- permissions: TupleWithRest(Tuple2([Union2([
24023
- Literal2("read"),
24024
- Literal2("update"),
24025
- Literal2("send"),
24026
- Literal2("quarantine.read")
24027
- ])]), [Union2([
24028
- Literal2("read"),
24029
- Literal2("update"),
24030
- Literal2("send"),
24031
- Literal2("quarantine.read")
24032
- ])]).annotate({ description: "`read` reads mailboxes, threads, and messages; `update` changes thread state, labels, drafts, and notes; `send` sends and replies; `quarantine.read` reads quarantined mail." }),
24033
- mailboxIds: optionalKey2(Union2([TupleWithRest(Tuple2([MailboxId2]), [MailboxId2]), Null2]).annotate({ description: "The mailboxes the key may act on. Omit to reach every mailbox the owner can." })),
24034
- sendMode: optionalKey2(Union2([MailboxSendMode2, Null2]).annotate({ description: "Defaults to `send`. With `approval`, each send waits until a person other than the key approves it." }))
24035
- }).annotate({ identifier: "ApiKeyMailboxAccess" });
24036
24154
  var CreateWebhookPayload = /* @__PURE__ */ Struct({
24037
24155
  name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(100).annotate({ expected: "a string with at most 100 code points" })).check(isMaxLength(100).annotate({ expected: "a value with a length of at most 100" })),
24038
24156
  url: String4,
@@ -24167,14 +24285,14 @@ var EmailAttachment2 = /* @__PURE__ */ Struct({
24167
24285
  contentType: String4,
24168
24286
  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" }))
24169
24287
  }).annotate({ identifier: "EmailAttachment" });
24170
- var TemplateData = /* @__PURE__ */ Union2([JsonObject, Null2]).annotate({ identifier: "TemplateData" });
24288
+ var TemplateData = /* @__PURE__ */ Union2([JsonObject2, Null2]).annotate({ identifier: "TemplateData" });
24171
24289
  var ContactConsent = /* @__PURE__ */ Struct({
24172
24290
  status: Union2([Literal2("opted_in"), Literal2("opted_out")]),
24173
24291
  source: String4,
24174
24292
  capturedAt: String4,
24175
- proof: Union2([JsonObject, Null2])
24293
+ proof: Union2([JsonObject2, Null2])
24176
24294
  }).annotate({ identifier: "ContactConsent" });
24177
- var JourneyWebhookConfig = /* @__PURE__ */ Struct({ data: optionalKey2(JsonObject) }).annotate({ identifier: "JourneyWebhookConfig" });
24295
+ var JourneyWebhookConfig = /* @__PURE__ */ Struct({ data: optionalKey2(JsonObject2) }).annotate({ identifier: "JourneyWebhookConfig" });
24178
24296
  var SkippedRecipient2 = /* @__PURE__ */ Struct({
24179
24297
  address: String4,
24180
24298
  reason: Union2([
@@ -24191,7 +24309,7 @@ var ContactEvent = /* @__PURE__ */ Struct({
24191
24309
  contactId: ContactId2,
24192
24310
  name: String4,
24193
24311
  source: Union2([Literal2("api"), Literal2("samva")]),
24194
- properties: JsonObject,
24312
+ properties: JsonObject2,
24195
24313
  occurredAt: String4,
24196
24314
  recordedAt: String4
24197
24315
  }).annotate({ identifier: "ContactEvent" });
@@ -24224,7 +24342,7 @@ var JourneyGroupJoinedTrigger = /* @__PURE__ */ Struct({
24224
24342
  var JourneySendEmailConfig = /* @__PURE__ */ Struct({
24225
24343
  template: Union2([TemplateId2, String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$", "u")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" }))]),
24226
24344
  senderId: optionalKey2(EmailSenderId2),
24227
- templateData: optionalKey2(JsonObject)
24345
+ templateData: optionalKey2(JsonObject2)
24228
24346
  }).annotate({ identifier: "JourneySendEmailConfig" });
24229
24347
  var ExtensionVersionRef = /* @__PURE__ */ Struct({
24230
24348
  id: ExtensionVersionId2,
@@ -24350,7 +24468,7 @@ var ApiKeyAccess = /* @__PURE__ */ Union2([Struct({ mode: Literal2("full") }), S
24350
24468
  mode: Literal2("restricted"),
24351
24469
  resources: ApiKeyResourceAccess,
24352
24470
  mailboxes: optionalKey2(Union2([ApiKeyMailboxAccess, Null2])),
24353
- namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Confines the key to one namespace: it reaches only that namespace's mailboxes. A key scoped to a namespace or to listed mailboxes holds mailbox access only." }))
24471
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Confines the key to one namespace: it reaches only that namespace's domains, senders, numbers, mailboxes, contacts, templates, and messages, never organization-level ones, and only endpoints that confine to a namespace (others answer 403). It holds grants only on `mailboxes`, `messages`, `email`, `domains`, `contacts`, and `templates`. A key scoped to listed mailboxes holds mailbox access only." }))
24354
24472
  })]).annotate({ identifier: "ApiKeyAccess" });
24355
24473
  var MessagePage = /* @__PURE__ */ Struct({
24356
24474
  items: ArraySchema(MessageSummary2),
@@ -24369,7 +24487,7 @@ var ContactIdentityChannel = /* @__PURE__ */ Struct({
24369
24487
  var CreateEventPayload = /* @__PURE__ */ Struct({
24370
24488
  contact: ContactEventReference,
24371
24489
  name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!(?:[Cc][Oo][Nn][Tt][Aa][Cc][Tt]|[Ss][Aa][Mm][Vv][Aa])\\.)[A-Za-z][A-Za-z0-9_.-]*$")).annotate({ expected: "a string matching the RegExp ^(?!(?:[Cc][Oo][Nn][Tt][Aa][Cc][Tt]|[Ss][Aa][Mm][Vv][Aa])\\.)[A-Za-z][A-Za-z0-9_.-]*$" })),
24372
- properties: optionalKey2(Union2([JsonObject, Null2])),
24490
+ properties: optionalKey2(Union2([JsonObject2, Null2])),
24373
24491
  occurredAt: optionalKey2(Union2([String4, Null2])),
24374
24492
  idempotencyKey: optionalKey2(Union2([String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" })), Null2]))
24375
24493
  }).annotate({ identifier: "CreateEventPayload" });
@@ -24698,6 +24816,7 @@ var apiStatuses = {
24698
24816
  NotImplementedError: 501,
24699
24817
  UnknownStatusError: 400,
24700
24818
  WhatsAppTemplateIneligibleError: 422,
24819
+ WhatsAppServiceWindowClosedError: 422,
24701
24820
  InternalError: 500,
24702
24821
  ExternalServiceError: 502,
24703
24822
  GatewayTimeoutError: 504
@@ -24760,6 +24879,9 @@ var apiErrorGuidance = (error) => {
24760
24879
  case "MailboxSendRefusedError":
24761
24880
  next = "Read the original action with samva mailboxes actions get; preserve its action ID and send key. Accepted email cannot be withdrawn; uncertain work requires reconciliation. Never create a replacement key as recovery.";
24762
24881
  break;
24882
+ case "WhatsAppServiceWindowClosedError":
24883
+ next = "Free-form WhatsApp text needs the customer's open 24-hour service window. Send an approved template instead: --template <templateId> with --data.";
24884
+ break;
24763
24885
  case "ConflictError":
24764
24886
  next = "Read the resource and resolve the conflict before retrying.";
24765
24887
  break;
@@ -24960,7 +25082,7 @@ var __exportAll = (all, no_symbols) => {
24960
25082
  };
24961
25083
 
24962
25084
  // ../sdk/dist/package.js
24963
- var version = "0.19.0";
25085
+ var version = "0.20.0";
24964
25086
 
24965
25087
  // ../sdk/dist/client-attribution.js
24966
25088
  var SDK_VERSION = version;
@@ -25320,6 +25442,16 @@ var commandTree = {
25320
25442
  actions: { list: {}, get: {}, approve: {}, deny: {}, cancel: {}, retry: {} },
25321
25443
  quarantine: { list: {}, release: {}, discard: {} }
25322
25444
  },
25445
+ namespaces: {
25446
+ list: {},
25447
+ create: {},
25448
+ get: {},
25449
+ update: {},
25450
+ delete: {},
25451
+ assign: {},
25452
+ unassign: {},
25453
+ usage: {}
25454
+ },
25323
25455
  extensions: {
25324
25456
  init: {},
25325
25457
  build: {},
@@ -25785,6 +25917,7 @@ var getAuthenticatedJsonForContext = fn2("CliClient.getAuthenticatedJson")(funct
25785
25917
  return yield* isObject(body) && typeof body._tag === "string" ? toCliApiError(`Request to ${url} failed`, body) : new SamvaCliError({ message: `Request to ${url} failed: HTTP ${response.status}` });
25786
25918
  });
25787
25919
  var getAuthenticatedJson = (path) => flatMap3(resolveExecutionContext, (context) => getAuthenticatedJsonForContext(context, path));
25920
+ var postAuthenticatedJson = (path, request) => flatMap3(resolveExecutionContext, (context) => getAuthenticatedJsonForContext(context, path, request));
25788
25921
 
25789
25922
  // src/lib/output.ts
25790
25923
  var CLI_SCHEMA_VERSION = 1;
@@ -26437,6 +26570,7 @@ var API_KEY_STATEMENT = {
26437
26570
  };
26438
26571
  var API_KEY_RESOURCES = Object.keys(API_KEY_STATEMENT);
26439
26572
  var API_KEY_LEVEL_RESOURCES = API_KEY_RESOURCES.filter((resource) => resource !== "mailboxes");
26573
+ var API_KEY_MAILBOX_ACTIONS = mailboxKeyActions;
26440
26574
  function apiKeyAccessLevels(resource) {
26441
26575
  return API_KEY_STATEMENT[resource].some((action) => action !== "read") ? ["read", "write"] : ["read"];
26442
26576
  }
@@ -27450,6 +27584,22 @@ var SDK_OPERATION_CALLS = {
27450
27584
  kind: "path",
27451
27585
  paths: ["id"]
27452
27586
  },
27587
+ namespacesAssignResource: {
27588
+ kind: "pathPayload",
27589
+ paths: ["id"]
27590
+ },
27591
+ namespacesRemoveResource: {
27592
+ kind: "path",
27593
+ paths: [
27594
+ "id",
27595
+ "type",
27596
+ "resourceId"
27597
+ ]
27598
+ },
27599
+ namespacesGetUsage: {
27600
+ kind: "pathParams",
27601
+ paths: ["id"]
27602
+ },
27453
27603
  extensionsList: { kind: "params" },
27454
27604
  extensionsPublish: { kind: "payload" },
27455
27605
  extensionsGet: {
@@ -27546,10 +27696,6 @@ var SamvaErrorMetadata = {
27546
27696
  categories: ["transient"],
27547
27697
  retryable: true
27548
27698
  },
27549
- MailboxChannelUnsupportedError: {
27550
- categories: [],
27551
- retryable: false
27552
- },
27553
27699
  MailboxSendConflictError: {
27554
27700
  categories: [],
27555
27701
  retryable: false
@@ -28340,6 +28486,9 @@ var SamvaOperations = {
28340
28486
  namespacesGet: operationMetadata74,
28341
28487
  namespacesRemove: operationMetadata75,
28342
28488
  namespacesUpdate: operationMetadata76,
28489
+ namespacesAssignResource: operationMetadata73,
28490
+ namespacesRemoveResource: operationMetadata75,
28491
+ namespacesGetUsage: operationMetadata74,
28343
28492
  operationsList: operationMetadata77,
28344
28493
  operationsGet: operationMetadata78,
28345
28494
  operationsRetry: operationMetadata79,
@@ -28919,7 +29068,7 @@ var parseGrant = (raw) => {
28919
29068
  if (resource === "mailboxes") {
28920
29069
  return new CliUsageError({
28921
29070
  code: "invalid_grant",
28922
- message: "--grant does not cover mailboxes; mailbox and namespace access are set with `samva api`."
29071
+ message: "--grant does not cover mailboxes; use --mailbox-permission <action> (with optional --mailbox and --send-mode) instead."
28923
29072
  });
28924
29073
  }
28925
29074
  if (!isLevelResource(resource) || !isGrantLevel(level)) {
@@ -28936,19 +29085,52 @@ var parseGrant = (raw) => {
28936
29085
  }
28937
29086
  return { resource, level };
28938
29087
  };
28939
- var accessFromFlags = (grants, fullAccess) => gen2(function* () {
28940
- if (fullAccess && grants.length > 0) {
29088
+ var repeated = (values) => values.find((value, index) => values.indexOf(value) !== index);
29089
+ var mailboxAccessFromFlags = (flags) => gen2(function* () {
29090
+ if (flags.permissions.length === 0) {
29091
+ if (flags.mailboxIds.length > 0 || isSome2(flags.sendMode)) {
29092
+ return yield* new CliUsageError({
29093
+ code: "mailbox_permission_required",
29094
+ message: `--mailbox and --send-mode narrow mailbox access; also pass --mailbox-permission ${API_KEY_MAILBOX_ACTIONS.join("|")}.`
29095
+ });
29096
+ }
29097
+ return;
29098
+ }
29099
+ const duplicatePermission = repeated(flags.permissions);
29100
+ if (duplicatePermission !== undefined) {
29101
+ return yield* new CliUsageError({
29102
+ code: "invalid_mailbox_access",
29103
+ message: `--mailbox-permission names ${duplicatePermission} more than once.`
29104
+ });
29105
+ }
29106
+ const duplicateMailbox = repeated(flags.mailboxIds);
29107
+ if (duplicateMailbox !== undefined) {
29108
+ return yield* new CliUsageError({
29109
+ code: "invalid_mailbox_access",
29110
+ message: `--mailbox names ${duplicateMailbox} more than once.`
29111
+ });
29112
+ }
29113
+ return {
29114
+ permissions: flags.permissions,
29115
+ ...flags.mailboxIds.length > 0 ? { mailboxIds: flags.mailboxIds } : {},
29116
+ ...isSome2(flags.sendMode) ? { sendMode: flags.sendMode.value } : {}
29117
+ };
29118
+ });
29119
+ var accessFromFlags = (grants, fullAccess, mailbox, namespace) => gen2(function* () {
29120
+ const restrictedFlags = grants.length > 0 || mailbox.permissions.length > 0 || mailbox.mailboxIds.length > 0 || isSome2(mailbox.sendMode) || isSome2(namespace);
29121
+ if (fullAccess && restrictedFlags) {
28941
29122
  return yield* new CliUsageError({
28942
29123
  code: "access_conflict",
28943
- message: "Pass either --full-access or --grant <resource>=read|write, not both."
29124
+ message: "Pass either --full-access or restricted access (--grant, --mailbox-permission, --namespace), not both."
28944
29125
  });
28945
29126
  }
28946
29127
  if (fullAccess)
28947
29128
  return { mode: "full" };
28948
- if (grants.length === 0) {
29129
+ const mailboxes = yield* mailboxAccessFromFlags(mailbox);
29130
+ if (grants.length === 0 && mailboxes === undefined) {
28949
29131
  return yield* new CliUsageError({
28950
29132
  code: "access_required",
28951
- message: "Choose the key's access: --full-access, or one or more --grant <resource>=read|write."
29133
+ message: "Choose the key's access: --full-access, or one or more --grant <resource>=read|write and/or --mailbox-permission <action>."
28952
29134
  });
28953
29135
  }
28954
29136
  const resources = {};
@@ -28964,7 +29146,12 @@ var accessFromFlags = (grants, fullAccess) => gen2(function* () {
28964
29146
  }
28965
29147
  resources[grant.resource] = grant.level;
28966
29148
  }
28967
- return { mode: "restricted", resources };
29149
+ return {
29150
+ mode: "restricted",
29151
+ resources,
29152
+ ...mailboxes === undefined ? {} : { mailboxes },
29153
+ ...isSome2(namespace) ? { namespaceId: namespace.value } : {}
29154
+ };
28968
29155
  });
28969
29156
  var parseExpiresAt = (raw) => Number.isNaN(Date.parse(raw)) ? fail6(new CliUsageError({
28970
29157
  code: "invalid_expires_at",
@@ -28978,7 +29165,12 @@ var describeAccess = (access) => {
28978
29165
  return "full";
28979
29166
  const grants = Object.entries(access.resources).filter(([, level]) => level !== undefined).map(([resource, level]) => `${resource}:${level}`);
28980
29167
  if (access.mailboxes !== undefined && access.mailboxes !== null) {
28981
- grants.push(`mailboxes:${access.mailboxes.permissions.join("+")}`);
29168
+ const { permissions, mailboxIds, sendMode } = access.mailboxes;
29169
+ const scope = [
29170
+ ...mailboxIds === undefined || mailboxIds === null ? [] : [mailboxIds.join("+")],
29171
+ ...sendMode === undefined || sendMode === "send" ? [] : [`${sendMode} sends`]
29172
+ ];
29173
+ grants.push(`mailboxes:${permissions.join("+")}${scope.length === 0 ? "" : ` [${scope.join("; ")}]`}`);
28982
29174
  }
28983
29175
  if (access.namespaceId !== undefined && access.namespaceId !== null)
28984
29176
  grants.push(`namespace:${access.namespaceId}`);
@@ -29057,11 +29249,19 @@ var create2 = make29("create", {
29057
29249
  description: String9("description").pipe(withDescription2("What the key is for"), optional4),
29058
29250
  expiresAt: String9("expires-at").pipe(withDescription2("When the key stops working, an ISO 8601 instant"), optional4),
29059
29251
  grant: String9("grant").pipe(withDescription2(`Give a restricted key a resource at a level, <resource>=read|write (repeatable). Resources: ${GRANTABLE_RESOURCES.join(", ")}`), atLeast2(0)),
29060
- fullAccess: Boolean6("full-access").pipe(withDescription2("Give the key its owner's full access instead of --grant"), withDefault5(false)),
29252
+ mailboxPermission: Literals3("mailbox-permission", API_KEY_MAILBOX_ACTIONS).pipe(withDescription2(`Let a restricted key work in mailboxes with this action (repeatable): ${API_KEY_MAILBOX_ACTIONS.join(", ")}`), atLeast2(0)),
29253
+ mailbox: String9("mailbox").pipe(withSchema2(MailboxId), withDescription2("Confine the mailbox access to this mailbox (repeatable); omit for every mailbox the owner reaches"), atLeast2(0)),
29254
+ sendMode: Literals3("send-mode", mailboxSendModes).pipe(withDescription2("With approval, each send waits until a person other than the key approves it (default send)"), optional4),
29255
+ namespace: String9("namespace").pipe(withSchema2(NamespaceId), withDescription2("Confine a restricted key to one namespace (ns_...)"), optional4),
29256
+ fullAccess: Boolean6("full-access").pipe(withDescription2("Give the key its owner's full access instead of restricted access"), withDefault5(false)),
29061
29257
  dryRun: dryRunFlag,
29062
29258
  json: jsonFlag
29063
29259
  }).pipe(withDescription3("Create an API key. The secret is shown once; the API refuses access you do not hold."), withExamples([
29064
29260
  { command: "samva api-keys create --name ci --grant email=write --dry-run" },
29261
+ {
29262
+ command: "samva api-keys create --name agent --mailbox-permission read --mailbox-permission send --mailbox mbx_1234567890123456 --send-mode approval",
29263
+ description: "A key that works in one mailbox and needs a person to approve each send"
29264
+ },
29065
29265
  {
29066
29266
  command: "samva api-keys create --name ci --grant email=write --json | jq -r .data.key",
29067
29267
  description: "Pipe the secret into another tool"
@@ -29069,8 +29269,20 @@ var create2 = make29("create", {
29069
29269
  {
29070
29270
  command: "samva api-keys create --name deploy --full-access --expires-at 2027-01-01T00:00:00Z"
29071
29271
  }
29072
- ]), withHandler(({ name, description, expiresAt, grant, fullAccess, dryRun, json }) => withJsonQuiet(json, gen2(function* () {
29073
- const access = yield* accessFromFlags(grant, fullAccess);
29272
+ ]), withHandler(({
29273
+ name,
29274
+ description,
29275
+ expiresAt,
29276
+ grant,
29277
+ mailboxPermission,
29278
+ mailbox,
29279
+ sendMode,
29280
+ namespace,
29281
+ fullAccess,
29282
+ dryRun,
29283
+ json
29284
+ }) => withJsonQuiet(json, gen2(function* () {
29285
+ const access = yield* accessFromFlags(grant, fullAccess, { permissions: mailboxPermission, mailboxIds: mailbox, sendMode }, namespace);
29074
29286
  const expires = yield* match(expiresAt, {
29075
29287
  onNone: () => void_3,
29076
29288
  onSome: parseExpiresAt
@@ -29086,7 +29298,11 @@ var create2 = make29("create", {
29086
29298
  });
29087
29299
  if (dryRun) {
29088
29300
  if (json) {
29089
- return yield* printJson({ dryRun: true, action: "api-keys.create", request: payload });
29301
+ return yield* printJson({
29302
+ dryRun: true,
29303
+ action: "api-keys.create",
29304
+ request: payload
29305
+ });
29090
29306
  }
29091
29307
  return yield* printFields([
29092
29308
  ["Action", "api-keys.create"],
@@ -29109,13 +29325,17 @@ var update3 = make29("update", {
29109
29325
  id: idArgument,
29110
29326
  name: String9("name").pipe(withDescription2("New key name"), optional4),
29111
29327
  description: String9("description").pipe(withDescription2("New description"), optional4),
29328
+ sendMode: Literals3("send-mode", mailboxSendModes).pipe(withDescription2("Change a mailbox key's send mode: approval holds each send for a person other than the key, send releases them. Takes a person signed in with samva login"), optional4),
29112
29329
  dryRun: dryRunFlag,
29113
29330
  json: jsonFlag
29114
- }).pipe(withDescription3("Rename an API key or change its description. Access is fixed at creation; create a new key to change it."), withExamples([{ command: "samva api-keys update key_abc123 --name ci-prod --dry-run" }]), withHandler(({ id, name, description, dryRun, json }) => withJsonQuiet(json, gen2(function* () {
29115
- if (isNone2(name) && isNone2(description)) {
29331
+ }).pipe(withDescription3("Rename an API key, change its description, or change a mailbox key's send mode. Its other access is fixed at creation; create a new key to change it."), withExamples([
29332
+ { command: "samva api-keys update key_abc123 --name ci-prod --dry-run" },
29333
+ { command: "samva api-keys update key_abc123 --send-mode approval" }
29334
+ ]), withHandler(({ id, name, description, sendMode, dryRun, json }) => withJsonQuiet(json, gen2(function* () {
29335
+ if (isNone2(name) && isNone2(description) && isNone2(sendMode)) {
29116
29336
  return yield* new CliUsageError({
29117
29337
  code: "update_required",
29118
- message: "Pass --name, --description, or both."
29338
+ message: "Pass --name, --description, --send-mode, or a combination."
29119
29339
  });
29120
29340
  }
29121
29341
  const payload = yield* decodeRequest(ApiKeysUpdateRequestJson, {
@@ -29123,6 +29343,10 @@ var update3 = make29("update", {
29123
29343
  ...match(description, {
29124
29344
  onNone: () => ({}),
29125
29345
  onSome: (value) => ({ description: value })
29346
+ }),
29347
+ ...match(sendMode, {
29348
+ onNone: () => ({}),
29349
+ onSome: (value) => ({ mailboxes: { sendMode: value } })
29126
29350
  })
29127
29351
  });
29128
29352
  if (dryRun) {
@@ -29138,7 +29362,8 @@ var update3 = make29("update", {
29138
29362
  ["Action", "api-keys.update"],
29139
29363
  ["API key", id],
29140
29364
  ["Name", payload.name],
29141
- ["Description", payload.description]
29365
+ ["Description", payload.description],
29366
+ ["Send mode", payload.mailboxes?.sendMode]
29142
29367
  ]);
29143
29368
  }
29144
29369
  const client = yield* getClientProvider;
@@ -53935,6 +54160,20 @@ var CampaignRunId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ ne
53935
54160
  expected: "a string matching the RegExp ^crun_[0-9a-hjkmnp-tv-z]{16,24}$",
53936
54161
  identifier: "CampaignRunId"
53937
54162
  })).pipe(brand("CampaignRunId"));
54163
+ var CampaignRunSkippedReason = /* @__PURE__ */ Struct({
54164
+ reason: Union2([
54165
+ Literal2("unsubscribed"),
54166
+ Literal2("blocked"),
54167
+ Literal2("suppressed"),
54168
+ Literal2("opted_out"),
54169
+ Literal2("unreachable"),
54170
+ Literal2("no_identity"),
54171
+ Literal2("inactive"),
54172
+ Literal2("run_cancelled"),
54173
+ Literal2("run_failed")
54174
+ ]),
54175
+ count: Finite.check(isFinite4().annotate({ expected: "a finite number" }))
54176
+ }).annotate({ identifier: "CampaignRunSkippedReason" });
53938
54177
  var CampaignRecipientId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new RegExp("^crcpt_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
53939
54178
  expected: "a string matching the RegExp ^crcpt_[0-9a-hjkmnp-tv-z]{16,24}$",
53940
54179
  identifier: "CampaignRecipientId"
@@ -53987,6 +54226,8 @@ var CampaignRecipientPage = /* @__PURE__ */ Struct({
53987
54226
  Literal2("unsubscribed"),
53988
54227
  Literal2("blocked"),
53989
54228
  Literal2("suppressed"),
54229
+ Literal2("opted_out"),
54230
+ Literal2("unreachable"),
53990
54231
  Literal2("no_identity"),
53991
54232
  Literal2("inactive"),
53992
54233
  Literal2("run_cancelled"),
@@ -54063,6 +54304,7 @@ var CampaignRun = /* @__PURE__ */ Struct({
54063
54304
  dispatchedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
54064
54305
  failedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
54065
54306
  skippedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
54307
+ skippedReasons: ArraySchema(CampaignRunSkippedReason),
54066
54308
  estimatedCompletionAt: Union2([String4, Null2]),
54067
54309
  failureReason: Union2([String4, Null2]),
54068
54310
  holdReason: Union2([String4, Null2]),
@@ -54900,6 +55142,10 @@ var printRun = (run) => printFields([
54900
55142
  ["Dispatched", String(run.dispatchedCount)],
54901
55143
  ["Failed", String(run.failedCount)],
54902
55144
  ["Skipped", String(run.skippedCount)],
55145
+ [
55146
+ "Skipped by reason",
55147
+ (run.skippedReasons ?? []).map(({ reason, count }) => `${reason} ${count}`).join(", ")
55148
+ ],
54903
55149
  ["Failure", run.failureReason]
54904
55150
  ]);
54905
55151
  var runCreate = make29("create", {
@@ -54993,7 +55239,11 @@ var runList = make29("list", {
54993
55239
  ["Scheduled for", run.scheduledFor],
54994
55240
  ["Dispatched", String(run.dispatchedCount)],
54995
55241
  ["Failed", String(run.failedCount)],
54996
- ["Skipped", String(run.skippedCount)]
55242
+ ["Skipped", String(run.skippedCount)],
55243
+ [
55244
+ "Skipped by reason",
55245
+ run.skippedReasons.map(({ reason, count }) => `${reason} ${count}`).join(", ")
55246
+ ]
54997
55247
  ]);
54998
55248
  yield* log("");
54999
55249
  }
@@ -55305,6 +55555,7 @@ var ContactProfileUpdate = /* @__PURE__ */ Struct({
55305
55555
  }).annotate({ identifier: "ContactProfileUpdate" });
55306
55556
  var ContactSummary = /* @__PURE__ */ Struct({
55307
55557
  id: ContactId2,
55558
+ namespaceId: Union2([NamespaceId2, Null2]),
55308
55559
  name: String4,
55309
55560
  displayName: Union2([String4, Null2]),
55310
55561
  status: Union2([
@@ -55327,6 +55578,7 @@ var ContactPage = /* @__PURE__ */ Struct({
55327
55578
  }).annotate({ identifier: "ContactPage" });
55328
55579
  var Contact = /* @__PURE__ */ Struct({
55329
55580
  id: ContactId2,
55581
+ namespaceId: Union2([NamespaceId2, Null2]),
55330
55582
  name: String4,
55331
55583
  displayName: Union2([String4, Null2]),
55332
55584
  avatar: Union2([String4, Null2]),
@@ -55342,13 +55594,14 @@ var Contact = /* @__PURE__ */ Struct({
55342
55594
  profile: Union2([ContactProfile, Null2]),
55343
55595
  preferences: Union2([ContactPreferences, Null2]),
55344
55596
  tags: ArraySchema(String4),
55345
- metadata: Union2([JsonObject, Null2]),
55597
+ metadata: Union2([JsonObject2, Null2]),
55346
55598
  createdAt: String4,
55347
55599
  updatedAt: String4
55348
55600
  }).annotate({ identifier: "Contact" });
55349
55601
  var ContactsListQuery = /* @__PURE__ */ Struct({
55350
55602
  limit: optionalKey2(Union2([String4, Null2])),
55351
55603
  cursor: optionalKey2(Union2([Cursor, Null2])),
55604
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55352
55605
  search: optionalKey2(Union2([String4, Null2])),
55353
55606
  status: optionalKey2(Union2([Union2([
55354
55607
  Literal2("active"),
@@ -55369,6 +55622,7 @@ var ContactsList422 = ValidationError2;
55369
55622
  var ContactsList500 = InternalError2;
55370
55623
  var ContactsList504 = GatewayTimeoutError2;
55371
55624
  var ContactsCreateRequestJson = /* @__PURE__ */ Struct({
55625
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55372
55626
  name: String4,
55373
55627
  displayName: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55374
55628
  avatar: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
@@ -55384,12 +55638,13 @@ var ContactsCreateRequestJson = /* @__PURE__ */ Struct({
55384
55638
  ]), Null2])),
55385
55639
  statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55386
55640
  externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55387
- metadata: optionalKey2(Union2([Union2([JsonObject, Null2]), Null2]))
55641
+ metadata: optionalKey2(Union2([Union2([JsonObject2, Null2]), Null2]))
55388
55642
  });
55389
55643
  var ContactsCreate201 = Contact;
55390
55644
  var ContactsCreate401 = UnauthorizedError2;
55391
55645
  var ContactsCreate402 = PaymentRequiredError2;
55392
55646
  var ContactsCreate403 = ForbiddenError2;
55647
+ var ContactsCreate404 = ResourceNotFoundError2;
55393
55648
  var ContactsCreate409 = ConflictError2;
55394
55649
  var ContactsCreate422 = ValidationError2;
55395
55650
  var ContactsCreate500 = InternalError2;
@@ -55427,7 +55682,7 @@ var ContactsUpdateRequestJson = /* @__PURE__ */ Struct({
55427
55682
  ]), Null2])),
55428
55683
  statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55429
55684
  externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55430
- metadata: optionalKey2(Union2([JsonObject, Null2]))
55685
+ metadata: optionalKey2(Union2([JsonObject2, Null2]))
55431
55686
  });
55432
55687
  var ContactsUpdate200 = Contact;
55433
55688
  var ContactsUpdate401 = UnauthorizedError2;
@@ -55512,7 +55767,7 @@ var ContactsSetConsentRequestJson = /* @__PURE__ */ Struct({
55512
55767
  status: Union2([Literal2("opted_in"), Literal2("opted_out")]),
55513
55768
  source: String4.annotate({ description: "Where the consent was captured, such as a form URL or a checkout step." }).check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(200).annotate({ expected: "a string with at most 200 code points" })).check(isMaxLength(200).annotate({ expected: "a value with a length of at most 200" })),
55514
55769
  capturedAt: String4,
55515
- proof: optionalKey2(Union2([JsonObject, Null2]))
55770
+ proof: optionalKey2(Union2([JsonObject2, Null2]))
55516
55771
  });
55517
55772
  var ContactsSetConsent200 = Contact;
55518
55773
  var ContactsSetConsent401 = UnauthorizedError2;
@@ -55551,6 +55806,7 @@ var ContactsBulkDelete500 = InternalError2;
55551
55806
  var ContactsBulkDelete502 = BillingProviderError;
55552
55807
  var ContactsBulkDelete504 = GatewayTimeoutError2;
55553
55808
  var ContactsBulkImportRequestJson = /* @__PURE__ */ Struct({
55809
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55554
55810
  contacts: ArraySchema(Struct({
55555
55811
  name: String4,
55556
55812
  displayName: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
@@ -55567,7 +55823,7 @@ var ContactsBulkImportRequestJson = /* @__PURE__ */ Struct({
55567
55823
  ]), Null2])),
55568
55824
  statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55569
55825
  externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55570
- metadata: optionalKey2(Union2([Union2([JsonObject, Null2]), Null2]))
55826
+ metadata: optionalKey2(Union2([Union2([JsonObject2, Null2]), Null2]))
55571
55827
  })),
55572
55828
  onConflict: optionalKey2(Union2([Union2([Literal2("skip"), Literal2("update")]), Null2]))
55573
55829
  });
@@ -55592,6 +55848,7 @@ var ContactsBulkImport200 = /* @__PURE__ */ Struct({
55592
55848
  var ContactsBulkImport401 = UnauthorizedError2;
55593
55849
  var ContactsBulkImport402 = PaymentRequiredError2;
55594
55850
  var ContactsBulkImport403 = ForbiddenError2;
55851
+ var ContactsBulkImport404 = ResourceNotFoundError2;
55595
55852
  var ContactsBulkImport422 = ValidationError2;
55596
55853
  var ContactsBulkImport500 = InternalError2;
55597
55854
  var ContactsBulkImport502 = BillingProviderError;
@@ -55653,6 +55910,7 @@ var ContactsExport422 = ValidationError2;
55653
55910
  var ContactsExport500 = InternalError2;
55654
55911
  var ContactsExport504 = GatewayTimeoutError2;
55655
55912
  var ContactsFindRequestJson = /* @__PURE__ */ Struct({
55913
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55656
55914
  email: optionalKey2(Union2([String4, Null2])),
55657
55915
  phone: optionalKey2(Union2([String4, Null2])),
55658
55916
  externalId: optionalKey2(Union2([String4, Null2]))
@@ -55660,11 +55918,13 @@ var ContactsFindRequestJson = /* @__PURE__ */ Struct({
55660
55918
  var ContactsFind200 = /* @__PURE__ */ Union2([Contact, Null2]);
55661
55919
  var ContactsFind401 = UnauthorizedError2;
55662
55920
  var ContactsFind403 = ForbiddenError2;
55921
+ var ContactsFind404 = ResourceNotFoundError2;
55663
55922
  var ContactsFind409 = ConflictError2;
55664
55923
  var ContactsFind422 = ValidationError2;
55665
55924
  var ContactsFind500 = InternalError2;
55666
55925
  var ContactsFind504 = GatewayTimeoutError2;
55667
55926
  var ContactsFindOrCreateRequestJson = /* @__PURE__ */ Struct({
55927
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55668
55928
  lookup: ContactLookup,
55669
55929
  create: optionalKey2(Union2([Struct({
55670
55930
  name: optionalKey2(Union2([String4, Null2])),
@@ -55682,6 +55942,7 @@ var ContactsFindOrCreate200 = /* @__PURE__ */ Struct({
55682
55942
  var ContactsFindOrCreate401 = UnauthorizedError2;
55683
55943
  var ContactsFindOrCreate402 = PaymentRequiredError2;
55684
55944
  var ContactsFindOrCreate403 = ForbiddenError2;
55945
+ var ContactsFindOrCreate404 = ResourceNotFoundError2;
55685
55946
  var ContactsFindOrCreate409 = ConflictError2;
55686
55947
  var ContactsFindOrCreate422 = ValidationError2;
55687
55948
  var ContactsFindOrCreate500 = InternalError2;
@@ -55704,6 +55965,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55704
55965
  ContactsCreate401.pipe(status(401)),
55705
55966
  ContactsCreate402.pipe(status(402)),
55706
55967
  ContactsCreate403.pipe(status(403)),
55968
+ ContactsCreate404.pipe(status(404)),
55707
55969
  ContactsCreate409.pipe(status(409)),
55708
55970
  ContactsCreate422.pipe(status(422)),
55709
55971
  ContactsCreate500,
@@ -55860,6 +56122,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55860
56122
  ContactsBulkImport401.pipe(status(401)),
55861
56123
  ContactsBulkImport402.pipe(status(402)),
55862
56124
  ContactsBulkImport403.pipe(status(403)),
56125
+ ContactsBulkImport404.pipe(status(404)),
55863
56126
  ContactsBulkImport422.pipe(status(422)),
55864
56127
  ContactsBulkImport500,
55865
56128
  ContactsBulkImport502.pipe(status(502)),
@@ -55903,6 +56166,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55903
56166
  error: [
55904
56167
  ContactsFind401.pipe(status(401)),
55905
56168
  ContactsFind403.pipe(status(403)),
56169
+ ContactsFind404.pipe(status(404)),
55906
56170
  ContactsFind409.pipe(status(409)),
55907
56171
  ContactsFind422.pipe(status(422)),
55908
56172
  ContactsFind500,
@@ -55915,6 +56179,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55915
56179
  ContactsFindOrCreate401.pipe(status(401)),
55916
56180
  ContactsFindOrCreate402.pipe(status(402)),
55917
56181
  ContactsFindOrCreate403.pipe(status(403)),
56182
+ ContactsFindOrCreate404.pipe(status(404)),
55918
56183
  ContactsFindOrCreate409.pipe(status(409)),
55919
56184
  ContactsFindOrCreate422.pipe(status(422)),
55920
56185
  ContactsFindOrCreate500,
@@ -55930,6 +56195,15 @@ var list7 = /* @__PURE__ */ make43("contactsList");
55930
56195
  var get13 = /* @__PURE__ */ make43("contactsGet");
55931
56196
  var listEvents = /* @__PURE__ */ forGroup(ContactEventsGroup)("contactEventsListEvents");
55932
56197
 
56198
+ // src/lib/namespace.ts
56199
+ var namespaceFlag = (what) => String9("namespace").pipe(withSchema2(NamespaceId), withDescription2(what === "list" ? "Only resources in this namespace (ns_...)" : "Place the resource in this namespace (ns_...); omit for organization level"), optional4);
56200
+ var namespaceField = (namespace) => match(namespace, {
56201
+ onNone: () => ({}),
56202
+ onSome: (namespaceId) => ({ namespaceId })
56203
+ });
56204
+ var placedAsRequested = (namespace, existing) => isNone2(namespace) || existing === namespace.value;
56205
+ var placementLabel = (namespaceId) => namespaceId === null ? "organization level" : `namespace ${namespaceId}`;
56206
+
55933
56207
  // src/commands/contacts.ts
55934
56208
  var optionalString = (name, description) => String9(name).pipe(withDescription2(description), optional4);
55935
56209
  var list8 = make29("list", {
@@ -55942,6 +56216,7 @@ var list8 = make29("list", {
55942
56216
  limit: Int5("limit").pipe(withDescription2("Maximum contacts per page"), optional4),
55943
56217
  after: optionalString("after", "Only contacts created after this ISO 8601 instant"),
55944
56218
  before: optionalString("before", "Only contacts created before this ISO 8601 instant"),
56219
+ namespace: namespaceFlag("list"),
55945
56220
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
55946
56221
  json: jsonFlag
55947
56222
  }).pipe(withDescription3("List and search contacts with optional custom-field projection and filtering"), withExamples([
@@ -55959,6 +56234,7 @@ var list8 = make29("list", {
55959
56234
  limit,
55960
56235
  after,
55961
56236
  before,
56237
+ namespace,
55962
56238
  all,
55963
56239
  json
55964
56240
  }) => gen2(function* () {
@@ -55989,7 +56265,8 @@ var list8 = make29("list", {
55989
56265
  customFieldValue: getOrUndefined(customFieldValue),
55990
56266
  limit: getOrUndefined(limit)?.toString(),
55991
56267
  after: getOrUndefined(after),
55992
- before: getOrUndefined(before)
56268
+ before: getOrUndefined(before),
56269
+ ...namespaceField(namespace)
55993
56270
  };
55994
56271
  const listPage = (pageCursor) => list7({ ...query, cursor: pageCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list contacts", error, { cursor: pageCursor ?? null })));
55995
56272
  let nextCursor = getOrUndefined(cursor);
@@ -56014,6 +56291,7 @@ var list8 = make29("list", {
56014
56291
  ["Last active", contact.lastActiveAt],
56015
56292
  ["Created", contact.createdAt],
56016
56293
  ["Status", contact.status],
56294
+ ["Namespace", contact.namespaceId ?? "organization"],
56017
56295
  ["Tags", contact.tags.join(", ")],
56018
56296
  [
56019
56297
  "Custom fields",
@@ -56044,6 +56322,7 @@ var get14 = make29("get", {
56044
56322
  ["Display name", contact.displayName],
56045
56323
  ["Avatar", contact.avatar],
56046
56324
  ["Status", contact.status],
56325
+ ["Namespace", contact.namespaceId ?? "organization"],
56047
56326
  ["Reason", contact.statusReason],
56048
56327
  ["External ID", contact.externalId],
56049
56328
  ["Identities", JSON.stringify(contact.identities)],
@@ -56418,6 +56697,7 @@ var EmailDomainPage = /* @__PURE__ */ Struct({
56418
56697
  ]),
56419
56698
  dkimSelector: optionalKey2(Union2([String4, Null2])),
56420
56699
  dkimPublicKey: optionalKey2(Union2([String4, Null2])),
56700
+ namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the domain belongs to, or null at organization level. Only that namespace's keys and organization-wide callers reach it." }),
56421
56701
  isDefault: Boolean3,
56422
56702
  deliverability: DeliverabilityFacts,
56423
56703
  series: SendsSeries,
@@ -56459,6 +56739,7 @@ var EmailDomainDetailed = /* @__PURE__ */ Struct({
56459
56739
  priority: optionalKey2(Union2([Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })), Null2]))
56460
56740
  })),
56461
56741
  verifiedAt: Union2([String4, Null2]),
56742
+ namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the domain belongs to, or null at organization level. Only that namespace's keys and organization-wide callers reach it." }),
56462
56743
  isDefault: Boolean3,
56463
56744
  deliverability: DeliverabilityFacts,
56464
56745
  createdAt: String4,
@@ -56651,6 +56932,7 @@ var EmailSenderPage = /* @__PURE__ */ Struct({
56651
56932
  email: String4,
56652
56933
  name: Union2([String4, Null2]),
56653
56934
  domainId: Union2([EmailDomainId2, Null2]),
56935
+ namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the sender belongs to, or null at organization level. A sender on a domain takes the domain's namespace." }),
56654
56936
  verificationStatus: Union2([
56655
56937
  Literal2("pending"),
56656
56938
  Literal2("verified"),
@@ -57069,7 +57351,8 @@ var EmailGetCatchAllStats504 = GatewayTimeoutError2;
57069
57351
  var EmailListDomainsQuery = /* @__PURE__ */ Struct({
57070
57352
  limit: optionalKey2(Union2([String4, Null2])),
57071
57353
  cursor: optionalKey2(Union2([Cursor, Null2])),
57072
- sendable: optionalKey2(Union2([Literal2("true"), Null2]))
57354
+ sendable: optionalKey2(Union2([Literal2("true"), Null2])),
57355
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57073
57356
  });
57074
57357
  var EmailListDomains200 = EmailDomainPage;
57075
57358
  var EmailListDomains401 = UnauthorizedError2;
@@ -57082,12 +57365,14 @@ var EmailAddDomainRequestJson = /* @__PURE__ */ Struct({
57082
57365
  connection: optionalKey2(Union2([Struct({
57083
57366
  connectionId: String4,
57084
57367
  zone: String4
57085
- }), Null2]))
57368
+ }), Null2])),
57369
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57086
57370
  });
57087
57371
  var EmailAddDomain201 = EmailDomainDetailed;
57088
57372
  var EmailAddDomain401 = UnauthorizedError2;
57089
57373
  var EmailAddDomain402 = PaymentRequiredError2;
57090
57374
  var EmailAddDomain403 = ForbiddenError2;
57375
+ var EmailAddDomain404 = ResourceNotFoundError2;
57091
57376
  var EmailAddDomain409 = ConflictError2;
57092
57377
  var EmailAddDomain422 = ValidationError2;
57093
57378
  var EmailAddDomain429 = RateLimitedError2;
@@ -57139,6 +57424,7 @@ var EmailGetCustomTrackingPathParams = /* @__PURE__ */ Struct({ id: EmailDomainI
57139
57424
  var EmailGetCustomTracking200 = CustomTrackingStatus;
57140
57425
  var EmailGetCustomTracking401 = UnauthorizedError2;
57141
57426
  var EmailGetCustomTracking403 = ForbiddenError2;
57427
+ var EmailGetCustomTracking404 = ResourceNotFoundError2;
57142
57428
  var EmailGetCustomTracking422 = ValidationError2;
57143
57429
  var EmailGetCustomTracking500 = InternalError2;
57144
57430
  var EmailGetCustomTracking504 = GatewayTimeoutError2;
@@ -57147,6 +57433,7 @@ var EmailEnableCustomTrackingRequestJson = /* @__PURE__ */ Struct({ label: optio
57147
57433
  var EmailEnableCustomTracking200 = CustomTrackingStatus;
57148
57434
  var EmailEnableCustomTracking401 = UnauthorizedError2;
57149
57435
  var EmailEnableCustomTracking403 = ForbiddenError2;
57436
+ var EmailEnableCustomTracking404 = ResourceNotFoundError2;
57150
57437
  var EmailEnableCustomTracking409 = ConflictError2;
57151
57438
  var EmailEnableCustomTracking422 = ValidationError2;
57152
57439
  var EmailEnableCustomTracking500 = InternalError2;
@@ -57156,6 +57443,7 @@ var EmailDisableCustomTrackingPathParams = /* @__PURE__ */ Struct({ id: EmailDom
57156
57443
  var EmailDisableCustomTracking200 = SuccessResult;
57157
57444
  var EmailDisableCustomTracking401 = UnauthorizedError2;
57158
57445
  var EmailDisableCustomTracking403 = ForbiddenError2;
57446
+ var EmailDisableCustomTracking404 = ResourceNotFoundError2;
57159
57447
  var EmailDisableCustomTracking409 = ConflictError2;
57160
57448
  var EmailDisableCustomTracking422 = ValidationError2;
57161
57449
  var EmailDisableCustomTracking500 = InternalError2;
@@ -57188,6 +57476,7 @@ var EmailCompleteCustomTrackingDomainConnectRequestJson = /* @__PURE__ */ Struct
57188
57476
  var EmailCompleteCustomTrackingDomainConnect200 = CustomTrackingDomainConnectCompleteResult;
57189
57477
  var EmailCompleteCustomTrackingDomainConnect401 = UnauthorizedError2;
57190
57478
  var EmailCompleteCustomTrackingDomainConnect403 = ForbiddenError2;
57479
+ var EmailCompleteCustomTrackingDomainConnect404 = ResourceNotFoundError2;
57191
57480
  var EmailCompleteCustomTrackingDomainConnect422 = ValidationError2;
57192
57481
  var EmailCompleteCustomTrackingDomainConnect500 = InternalError2;
57193
57482
  var EmailCompleteCustomTrackingDomainConnect504 = GatewayTimeoutError2;
@@ -57297,6 +57586,7 @@ var EmailDetectRegistrar200 = /* @__PURE__ */ Struct({
57297
57586
  });
57298
57587
  var EmailDetectRegistrar401 = UnauthorizedError2;
57299
57588
  var EmailDetectRegistrar403 = ForbiddenError2;
57589
+ var EmailDetectRegistrar404 = ResourceNotFoundError2;
57300
57590
  var EmailDetectRegistrar422 = ValidationError2;
57301
57591
  var EmailDetectRegistrar500 = InternalError2;
57302
57592
  var EmailDetectRegistrar504 = GatewayTimeoutError2;
@@ -57540,7 +57830,8 @@ var EmailListSendersQuery = /* @__PURE__ */ Struct({
57540
57830
  Literal2("failed")
57541
57831
  ]), Null2])),
57542
57832
  isActive: optionalKey2(Union2([String4, Null2])),
57543
- isDefault: optionalKey2(Union2([String4, Null2]))
57833
+ isDefault: optionalKey2(Union2([String4, Null2])),
57834
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57544
57835
  });
57545
57836
  var EmailListSenders200 = EmailSenderPage;
57546
57837
  var EmailListSenders401 = UnauthorizedError2;
@@ -57553,7 +57844,8 @@ var EmailAddSenderRequestJson = /* @__PURE__ */ Struct({
57553
57844
  email: String4,
57554
57845
  domainId: optionalKey2(Union2([EmailDomainId2, Null2])),
57555
57846
  name: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
57556
- replyToEmails: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2]))
57847
+ replyToEmails: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2])),
57848
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57557
57849
  });
57558
57850
  var EmailAddSender201 = /* @__PURE__ */ Struct({
57559
57851
  id: EmailSenderId2,
@@ -57587,6 +57879,7 @@ var EmailGetSender200 = /* @__PURE__ */ Struct({
57587
57879
  email: String4,
57588
57880
  name: Union2([String4, Null2]),
57589
57881
  domainId: Union2([EmailDomainId2, Null2]),
57882
+ namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the sender belongs to, or null at organization level. A sender on a domain takes the domain's namespace." }),
57590
57883
  verificationStatus: Union2([
57591
57884
  Literal2("pending"),
57592
57885
  Literal2("verified"),
@@ -57842,13 +58135,14 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57842
58135
  EmailListDomains500,
57843
58136
  EmailListDomains504.pipe(status(504))
57844
58137
  ]
57845
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listDomains").annotate(Summary, "List sending domains").annotate(Description, "Returns the organization's sending domains, newest first. Pass `nextCursor` back as `cursor` for the next page; it is null on the last page. `sendable=true` lists only domains a send can use now: active, and verified, or verified before and degraded since. Each row carries `deliverability` (bounce and complaint rates over the last 24 hours, the window the 5% bounce limit is enforced over) and `series`, the last 14 days of daily email sends attributed to the domain, oldest first."), post("emailAddDomain", "/v1/email/domains", {
58138
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listDomains").annotate(Summary, "List sending domains").annotate(Description, "Returns the organization's sending domains, newest first. A namespace-scoped key lists only its namespace's domains; an organization-wide caller lists every domain, or one namespace's with `namespaceId`. Pass `nextCursor` back as `cursor` for the next page; it is null on the last page. `sendable=true` lists only domains a send can use now: active, and verified, or verified before and degraded since. Each row carries `deliverability` (bounce and complaint rates over the last 24 hours, the window the 5% bounce limit is enforced over) and `series`, the last 14 days of daily email sends attributed to the domain, oldest first."), post("emailAddDomain", "/v1/email/domains", {
57846
58139
  payload: EmailAddDomainRequestJson,
57847
58140
  success: EmailAddDomain201.pipe(status(201)),
57848
58141
  error: [
57849
58142
  EmailAddDomain401.pipe(status(401)),
57850
58143
  EmailAddDomain402.pipe(status(402)),
57851
58144
  EmailAddDomain403.pipe(status(403)),
58145
+ EmailAddDomain404.pipe(status(404)),
57852
58146
  EmailAddDomain409.pipe(status(409)),
57853
58147
  EmailAddDomain422.pipe(status(422)),
57854
58148
  EmailAddDomain429.pipe(status(429)),
@@ -57856,7 +58150,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57856
58150
  EmailAddDomain502.pipe(status(502)),
57857
58151
  EmailAddDomain504.pipe(status(504))
57858
58152
  ]
57859
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.addDomain").annotate(Summary, "Add a sending domain").annotate(Description, "Registers a domain for sending and returns it with the DNS records required to verify ownership and configure DKIM. Responds with 201. Supplying a connection attaches the domain to that DNS account; the domain must sit inside the zone given with it. When Samva cannot register another sending domain right now, this responds with 429 and no domain is created. A banned organization is refused with 403."), get5("emailGetDomainById", "/v1/email/domains/:id", {
58153
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.addDomain").annotate(Summary, "Add a sending domain").annotate(Description, "Registers a domain for sending and returns it with the DNS records required to verify ownership and configure DKIM. Responds with 201. Supplying a connection attaches the domain to that DNS account; the domain must sit inside the zone given with it. When Samva cannot register another sending domain right now, this responds with 429 and no domain is created. A banned organization is refused with 403. `namespaceId` places the domain in a namespace, and only that namespace's keys and organization-wide callers reach it; a namespace-scoped key always adds to its own namespace."), get5("emailGetDomainById", "/v1/email/domains/:id", {
57860
58154
  params: EmailGetDomainByIdPathParams,
57861
58155
  success: EmailGetDomainById200,
57862
58156
  error: [
@@ -57897,6 +58191,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57897
58191
  error: [
57898
58192
  EmailGetCustomTracking401.pipe(status(401)),
57899
58193
  EmailGetCustomTracking403.pipe(status(403)),
58194
+ EmailGetCustomTracking404.pipe(status(404)),
57900
58195
  EmailGetCustomTracking422.pipe(status(422)),
57901
58196
  EmailGetCustomTracking500,
57902
58197
  EmailGetCustomTracking504.pipe(status(504))
@@ -57908,6 +58203,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57908
58203
  error: [
57909
58204
  EmailEnableCustomTracking401.pipe(status(401)),
57910
58205
  EmailEnableCustomTracking403.pipe(status(403)),
58206
+ EmailEnableCustomTracking404.pipe(status(404)),
57911
58207
  EmailEnableCustomTracking409.pipe(status(409)),
57912
58208
  EmailEnableCustomTracking422.pipe(status(422)),
57913
58209
  EmailEnableCustomTracking500,
@@ -57920,6 +58216,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57920
58216
  error: [
57921
58217
  EmailDisableCustomTracking401.pipe(status(401)),
57922
58218
  EmailDisableCustomTracking403.pipe(status(403)),
58219
+ EmailDisableCustomTracking404.pipe(status(404)),
57923
58220
  EmailDisableCustomTracking409.pipe(status(409)),
57924
58221
  EmailDisableCustomTracking422.pipe(status(422)),
57925
58222
  EmailDisableCustomTracking500,
@@ -57957,6 +58254,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57957
58254
  error: [
57958
58255
  EmailCompleteCustomTrackingDomainConnect401.pipe(status(401)),
57959
58256
  EmailCompleteCustomTrackingDomainConnect403.pipe(status(403)),
58257
+ EmailCompleteCustomTrackingDomainConnect404.pipe(status(404)),
57960
58258
  EmailCompleteCustomTrackingDomainConnect422.pipe(status(422)),
57961
58259
  EmailCompleteCustomTrackingDomainConnect500,
57962
58260
  EmailCompleteCustomTrackingDomainConnect504.pipe(status(504))
@@ -58079,6 +58377,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58079
58377
  error: [
58080
58378
  EmailDetectRegistrar401.pipe(status(401)),
58081
58379
  EmailDetectRegistrar403.pipe(status(403)),
58380
+ EmailDetectRegistrar404.pipe(status(404)),
58082
58381
  EmailDetectRegistrar422.pipe(status(422)),
58083
58382
  EmailDetectRegistrar500,
58084
58383
  EmailDetectRegistrar504.pipe(status(504))
@@ -58306,7 +58605,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58306
58605
  EmailListSenders500,
58307
58606
  EmailListSenders504.pipe(status(504))
58308
58607
  ]
58309
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listSenders").annotate(Summary, "List senders").annotate(Description, "Returns senders, newest first, optionally filtered by verification status, active state, or default flag. Pass `nextCursor` back as `cursor` for the next page; it is null on the last page. Each row carries `deliverability` (bounce and complaint rates over the last 24 hours) and `series`, the last 14 days of daily email sends from the address, oldest first."), post("emailAddSender", "/v1/email/senders", {
58608
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listSenders").annotate(Summary, "List senders").annotate(Description, "Returns senders, newest first. A namespace-scoped key lists only its namespace's senders; an organization-wide caller lists every sender, or one namespace's with `namespaceId`. Optionally filtered by verification status, active state, or default flag. Pass `nextCursor` back as `cursor` for the next page; it is null on the last page. Each row carries `deliverability` (bounce and complaint rates over the last 24 hours) and `series`, the last 14 days of daily email sends from the address, oldest first."), post("emailAddSender", "/v1/email/senders", {
58310
58609
  headers: EmailAddSenderHeaders,
58311
58610
  payload: EmailAddSenderRequestJson,
58312
58611
  success: EmailAddSender201.pipe(status(201)),
@@ -58320,7 +58619,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58320
58619
  EmailAddSender502.pipe(status(502)),
58321
58620
  EmailAddSender504.pipe(status(504))
58322
58621
  ]
58323
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.addSender").annotate(Summary, "Add a sender").annotate(Description, "Creates a sender. The required Idempotency-Key replays the original sender for an identical request and conflicts when reused with different input."), get5("emailGetSender", "/v1/email/senders/:id", {
58622
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.addSender").annotate(Summary, "Add a sender").annotate(Description, "Creates a sender. A sender on a domain takes the domain's namespace, and a `namespaceId` that names another namespace is refused; a sender with no domain joins `namespaceId`, or its key's namespace. A namespace-scoped key cannot add a sender on a domain outside its namespace. The required Idempotency-Key replays the original sender for an identical request and conflicts when reused with different input."), get5("emailGetSender", "/v1/email/senders/:id", {
58324
58623
  params: EmailGetSenderPathParams,
58325
58624
  success: EmailGetSender200,
58326
58625
  error: [
@@ -58353,7 +58652,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58353
58652
  EmailSetDefaultSender500,
58354
58653
  EmailSetDefaultSender504.pipe(status(504))
58355
58654
  ]
58356
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.setDefaultSender").annotate(Summary, "Set the organization default sender").annotate(Description, "Marks a verified, active sender as the organization default, atomically clearing any previous default. Omitted-`from` sends use it when neither the request nor the template names a `from`; with no default, the organization's sole verified sender is used."), get5("emailCheckSenderVerification", "/v1/email/senders/:id/verification", {
58655
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.setDefaultSender").annotate(Summary, "Set the default sender").annotate(Description, "Marks a verified, active sender as the default of its scope, atomically clearing the previous default of the same scope: the organization level, or the sender's namespace. Omitted-`from` sends use it when neither the request nor the template names a `from`; with no default, the organization's sole verified sender is used."), get5("emailCheckSenderVerification", "/v1/email/senders/:id/verification", {
58357
58656
  params: EmailCheckSenderVerificationPathParams,
58358
58657
  success: EmailCheckSenderVerification200,
58359
58658
  error: [
@@ -58969,6 +59268,7 @@ var MessagesListQuery = /* @__PURE__ */ Struct({
58969
59268
  conversationId: optionalKey2(Union2([ConversationId2, Null2])),
58970
59269
  contactId: optionalKey2(Union2([ContactId2, Null2])),
58971
59270
  from: optionalKey2(Union2([String4, Null2])),
59271
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Only this namespace's messages. A key scoped to a namespace always lists its own." })),
58972
59272
  after: optionalKey2(Union2([String4, Null2])),
58973
59273
  before: optionalKey2(Union2([String4, Null2]))
58974
59274
  });
@@ -59806,12 +60106,13 @@ ${payload.limitations}`);
59806
60106
  var list9 = make29("list", {
59807
60107
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
59808
60108
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
60109
+ namespace: namespaceFlag("list"),
59809
60110
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
59810
60111
  json: jsonFlag
59811
60112
  }).pipe(withDescription3("List email sending domains"), withExamples([
59812
60113
  { command: "samva email domains list" },
59813
60114
  { command: "samva email domains list --json" }
59814
- ]), withHandler(({ cursor, limit, all, json }) => gen2(function* () {
60115
+ ]), withHandler(({ cursor, limit, namespace, all, json }) => gen2(function* () {
59815
60116
  if (all && !isJsonLinesRequested())
59816
60117
  return yield* new CliUsageError({
59817
60118
  code: "all_requires_jsonl",
@@ -59820,7 +60121,11 @@ var list9 = make29("list", {
59820
60121
  const client = yield* getClientProvider;
59821
60122
  const cursorValue = getOrUndefined(cursor);
59822
60123
  const limitValue = getOrUndefined(limit);
59823
- const query = { cursor: cursorValue, limit: limitValue?.toString() };
60124
+ const query = {
60125
+ cursor: cursorValue,
60126
+ limit: limitValue?.toString(),
60127
+ ...namespaceField(namespace)
60128
+ };
59824
60129
  if (all) {
59825
60130
  let nextCursor = cursorValue;
59826
60131
  for (;; ) {
@@ -59848,6 +60153,7 @@ var list9 = make29("list", {
59848
60153
  ["Domain", domain.domain],
59849
60154
  ["Phase", domain.phase],
59850
60155
  ["Default", domain.isDefault ? "yes" : "no"],
60156
+ ["Namespace", domain.namespaceId ?? "organization"],
59851
60157
  ["ID", domain.id]
59852
60158
  ]);
59853
60159
  yield* log("");
@@ -59857,6 +60163,7 @@ var list9 = make29("list", {
59857
60163
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
59858
60164
  var add2 = make29("add", {
59859
60165
  domain: String9("domain").pipe(withDescription2("Domain to add, e.g. example.com")),
60166
+ namespace: namespaceFlag("create"),
59860
60167
  dryRun: Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false)),
59861
60168
  json: jsonFlag
59862
60169
  }).pipe(withDescription3("Add an email sending domain"), withExamples([
@@ -59867,15 +60174,24 @@ var add2 = make29("add", {
59867
60174
  {
59868
60175
  command: "samva email domains add --domain example.com",
59869
60176
  description: "Apply domain add"
60177
+ },
60178
+ {
60179
+ command: "samva email domains add --domain customer.example --namespace ns_7q2xk9mvt4znw8rh",
60180
+ description: "Add the domain to a namespace"
59870
60181
  }
59871
- ]), withHandler(({ domain, dryRun, json }) => gen2(function* () {
60182
+ ]), withHandler(({ domain, namespace, dryRun, json }) => gen2(function* () {
59872
60183
  if (dryRun) {
59873
60184
  if (json)
59874
- return yield* printJson({ dryRun: true, action: "email.domains.add", domain });
60185
+ return yield* printJson({
60186
+ dryRun: true,
60187
+ action: "email.domains.add",
60188
+ domain,
60189
+ ...namespaceField(namespace)
60190
+ });
59875
60191
  return yield* log(`[dry-run] Would add domain "${domain}".`);
59876
60192
  }
59877
60193
  const client = yield* getClientProvider;
59878
- yield* matchEffect3(addDomain({ domain }).pipe(client.provide), {
60194
+ yield* matchEffect3(addDomain({ domain, ...namespaceField(namespace) }).pipe(client.provide), {
59879
60195
  onFailure: (error) => {
59880
60196
  const conflict = getConflictError(error);
59881
60197
  if (!conflict) {
@@ -59901,6 +60217,8 @@ var add2 = make29("add", {
59901
60217
  });
59902
60218
  return gen2(function* () {
59903
60219
  const existing = yield* findExisting;
60220
+ if (!placedAsRequested(namespace, existing.namespaceId))
60221
+ return yield* toCliApiError(`Domain "${existing.domain}" already exists at ${placementLabel(existing.namespaceId)}; move it with \`samva namespaces assign\``, error);
59904
60222
  if (json)
59905
60223
  yield* printJson({ ...existing, idempotent: true });
59906
60224
  else
@@ -60414,7 +60732,7 @@ var waitingLine = (message) => {
60414
60732
  const reason = message.waitReason.replaceAll("-", " ");
60415
60733
  return message.reviewExpectedAt === null ? reason : `${reason} (expected by ${message.reviewExpectedAt})`;
60416
60734
  };
60417
- var skippedRecipientsLine = (message) => message.skippedRecipients.length === 0 ? null : message.skippedRecipients.map((recipient) => `${recipient.address} (${recipient.reason}${recipient.unsubscribeGroupId === undefined ? "" : `, group ${recipient.unsubscribeGroupId}`})`).join("; ");
60735
+ var skippedRecipientsLine = (message) => message.skippedRecipients.length === 0 ? null : message.skippedRecipients.map((recipient) => `${recipient.address} (${recipient.reason}${recipient.unsubscribeGroupId == null ? "" : `, group ${recipient.unsubscribeGroupId}`})`).join("; ");
60418
60736
  var printMessage = (message) => printFields([
60419
60737
  ["Message ID", message.id],
60420
60738
  ["Channel", message.channel],
@@ -60985,12 +61303,13 @@ ${truncateForDisplay(JSON.stringify(request.templateData, null, 2))}`);
60985
61303
  var list12 = make29("list", {
60986
61304
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
60987
61305
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
61306
+ namespace: namespaceFlag("list"),
60988
61307
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
60989
61308
  json: jsonFlag
60990
61309
  }).pipe(withDescription3("List verified sender addresses"), withExamples([
60991
61310
  { command: "samva email senders list" },
60992
61311
  { command: "samva email senders list --json" }
60993
- ]), withHandler(({ cursor, limit, all, json }) => gen2(function* () {
61312
+ ]), withHandler(({ cursor, limit, namespace, all, json }) => gen2(function* () {
60994
61313
  if (all && !isJsonLinesRequested())
60995
61314
  return yield* new CliUsageError({
60996
61315
  code: "all_requires_jsonl",
@@ -60999,7 +61318,11 @@ var list12 = make29("list", {
60999
61318
  const client = yield* getClientProvider;
61000
61319
  const cursorValue = getOrUndefined(cursor);
61001
61320
  const limitValue = getOrUndefined(limit);
61002
- const query = { cursor: cursorValue, limit: limitValue?.toString() };
61321
+ const query = {
61322
+ cursor: cursorValue,
61323
+ limit: limitValue?.toString(),
61324
+ ...namespaceField(namespace)
61325
+ };
61003
61326
  if (all) {
61004
61327
  let nextCursor = cursorValue;
61005
61328
  for (;; ) {
@@ -61029,6 +61352,7 @@ var list12 = make29("list", {
61029
61352
  ["Status", sender.verificationStatus],
61030
61353
  ["Provider", sender.providerLifecycle],
61031
61354
  ["Default", sender.isDefault ? "yes" : "no"],
61355
+ ["Namespace", sender.namespaceId ?? "organization"],
61032
61356
  ["ID", sender.id]
61033
61357
  ]);
61034
61358
  yield* log("");
@@ -61039,6 +61363,7 @@ var list12 = make29("list", {
61039
61363
  var add3 = make29("add", {
61040
61364
  email: String9("email").pipe(withDescription2("Sender email address")),
61041
61365
  name: String9("name").pipe(withDescription2("Display name for the sender"), optional4),
61366
+ namespace: namespaceFlag("create"),
61042
61367
  dryRun: Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false)),
61043
61368
  json: jsonFlag
61044
61369
  }).pipe(withDescription3("Add a sender address"), withExamples([
@@ -61050,7 +61375,7 @@ var add3 = make29("add", {
61050
61375
  command: "samva email senders add --email hello@example.com",
61051
61376
  description: "Apply sender add"
61052
61377
  }
61053
- ]), withHandler(({ email, name, dryRun, json }) => gen2(function* () {
61378
+ ]), withHandler(({ email, name, namespace, dryRun, json }) => gen2(function* () {
61054
61379
  const nameValue = getOrUndefined(name);
61055
61380
  if (dryRun) {
61056
61381
  if (json)
@@ -61058,14 +61383,16 @@ var add3 = make29("add", {
61058
61383
  dryRun: true,
61059
61384
  action: "email.senders.add",
61060
61385
  email,
61061
- name: nameValue
61386
+ name: nameValue,
61387
+ ...namespaceField(namespace)
61062
61388
  });
61063
61389
  return yield* log(`[dry-run] Would add sender "${email}".`);
61064
61390
  }
61065
61391
  const client = yield* getClientProvider;
61066
61392
  yield* matchEffect3(addSender({
61067
61393
  email,
61068
- ...nameValue === undefined ? {} : { name: nameValue }
61394
+ ...nameValue === undefined ? {} : { name: nameValue },
61395
+ ...namespaceField(namespace)
61069
61396
  }).pipe(client.provide), {
61070
61397
  onFailure: (error) => {
61071
61398
  const conflict = getConflictError(error);
@@ -61078,6 +61405,8 @@ var add3 = make29("add", {
61078
61405
  const listed = yield* listSenders({ cursor, limit: "100" }).pipe(client.provide, mapError2((listError) => toCliApiError("Sender may already exist but could not verify idempotently", listError)));
61079
61406
  const existing = (conflict.id ? listed.items.find((item) => item.id === conflict.id) : undefined) ?? listed.items.find((item) => item.email === email);
61080
61407
  if (existing) {
61408
+ if (!placedAsRequested(namespace, existing.namespaceId))
61409
+ return yield* toCliApiError(`Sender "${existing.email}" already exists at ${placementLabel(existing.namespaceId)}; move its domain, or the sender, with \`samva namespaces assign\``, error);
61081
61410
  if (json)
61082
61411
  yield* printJson({ ...existing, idempotent: true });
61083
61412
  else {
@@ -61319,7 +61648,7 @@ var BatchEventsResult = /* @__PURE__ */ Struct({
61319
61648
  var EventsCreateRequestJson = /* @__PURE__ */ Struct({
61320
61649
  contact: ContactEventReference,
61321
61650
  name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!(?:[Cc][Oo][Nn][Tt][Aa][Cc][Tt]|[Ss][Aa][Mm][Vv][Aa])\\.)[A-Za-z][A-Za-z0-9_.-]*$")).annotate({ expected: "a string matching the RegExp ^(?!(?:[Cc][Oo][Nn][Tt][Aa][Cc][Tt]|[Ss][Aa][Mm][Vv][Aa])\\.)[A-Za-z][A-Za-z0-9_.-]*$" })),
61322
- properties: optionalKey2(Union2([JsonObject, Null2])),
61651
+ properties: optionalKey2(Union2([JsonObject2, Null2])),
61323
61652
  occurredAt: optionalKey2(Union2([String4, Null2])),
61324
61653
  idempotencyKey: optionalKey2(Union2([String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" })), Null2]))
61325
61654
  });
@@ -62135,6 +62464,7 @@ Bun.serve({ fetch: createWebhookHandler(extension, { apiKey, webhookSecret }) })
62135
62464
  });
62136
62465
  // src/lib/mailbox-errors.ts
62137
62466
  var undecodedStatus = (error) => isHttpClientError(error) ? error.response?.status : undefined;
62467
+ var isUnreadable404 = (error) => error instanceof SamvaCliError && error.message.includes("HTTP 404, unreadable body");
62138
62468
  var GATED_NEXT = "Mailboxes are not enabled for this organization (the `mailbox` launch flag is off). Mailbox commands work once it is enabled.";
62139
62469
  var personOnlyNext = (action) => {
62140
62470
  switch (action) {
@@ -62159,12 +62489,21 @@ var personOnlyNext = (action) => {
62159
62489
  }
62160
62490
  };
62161
62491
  var mailboxApiError = (prefix, error, options = {}) => {
62162
- if (undecodedStatus(error) === 404)
62492
+ if (undecodedStatus(error) === 404 || isUnreadable404(error))
62163
62493
  return new SamvaCliError({
62164
62494
  message: `${prefix}: mailboxes are not enabled for this organization.`,
62165
62495
  api: { reason: "FlagDisabledError", status: 404, details: {}, next: GATED_NEXT }
62166
62496
  });
62167
62497
  const failure = toCliApiError(prefix, error);
62498
+ const flag = failure.api?.details.flag;
62499
+ if (failure.api?.reason === "FlagDisabledError" && (flag === "whatsapp" || flag === "sms"))
62500
+ return new SamvaCliError({
62501
+ message: failure.message,
62502
+ api: {
62503
+ ...failure.api,
62504
+ next: `${flag === "sms" ? "SMS" : "WhatsApp"} is not enabled for this organization. Mailboxes work on email until it is.`
62505
+ }
62506
+ });
62168
62507
  if (options.personOnly !== undefined && failure.api?.reason === "ForbiddenError")
62169
62508
  return new SamvaCliError({
62170
62509
  message: failure.message,
@@ -64332,10 +64671,10 @@ var MailboxesCreateRequestJson = /* @__PURE__ */ Struct({
64332
64671
  var MailboxesCreate201 = Mailbox2;
64333
64672
  var MailboxesCreate401 = UnauthorizedError2;
64334
64673
  var MailboxesCreate402 = PaymentRequiredError2;
64335
- var MailboxesCreate403 = ForbiddenError2;
64674
+ var MailboxesCreate403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
64336
64675
  var MailboxesCreate404 = ResourceNotFoundError2;
64337
64676
  var MailboxesCreate409 = ConflictError2;
64338
- var MailboxesCreate422 = /* @__PURE__ */ Union2([ValidationError2, MailboxChannelUnsupportedError2]);
64677
+ var MailboxesCreate422 = ValidationError2;
64339
64678
  var MailboxesCreate500 = InternalError2;
64340
64679
  var MailboxesCreate502 = BillingProviderError;
64341
64680
  var MailboxesCreate504 = GatewayTimeoutError2;
@@ -64419,13 +64758,14 @@ var MailboxesApproveAction202 = MailboxPendingAction;
64419
64758
  var MailboxesApproveAction401 = UnauthorizedError2;
64420
64759
  var MailboxesApproveAction402 = PaymentRequiredError2;
64421
64760
  var MailboxesApproveAction403 = /* @__PURE__ */ Union2([
64761
+ FlagDisabledError,
64422
64762
  MailboxSendRefusedError2,
64423
64763
  OnboardingReviewRequiredError2,
64424
64764
  ForbiddenError2
64425
64765
  ]);
64426
64766
  var MailboxesApproveAction404 = ResourceNotFoundError2;
64427
64767
  var MailboxesApproveAction409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64428
- var MailboxesApproveAction422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64768
+ var MailboxesApproveAction422 = ValidationError2;
64429
64769
  var MailboxesApproveAction429 = RateLimitedError2;
64430
64770
  var MailboxesApproveAction500 = InternalError2;
64431
64771
  var MailboxesApproveAction502 = BillingProviderError;
@@ -64440,13 +64780,14 @@ var MailboxesCancelAction202 = MailboxPendingSendReceipt;
64440
64780
  var MailboxesCancelAction401 = UnauthorizedError2;
64441
64781
  var MailboxesCancelAction402 = PaymentRequiredError2;
64442
64782
  var MailboxesCancelAction403 = /* @__PURE__ */ Union2([
64783
+ FlagDisabledError,
64443
64784
  MailboxSendRefusedError2,
64444
64785
  OnboardingReviewRequiredError2,
64445
64786
  ForbiddenError2
64446
64787
  ]);
64447
64788
  var MailboxesCancelAction404 = ResourceNotFoundError2;
64448
64789
  var MailboxesCancelAction409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64449
- var MailboxesCancelAction422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64790
+ var MailboxesCancelAction422 = ValidationError2;
64450
64791
  var MailboxesCancelAction429 = RateLimitedError2;
64451
64792
  var MailboxesCancelAction500 = InternalError2;
64452
64793
  var MailboxesCancelAction502 = BillingProviderError;
@@ -64474,13 +64815,14 @@ var MailboxesRetryAction202 = MailboxPendingSendReceipt;
64474
64815
  var MailboxesRetryAction401 = UnauthorizedError2;
64475
64816
  var MailboxesRetryAction402 = PaymentRequiredError2;
64476
64817
  var MailboxesRetryAction403 = /* @__PURE__ */ Union2([
64818
+ FlagDisabledError,
64477
64819
  MailboxSendRefusedError2,
64478
64820
  OnboardingReviewRequiredError2,
64479
64821
  ForbiddenError2
64480
64822
  ]);
64481
64823
  var MailboxesRetryAction404 = ResourceNotFoundError2;
64482
64824
  var MailboxesRetryAction409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64483
- var MailboxesRetryAction422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64825
+ var MailboxesRetryAction422 = ValidationError2;
64484
64826
  var MailboxesRetryAction429 = RateLimitedError2;
64485
64827
  var MailboxesRetryAction500 = InternalError2;
64486
64828
  var MailboxesRetryAction502 = BillingProviderError;
@@ -64529,7 +64871,7 @@ var MailboxesCreateDraft201 = MailboxDraft;
64529
64871
  var MailboxesCreateDraft401 = UnauthorizedError2;
64530
64872
  var MailboxesCreateDraft403 = ForbiddenError2;
64531
64873
  var MailboxesCreateDraft404 = ResourceNotFoundError2;
64532
- var MailboxesCreateDraft422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64874
+ var MailboxesCreateDraft422 = ValidationError2;
64533
64875
  var MailboxesCreateDraft500 = InternalError2;
64534
64876
  var MailboxesCreateDraft504 = GatewayTimeoutError2;
64535
64877
  var MailboxesGetDraftPathParams = /* @__PURE__ */ Struct({
@@ -64586,13 +64928,14 @@ var MailboxesSendDraft202 = MailboxPendingSendReceipt;
64586
64928
  var MailboxesSendDraft401 = UnauthorizedError2;
64587
64929
  var MailboxesSendDraft402 = PaymentRequiredError2;
64588
64930
  var MailboxesSendDraft403 = /* @__PURE__ */ Union2([
64931
+ FlagDisabledError,
64589
64932
  MailboxSendRefusedError2,
64590
64933
  OnboardingReviewRequiredError2,
64591
64934
  ForbiddenError2
64592
64935
  ]);
64593
64936
  var MailboxesSendDraft404 = ResourceNotFoundError2;
64594
64937
  var MailboxesSendDraft409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64595
- var MailboxesSendDraft422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64938
+ var MailboxesSendDraft422 = ValidationError2;
64596
64939
  var MailboxesSendDraft429 = RateLimitedError2;
64597
64940
  var MailboxesSendDraft500 = InternalError2;
64598
64941
  var MailboxesSendDraft502 = BillingProviderError;
@@ -64606,10 +64949,10 @@ var MailboxesCreateEndpointRequestJson = /* @__PURE__ */ Struct({
64606
64949
  });
64607
64950
  var MailboxesCreateEndpoint201 = Mailbox2;
64608
64951
  var MailboxesCreateEndpoint401 = UnauthorizedError2;
64609
- var MailboxesCreateEndpoint403 = ForbiddenError2;
64952
+ var MailboxesCreateEndpoint403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
64610
64953
  var MailboxesCreateEndpoint404 = ResourceNotFoundError2;
64611
64954
  var MailboxesCreateEndpoint409 = ConflictError2;
64612
- var MailboxesCreateEndpoint422 = /* @__PURE__ */ Union2([ValidationError2, MailboxChannelUnsupportedError2]);
64955
+ var MailboxesCreateEndpoint422 = ValidationError2;
64613
64956
  var MailboxesCreateEndpoint500 = InternalError2;
64614
64957
  var MailboxesCreateEndpoint504 = GatewayTimeoutError2;
64615
64958
  var MailboxesRemoveEndpointPathParams = /* @__PURE__ */ Struct({
@@ -64794,13 +65137,14 @@ var MailboxesSendMessage202 = MailboxPendingSendReceipt;
64794
65137
  var MailboxesSendMessage401 = UnauthorizedError2;
64795
65138
  var MailboxesSendMessage402 = PaymentRequiredError2;
64796
65139
  var MailboxesSendMessage403 = /* @__PURE__ */ Union2([
65140
+ FlagDisabledError,
64797
65141
  MailboxSendRefusedError2,
64798
65142
  OnboardingReviewRequiredError2,
64799
65143
  ForbiddenError2
64800
65144
  ]);
64801
65145
  var MailboxesSendMessage404 = ResourceNotFoundError2;
64802
65146
  var MailboxesSendMessage409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64803
- var MailboxesSendMessage422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65147
+ var MailboxesSendMessage422 = ValidationError2;
64804
65148
  var MailboxesSendMessage429 = RateLimitedError2;
64805
65149
  var MailboxesSendMessage500 = InternalError2;
64806
65150
  var MailboxesSendMessage502 = BillingProviderError;
@@ -64873,13 +65217,14 @@ var MailboxesForward202 = MailboxPendingSendReceipt;
64873
65217
  var MailboxesForward401 = UnauthorizedError2;
64874
65218
  var MailboxesForward402 = PaymentRequiredError2;
64875
65219
  var MailboxesForward403 = /* @__PURE__ */ Union2([
65220
+ FlagDisabledError,
64876
65221
  MailboxSendRefusedError2,
64877
65222
  OnboardingReviewRequiredError2,
64878
65223
  ForbiddenError2
64879
65224
  ]);
64880
65225
  var MailboxesForward404 = ResourceNotFoundError2;
64881
65226
  var MailboxesForward409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64882
- var MailboxesForward422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65227
+ var MailboxesForward422 = ValidationError2;
64883
65228
  var MailboxesForward429 = RateLimitedError2;
64884
65229
  var MailboxesForward500 = InternalError2;
64885
65230
  var MailboxesForward502 = BillingProviderError;
@@ -64926,13 +65271,14 @@ var MailboxesReply202 = MailboxPendingSendReceipt;
64926
65271
  var MailboxesReply401 = UnauthorizedError2;
64927
65272
  var MailboxesReply402 = PaymentRequiredError2;
64928
65273
  var MailboxesReply403 = /* @__PURE__ */ Union2([
65274
+ FlagDisabledError,
64929
65275
  MailboxSendRefusedError2,
64930
65276
  OnboardingReviewRequiredError2,
64931
65277
  ForbiddenError2
64932
65278
  ]);
64933
65279
  var MailboxesReply404 = ResourceNotFoundError2;
64934
65280
  var MailboxesReply409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64935
- var MailboxesReply422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65281
+ var MailboxesReply422 = ValidationError2;
64936
65282
  var MailboxesReply429 = RateLimitedError2;
64937
65283
  var MailboxesReply500 = InternalError2;
64938
65284
  var MailboxesReply502 = BillingProviderError;
@@ -64956,13 +65302,14 @@ var MailboxesReplyAll202 = MailboxPendingSendReceipt;
64956
65302
  var MailboxesReplyAll401 = UnauthorizedError2;
64957
65303
  var MailboxesReplyAll402 = PaymentRequiredError2;
64958
65304
  var MailboxesReplyAll403 = /* @__PURE__ */ Union2([
65305
+ FlagDisabledError,
64959
65306
  MailboxSendRefusedError2,
64960
65307
  OnboardingReviewRequiredError2,
64961
65308
  ForbiddenError2
64962
65309
  ]);
64963
65310
  var MailboxesReplyAll404 = ResourceNotFoundError2;
64964
65311
  var MailboxesReplyAll409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64965
- var MailboxesReplyAll422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65312
+ var MailboxesReplyAll422 = ValidationError2;
64966
65313
  var MailboxesReplyAll429 = RateLimitedError2;
64967
65314
  var MailboxesReplyAll500 = InternalError2;
64968
65315
  var MailboxesReplyAll502 = BillingProviderError;
@@ -65247,7 +65594,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65247
65594
  MailboxesCreate502.pipe(status(502)),
65248
65595
  MailboxesCreate504.pipe(status(504))
65249
65596
  ]
65250
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.create").annotate(Summary, "Create a mailbox").annotate(Description, "Creates a mailbox with one endpoint and returns it with status 201; the caller gets an admin grant on it. Email is the channel a mailbox endpoint uses today; another channel is refused (422). An email endpoint's address must be under the organization's Samva-hosted mail domain or a verified domain with receiving enabled, and the mailbox sends from it. The slug defaults to the address's local part. Pass `slug` when that is taken or not a valid slug. The mailbox receives mail from now on; mail that arrived earlier is not added to it. Conflicts if the address or slug is already in use. Returns 402 when the organization is at its plan's mailbox allowance or at its mailbox storage allowance; incoming mail is still received past the storage allowance."), get5("mailboxesGet", "/v1/mailboxes/:id", {
65597
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.create").annotate(Summary, "Create a mailbox").annotate(Description, "Creates a mailbox with one endpoint and returns it with status 201; the caller gets an admin grant on it. An email endpoint's address must be under the organization's Samva-hosted mail domain or a verified domain with receiving enabled, and the mailbox sends from it. A phone endpoint's address is a number the organization connected on that channel, in E.164 form. The slug defaults to the address's local part, or a phone number's digits. Pass `slug` when that is taken or not a valid slug. The mailbox receives mail from now on; mail that arrived earlier is not added to it. Conflicts if the address or slug is already in use. Returns 402 when the organization is at its plan's mailbox allowance or at its mailbox storage allowance; incoming mail is still received past the storage allowance."), get5("mailboxesGet", "/v1/mailboxes/:id", {
65251
65598
  params: MailboxesGetPathParams,
65252
65599
  success: MailboxesGet200,
65253
65600
  error: [
@@ -65402,7 +65749,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65402
65749
  MailboxesCreateDraft500,
65403
65750
  MailboxesCreateDraft504.pipe(status(504))
65404
65751
  ]
65405
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.createDraft").annotate(Summary, "Create a draft").annotate(Description, "Saves a draft of a new message, or of a reply when `inReplyToMessageId` names a message in the mailbox, and returns it with status 201. Email drafts are the kind a mailbox saves today; another channel is refused (422). Send it with `POST /v1/mailboxes/{id}/drafts/{draftId}/send`."), get5("mailboxesGetDraft", "/v1/mailboxes/:id/drafts/:draftId", {
65752
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.createDraft").annotate(Summary, "Create a draft").annotate(Description, "Saves a draft of a new message, or of a reply when `inReplyToMessageId` names a message in the mailbox, and returns it with status 201. A phone channel's draft holds a recipient number and text. Send it with `POST /v1/mailboxes/{id}/drafts/{draftId}/send`."), get5("mailboxesGetDraft", "/v1/mailboxes/:id/drafts/:draftId", {
65406
65753
  params: MailboxesGetDraftPathParams,
65407
65754
  success: MailboxesGetDraft200,
65408
65755
  error: [
@@ -65467,7 +65814,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65467
65814
  MailboxesCreateEndpoint500,
65468
65815
  MailboxesCreateEndpoint504.pipe(status(504))
65469
65816
  ]
65470
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.createEndpoint").annotate(Summary, "Add an endpoint to a mailbox").annotate(Description, "Adds an endpoint to a mailbox and returns the mailbox with status 201. It follows the same rules as the endpoint of a new mailbox: email is the channel a mailbox endpoint uses today (422 otherwise), the address must be under the organization's Samva-hosted mail domain or a verified domain with receiving enabled, and no mailbox may already hold it (409). Messages sent to it reach the mailbox from now on. It becomes the default on its channel only when the mailbox has no endpoint there yet."), del("mailboxesRemoveEndpoint", "/v1/mailboxes/:id/endpoints/:endpointId", {
65817
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.createEndpoint").annotate(Summary, "Add an endpoint to a mailbox").annotate(Description, "Adds an endpoint to a mailbox and returns the mailbox with status 201. It follows the same rules as the endpoint of a new mailbox: an email address must be under the organization's Samva-hosted mail domain or a verified domain with receiving enabled, a phone number must be one the organization connected on that channel, and no mailbox may already hold it (409). Messages sent to it reach the mailbox from now on. It becomes the default on its channel only when the mailbox has no endpoint there yet."), del("mailboxesRemoveEndpoint", "/v1/mailboxes/:id/endpoints/:endpointId", {
65471
65818
  params: MailboxesRemoveEndpointPathParams,
65472
65819
  success: MailboxesRemoveEndpoint200,
65473
65820
  error: [
@@ -65628,7 +65975,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65628
65975
  MailboxesSendMessage503.pipe(status(503)),
65629
65976
  MailboxesSendMessage504.pipe(status(504))
65630
65977
  ]
65631
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.sendMessage").annotate(Summary, "Send a new message").annotate(Description, "Starts a new conversation from the mailbox's default endpoint on the channel the body names (email when omitted); a channel the mailbox cannot send on yet is refused (422). Records a send action and returns 202 with its current receipt and a Location for action status. An installation, grant, or policy may require approval; otherwise the send is queued. Observe the same action through acceptance and mailbox completion. A policy refusal returns 403 with the recorded receipt."), get5("mailboxesGetMessage", "/v1/mailboxes/:id/messages/:messageId", {
65978
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "mailboxes.sendMessage").annotate(Summary, "Send a new message").annotate(Description, "Starts a new conversation from the mailbox's default endpoint on the channel the body names (email when omitted); a mailbox with no endpoint on that channel is refused (422). A message to a number joins the mailbox's thread with that number when it has one. Records a send action and returns 202 with its current receipt and a Location for action status. An installation, grant, or policy may require approval; otherwise the send is queued. Observe the same action through acceptance and mailbox completion. A policy refusal returns 403 with the recorded receipt."), get5("mailboxesGetMessage", "/v1/mailboxes/:id/messages/:messageId", {
65632
65979
  params: MailboxesGetMessagePathParams,
65633
65980
  success: MailboxesGetMessage200,
65634
65981
  error: [
@@ -65734,7 +66081,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65734
66081
  MailboxesReply503.pipe(status(503)),
65735
66082
  MailboxesReply504.pipe(status(504))
65736
66083
  ]
65737
- }).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 and from the thread's endpoint. The server sets the recipients, subject, and threading headers. The body's `channel` must match the thread's."), post("mailboxesReplyAll", "/v1/mailboxes/:id/messages/:messageId/reply-all", {
66084
+ }).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 and from the thread's endpoint. The server sets the recipients, subject, and threading headers. The body's `channel` must match the thread's. On a phone channel the reply goes to the number on the other side of the thread."), post("mailboxesReplyAll", "/v1/mailboxes/:id/messages/:messageId/reply-all", {
65738
66085
  params: MailboxesReplyAllPathParams,
65739
66086
  headers: MailboxesReplyAllHeaders,
65740
66087
  payload: MailboxesReplyAllRequestJson,
@@ -65752,7 +66099,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65752
66099
  MailboxesReplyAll503.pipe(status(503)),
65753
66100
  MailboxesReplyAll504.pipe(status(504))
65754
66101
  ]
65755
- }).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 and from the thread's endpoint."), post("mailboxesPause", "/v1/mailboxes/:id/pause", {
66102
+ }).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 and from the thread's endpoint. A phone thread has one other side, so it answers like a reply."), post("mailboxesPause", "/v1/mailboxes/:id/pause", {
65756
66103
  params: MailboxesPausePathParams,
65757
66104
  success: MailboxesPause200,
65758
66105
  error: [
@@ -66133,7 +66480,7 @@ var refusalNext = (failure) => {
66133
66480
  case "ForbiddenError":
66134
66481
  return "Use a credential that may read mailboxes and follow the API message.";
66135
66482
  case "ResourceNotFoundError":
66136
- return "Run samva mailboxes list to find the mailboxes this credential can read, then retry with those --mailbox ids.";
66483
+ return "Run samva mailboxes list to find the mailboxes this credential can read, then retry with those mailbox ids.";
66137
66484
  case "CursorExpiredError":
66138
66485
  return "Events after your cursor expired. Read current state from the API and reconnect without --cursor.";
66139
66486
  case "ValidationError":
@@ -66260,12 +66607,16 @@ var tailEvents = (options) => gen2(function* () {
66260
66607
  })), mapError4(streamError), options.limit === undefined ? (stream) => stream : take3(options.limit), interruptWhen2(interrupted), runForEach2(options.onEvent), raceFirst2(interrupted.pipe(andThen2(sleep2(HANDLER_DRAIN)))))));
66261
66608
  });
66262
66609
  var mailboxesEventsCommand = make29("events", {
66610
+ mailbox: String10("mailbox-id").pipe(withDescription4("Mailboxes to follow; omit to follow every mailbox the credential reads"), withSchema3(MailboxId), atLeast3(0)),
66263
66611
  cursor: String9("cursor").pipe(withDescription2("Replay events after a cursor from an earlier event frame, then go live"), optional4),
66264
- mailbox: String9("mailbox").pipe(withSchema2(MailboxId), atLeast2(0)),
66265
66612
  limit: Int5("limit").pipe(optional4),
66266
66613
  noReconnect: Boolean6("no-reconnect").pipe(withDefault5(false), withDescription2("Exit non-zero with the last cursor when the connection drops, instead of reconnecting from it"))
66267
66614
  }).pipe(withDescription3("Tail mailbox events, one record per line; --jsonl wraps each in a result envelope; a dropped connection reconnects from the last cursor; Ctrl+C exits cleanly"), withExamples([
66268
- { command: "samva mailboxes events --mailbox mbx_1234567890123456 --limit 10" },
66615
+ { command: "samva mailboxes events mbx_1234567890123456 --limit 10" },
66616
+ {
66617
+ command: "samva mailboxes events mbx_1234567890123456 mbx_6543210987654321 --jsonl",
66618
+ description: "Follow several mailboxes"
66619
+ },
66269
66620
  { command: "samva mailboxes events --jsonl", description: "Stream envelopes for automation" },
66270
66621
  { command: "samva mailboxes events --cursor <cursor-from-an-event-frame>" },
66271
66622
  {
@@ -66553,17 +66904,36 @@ var HumanProfile = Struct({
66553
66904
  source: optional2(Literals(["api", "import", "manual", "form"]))
66554
66905
  });
66555
66906
 
66556
- // ../core/src/shared/json.ts
66557
- var JsonObject2 = Record(String4, Json2).annotate({
66558
- identifier: "JsonObject"
66559
- });
66560
- var UnknownRecord = Record(String4, Unknown2).annotate({
66561
- identifier: "UnknownRecord"
66562
- });
66563
- var decodeJsonString = decodeSync(fromJsonString2(Json2));
66564
-
66565
- // ../core/src/templates/variable-values.ts
66566
- var TemplateVariableValues = JsonObject2;
66907
+ // ../core/src/whatsapp/template-dispatch.ts
66908
+ var CONTACT_BINDING_FIELDS = [
66909
+ "id",
66910
+ "name",
66911
+ "displayName",
66912
+ "externalId",
66913
+ "phone",
66914
+ "email",
66915
+ "firstName",
66916
+ "lastName",
66917
+ "company",
66918
+ "jobTitle"
66919
+ ];
66920
+ var WhatsAppTemplateBinding = Union2([
66921
+ Struct({ contact: Literals(CONTACT_BINDING_FIELDS) }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppTemplateContactBinding" }),
66922
+ Struct({ customField: NonEmptyString }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppTemplateCustomFieldBinding" })
66923
+ ]).annotate({ identifier: "WhatsAppTemplateBinding" });
66924
+ var WhatsAppTemplateBindings = Record(NonEmptyString, WhatsAppTemplateBinding).annotate({
66925
+ identifier: "WhatsAppTemplateBindings",
66926
+ description: "Template parameters filled per recipient: parameter name to the contact field it reads."
66927
+ });
66928
+ var WhatsAppTemplateDispatch = Struct({
66929
+ template: TemplateRef,
66930
+ templateData: optionalKey2(TemplateVariableValues).annotate({
66931
+ identifier: "WhatsAppTemplateDispatchData"
66932
+ }),
66933
+ bindings: optionalKey2(WhatsAppTemplateBindings),
66934
+ businessAccountId: optionalKey2(WhatsAppBusinessAccountId)
66935
+ }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppTemplateDispatch" });
66936
+ var BoundTemplateData = taggedEnum();
66567
66937
  // ../core/src/organizations/reserved-hostnames.ts
66568
66938
  var RESERVED_HOSTNAMES = new Set([
66569
66939
  "apex",
@@ -66690,6 +67060,9 @@ class AnyGrant extends Service()("samva/ResourcePermission/AnyGrant") {
66690
67060
 
66691
67061
  class Unscoped extends Service()("samva/ResourcePermission/Unscoped") {
66692
67062
  }
67063
+
67064
+ class NamespaceScoped extends Service()("samva/ResourcePermission/NamespaceScoped") {
67065
+ }
66693
67066
  function sendGrants(channel) {
66694
67067
  return [
66695
67068
  { resource: "messages", action: "create" },
@@ -66928,7 +67301,7 @@ var ContactEventReference2 = Union2([
66928
67301
  var CreateEventPayload2 = Struct({
66929
67302
  contact: ContactEventReference2,
66930
67303
  name: NonEmptyString.check(isMaxLength(EVENT_NAME_MAX_LENGTH), isPattern2(EVENT_NAME_PATTERN)),
66931
- properties: optional2(JsonObject2),
67304
+ properties: optional2(JsonObject),
66932
67305
  occurredAt: optional2(DateFromString),
66933
67306
  idempotencyKey: optional2(NonEmptyString.check(isMaxLength(EVENT_IDEMPOTENCY_KEY_MAX_LENGTH)))
66934
67307
  }).annotate({ identifier: "CreateEventPayload" });
@@ -66937,7 +67310,7 @@ var ContactEvent2 = Struct({
66937
67310
  contactId: ContactId,
66938
67311
  name: String4,
66939
67312
  source: Literals(["api", "samva"]),
66940
- properties: JsonObject2,
67313
+ properties: JsonObject,
66941
67314
  occurredAt: DateFromString,
66942
67315
  recordedAt: DateFromString
66943
67316
  }).annotate({ identifier: "ContactEvent" });
@@ -66980,7 +67353,7 @@ class EventsGroup2 extends make37("events").add(post("create", "/", {
66980
67353
  }).annotateMerge(annotations({
66981
67354
  summary: "Record contact events in a batch",
66982
67355
  description: "Validates the full request shape, contact references, and event names before processing. A schema failure rejects the entire batch without writes. Between 1 and 100 valid entries are then processed in input order, with independent indexed results for properties limits, contact resolution, and idempotency."
66983
- }))).prefix("/v1/events").middleware(ResourceAuthorization).middleware(JourneysGate).middleware(OrgContext).annotate(GroupResource, "contacts").annotateMerge(annotations({ title: "Events", description: "Custom contact event ingestion" })) {
67356
+ }))).prefix("/v1/events").middleware(ResourceAuthorization).middleware(JourneysGate).middleware(OrgContext).annotate(GroupResource, "contacts").annotate(NamespaceScoped, "Events resolve and list contacts only in the key's namespace").annotateMerge(annotations({ title: "Events", description: "Custom contact event ingestion" })) {
66984
67357
  }
66985
67358
 
66986
67359
  class ContactEventsGroup2 extends make37("contactEvents").add(get5("listEvents", "/:id/events", {
@@ -66991,7 +67364,7 @@ class ContactEventsGroup2 extends make37("contactEvents").add(get5("listEvents",
66991
67364
  }).annotateMerge(annotations({
66992
67365
  summary: "List contact events",
66993
67366
  description: "Returns custom and Samva lifecycle events, newest occurrence first, within the 90-day retention window. Pass nextCursor back as cursor for the next page."
66994
- }))).prefix("/v1/contacts").middleware(ResourceAuthorization).middleware(JourneysGate).middleware(OrgContext).annotate(GroupResource, "contacts").annotateMerge(annotations({
67367
+ }))).prefix("/v1/contacts").middleware(ResourceAuthorization).middleware(JourneysGate).middleware(OrgContext).annotate(GroupResource, "contacts").annotate(NamespaceScoped, "Events resolve and list contacts only in the key's namespace").annotateMerge(annotations({
66995
67368
  title: "Contact events",
66996
67369
  description: "A contact's custom and lifecycle event timeline"
66997
67370
  })) {
@@ -67116,7 +67489,7 @@ var JourneyUpdateTagsConfig2 = Struct({
67116
67489
  });
67117
67490
  return issues;
67118
67491
  })).pipe(rejectExcessProperties).annotate({ identifier: "JourneyUpdateTagsConfig" });
67119
- var JourneyWebhookConfig2 = Struct({ data: optionalKey2(JsonObject2) }).pipe(rejectExcessProperties).annotate({ identifier: "JourneyWebhookConfig" });
67492
+ var JourneyWebhookConfig2 = Struct({ data: optionalKey2(JsonObject) }).pipe(rejectExcessProperties).annotate({ identifier: "JourneyWebhookConfig" });
67120
67493
  var JourneyEmptyConfig2 = Record(String4, Never2).annotate({
67121
67494
  identifier: "JourneyEmptyConfig"
67122
67495
  });
@@ -67138,6 +67511,11 @@ var JourneyNode2 = Union2([
67138
67511
  config: JourneySendEmailConfig2,
67139
67512
  next: nextNode
67140
67513
  }).pipe(rejectExcessProperties).annotate({ identifier: "JourneySendEmailNode" }),
67514
+ Struct({
67515
+ type: Literal2("send_whatsapp"),
67516
+ config: WhatsAppTemplateDispatch,
67517
+ next: nextNode
67518
+ }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppJourneySendNode" }),
67141
67519
  Struct({ type: Literal2("wait"), config: JourneyWaitConfig2, next: nextNode }).pipe(rejectExcessProperties).annotate({ identifier: "JourneyWaitNode" }),
67142
67520
  Struct({
67143
67521
  type: Literal2("wait_for_event"),
@@ -67261,7 +67639,7 @@ var JourneyRunCounts = /* @__PURE__ */ Struct({
67261
67639
  var JourneyRunTrigger = /* @__PURE__ */ Struct({
67262
67640
  eventId: String4,
67263
67641
  eventName: String4,
67264
- properties: JsonObject
67642
+ properties: JsonObject2
67265
67643
  }).annotate({ identifier: "JourneyRunTrigger" });
67266
67644
  var JourneyListItem = /* @__PURE__ */ Struct({
67267
67645
  id: JourneyId2,
@@ -67367,7 +67745,7 @@ var JourneysCreateRequestJson = /* @__PURE__ */ Struct({
67367
67745
  var JourneysCreate201 = Journey;
67368
67746
  var JourneysCreate401 = UnauthorizedError2;
67369
67747
  var JourneysCreate402 = PaymentRequiredError2;
67370
- var JourneysCreate403 = ForbiddenError2;
67748
+ var JourneysCreate403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67371
67749
  var JourneysCreate404 = ResourceNotFoundError2;
67372
67750
  var JourneysCreate409 = ConflictError2;
67373
67751
  var JourneysCreate422 = ValidationError2;
@@ -67417,7 +67795,7 @@ var JourneysReplaceDraftRequestJson = /* @__PURE__ */ Struct({
67417
67795
  var JourneysReplaceDraft200 = Journey;
67418
67796
  var JourneysReplaceDraft401 = UnauthorizedError2;
67419
67797
  var JourneysReplaceDraft402 = PaymentRequiredError2;
67420
- var JourneysReplaceDraft403 = ForbiddenError2;
67798
+ var JourneysReplaceDraft403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67421
67799
  var JourneysReplaceDraft404 = ResourceNotFoundError2;
67422
67800
  var JourneysReplaceDraft409 = ConflictError2;
67423
67801
  var JourneysReplaceDraft422 = ValidationError2;
@@ -67438,7 +67816,7 @@ var JourneysPublishRequestJson = /* @__PURE__ */ Struct({ revision: String4.chec
67438
67816
  var JourneysPublish200 = Journey;
67439
67817
  var JourneysPublish401 = UnauthorizedError2;
67440
67818
  var JourneysPublish402 = PaymentRequiredError2;
67441
- var JourneysPublish403 = ForbiddenError2;
67819
+ var JourneysPublish403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67442
67820
  var JourneysPublish404 = ResourceNotFoundError2;
67443
67821
  var JourneysPublish409 = ConflictError2;
67444
67822
  var JourneysPublish422 = ValidationError2;
@@ -67449,7 +67827,7 @@ var JourneysResumePathParams = /* @__PURE__ */ Struct({ id: JourneyId2 });
67449
67827
  var JourneysResume200 = Journey;
67450
67828
  var JourneysResume401 = UnauthorizedError2;
67451
67829
  var JourneysResume402 = PaymentRequiredError2;
67452
- var JourneysResume403 = ForbiddenError2;
67830
+ var JourneysResume403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67453
67831
  var JourneysResume404 = ResourceNotFoundError2;
67454
67832
  var JourneysResume409 = ConflictError2;
67455
67833
  var JourneysResume422 = ValidationError2;
@@ -70910,10 +71288,15 @@ var MailboxThreadState2 = Struct({
70910
71288
  var MailboxThreadSummary2 = Struct(threadSummaryFields).annotate({
70911
71289
  identifier: "MailboxThreadSummary"
70912
71290
  });
71291
+ var MailboxWhatsAppServiceWindow = Struct({
71292
+ open: Boolean3,
71293
+ expiresAt: NullOr(DateFromString)
71294
+ }).annotate({ identifier: "MailboxWhatsAppServiceWindow" });
70913
71295
  var MailboxThread2 = Struct({
70914
71296
  ...threadSummaryFields,
70915
71297
  conversationId: ConversationId,
70916
71298
  participants: ArraySchema(MailboxThreadParticipantSchema),
71299
+ whatsappServiceWindow: NullOr(MailboxWhatsAppServiceWindow),
70917
71300
  createdAt: DateFromString
70918
71301
  }).annotate({ identifier: "MailboxThread" });
70919
71302
  var MailboxMessageAuthentication2 = Struct({
@@ -70960,18 +71343,23 @@ var MailboxEmailMessage = Struct({
70960
71343
  attachments: ArraySchema(MailboxMessageAttachmentSchema)
70961
71344
  }).annotate({ identifier: "MailboxEmailMessage" });
70962
71345
  var MailboxChatMedia = Struct({
70963
- id: AttachmentId,
70964
- contentType: String4,
71346
+ type: String4,
71347
+ contentType: NullOr(String4),
70965
71348
  filename: NullOr(String4),
70966
- size: NullOr(Count),
70967
71349
  caption: NullOr(String4)
70968
71350
  }).annotate({ identifier: "MailboxChatMedia" });
71351
+ var MailboxChatMessageTemplate = Struct({
71352
+ name: String4,
71353
+ language: String4
71354
+ }).annotate({ identifier: "MailboxChatMessageTemplate" });
70969
71355
  var MailboxChatMessage = Struct({
70970
71356
  ...messageFields,
70971
71357
  channel: Literals(["whatsapp", "sms"]),
70972
71358
  to: ArraySchema(String4),
70973
71359
  text: NullOr(String4),
70974
71360
  media: ArraySchema(MailboxChatMedia),
71361
+ template: NullOr(MailboxChatMessageTemplate),
71362
+ summary: NullOr(String4),
70975
71363
  contextMessageId: NullOr(MessageId)
70976
71364
  }).annotate({ identifier: "MailboxChatMessage" });
70977
71365
  var MailboxMessage2 = Union2([MailboxEmailMessage, MailboxChatMessage]).annotate({
@@ -71083,6 +71471,10 @@ var printMailboxSummary = (data) => gen2(function* () {
71083
71471
  ["Created", data.createdAt]
71084
71472
  ]);
71085
71473
  });
71474
+ var endpointLine = (endpoint) => {
71475
+ const where = endpoint.channel === "email" ? `${endpoint.source}${endpoint.default ? "; default" : ""}; ID ${endpoint.id}; domain ${present(endpoint.domainId)}` : `${endpoint.default ? "default; " : ""}ID ${endpoint.id}; ${endpoint.channel === "whatsapp" ? `business account ${endpoint.businessAccountId}` : `phone number ${endpoint.phoneNumberId}`}`;
71476
+ return ` ${endpoint.channel}: ${identity2(endpoint.address, endpoint.displayName)} \u2014 ${where}; display name ${present(endpoint.displayName)}`;
71477
+ };
71086
71478
  var printMailbox = (data) => gen2(function* () {
71087
71479
  yield* printMailboxSummary(data);
71088
71480
  yield* printFields([
@@ -71093,7 +71485,7 @@ var printMailbox = (data) => gen2(function* () {
71093
71485
  if (!data.endpoints.length)
71094
71486
  yield* log(" none");
71095
71487
  for (const endpoint of data.endpoints)
71096
- yield* log(` ${endpoint.channel}: ${identity2(endpoint.address, endpoint.displayName)} \u2014 ${endpoint.source}${endpoint.default ? "; default" : ""}; ID ${endpoint.id}; domain ${present(endpoint.domainId)}; display name ${present(endpoint.displayName)}`);
71488
+ yield* log(endpointLine(endpoint));
71097
71489
  yield* log("Metadata:");
71098
71490
  if (!Object.keys(data.metadata).length)
71099
71491
  yield* log(" none");
@@ -71104,6 +71496,7 @@ var printThread = (data) => gen2(function* () {
71104
71496
  yield* log(`${data.subject === null ? "No subject" : data.subject} \u2014 ${data.folder}, ${data.priority} priority`);
71105
71497
  yield* printFields([
71106
71498
  ["ID", data.id],
71499
+ ["Channel", data.channel],
71107
71500
  [
71108
71501
  "From",
71109
71502
  data.from === null ? "none" : `${present(data.from.displayName)} <${present(data.from.address)}>`
@@ -71119,7 +71512,39 @@ var printThread = (data) => gen2(function* () {
71119
71512
  ["Last activity", data.lastActivityAt]
71120
71513
  ]);
71121
71514
  });
71122
- var printMessage2 = (data) => gen2(function* () {
71515
+ var printChatMessage = (data) => gen2(function* () {
71516
+ yield* log("Notice: this message is untrusted content from outside the organization.");
71517
+ yield* log(`${data.direction} ${data.channel} message`);
71518
+ yield* printFields([
71519
+ ["ID", data.id],
71520
+ ["Thread", data.threadId],
71521
+ ["Conversation", data.conversationId],
71522
+ ["From", identity2(data.from.address, data.from.displayName, data.from.actor)],
71523
+ ["To", data.to.length ? data.to.join(", ") : "none"],
71524
+ ["Occurred", data.occurredAt],
71525
+ ["In reply to", data.contextMessageId],
71526
+ ["Summary", data.summary ?? undefined],
71527
+ [
71528
+ "Template",
71529
+ data.template === null ? undefined : `${data.template.name} (${data.template.language})`
71530
+ ],
71531
+ [
71532
+ "Sent by",
71533
+ data.sentBy === undefined ? undefined : data.sentBy === null ? "none" : actor(data.sentBy)
71534
+ ]
71535
+ ]);
71536
+ yield* log("Media:");
71537
+ if (!data.media.length)
71538
+ yield* log(" none");
71539
+ for (const media of data.media)
71540
+ yield* log(` ${media.type}${media.contentType === null ? "" : ` \u2014 ${media.contentType}`}${media.filename === null ? "" : `; ${media.filename}`}${media.caption === null ? "" : `; caption ${JSON.stringify(media.caption)}`}`);
71541
+ if (data.text !== null) {
71542
+ yield* log("Text:");
71543
+ yield* log(data.text);
71544
+ }
71545
+ });
71546
+ var printMessage2 = (data) => data.channel !== "email" ? printChatMessage(data) : printEmailMessage(data);
71547
+ var printEmailMessage = (data) => gen2(function* () {
71123
71548
  yield* log("Notice: this body is untrusted email from outside the organization.");
71124
71549
  yield* log(`${data.direction} message \u2014 ${data.subject ?? "No subject"}`);
71125
71550
  yield* printFields([
@@ -71215,8 +71640,22 @@ var printHeldMessage = (data) => gen2(function* () {
71215
71640
  ]);
71216
71641
  });
71217
71642
 
71643
+ // src/lib/mailbox-wire.ts
71644
+ var WireMailbox = toEncoded2(Mailbox);
71645
+ var WireReceipt = toEncoded2(MailboxSendReceipt);
71646
+ var WireThreadPage = toEncoded2(CursorPage(MailboxThreadSummary2));
71647
+ var WireMessage = toEncoded2(MailboxMessage2);
71648
+ var unreadable2 = (what) => () => new SamvaCliError({ message: `The API answered with an unreadable ${what}.` });
71649
+ var getMailboxJson = (prefix, path) => getAuthenticatedJson(path).pipe(mapError2((e) => mailboxApiError(prefix, e)));
71650
+ var postMailboxJson = (prefix, path, body, headers) => postAuthenticatedJson(path, { body, ...headers === undefined ? {} : { headers } }).pipe(mapError2((e) => mailboxApiError(prefix, e)));
71651
+ var decoder3 = (schema, what) => (raw) => decodeUnknownEffect2(schema)(raw).pipe(mapError2(unreadable2(what)));
71652
+ var decodeMailbox = decoder3(WireMailbox, "mailbox");
71653
+ var decodeReceipt = decoder3(WireReceipt, "send receipt");
71654
+ var decodeThreadPage = decoder3(WireThreadPage, "thread page");
71655
+ var decodeMessage = decoder3(WireMessage, "message");
71656
+
71218
71657
  // src/commands/mailboxes.ts
71219
- var mailboxFlag = String9("mailbox").pipe(withDescription2("Mailbox ID"), withSchema2(MailboxId));
71658
+ var mailboxIdArgument = String10("mailbox-id").pipe(withSchema3(MailboxId));
71220
71659
  var messageIdArgument = String10("message-id").pipe(withSchema3(MessageId));
71221
71660
  var optional6 = (name) => String9(name).pipe(optional4);
71222
71661
  var pageFlags2 = {
@@ -71241,11 +71680,46 @@ var body2 = (text, html) => {
71241
71680
  ...isSome2(html) ? { html: html.value } : {}
71242
71681
  });
71243
71682
  };
71683
+ var channelFlag2 = Literals3("channel", ["email", "whatsapp", "sms"]).pipe(withDescription2("The channel: email, or a connected whatsapp or sms number"), withDefault5("email"));
71684
+ var chatOnlyFlags = {
71685
+ template: String9("template").pipe(withDescription2("WhatsApp only: send this approved template (tmpl_\u2026) instead of --text"), optional4),
71686
+ data: String9("data").pipe(withDescription2("WhatsApp only: the template's variables as a JSON object"), optional4)
71687
+ };
71688
+ var usage2 = (code, message) => new CliUsageError({ code, message });
71689
+ var chatContent = (channel, flags) => gen2(function* () {
71690
+ if (isSome2(flags.html))
71691
+ return yield* usage2("mailbox_chat_html", `--html is for email; a ${channel} message is text.`);
71692
+ if (isSome2(flags.text) === isSome2(flags.template))
71693
+ return yield* usage2("mailbox_chat_content_required", channel === "whatsapp" ? "Provide exactly one of --text or --template." : "Provide --text; a template sends on WhatsApp only.");
71694
+ if (isNone2(flags.template)) {
71695
+ if (isSome2(flags.data))
71696
+ return yield* usage2("mailbox_chat_data", "--data needs --template.");
71697
+ return isSome2(flags.text) ? { text: flags.text.value } : {};
71698
+ }
71699
+ if (channel !== "whatsapp")
71700
+ return yield* usage2("mailbox_chat_template", "A template sends on WhatsApp only.");
71701
+ const templateId = yield* decodeEffect2(TemplateId)(flags.template.value).pipe(mapError2(() => usage2("mailbox_chat_template", "--template must be an approved template id (tmpl_\u2026).")));
71702
+ const dataText = getOrUndefined(flags.data);
71703
+ if (dataText === undefined)
71704
+ return { templateId };
71705
+ const raw = yield* try_3({
71706
+ try: () => JSON.parse(dataText),
71707
+ catch: () => usage2("mailbox_chat_data", "--data must be valid JSON.")
71708
+ });
71709
+ if (!isObject(raw) || Array.isArray(raw))
71710
+ return yield* usage2("mailbox_chat_data", "--data must be a JSON object.");
71711
+ return { templateId, templateData: raw };
71712
+ });
71713
+ var keyHeader = (key) => isSome2(key) ? { "idempotency-key": key.value } : undefined;
71244
71714
  var checkCursor = (cursor) => cursor === undefined ? succeed6(undefined) : decodeEffect2(Cursor2)(cursor).pipe(as2(cursor), mapError2(() => new CliUsageError({
71245
71715
  code: "mailbox_cursor_invalid",
71246
71716
  message: "The cursor is not a nextCursor this command printed."
71247
71717
  })));
71248
71718
  var pageLimit = (limit) => getOrUndefined(limit)?.toString();
71719
+ var searchParams = (values) => {
71720
+ const query = new URLSearchParams(Object.entries(values).filter((entry) => entry[1] !== undefined)).toString();
71721
+ return query === "" ? "" : `?${query}`;
71722
+ };
71249
71723
  var followPages = (options) => gen2(function* () {
71250
71724
  if (options.all && !isJsonLinesRequested())
71251
71725
  return yield* new CliUsageError({
@@ -71305,16 +71779,32 @@ var list19 = make29("list", {
71305
71779
  });
71306
71780
  })));
71307
71781
  var create9 = make29("create", {
71308
- address: String9("address").pipe(withDescription2("The mailbox's email address, such as support@acme.samva.email")),
71782
+ channel: channelFlag2,
71783
+ address: String9("address").pipe(withDescription2("The mailbox's address: an email address such as support@acme.samva.email, or on whatsapp and sms a number you connected, in E.164 form such as +14155550123")),
71309
71784
  name: String9("name"),
71310
- slug: String9("slug").pipe(withDescription2("Defaults to the address's local part"), optional4),
71785
+ slug: String9("slug").pipe(withDescription2("Defaults to the address's local part, or a phone number's digits"), optional4),
71311
71786
  namespace: String9("namespace").pipe(withSchema2(NamespaceId), optional4),
71312
71787
  json: jsonFlag
71313
- }).pipe(withDescription3("Create a mailbox with one email endpoint"), withExamples([
71788
+ }).pipe(withDescription3("Create a mailbox with one endpoint on a channel (email by default)"), withExamples([
71314
71789
  {
71315
71790
  command: "samva mailboxes create --address support@acme.samva.email --name Support"
71791
+ },
71792
+ {
71793
+ command: "samva mailboxes create --channel whatsapp --address +14155550123 --name Concierge",
71794
+ description: "A mailbox on a connected WhatsApp number"
71795
+ }
71796
+ ]), withHandler(({ channel, address, name, slug, namespace, json }) => gen2(function* () {
71797
+ if (channel !== "email") {
71798
+ const raw = yield* postMailboxJson("Could not create mailbox", "/v1/mailboxes", {
71799
+ endpoint: { channel, address },
71800
+ name,
71801
+ ...isSome2(slug) ? { slug: slug.value } : {},
71802
+ ...isSome2(namespace) ? { namespaceId: namespace.value } : {}
71803
+ });
71804
+ if (json)
71805
+ return yield* printJson(raw);
71806
+ return yield* printMailbox(yield* decodeMailbox(raw));
71316
71807
  }
71317
- ]), withHandler(({ address, name, slug, namespace, json }) => gen2(function* () {
71318
71808
  const client = yield* getClientProvider;
71319
71809
  const data = yield* create6({
71320
71810
  endpoint: { channel: "email", address },
@@ -71326,11 +71816,10 @@ var create9 = make29("create", {
71326
71816
  return yield* printJson(data);
71327
71817
  yield* printMailbox(data);
71328
71818
  })));
71329
- var mailboxIdArgument = String10("mailbox-id").pipe(withSchema3(MailboxId));
71330
71819
  var get22 = make29("get", { id: mailboxIdArgument, json: jsonFlag }).pipe(withDescription3("Inspect a mailbox's endpoints and settings"), withHandler(({ id, json }) => gen2(function* () {
71331
- const client = yield* getClientProvider;
71332
- const result = yield* get19({ id }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read mailbox", e)));
71333
- yield* json ? printJson(result) : printMailbox(result);
71820
+ const raw = yield* getMailboxJson("Could not read mailbox", `/v1/mailboxes/${id}`);
71821
+ const result = yield* decodeMailbox(raw);
71822
+ yield* json ? printJson(raw) : printMailbox(result);
71334
71823
  })));
71335
71824
  var update9 = make29("update", {
71336
71825
  id: mailboxIdArgument,
@@ -71385,18 +71874,23 @@ var update9 = make29("update", {
71385
71874
  yield* json ? printJson(result) : printMailbox(result);
71386
71875
  })));
71387
71876
  var endpointAdd = make29("add", {
71388
- mailbox: mailboxFlag,
71389
- address: String9("address").pipe(withDescription2("The email address to add, such as billing@acme.samva.email")),
71877
+ mailbox: mailboxIdArgument,
71878
+ channel: channelFlag2,
71879
+ address: String9("address").pipe(withDescription2("The address to add: an email address such as billing@acme.samva.email, or on whatsapp and sms a number you connected, in E.164 form such as +14155550123")),
71390
71880
  displayName: String9("display-name").pipe(withDescription2("The sender name messages from this endpoint carry"), optional4),
71391
71881
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
71392
71882
  json: jsonFlag
71393
- }).pipe(withDescription3("Add an email endpoint to a mailbox"), withExamples([
71883
+ }).pipe(withDescription3("Add an endpoint on a channel (email by default) to a mailbox"), withExamples([
71394
71884
  {
71395
- command: "samva mailboxes endpoints add --mailbox mbx_1234567890123456 --address billing@acme.samva.email"
71885
+ command: "samva mailboxes endpoints add mbx_1234567890123456 --address billing@acme.samva.email"
71886
+ },
71887
+ {
71888
+ command: "samva mailboxes endpoints add mbx_1234567890123456 --channel whatsapp --address +14155550123",
71889
+ description: "Add a connected WhatsApp number"
71396
71890
  }
71397
- ]), withHandler(({ mailbox, address, displayName, dryRun, json }) => gen2(function* () {
71891
+ ]), withHandler(({ mailbox, channel, address, displayName, dryRun, json }) => gen2(function* () {
71398
71892
  const payload = {
71399
- channel: "email",
71893
+ channel,
71400
71894
  address,
71401
71895
  displayName: getOrUndefined(displayName)
71402
71896
  };
@@ -71407,14 +71901,24 @@ var endpointAdd = make29("add", {
71407
71901
  id: mailbox,
71408
71902
  request: payload
71409
71903
  }) : log(`[dry-run] Would add ${address} to mailbox ${mailbox}.`);
71904
+ if (channel !== "email") {
71905
+ const raw = yield* postMailboxJson("Could not add the endpoint", `/v1/mailboxes/${mailbox}/endpoints`, payload);
71906
+ if (json)
71907
+ return yield* printJson(raw);
71908
+ return yield* printMailbox(yield* decodeMailbox(raw));
71909
+ }
71410
71910
  const client = yield* getClientProvider;
71411
- const result = yield* createEndpoint({ id: mailbox, ...payload }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not add the endpoint", e)));
71911
+ const result = yield* createEndpoint({
71912
+ id: mailbox,
71913
+ ...payload,
71914
+ channel: "email"
71915
+ }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not add the endpoint", e)));
71412
71916
  yield* json ? printJson(result) : printMailbox(result);
71413
71917
  })));
71414
71918
  var endpointIdArgument = String10("endpoint-id").pipe(withSchema3(MailboxEndpointId));
71415
71919
  var endpointUpdate = make29("update", {
71920
+ mailbox: mailboxIdArgument,
71416
71921
  endpointId: endpointIdArgument,
71417
- mailbox: mailboxFlag,
71418
71922
  displayName: String9("display-name").pipe(withDescription2("The sender name messages from this endpoint carry"), optional4),
71419
71923
  clearDisplayName: Boolean6("clear-display-name").pipe(withDescription2("Send under the mailbox's name again"), withDefault5(false)),
71420
71924
  makeDefault: Boolean6("default").pipe(withDescription2("Start new conversations from this endpoint on its channel"), withDefault5(false)),
@@ -71422,7 +71926,7 @@ var endpointUpdate = make29("update", {
71422
71926
  json: jsonFlag
71423
71927
  }).pipe(withDescription3("Rename an endpoint's sender or make it the mailbox's default"), withExamples([
71424
71928
  {
71425
- command: 'samva mailboxes endpoints update mbxep_1234567890123456 --mailbox mbx_1234567890123456 --display-name "Acme Billing" --default'
71929
+ command: 'samva mailboxes endpoints update mbx_1234567890123456 mbxep_1234567890123456 --display-name "Acme Billing" --default'
71426
71930
  }
71427
71931
  ]), withHandler(({ endpointId, mailbox, displayName, clearDisplayName, makeDefault, dryRun, json }) => gen2(function* () {
71428
71932
  if (isSome2(displayName) && clearDisplayName)
@@ -71456,14 +71960,14 @@ var endpointUpdate = make29("update", {
71456
71960
  yield* json ? printJson(result) : printMailbox(result);
71457
71961
  })));
71458
71962
  var endpointRemove = make29("remove", {
71963
+ mailbox: mailboxIdArgument,
71459
71964
  endpointId: endpointIdArgument,
71460
- mailbox: mailboxFlag,
71461
71965
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
71462
71966
  yes: Boolean6("yes").pipe(withDefault5(false)),
71463
71967
  json: jsonFlag
71464
71968
  }).pipe(withDescription3("Remove an endpoint from a mailbox; mail sent to it stops reaching the mailbox"), withExamples([
71465
71969
  {
71466
- command: "samva mailboxes endpoints remove mbxep_1234567890123456 --mailbox mbx_1234567890123456 --yes"
71970
+ command: "samva mailboxes endpoints remove mbx_1234567890123456 mbxep_1234567890123456 --yes"
71467
71971
  }
71468
71972
  ]), withHandler(({ endpointId, mailbox, dryRun, yes, json }) => gen2(function* () {
71469
71973
  if (dryRun)
@@ -71495,7 +71999,7 @@ var lifecycle = (verb) => make29(verb, {
71495
71999
  yield* json ? printJson(result) : printMailbox(result);
71496
72000
  })));
71497
72001
  var actionsList = make29("list", {
71498
- mailbox: mailboxFlag,
72002
+ mailbox: mailboxIdArgument,
71499
72003
  ...pageFlags2,
71500
72004
  state: Literals3("state", MailboxActionState.literals).pipe(optional4),
71501
72005
  after: instantFlag("after", "Only actions created after this ISO 8601 instant"),
@@ -71520,8 +72024,8 @@ var actionsList = make29("list", {
71520
72024
  });
71521
72025
  })));
71522
72026
  var actionDecision = (verb) => make29(verb, {
72027
+ mailbox: mailboxIdArgument,
71523
72028
  actionId: String10("action-id").pipe(withSchema3(MailboxActionId)),
71524
- mailbox: mailboxFlag,
71525
72029
  ...verb === "deny" ? {
71526
72030
  reason: optional6("reason").pipe(withDescription2("Denial reason; defaults to Denied by reviewer."))
71527
72031
  } : {},
@@ -71576,7 +72080,7 @@ var remove9 = make29("remove", {
71576
72080
  yield* log(`Removed mailbox ${id}. The messages it received stay with the organization.`);
71577
72081
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
71578
72082
  var threads = make29("threads", {
71579
- mailbox: mailboxFlag,
72083
+ mailbox: mailboxIdArgument,
71580
72084
  ...pageFlags2,
71581
72085
  query: optional6("query"),
71582
72086
  folder: Literals3("folder", MailboxThreadFolder2.literals).pipe(optional4),
@@ -71587,107 +72091,154 @@ var threads = make29("threads", {
71587
72091
  before: instantFlag("before", "Only threads whose last activity is before this ISO 8601 instant"),
71588
72092
  json: jsonFlag
71589
72093
  }).pipe(withDescription3("Search and list mailbox threads"), withExamples([
71590
- { command: "samva mailboxes threads --mailbox mbx_1234567890123456 --query invoice --json" },
72094
+ { command: "samva mailboxes threads mbx_1234567890123456 --query invoice --json" },
71591
72095
  {
71592
- command: "samva mailboxes threads --mailbox mbx_1234567890123456 --starred --after 2026-10-01T00:00:00Z"
72096
+ command: "samva mailboxes threads mbx_1234567890123456 --starred --after 2026-10-01T00:00:00Z"
71593
72097
  },
71594
- { command: "samva mailboxes threads --mailbox mbx_1234567890123456 --all --jsonl" }
71595
- ]), withHandler(({ mailbox, limit, cursor, all, query, folder, label, unread, starred, after, before, json }) => gen2(function* () {
71596
- const client = yield* getClientProvider;
71597
- yield* followPages({
71598
- all,
71599
- json,
71600
- cursor,
71601
- page: (pageCursor) => listThreads({
71602
- id: mailbox,
71603
- cursor: pageCursor,
71604
- limit: pageLimit(limit),
71605
- q: getOrUndefined(query),
71606
- folder: getOrUndefined(folder),
71607
- label: getOrUndefined(label),
71608
- unread: unread ? "true" : undefined,
71609
- starred: starred ? "true" : undefined,
71610
- after: getOrUndefined(after),
71611
- before: getOrUndefined(before)
71612
- }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list threads", e))),
71613
- empty: "No threads found.",
71614
- human: printThread
71615
- });
72098
+ { command: "samva mailboxes threads mbx_1234567890123456 --all --jsonl" }
72099
+ ]), withHandler(({ mailbox, limit, cursor, all, query, folder, label, unread, starred, after, before, json }) => followPages({
72100
+ all,
72101
+ json,
72102
+ cursor,
72103
+ page: (pageCursor) => getMailboxJson("Could not list threads", `/v1/mailboxes/${mailbox}/threads${searchParams({
72104
+ cursor: pageCursor,
72105
+ limit: pageLimit(limit),
72106
+ q: getOrUndefined(query),
72107
+ folder: getOrUndefined(folder),
72108
+ label: getOrUndefined(label),
72109
+ unread: unread ? "true" : undefined,
72110
+ starred: starred ? "true" : undefined,
72111
+ after: getOrUndefined(after),
72112
+ before: getOrUndefined(before)
72113
+ })}`).pipe(flatMap3(decodeThreadPage)),
72114
+ empty: "No threads found.",
72115
+ human: printThread
71616
72116
  })));
71617
72117
  var read2 = make29("read", {
72118
+ mailbox: mailboxIdArgument,
71618
72119
  messageId: messageIdArgument,
71619
- mailbox: mailboxFlag,
71620
72120
  json: jsonFlag
71621
72121
  }).pipe(withDescription3("Read a mailbox message"), withExamples([
71622
- { command: "samva mailboxes read msg_1234567890123456 --mailbox mbx_1234567890123456 --json" }
72122
+ { command: "samva mailboxes read mbx_1234567890123456 msg_1234567890123456 --json" }
71623
72123
  ]), withHandler(({ messageId, mailbox, json }) => gen2(function* () {
71624
- const client = yield* getClientProvider;
71625
- const data = yield* getMessage({ id: mailbox, messageId }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not read message", e)));
72124
+ const raw = yield* getMailboxJson("Could not read message", `/v1/mailboxes/${mailbox}/messages/${messageId}`);
72125
+ const data = yield* decodeMessage(raw);
71626
72126
  if (json)
71627
- return yield* printJson(data);
72127
+ return yield* printJson(raw);
71628
72128
  yield* printMessage2(data);
71629
72129
  })));
71630
72130
  var send7 = make29("send", {
71631
- mailbox: mailboxFlag,
71632
- to: String9("to").pipe(atLeast2(1)),
71633
- subject: String9("subject"),
72131
+ mailbox: mailboxIdArgument,
72132
+ channel: channelFlag2,
72133
+ to: String9("to").pipe(withDescription2("Recipient email address (repeatable), or one phone number in E.164 form"), atLeast2(1)),
72134
+ subject: String9("subject").pipe(withDescription2("Email only"), optional4),
71634
72135
  cc: String9("cc").pipe(atLeast2(0)),
71635
72136
  bcc: String9("bcc").pipe(atLeast2(0)),
71636
72137
  ...bodyFlags,
72138
+ ...chatOnlyFlags,
71637
72139
  json: jsonFlag
71638
- }).pipe(withDescription3("Send a message from a mailbox"), withExamples([
72140
+ }).pipe(withDescription3("Send a message from a mailbox: email by default, or to one phone number with --channel whatsapp or sms"), withExamples([
72141
+ {
72142
+ command: 'samva mailboxes send mbx_1234567890123456 --to recipient@example.com --subject Hello --text "Hello"'
72143
+ },
71639
72144
  {
71640
- command: 'samva mailboxes send --mailbox mbx_1234567890123456 --to recipient@example.com --subject Hello --text "Hello"'
72145
+ command: `samva mailboxes send mbx_1234567890123456 --channel whatsapp --to +14155550123 --template tmpl_1234567890123456 --data '{"name":"Ada"}'`,
72146
+ description: "Open a WhatsApp conversation with an approved template"
72147
+ },
72148
+ {
72149
+ command: 'samva mailboxes send mbx_1234567890123456 --channel sms --to +14155550123 --text "Your order shipped."'
71641
72150
  }
71642
- ]), withHandler(({ mailbox, to, subject, cc, bcc, text, html, idempotencyKey, json }) => gen2(function* () {
71643
- const content = yield* body2(text, html);
72151
+ ]), withHandler(({
72152
+ mailbox,
72153
+ channel,
72154
+ to,
72155
+ subject,
72156
+ cc,
72157
+ bcc,
72158
+ text,
72159
+ html,
72160
+ template,
72161
+ data,
72162
+ idempotencyKey,
72163
+ json
72164
+ }) => gen2(function* () {
71644
72165
  const [first, ...rest] = to;
71645
72166
  if (first === undefined)
71646
72167
  return yield* new CliUsageError({
71647
72168
  code: "mailbox_recipient_required",
71648
72169
  message: "Provide --to."
71649
72170
  });
72171
+ if (channel !== "email") {
72172
+ if (rest.length > 0 || cc.length > 0 || bcc.length > 0 || isSome2(subject))
72173
+ return yield* usage2("mailbox_chat_recipient", `A ${channel} message goes to one --to number; --subject, --cc, and --bcc are for email.`);
72174
+ const content = yield* chatContent(channel, { text, html, template, data });
72175
+ const raw = yield* postMailboxJson("Could not send message", `/v1/mailboxes/${mailbox}/messages`, { channel, to: first, ...content }, keyHeader(idempotencyKey));
72176
+ if (json)
72177
+ return yield* printJson(raw);
72178
+ return yield* printReceipt(yield* decodeReceipt(raw));
72179
+ }
72180
+ if (isSome2(template) || isSome2(data))
72181
+ return yield* usage2("mailbox_template_channel", "--template sends on WhatsApp only.");
72182
+ if (isNone2(subject))
72183
+ return yield* usage2("mailbox_subject_required", "An email needs --subject.");
72184
+ const content = yield* body2(text, html);
71650
72185
  const client = yield* getClientProvider;
71651
- const data = yield* sendMessage2({
72186
+ const result = yield* sendMessage2({
71652
72187
  id: mailbox,
71653
72188
  idempotencyKey: getOrUndefined(idempotencyKey),
71654
72189
  to: [first, ...rest],
71655
- subject,
72190
+ subject: subject.value,
71656
72191
  ...cc.length ? { cc } : {},
71657
72192
  ...bcc.length ? { bcc } : {},
71658
72193
  ...content
71659
72194
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not send message", e)));
71660
72195
  if (json)
71661
- return yield* printJson(data);
71662
- yield* printReceipt(data);
72196
+ return yield* printJson(result);
72197
+ yield* printReceipt(result);
71663
72198
  })));
72199
+ var messageChannel = (mailbox, messageId) => getMailboxJson("Could not read message", `/v1/mailboxes/${mailbox}/messages/${messageId}`).pipe(flatMap3((raw) => decodeUnknownEffect2(Struct({ channel: Literals(["email", "whatsapp", "sms"]) }))(raw).pipe(map7(({ channel }) => channel), mapError2(() => new SamvaCliError({ message: "The API answered with an unreadable message." })))));
71664
72200
  var reply2 = make29("reply", {
72201
+ mailbox: mailboxIdArgument,
71665
72202
  messageId: messageIdArgument,
71666
- mailbox: mailboxFlag,
71667
72203
  ...bodyFlags,
72204
+ ...chatOnlyFlags,
71668
72205
  all: Boolean6("all").pipe(withDefault5(false)),
71669
72206
  json: jsonFlag
71670
- }).pipe(withDescription3("Reply to a message; --all includes the other recipients"), withExamples([
72207
+ }).pipe(withDescription3("Reply to a message; --all includes the other recipients. A WhatsApp or SMS message is answered on its thread, with --text or a WhatsApp --template"), withExamples([
71671
72208
  {
71672
- command: 'samva mailboxes reply msg_1234567890123456 --mailbox mbx_1234567890123456 --text "Thanks" --all'
72209
+ command: 'samva mailboxes reply mbx_1234567890123456 msg_1234567890123456 --text "Thanks" --all'
72210
+ },
72211
+ {
72212
+ command: "samva mailboxes reply mbx_1234567890123456 msg_1234567890123456 --template tmpl_1234567890123456",
72213
+ description: "Answer a WhatsApp thread whose 24-hour service window has closed"
72214
+ }
72215
+ ]), withHandler(({ messageId, mailbox, text, html, template, data, idempotencyKey, all, json }) => gen2(function* () {
72216
+ const channel = isSome2(template) || isSome2(data) ? "whatsapp" : isSome2(html) || all || isNone2(text) ? "email" : yield* messageChannel(mailbox, messageId);
72217
+ if (channel !== "email") {
72218
+ if (all)
72219
+ return yield* usage2("mailbox_chat_all", "--all is for email; a chat reply has one recipient.");
72220
+ const content = yield* chatContent(channel, { text, html, template, data });
72221
+ const raw = yield* postMailboxJson("Could not reply", `/v1/mailboxes/${mailbox}/messages/${messageId}/reply`, { channel, ...content }, keyHeader(idempotencyKey));
72222
+ if (json)
72223
+ return yield* printJson(raw);
72224
+ return yield* printReceipt(yield* decodeReceipt(raw));
71673
72225
  }
71674
- ]), withHandler(({ messageId, mailbox, text, html, idempotencyKey, all, json }) => gen2(function* () {
71675
72226
  const payload = yield* body2(text, html);
71676
72227
  const client = yield* getClientProvider;
71677
- const data = yield* (all ? replyAll : reply)({
72228
+ const result = yield* (all ? replyAll : reply)({
71678
72229
  id: mailbox,
71679
72230
  messageId,
71680
72231
  idempotencyKey: getOrUndefined(idempotencyKey),
71681
72232
  ...payload
71682
72233
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not reply", e)));
71683
72234
  if (json)
71684
- return yield* printJson(data);
71685
- yield* printReceipt(data);
72235
+ return yield* printJson(result);
72236
+ yield* printReceipt(result);
71686
72237
  })));
71687
72238
  var actionIdArgument = String10("action-id").pipe(withSchema3(MailboxActionId));
71688
72239
  var actionGet = make29("get", {
72240
+ mailbox: mailboxIdArgument,
71689
72241
  actionId: actionIdArgument,
71690
- mailbox: mailboxFlag,
71691
72242
  json: jsonFlag
71692
72243
  }).pipe(withDescription3("Read a mailbox action and its current send progress"), withHandler(({ actionId, mailbox, json }) => gen2(function* () {
71693
72244
  const client = yield* getClientProvider;
@@ -71697,8 +72248,8 @@ var actionGet = make29("get", {
71697
72248
  yield* printAction(data);
71698
72249
  })));
71699
72250
  var actionCancel = make29("cancel", {
72251
+ mailbox: mailboxIdArgument,
71700
72252
  actionId: actionIdArgument,
71701
- mailbox: mailboxFlag,
71702
72253
  json: jsonFlag
71703
72254
  }).pipe(withDescription3("Cancel an unaccepted send as a permitted person signed in with samva login"), withHandler(({ actionId, mailbox, json }) => gen2(function* () {
71704
72255
  const client = yield* getClientProvider;
@@ -71712,8 +72263,8 @@ var actionCancel = make29("cancel", {
71712
72263
  ]);
71713
72264
  })));
71714
72265
  var actionRetry = make29("retry", {
72266
+ mailbox: mailboxIdArgument,
71715
72267
  actionId: actionIdArgument,
71716
- mailbox: mailboxFlag,
71717
72268
  json: jsonFlag
71718
72269
  }).pipe(withDescription3("Resume an eligible ended execution as a permitted person; preserves content and deadline"), withHandler(({ actionId, mailbox, json }) => gen2(function* () {
71719
72270
  const client = yield* getClientProvider;
@@ -71727,14 +72278,14 @@ var actionRetry = make29("retry", {
71727
72278
  ]);
71728
72279
  })));
71729
72280
  var quarantineList = make29("list", {
71730
- mailbox: mailboxFlag,
72281
+ mailbox: mailboxIdArgument,
71731
72282
  ...pageFlags2,
71732
72283
  after: instantFlag("after", "Only messages held after this ISO 8601 instant"),
71733
72284
  before: instantFlag("before", "Only messages held before this ISO 8601 instant"),
71734
72285
  json: jsonFlag
71735
72286
  }).pipe(withDescription3("List held messages without their bodies"), withExamples([
71736
- { command: "samva mailboxes quarantine list --mailbox mbx_1234567890123456 --json" },
71737
- { command: "samva mailboxes quarantine list --mailbox mbx_1234567890123456 --all --jsonl" }
72287
+ { command: "samva mailboxes quarantine list mbx_1234567890123456 --json" },
72288
+ { command: "samva mailboxes quarantine list mbx_1234567890123456 --all --jsonl" }
71738
72289
  ]), withHandler(({ mailbox, limit, cursor, all, after, before, json }) => gen2(function* () {
71739
72290
  const client = yield* getClientProvider;
71740
72291
  yield* followPages({
@@ -71753,12 +72304,12 @@ var quarantineList = make29("list", {
71753
72304
  });
71754
72305
  })));
71755
72306
  var release2 = make29("release", {
72307
+ mailbox: mailboxIdArgument,
71756
72308
  messageId: messageIdArgument,
71757
- mailbox: mailboxFlag,
71758
72309
  json: jsonFlag
71759
72310
  }).pipe(withDescription3("Release a held message as a person signed in with samva login"), withExamples([
71760
72311
  {
71761
- command: "samva mailboxes quarantine release msg_1234567890123456 --mailbox mbx_1234567890123456"
72312
+ command: "samva mailboxes quarantine release mbx_1234567890123456 msg_1234567890123456"
71762
72313
  }
71763
72314
  ]), withHandler(({ messageId, mailbox, json }) => gen2(function* () {
71764
72315
  const client = yield* getClientProvider;
@@ -71770,12 +72321,12 @@ var release2 = make29("release", {
71770
72321
  var discard = make29("discard", {
71771
72322
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
71772
72323
  yes: Boolean6("yes").pipe(withDefault5(false)),
72324
+ mailbox: mailboxIdArgument,
71773
72325
  messageId: messageIdArgument,
71774
- mailbox: mailboxFlag,
71775
72326
  json: jsonFlag
71776
72327
  }).pipe(withDescription3("Discard a held message for good as a person signed in with samva login"), withExamples([
71777
72328
  {
71778
- command: "samva mailboxes quarantine discard msg_1234567890123456 --mailbox mbx_1234567890123456"
72329
+ command: "samva mailboxes quarantine discard mbx_1234567890123456 msg_1234567890123456"
71779
72330
  }
71780
72331
  ]), withHandler(({ messageId, mailbox, dryRun, yes, json }) => gen2(function* () {
71781
72332
  if (dryRun)
@@ -71822,6 +72373,519 @@ var mailboxesCommand = make29("mailboxes").pipe(withDescription3("Mailbox readin
71822
72373
  make29("quarantine").pipe(withSubcommands([quarantineList, release2, discard]))
71823
72374
  ]));
71824
72375
 
72376
+ // ../sdk/dist/effect/generated/namespaces.js
72377
+ var NamespaceSummary = /* @__PURE__ */ Struct({
72378
+ id: NamespaceId2,
72379
+ name: String4,
72380
+ createdAt: String4
72381
+ }).annotate({ identifier: "NamespaceSummary" });
72382
+ var NamespaceUsage = /* @__PURE__ */ Struct({
72383
+ namespaceId: NamespaceId2,
72384
+ periodStart: String4,
72385
+ periodEnd: String4,
72386
+ emailCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
72387
+ totalMessages: Finite.check(isFinite4().annotate({ expected: "a finite number" }))
72388
+ }).annotate({ identifier: "NamespaceUsage" });
72389
+ var Namespace = /* @__PURE__ */ Struct({
72390
+ id: NamespaceId2,
72391
+ name: String4,
72392
+ createdAt: String4,
72393
+ metadata: NamespaceMetadata,
72394
+ updatedAt: String4
72395
+ }).annotate({ identifier: "Namespace" });
72396
+ var NamespaceResource = /* @__PURE__ */ Struct({
72397
+ type: NamespaceResourceType,
72398
+ id: String4,
72399
+ namespaceId: Union2([NamespaceId2, Null2])
72400
+ }).annotate({ identifier: "NamespaceResource" });
72401
+ var NamespacePage = /* @__PURE__ */ Struct({
72402
+ items: ArraySchema(NamespaceSummary),
72403
+ nextCursor: Union2([String4, Null2])
72404
+ }).annotate({ identifier: "NamespacePage" });
72405
+ var NamespacesListQuery = /* @__PURE__ */ Struct({
72406
+ limit: optionalKey2(Union2([String4, Null2])),
72407
+ cursor: optionalKey2(Union2([Cursor, Null2])),
72408
+ after: optionalKey2(Union2([String4, Null2])),
72409
+ before: optionalKey2(Union2([String4, Null2]))
72410
+ });
72411
+ var NamespacesList200 = NamespacePage;
72412
+ var NamespacesList401 = UnauthorizedError2;
72413
+ var NamespacesList403 = ForbiddenError2;
72414
+ var NamespacesList422 = ValidationError2;
72415
+ var NamespacesList500 = InternalError2;
72416
+ var NamespacesList504 = GatewayTimeoutError2;
72417
+ var NamespacesCreateRequestJson = /* @__PURE__ */ Struct({
72418
+ name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(128).annotate({ expected: "a string with at most 128 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^\\S[\\s\\S]*\\S$|^\\S$|^$", "u")).annotate({ expected: "a string matching the RegExp ^\\S[\\s\\S]*\\S$|^\\S$|^$" })).check(isMaxLength(128).annotate({ expected: "a value with a length of at most 128" })),
72419
+ metadata: optionalKey2(Union2([NamespaceMetadata, Null2]))
72420
+ });
72421
+ var NamespacesCreate201 = Namespace;
72422
+ var NamespacesCreate401 = UnauthorizedError2;
72423
+ var NamespacesCreate403 = ForbiddenError2;
72424
+ var NamespacesCreate409 = ConflictError2;
72425
+ var NamespacesCreate422 = ValidationError2;
72426
+ var NamespacesCreate500 = InternalError2;
72427
+ var NamespacesCreate504 = GatewayTimeoutError2;
72428
+ var NamespacesGetPathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72429
+ var NamespacesGet200 = Namespace;
72430
+ var NamespacesGet401 = UnauthorizedError2;
72431
+ var NamespacesGet403 = ForbiddenError2;
72432
+ var NamespacesGet404 = ResourceNotFoundError2;
72433
+ var NamespacesGet422 = ValidationError2;
72434
+ var NamespacesGet500 = InternalError2;
72435
+ var NamespacesGet504 = GatewayTimeoutError2;
72436
+ var NamespacesRemovePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72437
+ var NamespacesRemove200 = SuccessResponse2;
72438
+ var NamespacesRemove401 = UnauthorizedError2;
72439
+ var NamespacesRemove403 = ForbiddenError2;
72440
+ var NamespacesRemove404 = ResourceNotFoundError2;
72441
+ var NamespacesRemove409 = ConflictError2;
72442
+ var NamespacesRemove422 = ValidationError2;
72443
+ var NamespacesRemove500 = InternalError2;
72444
+ var NamespacesRemove504 = GatewayTimeoutError2;
72445
+ var NamespacesUpdatePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72446
+ var NamespacesUpdateRequestJson = /* @__PURE__ */ Struct({
72447
+ name: optionalKey2(Union2([String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(128).annotate({ expected: "a string with at most 128 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^\\S[\\s\\S]*\\S$|^\\S$|^$", "u")).annotate({ expected: "a string matching the RegExp ^\\S[\\s\\S]*\\S$|^\\S$|^$" })).check(isMaxLength(128).annotate({ expected: "a value with a length of at most 128" })), Null2])),
72448
+ metadata: optionalKey2(Union2([Record(String4, Union2([String4, Null2])), Null2]))
72449
+ });
72450
+ var NamespacesUpdate200 = Namespace;
72451
+ var NamespacesUpdate401 = UnauthorizedError2;
72452
+ var NamespacesUpdate403 = ForbiddenError2;
72453
+ var NamespacesUpdate404 = ResourceNotFoundError2;
72454
+ var NamespacesUpdate409 = ConflictError2;
72455
+ var NamespacesUpdate422 = ValidationError2;
72456
+ var NamespacesUpdate500 = InternalError2;
72457
+ var NamespacesUpdate504 = GatewayTimeoutError2;
72458
+ var NamespacesAssignResourcePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72459
+ var NamespacesAssignResourceRequestJson = /* @__PURE__ */ Struct({
72460
+ type: NamespaceResourceType,
72461
+ resourceId: String4.annotate({ description: "The resource's id, such as `dom_...` for a domain." })
72462
+ });
72463
+ var NamespacesAssignResource200 = NamespaceResource;
72464
+ var NamespacesAssignResource401 = UnauthorizedError2;
72465
+ var NamespacesAssignResource403 = ForbiddenError2;
72466
+ var NamespacesAssignResource404 = ResourceNotFoundError2;
72467
+ var NamespacesAssignResource409 = ConflictError2;
72468
+ var NamespacesAssignResource422 = ValidationError2;
72469
+ var NamespacesAssignResource500 = InternalError2;
72470
+ var NamespacesAssignResource504 = GatewayTimeoutError2;
72471
+ var NamespacesRemoveResourcePathParams = /* @__PURE__ */ Struct({
72472
+ id: NamespaceId2,
72473
+ type: NamespaceResourceType,
72474
+ resourceId: String4
72475
+ });
72476
+ var NamespacesRemoveResource200 = NamespaceResource;
72477
+ var NamespacesRemoveResource401 = UnauthorizedError2;
72478
+ var NamespacesRemoveResource403 = ForbiddenError2;
72479
+ var NamespacesRemoveResource404 = ResourceNotFoundError2;
72480
+ var NamespacesRemoveResource409 = ConflictError2;
72481
+ var NamespacesRemoveResource422 = ValidationError2;
72482
+ var NamespacesRemoveResource500 = InternalError2;
72483
+ var NamespacesRemoveResource504 = GatewayTimeoutError2;
72484
+ var NamespacesGetUsagePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72485
+ var NamespacesGetUsageQuery = /* @__PURE__ */ Struct({
72486
+ after: optionalKey2(Union2([String4, Null2])),
72487
+ before: optionalKey2(Union2([String4, Null2]))
72488
+ });
72489
+ var NamespacesGetUsage200 = NamespaceUsage;
72490
+ var NamespacesGetUsage401 = UnauthorizedError2;
72491
+ var NamespacesGetUsage403 = ForbiddenError2;
72492
+ var NamespacesGetUsage404 = ResourceNotFoundError2;
72493
+ var NamespacesGetUsage422 = ValidationError2;
72494
+ var NamespacesGetUsage500 = InternalError2;
72495
+ var NamespacesGetUsage504 = GatewayTimeoutError2;
72496
+ var NamespacesGroup = class extends make37("Namespaces").add(get5("namespacesList", "/v1/namespaces", {
72497
+ query: NamespacesListQuery,
72498
+ success: NamespacesList200,
72499
+ error: [
72500
+ NamespacesList401.pipe(status(401)),
72501
+ NamespacesList403.pipe(status(403)),
72502
+ NamespacesList422.pipe(status(422)),
72503
+ NamespacesList500,
72504
+ NamespacesList504.pipe(status(504))
72505
+ ]
72506
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.list").annotate(Summary, "List namespaces").annotate(Description, "Returns namespace summaries, newest first, filterable by creation time (`after`, `before`). Pass `nextCursor` back as `cursor` for the next page; it is null on the last page. Read a namespace's metadata with `GET /v1/namespaces/{id}`."), post("namespacesCreate", "/v1/namespaces", {
72507
+ payload: NamespacesCreateRequestJson,
72508
+ success: NamespacesCreate201.pipe(status(201)),
72509
+ error: [
72510
+ NamespacesCreate401.pipe(status(401)),
72511
+ NamespacesCreate403.pipe(status(403)),
72512
+ NamespacesCreate409.pipe(status(409)),
72513
+ NamespacesCreate422.pipe(status(422)),
72514
+ NamespacesCreate500,
72515
+ NamespacesCreate504.pipe(status(504))
72516
+ ]
72517
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.create").annotate(Summary, "Create a namespace").annotate(Description, "Creates a namespace with status 201. Names are unique within the organization; a duplicate conflicts."), get5("namespacesGet", "/v1/namespaces/:id", {
72518
+ params: NamespacesGetPathParams,
72519
+ success: NamespacesGet200,
72520
+ error: [
72521
+ NamespacesGet401.pipe(status(401)),
72522
+ NamespacesGet403.pipe(status(403)),
72523
+ NamespacesGet404.pipe(status(404)),
72524
+ NamespacesGet422.pipe(status(422)),
72525
+ NamespacesGet500,
72526
+ NamespacesGet504.pipe(status(504))
72527
+ ]
72528
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.get").annotate(Summary, "Get a namespace").annotate(Description, "Returns one namespace."), del("namespacesRemove", "/v1/namespaces/:id", {
72529
+ params: NamespacesRemovePathParams,
72530
+ success: NamespacesRemove200,
72531
+ error: [
72532
+ NamespacesRemove401.pipe(status(401)),
72533
+ NamespacesRemove403.pipe(status(403)),
72534
+ NamespacesRemove404.pipe(status(404)),
72535
+ NamespacesRemove409.pipe(status(409)),
72536
+ NamespacesRemove422.pipe(status(422)),
72537
+ NamespacesRemove500,
72538
+ NamespacesRemove504.pipe(status(504))
72539
+ ]
72540
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.remove").annotate(Summary, "Delete a namespace").annotate(Description, "Deletes an empty namespace. A namespace that still holds anything conflicts, and the error counts what remains: mailboxes, API keys, webhook endpoints filtered to it, domains, senders, contacts, or template projects. Delete each, or return it to organization level with `DELETE /v1/namespaces/{id}/resources/{type}/{resourceId}`; mailboxes, keys, and webhook endpoints cannot move and are deleted. Messages keep the namespace they ran in."), patch("namespacesUpdate", "/v1/namespaces/:id", {
72541
+ params: NamespacesUpdatePathParams,
72542
+ payload: NamespacesUpdateRequestJson,
72543
+ success: NamespacesUpdate200,
72544
+ error: [
72545
+ NamespacesUpdate401.pipe(status(401)),
72546
+ NamespacesUpdate403.pipe(status(403)),
72547
+ NamespacesUpdate404.pipe(status(404)),
72548
+ NamespacesUpdate409.pipe(status(409)),
72549
+ NamespacesUpdate422.pipe(status(422)),
72550
+ NamespacesUpdate500,
72551
+ NamespacesUpdate504.pipe(status(504))
72552
+ ]
72553
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.update").annotate(Summary, "Update a namespace").annotate(Description, "Updates the fields you name and keeps the rest. `metadata` merges into the stored metadata by key, and a `null` value deletes that key."), post("namespacesAssignResource", "/v1/namespaces/:id/resources", {
72554
+ params: NamespacesAssignResourcePathParams,
72555
+ payload: NamespacesAssignResourceRequestJson,
72556
+ success: NamespacesAssignResource200,
72557
+ error: [
72558
+ NamespacesAssignResource401.pipe(status(401)),
72559
+ NamespacesAssignResource403.pipe(status(403)),
72560
+ NamespacesAssignResource404.pipe(status(404)),
72561
+ NamespacesAssignResource409.pipe(status(409)),
72562
+ NamespacesAssignResource422.pipe(status(422)),
72563
+ NamespacesAssignResource500,
72564
+ NamespacesAssignResource504.pipe(status(504))
72565
+ ]
72566
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.assignResource").annotate(Summary, "Move a resource into a namespace").annotate(Description, "Moves a resource from organization level or another namespace into this one. A domain brings its senders; a sender on a domain cannot move alone (assign the domain); a contact brings its identities; a template brings every template in its project. A moved resource stops being a default. An address or external id the namespace already holds conflicts. Keys scoped to the old namespace stop reaching the resource at once. Mailboxes, API keys, and webhook endpoints keep the namespace they were created in."), del("namespacesRemoveResource", "/v1/namespaces/:id/resources/:type/:resourceId", {
72567
+ params: NamespacesRemoveResourcePathParams,
72568
+ success: NamespacesRemoveResource200,
72569
+ error: [
72570
+ NamespacesRemoveResource401.pipe(status(401)),
72571
+ NamespacesRemoveResource403.pipe(status(403)),
72572
+ NamespacesRemoveResource404.pipe(status(404)),
72573
+ NamespacesRemoveResource409.pipe(status(409)),
72574
+ NamespacesRemoveResource422.pipe(status(422)),
72575
+ NamespacesRemoveResource500,
72576
+ NamespacesRemoveResource504.pipe(status(504))
72577
+ ]
72578
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.removeResource").annotate(Summary, "Return a resource to organization level").annotate(Description, "Moves a resource out of this namespace to organization level, with what follows it as in `POST /v1/namespaces/{id}/resources`. A resource in a different namespace is not found."), get5("namespacesGetUsage", "/v1/namespaces/:id/usage", {
72579
+ params: NamespacesGetUsagePathParams,
72580
+ query: NamespacesGetUsageQuery,
72581
+ success: NamespacesGetUsage200,
72582
+ error: [
72583
+ NamespacesGetUsage401.pipe(status(401)),
72584
+ NamespacesGetUsage403.pipe(status(403)),
72585
+ NamespacesGetUsage404.pipe(status(404)),
72586
+ NamespacesGetUsage422.pipe(status(422)),
72587
+ NamespacesGetUsage500,
72588
+ NamespacesGetUsage504.pipe(status(504))
72589
+ ]
72590
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.getUsage").annotate(Summary, "Get namespace usage").annotate(Description, "Counts the messages the namespace sent and received in the window that count toward usage, by channel, with the same statuses as `GET /v1/organizations/usage`. A message counts toward the namespace it was sent or received in: that of the sender, mailbox, or key it used. The organization is billed for every namespace; read this to charge your own customer.")).annotate(Description, "Sub-tenants that confine domains, senders, mailboxes, contacts, templates, and API keys inside an organization") {
72591
+ };
72592
+
72593
+ // ../sdk/dist/effect/namespaces.js
72594
+ var make52 = /* @__PURE__ */ forGroup(NamespacesGroup);
72595
+ var list20 = /* @__PURE__ */ make52("namespacesList");
72596
+ var create10 = /* @__PURE__ */ make52("namespacesCreate");
72597
+ var get23 = /* @__PURE__ */ make52("namespacesGet");
72598
+ var update10 = /* @__PURE__ */ make52("namespacesUpdate");
72599
+ var remove10 = /* @__PURE__ */ make52("namespacesRemove");
72600
+ var assignResource = /* @__PURE__ */ make52("namespacesAssignResource");
72601
+ var removeResource = /* @__PURE__ */ make52("namespacesRemoveResource");
72602
+ var getUsage2 = /* @__PURE__ */ make52("namespacesGetUsage");
72603
+
72604
+ // src/commands/namespaces.ts
72605
+ var idArgument3 = String10("id").pipe(withDescription4("Namespace id (ns_...)"));
72606
+ var optionalString2 = (name, description) => String9(name).pipe(withDescription2(description), optional4);
72607
+ var dryRunFlag4 = Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false));
72608
+ var RESOURCE_FLAGS = ["domain", "sender", "contact", "template"];
72609
+ var resourceFlags = {
72610
+ domain: optionalString2("domain", "Domain id (dom_...)"),
72611
+ sender: optionalString2("sender", "Sender id"),
72612
+ contact: optionalString2("contact", "Contact id"),
72613
+ template: optionalString2("template", "Template id; its whole project moves with it")
72614
+ };
72615
+ var chosenResource = (flags) => {
72616
+ const chosen = RESOURCE_FLAGS.flatMap((type) => {
72617
+ const id = flags[type];
72618
+ return isSome2(id) ? [{ type, id: id.value }] : [];
72619
+ });
72620
+ if (chosen.length !== 1) {
72621
+ return new CliUsageError({
72622
+ code: "resource_flag_required",
72623
+ message: `Pass exactly one resource: ${RESOURCE_FLAGS.map((type) => `--${type} <id>`).join(", ")}.`
72624
+ });
72625
+ }
72626
+ return chosen[0];
72627
+ };
72628
+ var parsePairs = (flag, raw) => gen2(function* () {
72629
+ const metadata = {};
72630
+ for (const pair of raw) {
72631
+ const at = pair.indexOf("=");
72632
+ if (at <= 0) {
72633
+ return yield* new CliUsageError({
72634
+ code: "invalid_metadata",
72635
+ message: `${flag} must be key=value, got "${pair}".`
72636
+ });
72637
+ }
72638
+ metadata[pair.slice(0, at)] = pair.slice(at + 1);
72639
+ }
72640
+ return metadata;
72641
+ });
72642
+ var metadataRows = (metadata) => Object.entries(metadata).map(([key, value]) => [`Metadata ${key}`, value]);
72643
+ var list21 = make29("list", {
72644
+ cursor: optionalString2("cursor", "Resume after this nextCursor from a previous page"),
72645
+ limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
72646
+ after: optionalString2("after", "Only namespaces created after this ISO 8601 instant"),
72647
+ before: optionalString2("before", "Only namespaces created before this ISO 8601 instant"),
72648
+ all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
72649
+ json: jsonFlag
72650
+ }).pipe(withDescription3("List namespaces, newest first"), withExamples([
72651
+ { command: "samva namespaces list" },
72652
+ { command: "samva namespaces list --all --jsonl", description: "Stream every page as JSONL" }
72653
+ ]), withHandler(({ cursor, limit, after, before, all, json }) => gen2(function* () {
72654
+ if (all && !isJsonLinesRequested())
72655
+ return yield* new CliUsageError({
72656
+ code: "all_requires_jsonl",
72657
+ message: "--all is an unbounded traversal and requires --jsonl."
72658
+ });
72659
+ const client = yield* getClientProvider;
72660
+ const query = {
72661
+ limit: getOrUndefined(limit)?.toString(),
72662
+ after: getOrUndefined(after),
72663
+ before: getOrUndefined(before)
72664
+ };
72665
+ const page = (pageCursor) => list20({ ...query, cursor: pageCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list namespaces", error, { cursor: pageCursor ?? null })));
72666
+ let nextCursor = getOrUndefined(cursor);
72667
+ for (;; ) {
72668
+ const data = yield* page(nextCursor);
72669
+ if (isJsonLinesRequested()) {
72670
+ for (const item of data.items)
72671
+ yield* printJsonLine(item);
72672
+ } else if (json) {
72673
+ return yield* printJson(data);
72674
+ } else {
72675
+ if (data.items.length === 0) {
72676
+ return yield* log(`No namespaces yet. Create one with \`samva namespaces create "Acme"\`.`);
72677
+ }
72678
+ for (const item of data.items) {
72679
+ yield* printFields([
72680
+ ["ID", item.id],
72681
+ ["Name", item.name],
72682
+ ["Created", item.createdAt]
72683
+ ]);
72684
+ yield* log("");
72685
+ }
72686
+ if (data.nextCursor !== null)
72687
+ yield* printFields([["Next cursor", data.nextCursor]]);
72688
+ }
72689
+ if (!all || data.nextCursor === null)
72690
+ return;
72691
+ nextCursor = data.nextCursor;
72692
+ }
72693
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72694
+ var create11 = make29("create", {
72695
+ name: String10("name").pipe(withDescription4("Namespace name")),
72696
+ metadata: String9("metadata").pipe(withDescription2("Your own label, key=value (repeatable); Samva stores and never reads it"), atLeast2(0)),
72697
+ dryRun: dryRunFlag4,
72698
+ json: jsonFlag
72699
+ }).pipe(withDescription3("Create a namespace, a sub-tenant for one of your customers"), withExamples([
72700
+ { command: "samva namespaces create Acme --metadata customerId=cus_123" },
72701
+ { command: "samva namespaces create Acme --dry-run --json" }
72702
+ ]), withHandler(({ name, metadata, dryRun, json }) => gen2(function* () {
72703
+ const labels = yield* parsePairs("--metadata", metadata);
72704
+ const request = { name, ...metadata.length === 0 ? {} : { metadata: labels } };
72705
+ if (dryRun)
72706
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.create", request }) : printFields([["Action", "namespaces.create"], ["Name", name], ...metadataRows(labels)]);
72707
+ const client = yield* getClientProvider;
72708
+ const created = yield* create10(request).pipe(client.provide, mapError2((error) => toCliApiError("Could not create namespace", error)));
72709
+ if (json)
72710
+ return yield* printJson(created);
72711
+ yield* printFields([
72712
+ ["ID", created.id],
72713
+ ["Name", created.name],
72714
+ ...metadataRows(created.metadata),
72715
+ ["Created", created.createdAt]
72716
+ ]);
72717
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72718
+ var get24 = make29("get", { id: idArgument3, json: jsonFlag }).pipe(withDescription3("Get a namespace and its metadata"), withExamples([{ command: "samva namespaces get ns_7q2xk9mvt4znw8rh --json" }]), withHandler(({ id, json }) => gen2(function* () {
72719
+ const client = yield* getClientProvider;
72720
+ const namespace = yield* get23({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get namespace", error)));
72721
+ if (json)
72722
+ return yield* printJson(namespace);
72723
+ yield* printFields([
72724
+ ["ID", namespace.id],
72725
+ ["Name", namespace.name],
72726
+ ...metadataRows(namespace.metadata),
72727
+ ["Created", namespace.createdAt],
72728
+ ["Updated", namespace.updatedAt]
72729
+ ]);
72730
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72731
+ var update11 = make29("update", {
72732
+ id: idArgument3,
72733
+ name: optionalString2("name", "New name"),
72734
+ metadata: String9("metadata").pipe(withDescription2("Set a metadata label, key=value (repeatable); other keys are kept"), atLeast2(0)),
72735
+ unsetMetadata: String9("unset-metadata").pipe(withDescription2("Delete a metadata key (repeatable)"), atLeast2(0)),
72736
+ dryRun: dryRunFlag4,
72737
+ json: jsonFlag
72738
+ }).pipe(withDescription3("Rename a namespace or change its metadata"), withExamples([
72739
+ { command: "samva namespaces update ns_7q2xk9mvt4znw8rh --name Acme --metadata plan=pro" },
72740
+ { command: "samva namespaces update ns_7q2xk9mvt4znw8rh --unset-metadata plan" }
72741
+ ]), withHandler(({ id, name, metadata, unsetMetadata, dryRun, json }) => gen2(function* () {
72742
+ const labels = yield* parsePairs("--metadata", metadata);
72743
+ const conflicting = unsetMetadata.filter((key) => (key in labels));
72744
+ if (conflicting.length > 0) {
72745
+ return yield* new CliUsageError({
72746
+ code: "metadata_conflict",
72747
+ message: `--metadata and --unset-metadata both name ${conflicting.join(", ")}.`
72748
+ });
72749
+ }
72750
+ if (isNone2(name) && metadata.length === 0 && unsetMetadata.length === 0) {
72751
+ return yield* new CliUsageError({
72752
+ code: "nothing_to_update",
72753
+ message: "Pass --name, --metadata key=value, or --unset-metadata key."
72754
+ });
72755
+ }
72756
+ const merged = {
72757
+ ...labels,
72758
+ ...Object.fromEntries(unsetMetadata.map((key) => [key, null]))
72759
+ };
72760
+ const request = {
72761
+ ...match(name, { onNone: () => ({}), onSome: (value) => ({ name: value }) }),
72762
+ ...metadata.length === 0 && unsetMetadata.length === 0 ? {} : { metadata: merged }
72763
+ };
72764
+ if (dryRun)
72765
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.update", id, request }) : printFields([
72766
+ ["Action", "namespaces.update"],
72767
+ ["Namespace", id],
72768
+ ["Name", getOrUndefined(name)],
72769
+ ...metadataRows(labels),
72770
+ ...unsetMetadata.map((key) => [`Unset ${key}`, "yes"])
72771
+ ]);
72772
+ const client = yield* getClientProvider;
72773
+ const updated = yield* update10({ id, ...request }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update namespace", error)));
72774
+ if (json)
72775
+ return yield* printJson(updated);
72776
+ yield* printFields([
72777
+ ["ID", updated.id],
72778
+ ["Name", updated.name],
72779
+ ...metadataRows(updated.metadata),
72780
+ ["Updated", updated.updatedAt]
72781
+ ]);
72782
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72783
+ var remove11 = make29("delete", {
72784
+ id: idArgument3,
72785
+ dryRun: dryRunFlag4,
72786
+ yes: Boolean6("yes").pipe(withDefault5(false)),
72787
+ json: jsonFlag
72788
+ }).pipe(withDescription3("Delete an empty namespace; one that still holds anything is refused with a count of what remains"), withExamples([
72789
+ { command: "samva namespaces delete ns_7q2xk9mvt4znw8rh --dry-run" },
72790
+ { command: "samva namespaces delete ns_7q2xk9mvt4znw8rh --yes" }
72791
+ ]), withHandler(({ id, dryRun, yes, json }) => gen2(function* () {
72792
+ if (dryRun)
72793
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.delete", id }) : log(`[dry-run] Would delete namespace ${id}.`);
72794
+ yield* confirmDestructive({
72795
+ yes,
72796
+ json,
72797
+ message: `Delete namespace ${id}?`,
72798
+ nonInteractiveMessage: "Namespace deletion requires --yes in non-interactive mode. Preview with --dry-run."
72799
+ });
72800
+ const client = yield* getClientProvider;
72801
+ const result = yield* remove10({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not delete namespace", error)));
72802
+ if (json)
72803
+ return yield* printJson(result);
72804
+ yield* log(`Deleted namespace ${id}.`);
72805
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72806
+ var assign2 = make29("assign", {
72807
+ id: idArgument3,
72808
+ ...resourceFlags,
72809
+ dryRun: dryRunFlag4,
72810
+ json: jsonFlag
72811
+ }).pipe(withDescription3("Move a domain, sender, contact, or template into a namespace; pass exactly one resource flag"), withExamples([
72812
+ { command: "samva namespaces assign ns_7q2xk9mvt4znw8rh --domain dom_xyz789" },
72813
+ {
72814
+ command: "samva namespaces assign ns_7q2xk9mvt4znw8rh --contact contact_7q2xk9mvt4znw8rh --dry-run"
72815
+ }
72816
+ ]), withHandler(({ id, domain, sender, contact, template, dryRun, json }) => gen2(function* () {
72817
+ const resource = chosenResource({ domain, sender, contact, template });
72818
+ if (resource instanceof CliUsageError)
72819
+ return yield* resource;
72820
+ if (dryRun)
72821
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.assign", id, request: resource }) : log(`[dry-run] Would move ${resource.type} ${resource.id} into ${id}.`);
72822
+ const client = yield* getClientProvider;
72823
+ const moved = yield* assignResource({
72824
+ id,
72825
+ type: resource.type,
72826
+ resourceId: resource.id
72827
+ }).pipe(client.provide, mapError2((error) => toCliApiError("Could not assign resource", error)));
72828
+ if (json)
72829
+ return yield* printJson(moved);
72830
+ yield* printFields([
72831
+ ["Type", moved.type],
72832
+ ["ID", moved.id],
72833
+ ["Namespace", moved.namespaceId]
72834
+ ]);
72835
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72836
+ var unassign = make29("unassign", {
72837
+ id: idArgument3,
72838
+ ...resourceFlags,
72839
+ dryRun: dryRunFlag4,
72840
+ json: jsonFlag
72841
+ }).pipe(withDescription3("Return a domain, sender, contact, or template to organization level; pass exactly one resource flag"), withExamples([
72842
+ { command: "samva namespaces unassign ns_7q2xk9mvt4znw8rh --domain dom_xyz789" }
72843
+ ]), withHandler(({ id, domain, sender, contact, template, dryRun, json }) => gen2(function* () {
72844
+ const resource = chosenResource({ domain, sender, contact, template });
72845
+ if (resource instanceof CliUsageError)
72846
+ return yield* resource;
72847
+ if (dryRun)
72848
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.unassign", id, request: resource }) : log(`[dry-run] Would return ${resource.type} ${resource.id} from ${id} to organization level.`);
72849
+ const client = yield* getClientProvider;
72850
+ const moved = yield* removeResource({
72851
+ id,
72852
+ type: resource.type,
72853
+ resourceId: resource.id
72854
+ }).pipe(client.provide, mapError2((error) => toCliApiError("Could not unassign resource", error)));
72855
+ if (json)
72856
+ return yield* printJson(moved);
72857
+ yield* printFields([
72858
+ ["Type", moved.type],
72859
+ ["ID", moved.id],
72860
+ ["Namespace", moved.namespaceId ?? "organization"]
72861
+ ]);
72862
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72863
+ var usage3 = make29("usage", {
72864
+ id: idArgument3,
72865
+ after: optionalString2("after", "Start of the window, an ISO 8601 instant"),
72866
+ before: optionalString2("before", "End of the window, an ISO 8601 instant"),
72867
+ json: jsonFlag
72868
+ }).pipe(withDescription3("Count the messages a namespace sent and received in a window"), withExamples([
72869
+ { command: "samva namespaces usage ns_7q2xk9mvt4znw8rh --after 2026-10-01T00:00:00Z --json" }
72870
+ ]), withHandler(({ id, after, before, json }) => gen2(function* () {
72871
+ const client = yield* getClientProvider;
72872
+ const data = yield* getUsage2({
72873
+ id,
72874
+ after: getOrUndefined(after),
72875
+ before: getOrUndefined(before)
72876
+ }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get namespace usage", error)));
72877
+ if (json)
72878
+ return yield* printJson(data);
72879
+ yield* printFields([
72880
+ ["Namespace", data.namespaceId],
72881
+ ["Period start", data.periodStart],
72882
+ ["Period end", data.periodEnd],
72883
+ ["Email", data.emailCount],
72884
+ ["Total", data.totalMessages]
72885
+ ]);
72886
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72887
+ var namespacesCommand = make29("namespaces").pipe(withDescription3("Manage namespaces, the sub-tenants of your organization"), withExamples([{ command: "samva namespaces list --json" }]), withSubcommands([list21, create11, get24, update11, remove11, assign2, unassign, usage3]));
72888
+
71825
72889
  // ../sdk/dist/effect/generated/whoami.js
71826
72890
  var WhoamiUser = /* @__PURE__ */ Struct({
71827
72891
  id: String4,
@@ -71872,7 +72936,7 @@ var WhoamiGroup = class extends make37("Whoami").add(get5("whoamiGet", "/v1/whoa
71872
72936
  };
71873
72937
 
71874
72938
  // ../sdk/dist/effect/whoami.js
71875
- var get23 = /* @__PURE__ */ (/* @__PURE__ */ forGroup(WhoamiGroup))("whoamiGet");
72939
+ var get25 = /* @__PURE__ */ (/* @__PURE__ */ forGroup(WhoamiGroup))("whoamiGet");
71876
72940
 
71877
72941
  // src/commands/usage.ts
71878
72942
  var afterFlag2 = String9("after").pipe(withDescription2("Start of the window, an ISO 8601 instant (default: the start of this calendar month)"), optional4);
@@ -71909,7 +72973,7 @@ var usageCommand = make29("usage", {
71909
72973
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
71910
72974
 
71911
72975
  // src/commands/org.ts
71912
- var list20 = make29("list", { json: jsonFlag }).pipe(withDescription3("List the organizations you can access (multi-org under OAuth; single org under API key)"), withExamples([
72976
+ var list22 = make29("list", { json: jsonFlag }).pipe(withDescription3("List the organizations you can access (multi-org under OAuth; single org under API key)"), withExamples([
71913
72977
  {
71914
72978
  command: "samva org list",
71915
72979
  description: "List orgs (OAuth) or show API-key org"
@@ -71973,7 +73037,7 @@ var use = make29("use", { slug: String10("slug") }).pipe(withDescription3("Set t
71973
73037
  })));
71974
73038
  var currentForApiKey = gen2(function* () {
71975
73039
  const client = yield* getClientProvider;
71976
- return yield* get23().pipe(client.provide, mapError2((error) => {
73040
+ return yield* get25().pipe(client.provide, mapError2((error) => {
71977
73041
  const failure = toCliApiError("Could not look up the organization", error);
71978
73042
  return new SamvaCliError({
71979
73043
  message: `Could not look up the organization for SAMVA_API_KEY. ${failure.message}`,
@@ -72014,10 +73078,10 @@ var current = make29("current", { json: jsonFlag }).pipe(withDescription3("Show
72014
73078
  var orgCommand = make29("org").pipe(withDescription3(`Manage organizations. ${AGENT_AUTH_HINT}`), withExamples([
72015
73079
  { command: "samva org list", description: "List accessible organizations" },
72016
73080
  { command: "samva org use my-org-slug", description: "Set active org (OAuth)" }
72017
- ]), withSubcommands([list20, use, current, usageCommand]));
73081
+ ]), withSubcommands([list22, use, current, usageCommand]));
72018
73082
 
72019
73083
  // src/commands/profile.ts
72020
- var list21 = make29("list").pipe(withDescription3("List user-level execution profiles"), withHandler(fnUntraced2(function* () {
73084
+ var list23 = make29("list").pipe(withDescription3("List user-level execution profiles"), withHandler(fnUntraced2(function* () {
72021
73085
  const config = yield* readConfig;
72022
73086
  if ((yield* Json3) || (yield* JsonLines)) {
72023
73087
  return yield* printJson({
@@ -72051,7 +73115,7 @@ var show = make29("show", { name: String10("name").pipe(optional5) }).pipe(withD
72051
73115
  return yield* printJson(output);
72052
73116
  yield* log(`${output.name}${output.orgSlug ? ` ${output.orgSlug}` : ""}`);
72053
73117
  })));
72054
- var create10 = make29("create", {
73118
+ var create12 = make29("create", {
72055
73119
  name: String10("name"),
72056
73120
  org: String9("org").pipe(optional4)
72057
73121
  }).pipe(withDescription3("Create a non-secret execution profile"), withHandler(fnUntraced2(function* ({ name, org }) {
@@ -72081,7 +73145,7 @@ var use2 = make29("use", { name: String10("name") }).pipe(withDescription3("Sele
72081
73145
  yield* writeConfig({ ...config, activeProfile: name });
72082
73146
  yield* printResult({ action: "profile.use", name }, `Active profile set to ${name}.`);
72083
73147
  })));
72084
- var remove10 = make29("delete", {
73148
+ var remove12 = make29("delete", {
72085
73149
  name: String10("name"),
72086
73150
  yes: Boolean6("yes").pipe(withDefault5(false))
72087
73151
  }).pipe(withDescription3("Delete a profile and its OS-keyring credential"), withHandler(fnUntraced2(function* ({ name, yes }) {
@@ -72106,7 +73170,7 @@ var remove10 = make29("delete", {
72106
73170
  yield* (yield* Service4).clear(name);
72107
73171
  yield* printResult({ action: "profile.delete", name }, `Deleted profile ${name}.`);
72108
73172
  })));
72109
- var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list21, show, create10, use2, remove10]));
73173
+ var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list23, show, create12, use2, remove12]));
72110
73174
 
72111
73175
  // ../sdk/dist/effect/generated/scheduled-messages.js
72112
73176
  var ScheduledMessageId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new RegExp("^sched_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
@@ -72293,12 +73357,12 @@ var ScheduledMessagesGroup = class extends make37("Scheduled Messages").add(get5
72293
73357
  };
72294
73358
 
72295
73359
  // ../sdk/dist/effect/scheduled-messages.js
72296
- var make52 = /* @__PURE__ */ forGroup(ScheduledMessagesGroup);
72297
- var list22 = /* @__PURE__ */ make52("scheduledMessagesList");
72298
- var create11 = /* @__PURE__ */ make52("scheduledMessagesCreate");
72299
- var get24 = /* @__PURE__ */ make52("scheduledMessagesGet");
72300
- var cancel = /* @__PURE__ */ make52("scheduledMessagesCancel");
72301
- var resume4 = /* @__PURE__ */ make52("scheduledMessagesResume");
73360
+ var make53 = /* @__PURE__ */ forGroup(ScheduledMessagesGroup);
73361
+ var list24 = /* @__PURE__ */ make53("scheduledMessagesList");
73362
+ var create13 = /* @__PURE__ */ make53("scheduledMessagesCreate");
73363
+ var get26 = /* @__PURE__ */ make53("scheduledMessagesGet");
73364
+ var cancel = /* @__PURE__ */ make53("scheduledMessagesCancel");
73365
+ var resume4 = /* @__PURE__ */ make53("scheduledMessagesResume");
72302
73366
 
72303
73367
  // src/commands/scheduled.ts
72304
73368
  var SCHEDULED_STATUSES = [
@@ -72363,14 +73427,14 @@ var atFlag2 = String9("at").pipe(withDescription2("Absolute send instant as an I
72363
73427
  var timezoneFlag = String9("timezone").pipe(withDescription2("IANA timezone for the schedule, e.g. America/New_York"), optional4);
72364
73428
  var idempotencyKeyFlag3 = String9("idempotency-key").pipe(withDescription2("Idempotency key so retries do not schedule duplicates"), optional4);
72365
73429
  var referenceIdFlag = String9("reference-id").pipe(withDescription2("Your own reference id to correlate this schedule"), optional4);
72366
- var dryRunFlag4 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
73430
+ var dryRunFlag5 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
72367
73431
  var trackOpensFlag3 = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for this scheduled send; recipient opt-out wins"), optional4);
72368
73432
  var trackClicksFlag3 = Literals3("track-clicks", ["on", "off"]).pipe(withDescription2("Override click tracking for this scheduled send; recipient opt-out wins"), optional4);
72369
73433
  var statusFlag2 = Literals3("status", SCHEDULED_STATUSES).pipe(withDescription2("Filter by status"), optional4);
72370
73434
  var cursorFlag4 = String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4);
72371
73435
  var limitFlag4 = Int5("limit").pipe(withDescription2("Items per page"), optional4);
72372
73436
  var allFlag4 = Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false));
72373
- var create12 = make29("create", {
73437
+ var create14 = make29("create", {
72374
73438
  to: toFlag2,
72375
73439
  cc: ccFlag2,
72376
73440
  bcc: bccFlag2,
@@ -72388,7 +73452,7 @@ var create12 = make29("create", {
72388
73452
  referenceId: referenceIdFlag,
72389
73453
  trackOpens: trackOpensFlag3,
72390
73454
  trackClicks: trackClicksFlag3,
72391
- dryRun: dryRunFlag4,
73455
+ dryRun: dryRunFlag5,
72392
73456
  json: jsonFlag
72393
73457
  }).pipe(withDescription3("Schedule an email to send at a future time"), withExamples([
72394
73458
  {
@@ -72497,7 +73561,7 @@ Payload:
72497
73561
  ${truncateForDisplay(JSON.stringify(payload, null, 2))}`);
72498
73562
  }
72499
73563
  const client = yield* getClientProvider;
72500
- const data = yield* create11(payload).pipe(client.provide, mapError2((error) => toCliApiError("Failed to schedule message", error)));
73564
+ const data = yield* create13(payload).pipe(client.provide, mapError2((error) => toCliApiError("Failed to schedule message", error)));
72501
73565
  if (json)
72502
73566
  return yield* printJson(data);
72503
73567
  yield* logInfo(`Message scheduled.
@@ -72511,7 +73575,7 @@ ${truncateForDisplay(JSON.stringify(payload, null, 2))}`);
72511
73575
  yield* logInfo(`
72512
73576
  Inspect it: samva scheduled-messages get ${data.id}`);
72513
73577
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72514
- var list23 = make29("list", {
73578
+ var list25 = make29("list", {
72515
73579
  status: statusFlag2,
72516
73580
  cursor: cursorFlag4,
72517
73581
  limit: limitFlag4,
@@ -72546,7 +73610,7 @@ var list23 = make29("list", {
72546
73610
  if (all) {
72547
73611
  let nextCursor = cursorValue;
72548
73612
  for (;; ) {
72549
- const data = yield* list22({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
73613
+ const data = yield* list24({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
72550
73614
  for (const item of data.items)
72551
73615
  yield* printJsonLine(item);
72552
73616
  if (data.nextCursor === null)
@@ -72554,7 +73618,7 @@ var list23 = make29("list", {
72554
73618
  nextCursor = data.nextCursor;
72555
73619
  }
72556
73620
  }
72557
- const data = yield* list22(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
73621
+ const data = yield* list24(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
72558
73622
  if (isJsonLinesRequested()) {
72559
73623
  for (const item of data.items)
72560
73624
  yield* printJsonLine(item);
@@ -72578,9 +73642,9 @@ var list23 = make29("list", {
72578
73642
  if (data.nextCursor !== null)
72579
73643
  yield* printFields([["Next cursor", data.nextCursor]]);
72580
73644
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72581
- var get25 = 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* () {
73645
+ var get27 = 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* () {
72582
73646
  const client = yield* getClientProvider;
72583
- const data = yield* get24({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not fetch scheduled message", error)));
73647
+ const data = yield* get26({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not fetch scheduled message", error)));
72584
73648
  if (json)
72585
73649
  return yield* printJson(data);
72586
73650
  yield* printFields([
@@ -72661,7 +73725,7 @@ var scheduledMessagesCommand = make29("scheduled-messages").pipe(withDescription
72661
73725
  description: "Schedule an email"
72662
73726
  },
72663
73727
  { command: "samva scheduled-messages list", description: "List scheduled messages" }
72664
- ]), withSubcommands([create12, list23, get25, cancel2, resume5]));
73728
+ ]), withSubcommands([create14, list25, get27, cancel2, resume5]));
72665
73729
 
72666
73730
  // ../sdk/dist/effect/generated/subscriptions.js
72667
73731
  var SubscribeResult = /* @__PURE__ */ Struct({
@@ -72830,6 +73894,7 @@ var TemplateSummary = /* @__PURE__ */ Struct({
72830
73894
  name: String4,
72831
73895
  channel: Literal2("email"),
72832
73896
  projectId: TemplateProjectId2,
73897
+ namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the template's project belongs to; every entry in a project shares it. Null at organization level. A namespace-scoped key reaches only its own namespace's templates." }),
72833
73898
  entryPath: String4.check(isMaxCodePoints(1024).annotate({ expected: "a string with at most 1024 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$", "u")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })).check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })),
72834
73899
  status: Union2([
72835
73900
  Literal2("draft"),
@@ -72854,6 +73919,7 @@ var Template = /* @__PURE__ */ Struct({
72854
73919
  name: String4,
72855
73920
  channel: Literal2("email"),
72856
73921
  projectId: TemplateProjectId2,
73922
+ namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the template's project belongs to; every entry in a project shares it. Null at organization level. A namespace-scoped key reaches only its own namespace's templates." }),
72857
73923
  entryPath: String4.check(isMaxCodePoints(1024).annotate({ expected: "a string with at most 1024 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$", "u")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })).check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })),
72858
73924
  status: Union2([
72859
73925
  Literal2("draft"),
@@ -72937,7 +74003,8 @@ var TemplatesListQuery = /* @__PURE__ */ Struct({
72937
74003
  Literal2("archived")
72938
74004
  ]), Null2])),
72939
74005
  search: optionalKey2(Union2([String4, Null2])),
72940
- projectId: optionalKey2(Union2([TemplateProjectId2, Null2]))
74006
+ projectId: optionalKey2(Union2([TemplateProjectId2, Null2])),
74007
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Only templates in this namespace. A namespace-scoped key lists its own namespace's templates only." }))
72941
74008
  });
72942
74009
  var TemplatesList200 = TemplatePage;
72943
74010
  var TemplatesList401 = UnauthorizedError2;
@@ -72962,11 +74029,13 @@ var TemplatesCreateRequestJson = /* @__PURE__ */ Struct({
72962
74029
  Literal2("alert")
72963
74030
  ]), Null2]), Null2])),
72964
74031
  isActive: optionalKey2(Union2([Boolean3, Null2])),
74032
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the new template project belongs to; the project and every entry added to it share it. Omit for organization level. A namespace-scoped key always creates in its own namespace." })),
72965
74033
  idempotencyKey: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
72966
74034
  });
72967
74035
  var TemplatesCreate201 = Template;
72968
74036
  var TemplatesCreate401 = UnauthorizedError2;
72969
74037
  var TemplatesCreate403 = ForbiddenError2;
74038
+ var TemplatesCreate404 = ResourceNotFoundError2;
72970
74039
  var TemplatesCreate409 = ConflictError2;
72971
74040
  var TemplatesCreate422 = ValidationError2;
72972
74041
  var TemplatesCreate500 = InternalError2;
@@ -74592,6 +75661,7 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
74592
75661
  error: [
74593
75662
  TemplatesCreate401.pipe(status(401)),
74594
75663
  TemplatesCreate403.pipe(status(403)),
75664
+ TemplatesCreate404.pipe(status(404)),
74595
75665
  TemplatesCreate409.pipe(status(409)),
74596
75666
  TemplatesCreate422.pipe(status(422)),
74597
75667
  TemplatesCreate500,
@@ -74668,7 +75738,7 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
74668
75738
  TemplatesPublish500,
74669
75739
  TemplatesPublish504.pipe(status(504))
74670
75740
  ]
74671
- }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.publish").annotate(Summary, "Publish an exact template commit").annotate(Description, "Builds an exact Git commit and entry path, stores the immutable compiled IR and its assets, records the input contract it validates against, and makes that publication current."), get5("templatesGetPublication", "/v1/templates/:id/publications/:publicationId", {
75741
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.publish").annotate(Summary, "Publish an exact template commit").annotate(Description, "Builds an exact Git commit and entry path, stores the immutable compiled IR and its assets, records the input contract it validates against, and makes that publication current. A commit that compiles to the same build as an existing publication makes that publication current again instead of recording another."), get5("templatesGetPublication", "/v1/templates/:id/publications/:publicationId", {
74672
75742
  params: TemplatesGetPublicationPathParams,
74673
75743
  success: TemplatesGetPublication200,
74674
75744
  error: [
@@ -74980,24 +76050,24 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
74980
76050
  };
74981
76051
 
74982
76052
  // ../sdk/dist/effect/templates.js
74983
- var make53 = /* @__PURE__ */ forGroup(TemplatesGroup);
74984
- var list24 = /* @__PURE__ */ make53("templatesList");
74985
- var create13 = /* @__PURE__ */ make53("templatesCreate");
74986
- var addEntry = /* @__PURE__ */ make53("templatesAddEntry");
74987
- var getById = /* @__PURE__ */ make53("templatesGetById");
74988
- var remove11 = /* @__PURE__ */ make53("templatesRemove");
74989
- var update10 = /* @__PURE__ */ make53("templatesUpdate");
74990
- var openWorkspace = /* @__PURE__ */ make53("templatesOpenWorkspace");
74991
- var getGitRepository = /* @__PURE__ */ make53("templatesGetGitRepository");
74992
- var issueGitCredential = /* @__PURE__ */ make53("templatesIssueGitCredential");
74993
- var patchWorkspace = /* @__PURE__ */ make53("templatesPatchWorkspace");
74994
- var putWorkspaceAsset = /* @__PURE__ */ make53("templatesPutWorkspaceAsset");
74995
- var saveWorkspace = /* @__PURE__ */ make53("templatesSaveWorkspace");
74996
- var checkWorkspace = /* @__PURE__ */ make53("templatesCheckWorkspace");
74997
- var renderWorkspaceFixture = /* @__PURE__ */ make53("templatesRenderWorkspaceFixture");
74998
- var publish5 = /* @__PURE__ */ make53("templatesPublish");
74999
- var diffWorkspace = /* @__PURE__ */ make53("templatesDiffWorkspace");
75000
- var workspaceHistory = /* @__PURE__ */ make53("templatesWorkspaceHistory");
76053
+ var make54 = /* @__PURE__ */ forGroup(TemplatesGroup);
76054
+ var list26 = /* @__PURE__ */ make54("templatesList");
76055
+ var create15 = /* @__PURE__ */ make54("templatesCreate");
76056
+ var addEntry = /* @__PURE__ */ make54("templatesAddEntry");
76057
+ var getById = /* @__PURE__ */ make54("templatesGetById");
76058
+ var remove13 = /* @__PURE__ */ make54("templatesRemove");
76059
+ var update12 = /* @__PURE__ */ make54("templatesUpdate");
76060
+ var openWorkspace = /* @__PURE__ */ make54("templatesOpenWorkspace");
76061
+ var getGitRepository = /* @__PURE__ */ make54("templatesGetGitRepository");
76062
+ var issueGitCredential = /* @__PURE__ */ make54("templatesIssueGitCredential");
76063
+ var patchWorkspace = /* @__PURE__ */ make54("templatesPatchWorkspace");
76064
+ var putWorkspaceAsset = /* @__PURE__ */ make54("templatesPutWorkspaceAsset");
76065
+ var saveWorkspace = /* @__PURE__ */ make54("templatesSaveWorkspace");
76066
+ var checkWorkspace = /* @__PURE__ */ make54("templatesCheckWorkspace");
76067
+ var renderWorkspaceFixture = /* @__PURE__ */ make54("templatesRenderWorkspaceFixture");
76068
+ var publish5 = /* @__PURE__ */ make54("templatesPublish");
76069
+ var diffWorkspace = /* @__PURE__ */ make54("templatesDiffWorkspace");
76070
+ var workspaceHistory = /* @__PURE__ */ make54("templatesWorkspaceHistory");
75001
76071
 
75002
76072
  // src/commands/templates/dev-command.ts
75003
76073
  import { resolve as resolve8 } from "path";
@@ -75659,7 +76729,7 @@ var listProjectTemplates = fn2("Templates.listProjectTemplates")(function* (proj
75659
76729
  const templates = [];
75660
76730
  let cursor;
75661
76731
  for (;; ) {
75662
- const data = yield* list24({
76732
+ const data = yield* list26({
75663
76733
  projectId,
75664
76734
  cursor,
75665
76735
  limit: PROJECT_PAGE_SIZE.toString()
@@ -75818,7 +76888,7 @@ ${starter.value}` : ""}`))).slice(0, 48)}`
75818
76888
  }
75819
76889
  }
75820
76890
  const client = yield* getClientProvider;
75821
- const created = yield* create13(request).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template project", error)));
76891
+ const created = yield* create15(request).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template project", error)));
75822
76892
  const result = yield* cloneProject({ id: created.id, dir: root });
75823
76893
  const payload = { ...result, action: "templates.init" };
75824
76894
  if (json)
@@ -75988,7 +77058,7 @@ var move = make29("move", {
75988
77058
  });
75989
77059
  }
75990
77060
  const client = yield* getClientProvider;
75991
- const moved = yield* update10({ id: template.id, data: { entryPath: to } }).pipe(client.provide, mapError2((error) => toCliApiError("Could not move template entry", error)));
77061
+ const moved = yield* update12({ id: template.id, data: { entryPath: to } }).pipe(client.provide, mapError2((error) => toCliApiError("Could not move template entry", error)));
75992
77062
  if (json)
75993
77063
  return yield* printJson(moved);
75994
77064
  yield* printFields([
@@ -77019,7 +78089,7 @@ var readCatalog = fn2("templates.types.readCatalog")(function* () {
77019
78089
  const ids = [];
77020
78090
  let cursor;
77021
78091
  for (;; ) {
77022
- const data = yield* list24({
78092
+ const data = yield* list26({
77023
78093
  cursor,
77024
78094
  limit: CATALOG_PAGE_SIZE.toString()
77025
78095
  }).pipe(client.provide, mapError2(catalogError));
@@ -77343,7 +78413,7 @@ var workspaceCommand = make29("workspace").pipe(withDescription3("Author a templ
77343
78413
 
77344
78414
  // src/commands/templates.ts
77345
78415
  var tsconfigFlag = String9("tsconfig").pipe(withDescription2("TypeScript project used to check authored templates"), withDefault5("tsconfig.json"));
77346
- var dryRunFlag5 = Boolean6("dry-run").pipe(withDescription2("Show the request without calling the API"), withDefault5(false));
78416
+ var dryRunFlag6 = Boolean6("dry-run").pipe(withDescription2("Show the request without calling the API"), withDefault5(false));
77347
78417
  var templateIdArgument2 = String10("id").pipe(withDescription4("Remote template id"));
77348
78418
  var parseObject = (raw, flag) => try_3({
77349
78419
  try: () => JSON.parse(raw),
@@ -77709,9 +78779,10 @@ var build3 = make29("build", {
77709
78779
  var listRemote = make29("list", {
77710
78780
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
77711
78781
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
78782
+ namespace: namespaceFlag("list"),
77712
78783
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
77713
78784
  json: jsonFlag
77714
- }).pipe(withDescription3("List remote templates"), withExamples([{ command: "samva templates list --json" }]), withHandler(({ cursor, limit, all, json }) => gen2(function* () {
78785
+ }).pipe(withDescription3("List remote templates"), withExamples([{ command: "samva templates list --json" }]), withHandler(({ cursor, limit, namespace, all, json }) => gen2(function* () {
77715
78786
  if (all && !isJsonLinesRequested())
77716
78787
  return yield* new CliUsageError({
77717
78788
  code: "all_requires_jsonl",
@@ -77720,11 +78791,15 @@ var listRemote = make29("list", {
77720
78791
  const client = yield* getClientProvider;
77721
78792
  const cursorValue = getOrUndefined(cursor);
77722
78793
  const limitValue = getOrUndefined(limit);
77723
- const query = { cursor: cursorValue, limit: limitValue?.toString() };
78794
+ const query = {
78795
+ cursor: cursorValue,
78796
+ limit: limitValue?.toString(),
78797
+ ...namespaceField(namespace)
78798
+ };
77724
78799
  if (all) {
77725
78800
  let nextCursor = cursorValue;
77726
78801
  for (;; ) {
77727
- const data = yield* list24({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
78802
+ const data = yield* list26({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
77728
78803
  for (const item of data.items)
77729
78804
  yield* printJsonLine(item);
77730
78805
  if (data.nextCursor === null)
@@ -77732,7 +78807,7 @@ var listRemote = make29("list", {
77732
78807
  nextCursor = data.nextCursor;
77733
78808
  }
77734
78809
  }
77735
- const data = yield* list24(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
78810
+ const data = yield* list26(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
77736
78811
  if (isJsonLinesRequested()) {
77737
78812
  for (const item of data.items)
77738
78813
  yield* printJsonLine(item);
@@ -77745,7 +78820,8 @@ var listRemote = make29("list", {
77745
78820
  ["ID", item.id],
77746
78821
  ["Name", item.name],
77747
78822
  ["Slug", item.slug],
77748
- ["Status", item.status]
78823
+ ["Status", item.status],
78824
+ ["Namespace", item.namespaceId ?? "organization"]
77749
78825
  ]);
77750
78826
  if (data.nextCursor !== null)
77751
78827
  yield* printFields([["Next cursor", data.nextCursor]]);
@@ -77759,21 +78835,28 @@ var getRemote = make29("get", { id: templateIdArgument2, json: jsonFlag }).pipe(
77759
78835
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
77760
78836
  var createRemote = make29("create", {
77761
78837
  data: String9("data").pipe(withDescription2("Complete template JSON payload")),
77762
- dryRun: dryRunFlag5,
78838
+ namespace: namespaceFlag("create"),
78839
+ dryRun: dryRunFlag6,
77763
78840
  json: jsonFlag
77764
78841
  }).pipe(withDescription3("Create a remote template from JSON"), withExamples([
77765
78842
  {
77766
78843
  command: `samva templates create --data '{"name":"Welcome","projectName":"welcome-email","idempotencyKey":"welcome-email-v1"}' --dry-run`
77767
78844
  }
77768
- ]), withHandler(({ data, dryRun, json }) => gen2(function* () {
77769
- const payload = yield* decodePayload(data, "--data", CreateTemplatePayload);
78845
+ ]), withHandler(({ data, namespace, dryRun, json }) => gen2(function* () {
78846
+ const decoded = yield* decodePayload(data, "--data", CreateTemplatePayload);
78847
+ if (isSome2(namespace) && decoded.namespaceId != null && decoded.namespaceId !== namespace.value)
78848
+ return yield* new CliUsageError({
78849
+ code: "namespace_conflict",
78850
+ message: "--namespace and the namespaceId in --data name different namespaces."
78851
+ });
78852
+ const payload = { ...decoded, ...namespaceField(namespace) };
77770
78853
  if (dryRun)
77771
78854
  return yield* json ? printJson({ dryRun: true, action: "templates.create", request: payload }) : printFields([
77772
78855
  ["Action", "templates.create"],
77773
78856
  ...objectRows(payload, { explicit: true })
77774
78857
  ]);
77775
78858
  const client = yield* getClientProvider;
77776
- const result = yield* create13(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template", error)));
78859
+ const result = yield* create15(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template", error)));
77777
78860
  if (json)
77778
78861
  return yield* printJson(result);
77779
78862
  yield* printFields(objectRows(result));
@@ -77781,7 +78864,7 @@ var createRemote = make29("create", {
77781
78864
  var updateRemote = make29("update", {
77782
78865
  id: templateIdArgument2,
77783
78866
  data: String9("data").pipe(withDescription2("JSON object of template fields to update")),
77784
- dryRun: dryRunFlag5,
78867
+ dryRun: dryRunFlag6,
77785
78868
  json: jsonFlag
77786
78869
  }).pipe(withDescription3("Update a remote template from JSON"), withExamples([
77787
78870
  {
@@ -77797,14 +78880,14 @@ var updateRemote = make29("update", {
77797
78880
  ...objectRows(payload, { explicit: true })
77798
78881
  ]);
77799
78882
  const client = yield* getClientProvider;
77800
- const result = yield* update10({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update template", error)));
78883
+ const result = yield* update12({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update template", error)));
77801
78884
  if (json)
77802
78885
  return yield* printJson(result);
77803
78886
  yield* printFields(objectRows(result));
77804
78887
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
77805
78888
  var removeRemote = make29("remove", {
77806
78889
  id: templateIdArgument2,
77807
- dryRun: dryRunFlag5,
78890
+ dryRun: dryRunFlag6,
77808
78891
  yes: Boolean6("yes").pipe(withDescription2("Confirm destructive state change"), withDefault5(false)),
77809
78892
  json: jsonFlag
77810
78893
  }).pipe(withDescription3("Deactivate a remote template; its project file and publications remain"), withExamples([{ command: "samva templates remove tmpl_abc123 --dry-run" }]), withHandler(({ id, dryRun, yes, json }) => gen2(function* () {
@@ -77817,7 +78900,7 @@ var removeRemote = make29("remove", {
77817
78900
  nonInteractiveMessage: "remove requires --yes in non-interactive mode. Preview with --dry-run."
77818
78901
  });
77819
78902
  const client = yield* getClientProvider;
77820
- const result = yield* remove11({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove template", error)));
78903
+ const result = yield* remove13({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove template", error)));
77821
78904
  if (json)
77822
78905
  return yield* printJson(result);
77823
78906
  yield* printFields([
@@ -78453,20 +79536,20 @@ var WebhooksGroup = class extends make37("Webhooks").add(get5("webhooksList", "/
78453
79536
  };
78454
79537
 
78455
79538
  // ../sdk/dist/effect/webhooks.js
78456
- var make54 = /* @__PURE__ */ forGroup(WebhooksGroup);
78457
- var list25 = /* @__PURE__ */ make54("webhooksList");
78458
- var create14 = /* @__PURE__ */ make54("webhooksCreate");
78459
- var get26 = /* @__PURE__ */ make54("webhooksGet");
78460
- var remove12 = /* @__PURE__ */ make54("webhooksRemove");
78461
- var update11 = /* @__PURE__ */ make54("webhooksUpdate");
78462
- var test = /* @__PURE__ */ make54("webhooksTest");
78463
- var getLogs = /* @__PURE__ */ make54("webhooksGetLogs");
78464
- var getStats = /* @__PURE__ */ make54("webhooksGetStats");
78465
- var retryDelivery = /* @__PURE__ */ make54("webhooksRetryDelivery");
78466
- var regenerateSecret = /* @__PURE__ */ make54("webhooksRegenerateSecret");
79539
+ var make55 = /* @__PURE__ */ forGroup(WebhooksGroup);
79540
+ var list27 = /* @__PURE__ */ make55("webhooksList");
79541
+ var create16 = /* @__PURE__ */ make55("webhooksCreate");
79542
+ var get28 = /* @__PURE__ */ make55("webhooksGet");
79543
+ var remove14 = /* @__PURE__ */ make55("webhooksRemove");
79544
+ var update13 = /* @__PURE__ */ make55("webhooksUpdate");
79545
+ var test = /* @__PURE__ */ make55("webhooksTest");
79546
+ var getLogs = /* @__PURE__ */ make55("webhooksGetLogs");
79547
+ var getStats = /* @__PURE__ */ make55("webhooksGetStats");
79548
+ var retryDelivery = /* @__PURE__ */ make55("webhooksRetryDelivery");
79549
+ var regenerateSecret = /* @__PURE__ */ make55("webhooksRegenerateSecret");
78467
79550
 
78468
79551
  // src/commands/webhooks.ts
78469
- var idArgument3 = String10("id").pipe(withDescription4("Webhook id"));
79552
+ var idArgument4 = String10("id").pipe(withDescription4("Webhook id"));
78470
79553
  var parseObject2 = (raw, flag) => try_3({
78471
79554
  try: () => JSON.parse(raw),
78472
79555
  catch: () => new SamvaCliError({ message: `${flag} must be a valid JSON object.` })
@@ -78487,7 +79570,7 @@ var readData = (raw) => {
78487
79570
  message: `Could not read webhook test data from ${path}.`
78488
79571
  })));
78489
79572
  };
78490
- var list26 = make29("list", {
79573
+ var list28 = make29("list", {
78491
79574
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
78492
79575
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
78493
79576
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
@@ -78505,7 +79588,7 @@ var list26 = make29("list", {
78505
79588
  if (all) {
78506
79589
  let nextCursor = cursorValue;
78507
79590
  for (;; ) {
78508
- const data = yield* list25({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
79591
+ const data = yield* list27({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
78509
79592
  for (const item of data.items)
78510
79593
  yield* printJsonLine(item);
78511
79594
  if (data.nextCursor === null)
@@ -78513,7 +79596,7 @@ var list26 = make29("list", {
78513
79596
  nextCursor = data.nextCursor;
78514
79597
  }
78515
79598
  }
78516
- const data = yield* list25(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
79599
+ const data = yield* list27(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
78517
79600
  if (isJsonLinesRequested()) {
78518
79601
  for (const item of data.items)
78519
79602
  yield* printJsonLine(item);
@@ -78533,9 +79616,9 @@ var list26 = make29("list", {
78533
79616
  if (data.nextCursor !== null)
78534
79617
  yield* printFields([["Next cursor", data.nextCursor]]);
78535
79618
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78536
- var get27 = make29("get", { id: idArgument3, json: jsonFlag }).pipe(withDescription3("Get a customer webhook"), withExamples([{ command: "samva webhooks get wep_abc123 --json" }]), withHandler(({ id, json }) => gen2(function* () {
79619
+ var get29 = make29("get", { id: idArgument4, json: jsonFlag }).pipe(withDescription3("Get a customer webhook"), withExamples([{ command: "samva webhooks get wep_abc123 --json" }]), withHandler(({ id, json }) => gen2(function* () {
78537
79620
  const client = yield* getClientProvider;
78538
- const data = yield* get26({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get webhook", error)));
79621
+ const data = yield* get28({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get webhook", error)));
78539
79622
  if (json)
78540
79623
  return yield* printJson(data);
78541
79624
  yield* printFields([
@@ -78546,7 +79629,7 @@ var get27 = make29("get", { id: idArgument3, json: jsonFlag }).pipe(withDescript
78546
79629
  ]);
78547
79630
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78548
79631
  var logs = make29("logs", {
78549
- id: idArgument3,
79632
+ id: idArgument4,
78550
79633
  limit: Int5("limit").pipe(optional4),
78551
79634
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
78552
79635
  json: jsonFlag
@@ -78609,7 +79692,7 @@ var logs = make29("logs", {
78609
79692
  var statsAfterFlag = String9("after").pipe(withDescription2("Start of the daily series, an ISO 8601 instant (default: 30 days back)"), optional4);
78610
79693
  var statsBeforeFlag = String9("before").pipe(withDescription2("End of the daily series, an ISO 8601 instant (default: end of today)"), optional4);
78611
79694
  var stats3 = make29("stats", {
78612
- id: idArgument3,
79695
+ id: idArgument4,
78613
79696
  after: statsAfterFlag,
78614
79697
  before: statsBeforeFlag,
78615
79698
  json: jsonFlag
@@ -78637,7 +79720,7 @@ var stats3 = make29("stats", {
78637
79720
  ]);
78638
79721
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78639
79722
  var test2 = make29("test", {
78640
- id: idArgument3,
79723
+ id: idArgument4,
78641
79724
  data: String9("data").pipe(withDescription2("JSON object or @file to send as the signed test payload"), optional4),
78642
79725
  dryRun: Boolean6("dry-run").pipe(withDescription2("Validate and preview without sending a request"), withDefault5(false)),
78643
79726
  json: jsonFlag
@@ -78669,7 +79752,7 @@ var test2 = make29("test", {
78669
79752
  ]);
78670
79753
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78671
79754
  var retry4 = make29("retry", {
78672
- id: idArgument3,
79755
+ id: idArgument4,
78673
79756
  deliveryId: String10("delivery-id").pipe(withDescription4("Webhook delivery id")),
78674
79757
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78675
79758
  json: jsonFlag
@@ -78689,7 +79772,7 @@ var retry4 = make29("retry", {
78689
79772
  ]);
78690
79773
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78691
79774
  var rotate3 = make29("rotate-secret", {
78692
- id: idArgument3,
79775
+ id: idArgument4,
78693
79776
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78694
79777
  yes: Boolean6("yes").pipe(withDefault5(false)),
78695
79778
  json: jsonFlag
@@ -78714,7 +79797,7 @@ var rotate3 = make29("rotate-secret", {
78714
79797
  yield* error(`WARNING: ${warning}`);
78715
79798
  yield* log(secret);
78716
79799
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78717
- var create15 = make29("create", {
79800
+ var create17 = make29("create", {
78718
79801
  data: String9("data").pipe(withDescription2("Webhook JSON: name, url, eventTypes, and optional retry settings")),
78719
79802
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78720
79803
  json: jsonFlag
@@ -78730,7 +79813,7 @@ var create15 = make29("create", {
78730
79813
  ...objectRows(payload, { explicit: true })
78731
79814
  ]);
78732
79815
  const client = yield* getClientProvider;
78733
- const result = yield* create14(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create webhook", error)));
79816
+ const result = yield* create16(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create webhook", error)));
78734
79817
  const warning = "This signing secret is shown once. Store it now; `samva webhooks rotate-secret` issues a new one.";
78735
79818
  const secret = value2(result.secret);
78736
79819
  if (json)
@@ -78744,8 +79827,8 @@ var create15 = make29("create", {
78744
79827
  ["Signing secret", secret]
78745
79828
  ]);
78746
79829
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78747
- var update12 = make29("update", {
78748
- id: idArgument3,
79830
+ var update14 = make29("update", {
79831
+ id: idArgument4,
78749
79832
  data: String9("data").pipe(withDescription2("JSON object of webhook fields to update")),
78750
79833
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78751
79834
  json: jsonFlag
@@ -78762,13 +79845,13 @@ var update12 = make29("update", {
78762
79845
  ...objectRows(payload, { explicit: true })
78763
79846
  ]);
78764
79847
  const client = yield* getClientProvider;
78765
- const result = yield* update11({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update webhook", error)));
79848
+ const result = yield* update13({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update webhook", error)));
78766
79849
  if (json)
78767
79850
  return yield* printJson(result);
78768
79851
  yield* printFields(objectRows(result));
78769
79852
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78770
- var remove13 = make29("remove", {
78771
- id: idArgument3,
79853
+ var remove15 = make29("remove", {
79854
+ id: idArgument4,
78772
79855
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78773
79856
  yes: Boolean6("yes").pipe(withDefault5(false)),
78774
79857
  json: jsonFlag
@@ -78785,12 +79868,12 @@ var remove13 = make29("remove", {
78785
79868
  nonInteractiveMessage: "Permanent webhook deletion requires --yes in non-interactive mode. Preview with --dry-run."
78786
79869
  });
78787
79870
  const client = yield* getClientProvider;
78788
- const result = yield* remove12({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove webhook", error)));
79871
+ const result = yield* remove14({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove webhook", error)));
78789
79872
  if (json)
78790
79873
  return yield* printJson(result);
78791
79874
  yield* log(`Removed webhook ${id}.`);
78792
79875
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78793
- var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, and recover customer webhooks"), withExamples([{ command: "samva webhooks list --json" }]), withSubcommands([list26, get27, create15, update12, test2, logs, stats3, retry4, rotate3, remove13]));
79876
+ var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, and recover customer webhooks"), withExamples([{ command: "samva webhooks list --json" }]), withSubcommands([list28, get29, create17, update14, test2, logs, stats3, retry4, rotate3, remove15]));
78794
79877
 
78795
79878
  // src/lib/root-commands.ts
78796
79879
  var rootCommands = [
@@ -78808,6 +79891,7 @@ var rootCommands = [
78808
79891
  templatesCommand,
78809
79892
  brandsCommand,
78810
79893
  mailboxesCommand,
79894
+ namespacesCommand,
78811
79895
  extensionsCommand,
78812
79896
  webhooksCommand,
78813
79897
  apiCommand,