@samva/cli 0.15.0 → 0.16.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 +7 -0
  2. package/dist/bin.mjs +1261 -256
  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.16.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.16.0",
14172
+ "@samva/cli-darwin-x64": "workspace:0.16.0",
14173
+ "@samva/cli-linux-arm64": "workspace:0.16.0",
14174
+ "@samva/cli-linux-x64": "workspace:0.16.0"
14175
14175
  },
14176
14176
  engines: {
14177
14177
  node: ">=18"
@@ -20513,6 +20513,9 @@ var CAMPAIGN_RECIPIENT_SKIPPED_REASON_VALUES = [
20513
20513
  "unsubscribed",
20514
20514
  "blocked",
20515
20515
  "suppressed",
20516
+ "opted_out",
20517
+ "consent_required",
20518
+ "unreachable",
20516
20519
  "no_identity",
20517
20520
  "inactive",
20518
20521
  "run_cancelled",
@@ -20746,6 +20749,56 @@ var categorize = (errorClass, meta) => {
20746
20749
  return errorClass;
20747
20750
  };
20748
20751
 
20752
+ // ../core/src/shared/json.ts
20753
+ var JsonObject = Record(String4, Json2).annotate({
20754
+ identifier: "JsonObject"
20755
+ });
20756
+ var UnknownRecord = Record(String4, Unknown2).annotate({
20757
+ identifier: "UnknownRecord"
20758
+ });
20759
+ var decodeJsonString = decodeSync(fromJsonString2(Json2));
20760
+
20761
+ // ../core/src/templates/variable-values.ts
20762
+ var TemplateVariableValues = JsonObject;
20763
+
20764
+ // ../core/src/mailboxes/chat.ts
20765
+ var MailboxChatChannel = Literals(["whatsapp", "sms"]);
20766
+ var mailboxChatContentFields = {
20767
+ text: optional2(String4.check(isMinLength(1))),
20768
+ templateId: optional2(TemplateId),
20769
+ templateData: optional2(TemplateVariableValues)
20770
+ };
20771
+ var exactlyOneChatContent = makeFilter2((payload) => payload.text === undefined !== (payload.templateId === undefined) && (payload.templateId === undefined || payload.channel === "whatsapp") && (payload.templateData === undefined || payload.templateId !== undefined), {
20772
+ message: "Set exactly one of `text` or `templateId`; a template (with its `templateData`) sends on WhatsApp only."
20773
+ });
20774
+ var MailboxChatTemplate = Struct({
20775
+ templateId: TemplateId,
20776
+ templateChannelVariantId: TemplateChannelVariantId,
20777
+ templateData: NullOr(TemplateVariableValues)
20778
+ }).annotate({ identifier: "MailboxChatTemplate" });
20779
+
20780
+ class WhatsAppServiceWindowClosedError extends TaggedError3()("WhatsAppServiceWindowClosedError", {
20781
+ message: String4,
20782
+ closedAt: NullOr(String4)
20783
+ }, { httpApiStatus: 422 }) {
20784
+ }
20785
+ categorize(WhatsAppServiceWindowClosedError, { categories: ["validation"], retryable: false });
20786
+ var MailboxWhatsAppTemplateOption = Struct({
20787
+ templateId: TemplateId,
20788
+ slug: String4,
20789
+ name: String4,
20790
+ providerName: NullOr(String4),
20791
+ language: NullOr(String4),
20792
+ category: NullOr(String4),
20793
+ sendable: Boolean3,
20794
+ reason: NullOr(String4),
20795
+ inputSchema: NullOr(JsonObject)
20796
+ }).annotate({ identifier: "MailboxWhatsAppTemplateOption" });
20797
+ var MailboxWhatsAppTemplateOptions = Struct({
20798
+ endpointId: MailboxEndpointId,
20799
+ items: ArraySchema(MailboxWhatsAppTemplateOption)
20800
+ }).annotate({ identifier: "MailboxWhatsAppTemplateOptions" });
20801
+
20749
20802
  // ../core/src/shared/errors.ts
20750
20803
  class ResourceNotFoundError extends TaggedError3()("ResourceNotFoundError", {
20751
20804
  resource: String4,
@@ -20965,6 +21018,31 @@ class UnknownStatusError extends TaggedError3()("UnknownStatusError", {
20965
21018
  }
20966
21019
  }
20967
21020
 
21021
+ // ../core/src/mailboxes/endpoint-binding.ts
21022
+ var MailboxEmailEndpointBinding = Struct({
21023
+ channel: Literal2("email"),
21024
+ source: Literals(["samvaHosted", "verifiedDomain"]),
21025
+ localPart: String4,
21026
+ domain: String4,
21027
+ domainId: optional2(String4),
21028
+ subdomain: optional2(String4)
21029
+ }).annotate({ identifier: "MailboxEmailEndpointBinding" });
21030
+ var MailboxWhatsAppEndpointBinding = Struct({
21031
+ channel: Literal2("whatsapp"),
21032
+ businessAccountId: WhatsAppBusinessAccountId
21033
+ }).annotate({ identifier: "MailboxWhatsAppEndpointBinding" });
21034
+ var MailboxSmsEndpointBinding = Struct({
21035
+ channel: Literal2("sms"),
21036
+ phoneNumberId: SmsPhoneNumberId
21037
+ }).annotate({ identifier: "MailboxSmsEndpointBinding" });
21038
+ var MailboxEndpointBinding = Union2([
21039
+ MailboxEmailEndpointBinding,
21040
+ MailboxWhatsAppEndpointBinding,
21041
+ MailboxSmsEndpointBinding
21042
+ ]).annotate({
21043
+ identifier: "MailboxEndpointBinding"
21044
+ });
21045
+
20968
21046
  // ../core/src/mailboxes/mailbox.ts
20969
21047
  var mailboxChannels = ["email", "whatsapp", "sms"];
20970
21048
  var mailboxEventTypes = [
@@ -21065,10 +21143,6 @@ var MailboxChannel = Literals(mailboxChannels).annotate({
21065
21143
  identifier: "MailboxChannel",
21066
21144
  description: "The channel an endpoint, thread, or message belongs to."
21067
21145
  });
21068
-
21069
- class MailboxChannelUnsupportedError extends TaggedError3()("MailboxChannelUnsupportedError", { message: String4, channel: String4 }, { httpApiStatus: 422 }) {
21070
- }
21071
- categorize(MailboxChannelUnsupportedError, { categories: ["validation"], retryable: false });
21072
21146
  var endpointFields = {
21073
21147
  id: MailboxEndpointId,
21074
21148
  address: String4,
@@ -21081,7 +21155,21 @@ var MailboxEmailEndpoint = Struct({
21081
21155
  source: Literals(["samvaHosted", "verifiedDomain"]),
21082
21156
  domainId: NullOr(String4)
21083
21157
  }).annotate({ identifier: "MailboxEmailEndpoint" });
21084
- var MailboxEndpoint = Union2([MailboxEmailEndpoint]).annotate({
21158
+ var MailboxWhatsAppEndpoint = Struct({
21159
+ ...endpointFields,
21160
+ channel: Literal2("whatsapp"),
21161
+ businessAccountId: WhatsAppBusinessAccountId
21162
+ }).annotate({ identifier: "MailboxWhatsAppEndpoint" });
21163
+ var MailboxSmsEndpoint = Struct({
21164
+ ...endpointFields,
21165
+ channel: Literal2("sms"),
21166
+ phoneNumberId: SmsPhoneNumberId
21167
+ }).annotate({ identifier: "MailboxSmsEndpoint" });
21168
+ var MailboxEndpoint = Union2([
21169
+ MailboxEmailEndpoint,
21170
+ MailboxWhatsAppEndpoint,
21171
+ MailboxSmsEndpoint
21172
+ ]).annotate({
21085
21173
  identifier: "MailboxEndpoint"
21086
21174
  });
21087
21175
  var MailboxSendMode = Literals(mailboxSendModes).annotate({
@@ -21198,7 +21286,7 @@ var MailboxSendAttachment = Struct({
21198
21286
  })
21199
21287
  ])
21200
21288
  });
21201
- var MailboxSendIntent = Struct({
21289
+ var MailboxEmailSendIntent = Struct({
21202
21290
  channel: Literal2("email"),
21203
21291
  draftRevision: PositiveInt,
21204
21292
  from: String4,
@@ -21216,7 +21304,26 @@ var MailboxSendIntent = Struct({
21216
21304
  inReplyToMessageId: NullOr(MessageId)
21217
21305
  }).check(makeFilter2((intent) => intent.text !== null || intent.html !== null, {
21218
21306
  message: "A send intent requires text or html"
21219
- })).annotate({ identifier: "MailboxSendIntent" });
21307
+ })).annotate({ identifier: "MailboxEmailSendIntent" });
21308
+ var MailboxChatSendIntent = Struct({
21309
+ channel: MailboxChatChannel,
21310
+ draftRevision: PositiveInt,
21311
+ endpointId: MailboxEndpointId,
21312
+ sender: Union2([MailboxWhatsAppEndpointBinding, MailboxSmsEndpointBinding]),
21313
+ from: String4,
21314
+ to: String4,
21315
+ text: NullOr(String4),
21316
+ template: NullOr(MailboxChatTemplate),
21317
+ threadId: NullOr(MailboxThreadId),
21318
+ conversationId: NullOr(ConversationId),
21319
+ inReplyToMessageId: NullOr(MessageId)
21320
+ }).check(makeFilter2((intent) => intent.sender.channel === intent.channel && intent.text === null !== (intent.template === null) && (intent.template === null || intent.channel === "whatsapp"), {
21321
+ message: "A chat send intent carries text or a WhatsApp template, from an endpoint on its channel"
21322
+ })).annotate({ identifier: "MailboxChatSendIntent" });
21323
+ var MailboxSendIntent = Union2([
21324
+ MailboxEmailSendIntent,
21325
+ MailboxChatSendIntent
21326
+ ]).annotate({ identifier: "MailboxSendIntent" });
21220
21327
  var authorityFields = {
21221
21328
  actor: MailboxActorRef,
21222
21329
  installationId: NullOr(ExtensionInstallationId)
@@ -21277,10 +21384,10 @@ var SendMailboxEmailPayload = Struct({
21277
21384
  ...BodyFields
21278
21385
  }).annotate({ identifier: "SendMailboxEmailPayload" });
21279
21386
  var SendMailboxChatPayload = Struct({
21280
- channel: Literals(["whatsapp", "sms"]),
21387
+ channel: MailboxChatChannel,
21281
21388
  to: String4,
21282
- text: String4.check(isMinLength(1))
21283
- }).annotate({ identifier: "SendMailboxChatPayload" });
21389
+ ...mailboxChatContentFields
21390
+ }).check(exactlyOneChatContent).annotate({ identifier: "SendMailboxChatPayload" });
21284
21391
  var SendMailboxMessagePayload = Union2([
21285
21392
  SendMailboxEmailPayload,
21286
21393
  SendMailboxChatPayload
@@ -21292,9 +21399,9 @@ var ReplyMailboxEmailPayload = Struct({
21292
21399
  ...BodyFields
21293
21400
  }).annotate({ identifier: "ReplyMailboxEmailPayload" });
21294
21401
  var ReplyMailboxChatPayload = Struct({
21295
- channel: Literals(["whatsapp", "sms"]),
21296
- text: String4.check(isMinLength(1))
21297
- }).annotate({ identifier: "ReplyMailboxChatPayload" });
21402
+ channel: MailboxChatChannel,
21403
+ ...mailboxChatContentFields
21404
+ }).check(exactlyOneChatContent).annotate({ identifier: "ReplyMailboxChatPayload" });
21298
21405
  var ReplyMailboxMessagePayload = Union2([
21299
21406
  ReplyMailboxEmailPayload,
21300
21407
  ReplyMailboxChatPayload
@@ -21337,10 +21444,14 @@ var MailboxSendReceipt = Struct({
21337
21444
  return hasIdentity;
21338
21445
  return receipt.state === "uncertain" || !hasIdentity;
21339
21446
  }, { message: "A public message identity requires canonical acceptance" })).annotate({ identifier: "MailboxSendReceipt" });
21340
- var MailboxSendSnapshot = Struct({
21341
- ...MailboxSendIntent.fields,
21447
+ var MailboxEmailSendSnapshot = Struct({
21448
+ ...MailboxEmailSendIntent.fields,
21342
21449
  attachments: EmailAttachments
21343
- }).annotate({ identifier: "MailboxSendSnapshot" });
21450
+ }).annotate({ identifier: "MailboxEmailSendSnapshot" });
21451
+ var MailboxSendSnapshot = Union2([
21452
+ MailboxEmailSendSnapshot,
21453
+ MailboxChatSendIntent
21454
+ ]).annotate({ identifier: "MailboxSendSnapshot" });
21344
21455
 
21345
21456
  class MailboxSendConflictError extends TaggedError3()("MailboxSendConflictError", {
21346
21457
  message: String4,
@@ -21368,7 +21479,7 @@ var CreateMailboxEmailDraftPayload = Struct({
21368
21479
  inReplyToMessageId: optional2(MessageId)
21369
21480
  }).annotate({ identifier: "CreateMailboxEmailDraftPayload" });
21370
21481
  var CreateMailboxChatDraftPayload = Struct({
21371
- channel: Literals(["whatsapp", "sms"]),
21482
+ channel: MailboxChatChannel,
21372
21483
  to: optional2(String4),
21373
21484
  text: optional2(String4),
21374
21485
  inReplyToMessageId: optional2(MessageId)
@@ -23641,7 +23752,7 @@ var TemplateId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new R
23641
23752
  expected: "a string matching the RegExp ^tmpl_[0-9a-hjkmnp-tv-z]{16,24}$",
23642
23753
  identifier: "TemplateId"
23643
23754
  })).pipe(brand("TemplateId"));
23644
- var JsonObject = /* @__PURE__ */ Record(String4, JsonValue).annotate({ identifier: "JsonObject" });
23755
+ var JsonObject2 = /* @__PURE__ */ Record(String4, JsonValue).annotate({ identifier: "JsonObject" });
23645
23756
  var RenderLocale = /* @__PURE__ */ String4.check(isMaxCodePoints(64).annotate({
23646
23757
  expected: "a string with at most 64 code points",
23647
23758
  identifier: "RenderLocale"
@@ -23829,11 +23940,6 @@ var MailboxEndpointId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ *
23829
23940
  expected: "a string matching the RegExp ^mbxep_[0-9a-hjkmnp-tv-z]{16,24}$",
23830
23941
  identifier: "MailboxEndpointId"
23831
23942
  })).pipe(brand("MailboxEndpointId"));
23832
- var MailboxChannelUnsupportedError2 = class extends TaggedError3()("MailboxChannelUnsupportedError", Struct({
23833
- message: String4,
23834
- channel: String4
23835
- })) {
23836
- };
23837
23943
  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
23944
  expected: "an object with property names matching the schema",
23839
23945
  identifier: "MailboxMetadataPatch"
@@ -23990,6 +24096,16 @@ var DeliveryUnavailableError = class extends TaggedError3()("DeliveryUnavailable
23990
24096
  })) {
23991
24097
  };
23992
24098
  var IanaTimezone = /* @__PURE__ */ String4.annotate({ identifier: "IanaTimezone" });
24099
+ var NamespaceMetadata = /* @__PURE__ */ Record(String4, String4).annotate({
24100
+ description: "Your own labels for the namespace, such as the id of your customer it serves. Samva stores them and never reads them.",
24101
+ identifier: "NamespaceMetadata"
24102
+ });
24103
+ var NamespaceResourceType = /* @__PURE__ */ Union2([
24104
+ Literal2("domain"),
24105
+ Literal2("sender"),
24106
+ Literal2("contact"),
24107
+ Literal2("template")
24108
+ ]).annotate({ identifier: "NamespaceResourceType" });
23993
24109
  var OperationResource = /* @__PURE__ */ Struct({
23994
24110
  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
24111
  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 +24114,22 @@ var TemplateFromDefault = /* @__PURE__ */ Struct({
23998
24114
  email: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
23999
24115
  name: optionalKey2(Union2([String4, Null2]))
24000
24116
  }).annotate({ identifier: "TemplateFromDefault" });
24117
+ var TestWebhookPayload = /* @__PURE__ */ Struct({ data: optionalKey2(Union2([Record(String4, JsonValue), Null2])) }).annotate({ identifier: "TestWebhookPayload" });
24118
+ var ApiKeyMailboxAccess = /* @__PURE__ */ Struct({
24119
+ permissions: TupleWithRest(Tuple2([Union2([
24120
+ Literal2("read"),
24121
+ Literal2("update"),
24122
+ Literal2("send"),
24123
+ Literal2("quarantine.read")
24124
+ ])]), [Union2([
24125
+ Literal2("read"),
24126
+ Literal2("update"),
24127
+ Literal2("send"),
24128
+ Literal2("quarantine.read")
24129
+ ])]).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." }),
24130
+ 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." })),
24131
+ sendMode: optionalKey2(Union2([MailboxSendMode2, Null2]).annotate({ description: "Defaults to `send`. With `approval`, each send waits until a person other than the key approves it." }))
24132
+ }).annotate({ identifier: "ApiKeyMailboxAccess" });
24001
24133
  var CreateTemplatePayload = /* @__PURE__ */ Struct({
24002
24134
  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
24135
  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 +24147,9 @@ var CreateTemplatePayload = /* @__PURE__ */ Struct({
24015
24147
  Literal2("alert")
24016
24148
  ]), Null2]), Null2])),
24017
24149
  isActive: optionalKey2(Union2([Boolean3, Null2])),
24150
+ 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
24151
  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
24152
  }).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
24153
  var CreateWebhookPayload = /* @__PURE__ */ Struct({
24037
24154
  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
24155
  url: String4,
@@ -24167,14 +24284,14 @@ var EmailAttachment2 = /* @__PURE__ */ Struct({
24167
24284
  contentType: String4,
24168
24285
  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
24286
  }).annotate({ identifier: "EmailAttachment" });
24170
- var TemplateData = /* @__PURE__ */ Union2([JsonObject, Null2]).annotate({ identifier: "TemplateData" });
24287
+ var TemplateData = /* @__PURE__ */ Union2([JsonObject2, Null2]).annotate({ identifier: "TemplateData" });
24171
24288
  var ContactConsent = /* @__PURE__ */ Struct({
24172
24289
  status: Union2([Literal2("opted_in"), Literal2("opted_out")]),
24173
24290
  source: String4,
24174
24291
  capturedAt: String4,
24175
- proof: Union2([JsonObject, Null2])
24292
+ proof: Union2([JsonObject2, Null2])
24176
24293
  }).annotate({ identifier: "ContactConsent" });
24177
- var JourneyWebhookConfig = /* @__PURE__ */ Struct({ data: optionalKey2(JsonObject) }).annotate({ identifier: "JourneyWebhookConfig" });
24294
+ var JourneyWebhookConfig = /* @__PURE__ */ Struct({ data: optionalKey2(JsonObject2) }).annotate({ identifier: "JourneyWebhookConfig" });
24178
24295
  var SkippedRecipient2 = /* @__PURE__ */ Struct({
24179
24296
  address: String4,
24180
24297
  reason: Union2([
@@ -24191,7 +24308,7 @@ var ContactEvent = /* @__PURE__ */ Struct({
24191
24308
  contactId: ContactId2,
24192
24309
  name: String4,
24193
24310
  source: Union2([Literal2("api"), Literal2("samva")]),
24194
- properties: JsonObject,
24311
+ properties: JsonObject2,
24195
24312
  occurredAt: String4,
24196
24313
  recordedAt: String4
24197
24314
  }).annotate({ identifier: "ContactEvent" });
@@ -24224,7 +24341,7 @@ var JourneyGroupJoinedTrigger = /* @__PURE__ */ Struct({
24224
24341
  var JourneySendEmailConfig = /* @__PURE__ */ Struct({
24225
24342
  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
24343
  senderId: optionalKey2(EmailSenderId2),
24227
- templateData: optionalKey2(JsonObject)
24344
+ templateData: optionalKey2(JsonObject2)
24228
24345
  }).annotate({ identifier: "JourneySendEmailConfig" });
24229
24346
  var ExtensionVersionRef = /* @__PURE__ */ Struct({
24230
24347
  id: ExtensionVersionId2,
@@ -24350,7 +24467,7 @@ var ApiKeyAccess = /* @__PURE__ */ Union2([Struct({ mode: Literal2("full") }), S
24350
24467
  mode: Literal2("restricted"),
24351
24468
  resources: ApiKeyResourceAccess,
24352
24469
  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." }))
24470
+ 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
24471
  })]).annotate({ identifier: "ApiKeyAccess" });
24355
24472
  var MessagePage = /* @__PURE__ */ Struct({
24356
24473
  items: ArraySchema(MessageSummary2),
@@ -24369,7 +24486,7 @@ var ContactIdentityChannel = /* @__PURE__ */ Struct({
24369
24486
  var CreateEventPayload = /* @__PURE__ */ Struct({
24370
24487
  contact: ContactEventReference,
24371
24488
  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])),
24489
+ properties: optionalKey2(Union2([JsonObject2, Null2])),
24373
24490
  occurredAt: optionalKey2(Union2([String4, Null2])),
24374
24491
  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
24492
  }).annotate({ identifier: "CreateEventPayload" });
@@ -24698,6 +24815,7 @@ var apiStatuses = {
24698
24815
  NotImplementedError: 501,
24699
24816
  UnknownStatusError: 400,
24700
24817
  WhatsAppTemplateIneligibleError: 422,
24818
+ WhatsAppServiceWindowClosedError: 422,
24701
24819
  InternalError: 500,
24702
24820
  ExternalServiceError: 502,
24703
24821
  GatewayTimeoutError: 504
@@ -24760,6 +24878,9 @@ var apiErrorGuidance = (error) => {
24760
24878
  case "MailboxSendRefusedError":
24761
24879
  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
24880
  break;
24881
+ case "WhatsAppServiceWindowClosedError":
24882
+ next = "Free-form WhatsApp text needs the customer's open 24-hour service window. Send an approved template instead: --template <templateId> with --data.";
24883
+ break;
24763
24884
  case "ConflictError":
24764
24885
  next = "Read the resource and resolve the conflict before retrying.";
24765
24886
  break;
@@ -24960,7 +25081,7 @@ var __exportAll = (all, no_symbols) => {
24960
25081
  };
24961
25082
 
24962
25083
  // ../sdk/dist/package.js
24963
- var version = "0.19.0";
25084
+ var version = "0.20.0";
24964
25085
 
24965
25086
  // ../sdk/dist/client-attribution.js
24966
25087
  var SDK_VERSION = version;
@@ -25320,6 +25441,16 @@ var commandTree = {
25320
25441
  actions: { list: {}, get: {}, approve: {}, deny: {}, cancel: {}, retry: {} },
25321
25442
  quarantine: { list: {}, release: {}, discard: {} }
25322
25443
  },
25444
+ namespaces: {
25445
+ list: {},
25446
+ create: {},
25447
+ get: {},
25448
+ update: {},
25449
+ delete: {},
25450
+ assign: {},
25451
+ unassign: {},
25452
+ usage: {}
25453
+ },
25323
25454
  extensions: {
25324
25455
  init: {},
25325
25456
  build: {},
@@ -25785,6 +25916,7 @@ var getAuthenticatedJsonForContext = fn2("CliClient.getAuthenticatedJson")(funct
25785
25916
  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
25917
  });
25787
25918
  var getAuthenticatedJson = (path) => flatMap3(resolveExecutionContext, (context) => getAuthenticatedJsonForContext(context, path));
25919
+ var postAuthenticatedJson = (path, request) => flatMap3(resolveExecutionContext, (context) => getAuthenticatedJsonForContext(context, path, request));
25788
25920
 
25789
25921
  // src/lib/output.ts
25790
25922
  var CLI_SCHEMA_VERSION = 1;
@@ -27450,6 +27582,22 @@ var SDK_OPERATION_CALLS = {
27450
27582
  kind: "path",
27451
27583
  paths: ["id"]
27452
27584
  },
27585
+ namespacesAssignResource: {
27586
+ kind: "pathPayload",
27587
+ paths: ["id"]
27588
+ },
27589
+ namespacesRemoveResource: {
27590
+ kind: "path",
27591
+ paths: [
27592
+ "id",
27593
+ "type",
27594
+ "resourceId"
27595
+ ]
27596
+ },
27597
+ namespacesGetUsage: {
27598
+ kind: "pathParams",
27599
+ paths: ["id"]
27600
+ },
27453
27601
  extensionsList: { kind: "params" },
27454
27602
  extensionsPublish: { kind: "payload" },
27455
27603
  extensionsGet: {
@@ -27546,10 +27694,6 @@ var SamvaErrorMetadata = {
27546
27694
  categories: ["transient"],
27547
27695
  retryable: true
27548
27696
  },
27549
- MailboxChannelUnsupportedError: {
27550
- categories: [],
27551
- retryable: false
27552
- },
27553
27697
  MailboxSendConflictError: {
27554
27698
  categories: [],
27555
27699
  retryable: false
@@ -28340,6 +28484,9 @@ var SamvaOperations = {
28340
28484
  namespacesGet: operationMetadata74,
28341
28485
  namespacesRemove: operationMetadata75,
28342
28486
  namespacesUpdate: operationMetadata76,
28487
+ namespacesAssignResource: operationMetadata73,
28488
+ namespacesRemoveResource: operationMetadata75,
28489
+ namespacesGetUsage: operationMetadata74,
28343
28490
  operationsList: operationMetadata77,
28344
28491
  operationsGet: operationMetadata78,
28345
28492
  operationsRetry: operationMetadata79,
@@ -53935,6 +54082,20 @@ var CampaignRunId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ ne
53935
54082
  expected: "a string matching the RegExp ^crun_[0-9a-hjkmnp-tv-z]{16,24}$",
53936
54083
  identifier: "CampaignRunId"
53937
54084
  })).pipe(brand("CampaignRunId"));
54085
+ var CampaignRunSkippedReason = /* @__PURE__ */ Struct({
54086
+ reason: Union2([
54087
+ Literal2("unsubscribed"),
54088
+ Literal2("blocked"),
54089
+ Literal2("suppressed"),
54090
+ Literal2("opted_out"),
54091
+ Literal2("unreachable"),
54092
+ Literal2("no_identity"),
54093
+ Literal2("inactive"),
54094
+ Literal2("run_cancelled"),
54095
+ Literal2("run_failed")
54096
+ ]),
54097
+ count: Finite.check(isFinite4().annotate({ expected: "a finite number" }))
54098
+ }).annotate({ identifier: "CampaignRunSkippedReason" });
53938
54099
  var CampaignRecipientId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new RegExp("^crcpt_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
53939
54100
  expected: "a string matching the RegExp ^crcpt_[0-9a-hjkmnp-tv-z]{16,24}$",
53940
54101
  identifier: "CampaignRecipientId"
@@ -53987,6 +54148,8 @@ var CampaignRecipientPage = /* @__PURE__ */ Struct({
53987
54148
  Literal2("unsubscribed"),
53988
54149
  Literal2("blocked"),
53989
54150
  Literal2("suppressed"),
54151
+ Literal2("opted_out"),
54152
+ Literal2("unreachable"),
53990
54153
  Literal2("no_identity"),
53991
54154
  Literal2("inactive"),
53992
54155
  Literal2("run_cancelled"),
@@ -54063,6 +54226,7 @@ var CampaignRun = /* @__PURE__ */ Struct({
54063
54226
  dispatchedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
54064
54227
  failedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
54065
54228
  skippedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
54229
+ skippedReasons: ArraySchema(CampaignRunSkippedReason),
54066
54230
  estimatedCompletionAt: Union2([String4, Null2]),
54067
54231
  failureReason: Union2([String4, Null2]),
54068
54232
  holdReason: Union2([String4, Null2]),
@@ -54900,6 +55064,10 @@ var printRun = (run) => printFields([
54900
55064
  ["Dispatched", String(run.dispatchedCount)],
54901
55065
  ["Failed", String(run.failedCount)],
54902
55066
  ["Skipped", String(run.skippedCount)],
55067
+ [
55068
+ "Skipped by reason",
55069
+ (run.skippedReasons ?? []).map(({ reason, count }) => `${reason} ${count}`).join(", ")
55070
+ ],
54903
55071
  ["Failure", run.failureReason]
54904
55072
  ]);
54905
55073
  var runCreate = make29("create", {
@@ -54993,7 +55161,11 @@ var runList = make29("list", {
54993
55161
  ["Scheduled for", run.scheduledFor],
54994
55162
  ["Dispatched", String(run.dispatchedCount)],
54995
55163
  ["Failed", String(run.failedCount)],
54996
- ["Skipped", String(run.skippedCount)]
55164
+ ["Skipped", String(run.skippedCount)],
55165
+ [
55166
+ "Skipped by reason",
55167
+ run.skippedReasons.map(({ reason, count }) => `${reason} ${count}`).join(", ")
55168
+ ]
54997
55169
  ]);
54998
55170
  yield* log("");
54999
55171
  }
@@ -55305,6 +55477,7 @@ var ContactProfileUpdate = /* @__PURE__ */ Struct({
55305
55477
  }).annotate({ identifier: "ContactProfileUpdate" });
55306
55478
  var ContactSummary = /* @__PURE__ */ Struct({
55307
55479
  id: ContactId2,
55480
+ namespaceId: Union2([NamespaceId2, Null2]),
55308
55481
  name: String4,
55309
55482
  displayName: Union2([String4, Null2]),
55310
55483
  status: Union2([
@@ -55327,6 +55500,7 @@ var ContactPage = /* @__PURE__ */ Struct({
55327
55500
  }).annotate({ identifier: "ContactPage" });
55328
55501
  var Contact = /* @__PURE__ */ Struct({
55329
55502
  id: ContactId2,
55503
+ namespaceId: Union2([NamespaceId2, Null2]),
55330
55504
  name: String4,
55331
55505
  displayName: Union2([String4, Null2]),
55332
55506
  avatar: Union2([String4, Null2]),
@@ -55342,13 +55516,14 @@ var Contact = /* @__PURE__ */ Struct({
55342
55516
  profile: Union2([ContactProfile, Null2]),
55343
55517
  preferences: Union2([ContactPreferences, Null2]),
55344
55518
  tags: ArraySchema(String4),
55345
- metadata: Union2([JsonObject, Null2]),
55519
+ metadata: Union2([JsonObject2, Null2]),
55346
55520
  createdAt: String4,
55347
55521
  updatedAt: String4
55348
55522
  }).annotate({ identifier: "Contact" });
55349
55523
  var ContactsListQuery = /* @__PURE__ */ Struct({
55350
55524
  limit: optionalKey2(Union2([String4, Null2])),
55351
55525
  cursor: optionalKey2(Union2([Cursor, Null2])),
55526
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55352
55527
  search: optionalKey2(Union2([String4, Null2])),
55353
55528
  status: optionalKey2(Union2([Union2([
55354
55529
  Literal2("active"),
@@ -55369,6 +55544,7 @@ var ContactsList422 = ValidationError2;
55369
55544
  var ContactsList500 = InternalError2;
55370
55545
  var ContactsList504 = GatewayTimeoutError2;
55371
55546
  var ContactsCreateRequestJson = /* @__PURE__ */ Struct({
55547
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55372
55548
  name: String4,
55373
55549
  displayName: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55374
55550
  avatar: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
@@ -55384,12 +55560,13 @@ var ContactsCreateRequestJson = /* @__PURE__ */ Struct({
55384
55560
  ]), Null2])),
55385
55561
  statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55386
55562
  externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55387
- metadata: optionalKey2(Union2([Union2([JsonObject, Null2]), Null2]))
55563
+ metadata: optionalKey2(Union2([Union2([JsonObject2, Null2]), Null2]))
55388
55564
  });
55389
55565
  var ContactsCreate201 = Contact;
55390
55566
  var ContactsCreate401 = UnauthorizedError2;
55391
55567
  var ContactsCreate402 = PaymentRequiredError2;
55392
55568
  var ContactsCreate403 = ForbiddenError2;
55569
+ var ContactsCreate404 = ResourceNotFoundError2;
55393
55570
  var ContactsCreate409 = ConflictError2;
55394
55571
  var ContactsCreate422 = ValidationError2;
55395
55572
  var ContactsCreate500 = InternalError2;
@@ -55427,7 +55604,7 @@ var ContactsUpdateRequestJson = /* @__PURE__ */ Struct({
55427
55604
  ]), Null2])),
55428
55605
  statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55429
55606
  externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55430
- metadata: optionalKey2(Union2([JsonObject, Null2]))
55607
+ metadata: optionalKey2(Union2([JsonObject2, Null2]))
55431
55608
  });
55432
55609
  var ContactsUpdate200 = Contact;
55433
55610
  var ContactsUpdate401 = UnauthorizedError2;
@@ -55512,7 +55689,7 @@ var ContactsSetConsentRequestJson = /* @__PURE__ */ Struct({
55512
55689
  status: Union2([Literal2("opted_in"), Literal2("opted_out")]),
55513
55690
  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
55691
  capturedAt: String4,
55515
- proof: optionalKey2(Union2([JsonObject, Null2]))
55692
+ proof: optionalKey2(Union2([JsonObject2, Null2]))
55516
55693
  });
55517
55694
  var ContactsSetConsent200 = Contact;
55518
55695
  var ContactsSetConsent401 = UnauthorizedError2;
@@ -55551,6 +55728,7 @@ var ContactsBulkDelete500 = InternalError2;
55551
55728
  var ContactsBulkDelete502 = BillingProviderError;
55552
55729
  var ContactsBulkDelete504 = GatewayTimeoutError2;
55553
55730
  var ContactsBulkImportRequestJson = /* @__PURE__ */ Struct({
55731
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55554
55732
  contacts: ArraySchema(Struct({
55555
55733
  name: String4,
55556
55734
  displayName: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
@@ -55567,7 +55745,7 @@ var ContactsBulkImportRequestJson = /* @__PURE__ */ Struct({
55567
55745
  ]), Null2])),
55568
55746
  statusReason: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55569
55747
  externalId: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
55570
- metadata: optionalKey2(Union2([Union2([JsonObject, Null2]), Null2]))
55748
+ metadata: optionalKey2(Union2([Union2([JsonObject2, Null2]), Null2]))
55571
55749
  })),
55572
55750
  onConflict: optionalKey2(Union2([Union2([Literal2("skip"), Literal2("update")]), Null2]))
55573
55751
  });
@@ -55592,6 +55770,7 @@ var ContactsBulkImport200 = /* @__PURE__ */ Struct({
55592
55770
  var ContactsBulkImport401 = UnauthorizedError2;
55593
55771
  var ContactsBulkImport402 = PaymentRequiredError2;
55594
55772
  var ContactsBulkImport403 = ForbiddenError2;
55773
+ var ContactsBulkImport404 = ResourceNotFoundError2;
55595
55774
  var ContactsBulkImport422 = ValidationError2;
55596
55775
  var ContactsBulkImport500 = InternalError2;
55597
55776
  var ContactsBulkImport502 = BillingProviderError;
@@ -55653,6 +55832,7 @@ var ContactsExport422 = ValidationError2;
55653
55832
  var ContactsExport500 = InternalError2;
55654
55833
  var ContactsExport504 = GatewayTimeoutError2;
55655
55834
  var ContactsFindRequestJson = /* @__PURE__ */ Struct({
55835
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55656
55836
  email: optionalKey2(Union2([String4, Null2])),
55657
55837
  phone: optionalKey2(Union2([String4, Null2])),
55658
55838
  externalId: optionalKey2(Union2([String4, Null2]))
@@ -55660,11 +55840,13 @@ var ContactsFindRequestJson = /* @__PURE__ */ Struct({
55660
55840
  var ContactsFind200 = /* @__PURE__ */ Union2([Contact, Null2]);
55661
55841
  var ContactsFind401 = UnauthorizedError2;
55662
55842
  var ContactsFind403 = ForbiddenError2;
55843
+ var ContactsFind404 = ResourceNotFoundError2;
55663
55844
  var ContactsFind409 = ConflictError2;
55664
55845
  var ContactsFind422 = ValidationError2;
55665
55846
  var ContactsFind500 = InternalError2;
55666
55847
  var ContactsFind504 = GatewayTimeoutError2;
55667
55848
  var ContactsFindOrCreateRequestJson = /* @__PURE__ */ Struct({
55849
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2])),
55668
55850
  lookup: ContactLookup,
55669
55851
  create: optionalKey2(Union2([Struct({
55670
55852
  name: optionalKey2(Union2([String4, Null2])),
@@ -55682,6 +55864,7 @@ var ContactsFindOrCreate200 = /* @__PURE__ */ Struct({
55682
55864
  var ContactsFindOrCreate401 = UnauthorizedError2;
55683
55865
  var ContactsFindOrCreate402 = PaymentRequiredError2;
55684
55866
  var ContactsFindOrCreate403 = ForbiddenError2;
55867
+ var ContactsFindOrCreate404 = ResourceNotFoundError2;
55685
55868
  var ContactsFindOrCreate409 = ConflictError2;
55686
55869
  var ContactsFindOrCreate422 = ValidationError2;
55687
55870
  var ContactsFindOrCreate500 = InternalError2;
@@ -55704,6 +55887,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55704
55887
  ContactsCreate401.pipe(status(401)),
55705
55888
  ContactsCreate402.pipe(status(402)),
55706
55889
  ContactsCreate403.pipe(status(403)),
55890
+ ContactsCreate404.pipe(status(404)),
55707
55891
  ContactsCreate409.pipe(status(409)),
55708
55892
  ContactsCreate422.pipe(status(422)),
55709
55893
  ContactsCreate500,
@@ -55860,6 +56044,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55860
56044
  ContactsBulkImport401.pipe(status(401)),
55861
56045
  ContactsBulkImport402.pipe(status(402)),
55862
56046
  ContactsBulkImport403.pipe(status(403)),
56047
+ ContactsBulkImport404.pipe(status(404)),
55863
56048
  ContactsBulkImport422.pipe(status(422)),
55864
56049
  ContactsBulkImport500,
55865
56050
  ContactsBulkImport502.pipe(status(502)),
@@ -55903,6 +56088,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55903
56088
  error: [
55904
56089
  ContactsFind401.pipe(status(401)),
55905
56090
  ContactsFind403.pipe(status(403)),
56091
+ ContactsFind404.pipe(status(404)),
55906
56092
  ContactsFind409.pipe(status(409)),
55907
56093
  ContactsFind422.pipe(status(422)),
55908
56094
  ContactsFind500,
@@ -55915,6 +56101,7 @@ var ContactsGroup = class extends make37("Contacts").add(get5("contactsList", "/
55915
56101
  ContactsFindOrCreate401.pipe(status(401)),
55916
56102
  ContactsFindOrCreate402.pipe(status(402)),
55917
56103
  ContactsFindOrCreate403.pipe(status(403)),
56104
+ ContactsFindOrCreate404.pipe(status(404)),
55918
56105
  ContactsFindOrCreate409.pipe(status(409)),
55919
56106
  ContactsFindOrCreate422.pipe(status(422)),
55920
56107
  ContactsFindOrCreate500,
@@ -55930,6 +56117,15 @@ var list7 = /* @__PURE__ */ make43("contactsList");
55930
56117
  var get13 = /* @__PURE__ */ make43("contactsGet");
55931
56118
  var listEvents = /* @__PURE__ */ forGroup(ContactEventsGroup)("contactEventsListEvents");
55932
56119
 
56120
+ // src/lib/namespace.ts
56121
+ 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);
56122
+ var namespaceField = (namespace) => match(namespace, {
56123
+ onNone: () => ({}),
56124
+ onSome: (namespaceId) => ({ namespaceId })
56125
+ });
56126
+ var placedAsRequested = (namespace, existing) => isNone2(namespace) || existing === namespace.value;
56127
+ var placementLabel = (namespaceId) => namespaceId === null ? "organization level" : `namespace ${namespaceId}`;
56128
+
55933
56129
  // src/commands/contacts.ts
55934
56130
  var optionalString = (name, description) => String9(name).pipe(withDescription2(description), optional4);
55935
56131
  var list8 = make29("list", {
@@ -55942,6 +56138,7 @@ var list8 = make29("list", {
55942
56138
  limit: Int5("limit").pipe(withDescription2("Maximum contacts per page"), optional4),
55943
56139
  after: optionalString("after", "Only contacts created after this ISO 8601 instant"),
55944
56140
  before: optionalString("before", "Only contacts created before this ISO 8601 instant"),
56141
+ namespace: namespaceFlag("list"),
55945
56142
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
55946
56143
  json: jsonFlag
55947
56144
  }).pipe(withDescription3("List and search contacts with optional custom-field projection and filtering"), withExamples([
@@ -55959,6 +56156,7 @@ var list8 = make29("list", {
55959
56156
  limit,
55960
56157
  after,
55961
56158
  before,
56159
+ namespace,
55962
56160
  all,
55963
56161
  json
55964
56162
  }) => gen2(function* () {
@@ -55989,7 +56187,8 @@ var list8 = make29("list", {
55989
56187
  customFieldValue: getOrUndefined(customFieldValue),
55990
56188
  limit: getOrUndefined(limit)?.toString(),
55991
56189
  after: getOrUndefined(after),
55992
- before: getOrUndefined(before)
56190
+ before: getOrUndefined(before),
56191
+ ...namespaceField(namespace)
55993
56192
  };
55994
56193
  const listPage = (pageCursor) => list7({ ...query, cursor: pageCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list contacts", error, { cursor: pageCursor ?? null })));
55995
56194
  let nextCursor = getOrUndefined(cursor);
@@ -56014,6 +56213,7 @@ var list8 = make29("list", {
56014
56213
  ["Last active", contact.lastActiveAt],
56015
56214
  ["Created", contact.createdAt],
56016
56215
  ["Status", contact.status],
56216
+ ["Namespace", contact.namespaceId ?? "organization"],
56017
56217
  ["Tags", contact.tags.join(", ")],
56018
56218
  [
56019
56219
  "Custom fields",
@@ -56044,6 +56244,7 @@ var get14 = make29("get", {
56044
56244
  ["Display name", contact.displayName],
56045
56245
  ["Avatar", contact.avatar],
56046
56246
  ["Status", contact.status],
56247
+ ["Namespace", contact.namespaceId ?? "organization"],
56047
56248
  ["Reason", contact.statusReason],
56048
56249
  ["External ID", contact.externalId],
56049
56250
  ["Identities", JSON.stringify(contact.identities)],
@@ -56418,6 +56619,7 @@ var EmailDomainPage = /* @__PURE__ */ Struct({
56418
56619
  ]),
56419
56620
  dkimSelector: optionalKey2(Union2([String4, Null2])),
56420
56621
  dkimPublicKey: optionalKey2(Union2([String4, Null2])),
56622
+ 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
56623
  isDefault: Boolean3,
56422
56624
  deliverability: DeliverabilityFacts,
56423
56625
  series: SendsSeries,
@@ -56459,6 +56661,7 @@ var EmailDomainDetailed = /* @__PURE__ */ Struct({
56459
56661
  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
56662
  })),
56461
56663
  verifiedAt: Union2([String4, Null2]),
56664
+ 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
56665
  isDefault: Boolean3,
56463
56666
  deliverability: DeliverabilityFacts,
56464
56667
  createdAt: String4,
@@ -56651,6 +56854,7 @@ var EmailSenderPage = /* @__PURE__ */ Struct({
56651
56854
  email: String4,
56652
56855
  name: Union2([String4, Null2]),
56653
56856
  domainId: Union2([EmailDomainId2, Null2]),
56857
+ 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
56858
  verificationStatus: Union2([
56655
56859
  Literal2("pending"),
56656
56860
  Literal2("verified"),
@@ -57069,7 +57273,8 @@ var EmailGetCatchAllStats504 = GatewayTimeoutError2;
57069
57273
  var EmailListDomainsQuery = /* @__PURE__ */ Struct({
57070
57274
  limit: optionalKey2(Union2([String4, Null2])),
57071
57275
  cursor: optionalKey2(Union2([Cursor, Null2])),
57072
- sendable: optionalKey2(Union2([Literal2("true"), Null2]))
57276
+ sendable: optionalKey2(Union2([Literal2("true"), Null2])),
57277
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57073
57278
  });
57074
57279
  var EmailListDomains200 = EmailDomainPage;
57075
57280
  var EmailListDomains401 = UnauthorizedError2;
@@ -57082,12 +57287,14 @@ var EmailAddDomainRequestJson = /* @__PURE__ */ Struct({
57082
57287
  connection: optionalKey2(Union2([Struct({
57083
57288
  connectionId: String4,
57084
57289
  zone: String4
57085
- }), Null2]))
57290
+ }), Null2])),
57291
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57086
57292
  });
57087
57293
  var EmailAddDomain201 = EmailDomainDetailed;
57088
57294
  var EmailAddDomain401 = UnauthorizedError2;
57089
57295
  var EmailAddDomain402 = PaymentRequiredError2;
57090
57296
  var EmailAddDomain403 = ForbiddenError2;
57297
+ var EmailAddDomain404 = ResourceNotFoundError2;
57091
57298
  var EmailAddDomain409 = ConflictError2;
57092
57299
  var EmailAddDomain422 = ValidationError2;
57093
57300
  var EmailAddDomain429 = RateLimitedError2;
@@ -57139,6 +57346,7 @@ var EmailGetCustomTrackingPathParams = /* @__PURE__ */ Struct({ id: EmailDomainI
57139
57346
  var EmailGetCustomTracking200 = CustomTrackingStatus;
57140
57347
  var EmailGetCustomTracking401 = UnauthorizedError2;
57141
57348
  var EmailGetCustomTracking403 = ForbiddenError2;
57349
+ var EmailGetCustomTracking404 = ResourceNotFoundError2;
57142
57350
  var EmailGetCustomTracking422 = ValidationError2;
57143
57351
  var EmailGetCustomTracking500 = InternalError2;
57144
57352
  var EmailGetCustomTracking504 = GatewayTimeoutError2;
@@ -57147,6 +57355,7 @@ var EmailEnableCustomTrackingRequestJson = /* @__PURE__ */ Struct({ label: optio
57147
57355
  var EmailEnableCustomTracking200 = CustomTrackingStatus;
57148
57356
  var EmailEnableCustomTracking401 = UnauthorizedError2;
57149
57357
  var EmailEnableCustomTracking403 = ForbiddenError2;
57358
+ var EmailEnableCustomTracking404 = ResourceNotFoundError2;
57150
57359
  var EmailEnableCustomTracking409 = ConflictError2;
57151
57360
  var EmailEnableCustomTracking422 = ValidationError2;
57152
57361
  var EmailEnableCustomTracking500 = InternalError2;
@@ -57156,6 +57365,7 @@ var EmailDisableCustomTrackingPathParams = /* @__PURE__ */ Struct({ id: EmailDom
57156
57365
  var EmailDisableCustomTracking200 = SuccessResult;
57157
57366
  var EmailDisableCustomTracking401 = UnauthorizedError2;
57158
57367
  var EmailDisableCustomTracking403 = ForbiddenError2;
57368
+ var EmailDisableCustomTracking404 = ResourceNotFoundError2;
57159
57369
  var EmailDisableCustomTracking409 = ConflictError2;
57160
57370
  var EmailDisableCustomTracking422 = ValidationError2;
57161
57371
  var EmailDisableCustomTracking500 = InternalError2;
@@ -57188,6 +57398,7 @@ var EmailCompleteCustomTrackingDomainConnectRequestJson = /* @__PURE__ */ Struct
57188
57398
  var EmailCompleteCustomTrackingDomainConnect200 = CustomTrackingDomainConnectCompleteResult;
57189
57399
  var EmailCompleteCustomTrackingDomainConnect401 = UnauthorizedError2;
57190
57400
  var EmailCompleteCustomTrackingDomainConnect403 = ForbiddenError2;
57401
+ var EmailCompleteCustomTrackingDomainConnect404 = ResourceNotFoundError2;
57191
57402
  var EmailCompleteCustomTrackingDomainConnect422 = ValidationError2;
57192
57403
  var EmailCompleteCustomTrackingDomainConnect500 = InternalError2;
57193
57404
  var EmailCompleteCustomTrackingDomainConnect504 = GatewayTimeoutError2;
@@ -57297,6 +57508,7 @@ var EmailDetectRegistrar200 = /* @__PURE__ */ Struct({
57297
57508
  });
57298
57509
  var EmailDetectRegistrar401 = UnauthorizedError2;
57299
57510
  var EmailDetectRegistrar403 = ForbiddenError2;
57511
+ var EmailDetectRegistrar404 = ResourceNotFoundError2;
57300
57512
  var EmailDetectRegistrar422 = ValidationError2;
57301
57513
  var EmailDetectRegistrar500 = InternalError2;
57302
57514
  var EmailDetectRegistrar504 = GatewayTimeoutError2;
@@ -57540,7 +57752,8 @@ var EmailListSendersQuery = /* @__PURE__ */ Struct({
57540
57752
  Literal2("failed")
57541
57753
  ]), Null2])),
57542
57754
  isActive: optionalKey2(Union2([String4, Null2])),
57543
- isDefault: optionalKey2(Union2([String4, Null2]))
57755
+ isDefault: optionalKey2(Union2([String4, Null2])),
57756
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57544
57757
  });
57545
57758
  var EmailListSenders200 = EmailSenderPage;
57546
57759
  var EmailListSenders401 = UnauthorizedError2;
@@ -57553,7 +57766,8 @@ var EmailAddSenderRequestJson = /* @__PURE__ */ Struct({
57553
57766
  email: String4,
57554
57767
  domainId: optionalKey2(Union2([EmailDomainId2, Null2])),
57555
57768
  name: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
57556
- replyToEmails: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2]))
57769
+ replyToEmails: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2])),
57770
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]))
57557
57771
  });
57558
57772
  var EmailAddSender201 = /* @__PURE__ */ Struct({
57559
57773
  id: EmailSenderId2,
@@ -57587,6 +57801,7 @@ var EmailGetSender200 = /* @__PURE__ */ Struct({
57587
57801
  email: String4,
57588
57802
  name: Union2([String4, Null2]),
57589
57803
  domainId: Union2([EmailDomainId2, Null2]),
57804
+ 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
57805
  verificationStatus: Union2([
57591
57806
  Literal2("pending"),
57592
57807
  Literal2("verified"),
@@ -57842,13 +58057,14 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57842
58057
  EmailListDomains500,
57843
58058
  EmailListDomains504.pipe(status(504))
57844
58059
  ]
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", {
58060
+ }).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
58061
  payload: EmailAddDomainRequestJson,
57847
58062
  success: EmailAddDomain201.pipe(status(201)),
57848
58063
  error: [
57849
58064
  EmailAddDomain401.pipe(status(401)),
57850
58065
  EmailAddDomain402.pipe(status(402)),
57851
58066
  EmailAddDomain403.pipe(status(403)),
58067
+ EmailAddDomain404.pipe(status(404)),
57852
58068
  EmailAddDomain409.pipe(status(409)),
57853
58069
  EmailAddDomain422.pipe(status(422)),
57854
58070
  EmailAddDomain429.pipe(status(429)),
@@ -57856,7 +58072,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57856
58072
  EmailAddDomain502.pipe(status(502)),
57857
58073
  EmailAddDomain504.pipe(status(504))
57858
58074
  ]
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", {
58075
+ }).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
58076
  params: EmailGetDomainByIdPathParams,
57861
58077
  success: EmailGetDomainById200,
57862
58078
  error: [
@@ -57897,6 +58113,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57897
58113
  error: [
57898
58114
  EmailGetCustomTracking401.pipe(status(401)),
57899
58115
  EmailGetCustomTracking403.pipe(status(403)),
58116
+ EmailGetCustomTracking404.pipe(status(404)),
57900
58117
  EmailGetCustomTracking422.pipe(status(422)),
57901
58118
  EmailGetCustomTracking500,
57902
58119
  EmailGetCustomTracking504.pipe(status(504))
@@ -57908,6 +58125,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57908
58125
  error: [
57909
58126
  EmailEnableCustomTracking401.pipe(status(401)),
57910
58127
  EmailEnableCustomTracking403.pipe(status(403)),
58128
+ EmailEnableCustomTracking404.pipe(status(404)),
57911
58129
  EmailEnableCustomTracking409.pipe(status(409)),
57912
58130
  EmailEnableCustomTracking422.pipe(status(422)),
57913
58131
  EmailEnableCustomTracking500,
@@ -57920,6 +58138,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57920
58138
  error: [
57921
58139
  EmailDisableCustomTracking401.pipe(status(401)),
57922
58140
  EmailDisableCustomTracking403.pipe(status(403)),
58141
+ EmailDisableCustomTracking404.pipe(status(404)),
57923
58142
  EmailDisableCustomTracking409.pipe(status(409)),
57924
58143
  EmailDisableCustomTracking422.pipe(status(422)),
57925
58144
  EmailDisableCustomTracking500,
@@ -57957,6 +58176,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
57957
58176
  error: [
57958
58177
  EmailCompleteCustomTrackingDomainConnect401.pipe(status(401)),
57959
58178
  EmailCompleteCustomTrackingDomainConnect403.pipe(status(403)),
58179
+ EmailCompleteCustomTrackingDomainConnect404.pipe(status(404)),
57960
58180
  EmailCompleteCustomTrackingDomainConnect422.pipe(status(422)),
57961
58181
  EmailCompleteCustomTrackingDomainConnect500,
57962
58182
  EmailCompleteCustomTrackingDomainConnect504.pipe(status(504))
@@ -58079,6 +58299,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58079
58299
  error: [
58080
58300
  EmailDetectRegistrar401.pipe(status(401)),
58081
58301
  EmailDetectRegistrar403.pipe(status(403)),
58302
+ EmailDetectRegistrar404.pipe(status(404)),
58082
58303
  EmailDetectRegistrar422.pipe(status(422)),
58083
58304
  EmailDetectRegistrar500,
58084
58305
  EmailDetectRegistrar504.pipe(status(504))
@@ -58306,7 +58527,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58306
58527
  EmailListSenders500,
58307
58528
  EmailListSenders504.pipe(status(504))
58308
58529
  ]
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", {
58530
+ }).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
58531
  headers: EmailAddSenderHeaders,
58311
58532
  payload: EmailAddSenderRequestJson,
58312
58533
  success: EmailAddSender201.pipe(status(201)),
@@ -58320,7 +58541,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58320
58541
  EmailAddSender502.pipe(status(502)),
58321
58542
  EmailAddSender504.pipe(status(504))
58322
58543
  ]
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", {
58544
+ }).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
58545
  params: EmailGetSenderPathParams,
58325
58546
  success: EmailGetSender200,
58326
58547
  error: [
@@ -58353,7 +58574,7 @@ var EmailGroup = class extends make37("Email").add(get5("emailListBlocks", "/v1/
58353
58574
  EmailSetDefaultSender500,
58354
58575
  EmailSetDefaultSender504.pipe(status(504))
58355
58576
  ]
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", {
58577
+ }).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
58578
  params: EmailCheckSenderVerificationPathParams,
58358
58579
  success: EmailCheckSenderVerification200,
58359
58580
  error: [
@@ -58969,6 +59190,7 @@ var MessagesListQuery = /* @__PURE__ */ Struct({
58969
59190
  conversationId: optionalKey2(Union2([ConversationId2, Null2])),
58970
59191
  contactId: optionalKey2(Union2([ContactId2, Null2])),
58971
59192
  from: optionalKey2(Union2([String4, Null2])),
59193
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Only this namespace's messages. A key scoped to a namespace always lists its own." })),
58972
59194
  after: optionalKey2(Union2([String4, Null2])),
58973
59195
  before: optionalKey2(Union2([String4, Null2]))
58974
59196
  });
@@ -59806,12 +60028,13 @@ ${payload.limitations}`);
59806
60028
  var list9 = make29("list", {
59807
60029
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
59808
60030
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
60031
+ namespace: namespaceFlag("list"),
59809
60032
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
59810
60033
  json: jsonFlag
59811
60034
  }).pipe(withDescription3("List email sending domains"), withExamples([
59812
60035
  { command: "samva email domains list" },
59813
60036
  { command: "samva email domains list --json" }
59814
- ]), withHandler(({ cursor, limit, all, json }) => gen2(function* () {
60037
+ ]), withHandler(({ cursor, limit, namespace, all, json }) => gen2(function* () {
59815
60038
  if (all && !isJsonLinesRequested())
59816
60039
  return yield* new CliUsageError({
59817
60040
  code: "all_requires_jsonl",
@@ -59820,7 +60043,11 @@ var list9 = make29("list", {
59820
60043
  const client = yield* getClientProvider;
59821
60044
  const cursorValue = getOrUndefined(cursor);
59822
60045
  const limitValue = getOrUndefined(limit);
59823
- const query = { cursor: cursorValue, limit: limitValue?.toString() };
60046
+ const query = {
60047
+ cursor: cursorValue,
60048
+ limit: limitValue?.toString(),
60049
+ ...namespaceField(namespace)
60050
+ };
59824
60051
  if (all) {
59825
60052
  let nextCursor = cursorValue;
59826
60053
  for (;; ) {
@@ -59848,6 +60075,7 @@ var list9 = make29("list", {
59848
60075
  ["Domain", domain.domain],
59849
60076
  ["Phase", domain.phase],
59850
60077
  ["Default", domain.isDefault ? "yes" : "no"],
60078
+ ["Namespace", domain.namespaceId ?? "organization"],
59851
60079
  ["ID", domain.id]
59852
60080
  ]);
59853
60081
  yield* log("");
@@ -59857,6 +60085,7 @@ var list9 = make29("list", {
59857
60085
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
59858
60086
  var add2 = make29("add", {
59859
60087
  domain: String9("domain").pipe(withDescription2("Domain to add, e.g. example.com")),
60088
+ namespace: namespaceFlag("create"),
59860
60089
  dryRun: Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false)),
59861
60090
  json: jsonFlag
59862
60091
  }).pipe(withDescription3("Add an email sending domain"), withExamples([
@@ -59867,15 +60096,24 @@ var add2 = make29("add", {
59867
60096
  {
59868
60097
  command: "samva email domains add --domain example.com",
59869
60098
  description: "Apply domain add"
60099
+ },
60100
+ {
60101
+ command: "samva email domains add --domain customer.example --namespace ns_7q2xk9mvt4znw8rh",
60102
+ description: "Add the domain to a namespace"
59870
60103
  }
59871
- ]), withHandler(({ domain, dryRun, json }) => gen2(function* () {
60104
+ ]), withHandler(({ domain, namespace, dryRun, json }) => gen2(function* () {
59872
60105
  if (dryRun) {
59873
60106
  if (json)
59874
- return yield* printJson({ dryRun: true, action: "email.domains.add", domain });
60107
+ return yield* printJson({
60108
+ dryRun: true,
60109
+ action: "email.domains.add",
60110
+ domain,
60111
+ ...namespaceField(namespace)
60112
+ });
59875
60113
  return yield* log(`[dry-run] Would add domain "${domain}".`);
59876
60114
  }
59877
60115
  const client = yield* getClientProvider;
59878
- yield* matchEffect3(addDomain({ domain }).pipe(client.provide), {
60116
+ yield* matchEffect3(addDomain({ domain, ...namespaceField(namespace) }).pipe(client.provide), {
59879
60117
  onFailure: (error) => {
59880
60118
  const conflict = getConflictError(error);
59881
60119
  if (!conflict) {
@@ -59901,6 +60139,8 @@ var add2 = make29("add", {
59901
60139
  });
59902
60140
  return gen2(function* () {
59903
60141
  const existing = yield* findExisting;
60142
+ if (!placedAsRequested(namespace, existing.namespaceId))
60143
+ return yield* toCliApiError(`Domain "${existing.domain}" already exists at ${placementLabel(existing.namespaceId)}; move it with \`samva namespaces assign\``, error);
59904
60144
  if (json)
59905
60145
  yield* printJson({ ...existing, idempotent: true });
59906
60146
  else
@@ -60414,7 +60654,7 @@ var waitingLine = (message) => {
60414
60654
  const reason = message.waitReason.replaceAll("-", " ");
60415
60655
  return message.reviewExpectedAt === null ? reason : `${reason} (expected by ${message.reviewExpectedAt})`;
60416
60656
  };
60417
- var skippedRecipientsLine = (message) => message.skippedRecipients.length === 0 ? null : message.skippedRecipients.map((recipient) => `${recipient.address} (${recipient.reason}${recipient.unsubscribeGroupId === undefined ? "" : `, group ${recipient.unsubscribeGroupId}`})`).join("; ");
60657
+ var skippedRecipientsLine = (message) => message.skippedRecipients.length === 0 ? null : message.skippedRecipients.map((recipient) => `${recipient.address} (${recipient.reason}${recipient.unsubscribeGroupId == null ? "" : `, group ${recipient.unsubscribeGroupId}`})`).join("; ");
60418
60658
  var printMessage = (message) => printFields([
60419
60659
  ["Message ID", message.id],
60420
60660
  ["Channel", message.channel],
@@ -60985,12 +61225,13 @@ ${truncateForDisplay(JSON.stringify(request.templateData, null, 2))}`);
60985
61225
  var list12 = make29("list", {
60986
61226
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
60987
61227
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
61228
+ namespace: namespaceFlag("list"),
60988
61229
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
60989
61230
  json: jsonFlag
60990
61231
  }).pipe(withDescription3("List verified sender addresses"), withExamples([
60991
61232
  { command: "samva email senders list" },
60992
61233
  { command: "samva email senders list --json" }
60993
- ]), withHandler(({ cursor, limit, all, json }) => gen2(function* () {
61234
+ ]), withHandler(({ cursor, limit, namespace, all, json }) => gen2(function* () {
60994
61235
  if (all && !isJsonLinesRequested())
60995
61236
  return yield* new CliUsageError({
60996
61237
  code: "all_requires_jsonl",
@@ -60999,7 +61240,11 @@ var list12 = make29("list", {
60999
61240
  const client = yield* getClientProvider;
61000
61241
  const cursorValue = getOrUndefined(cursor);
61001
61242
  const limitValue = getOrUndefined(limit);
61002
- const query = { cursor: cursorValue, limit: limitValue?.toString() };
61243
+ const query = {
61244
+ cursor: cursorValue,
61245
+ limit: limitValue?.toString(),
61246
+ ...namespaceField(namespace)
61247
+ };
61003
61248
  if (all) {
61004
61249
  let nextCursor = cursorValue;
61005
61250
  for (;; ) {
@@ -61029,6 +61274,7 @@ var list12 = make29("list", {
61029
61274
  ["Status", sender.verificationStatus],
61030
61275
  ["Provider", sender.providerLifecycle],
61031
61276
  ["Default", sender.isDefault ? "yes" : "no"],
61277
+ ["Namespace", sender.namespaceId ?? "organization"],
61032
61278
  ["ID", sender.id]
61033
61279
  ]);
61034
61280
  yield* log("");
@@ -61039,6 +61285,7 @@ var list12 = make29("list", {
61039
61285
  var add3 = make29("add", {
61040
61286
  email: String9("email").pipe(withDescription2("Sender email address")),
61041
61287
  name: String9("name").pipe(withDescription2("Display name for the sender"), optional4),
61288
+ namespace: namespaceFlag("create"),
61042
61289
  dryRun: Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false)),
61043
61290
  json: jsonFlag
61044
61291
  }).pipe(withDescription3("Add a sender address"), withExamples([
@@ -61050,7 +61297,7 @@ var add3 = make29("add", {
61050
61297
  command: "samva email senders add --email hello@example.com",
61051
61298
  description: "Apply sender add"
61052
61299
  }
61053
- ]), withHandler(({ email, name, dryRun, json }) => gen2(function* () {
61300
+ ]), withHandler(({ email, name, namespace, dryRun, json }) => gen2(function* () {
61054
61301
  const nameValue = getOrUndefined(name);
61055
61302
  if (dryRun) {
61056
61303
  if (json)
@@ -61058,14 +61305,16 @@ var add3 = make29("add", {
61058
61305
  dryRun: true,
61059
61306
  action: "email.senders.add",
61060
61307
  email,
61061
- name: nameValue
61308
+ name: nameValue,
61309
+ ...namespaceField(namespace)
61062
61310
  });
61063
61311
  return yield* log(`[dry-run] Would add sender "${email}".`);
61064
61312
  }
61065
61313
  const client = yield* getClientProvider;
61066
61314
  yield* matchEffect3(addSender({
61067
61315
  email,
61068
- ...nameValue === undefined ? {} : { name: nameValue }
61316
+ ...nameValue === undefined ? {} : { name: nameValue },
61317
+ ...namespaceField(namespace)
61069
61318
  }).pipe(client.provide), {
61070
61319
  onFailure: (error) => {
61071
61320
  const conflict = getConflictError(error);
@@ -61078,6 +61327,8 @@ var add3 = make29("add", {
61078
61327
  const listed = yield* listSenders({ cursor, limit: "100" }).pipe(client.provide, mapError2((listError) => toCliApiError("Sender may already exist but could not verify idempotently", listError)));
61079
61328
  const existing = (conflict.id ? listed.items.find((item) => item.id === conflict.id) : undefined) ?? listed.items.find((item) => item.email === email);
61080
61329
  if (existing) {
61330
+ if (!placedAsRequested(namespace, existing.namespaceId))
61331
+ return yield* toCliApiError(`Sender "${existing.email}" already exists at ${placementLabel(existing.namespaceId)}; move its domain, or the sender, with \`samva namespaces assign\``, error);
61081
61332
  if (json)
61082
61333
  yield* printJson({ ...existing, idempotent: true });
61083
61334
  else {
@@ -61319,7 +61570,7 @@ var BatchEventsResult = /* @__PURE__ */ Struct({
61319
61570
  var EventsCreateRequestJson = /* @__PURE__ */ Struct({
61320
61571
  contact: ContactEventReference,
61321
61572
  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])),
61573
+ properties: optionalKey2(Union2([JsonObject2, Null2])),
61323
61574
  occurredAt: optionalKey2(Union2([String4, Null2])),
61324
61575
  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
61576
  });
@@ -62135,6 +62386,7 @@ Bun.serve({ fetch: createWebhookHandler(extension, { apiKey, webhookSecret }) })
62135
62386
  });
62136
62387
  // src/lib/mailbox-errors.ts
62137
62388
  var undecodedStatus = (error) => isHttpClientError(error) ? error.response?.status : undefined;
62389
+ var isUnreadable404 = (error) => error instanceof SamvaCliError && error.message.includes("HTTP 404, unreadable body");
62138
62390
  var GATED_NEXT = "Mailboxes are not enabled for this organization (the `mailbox` launch flag is off). Mailbox commands work once it is enabled.";
62139
62391
  var personOnlyNext = (action) => {
62140
62392
  switch (action) {
@@ -62159,12 +62411,21 @@ var personOnlyNext = (action) => {
62159
62411
  }
62160
62412
  };
62161
62413
  var mailboxApiError = (prefix, error, options = {}) => {
62162
- if (undecodedStatus(error) === 404)
62414
+ if (undecodedStatus(error) === 404 || isUnreadable404(error))
62163
62415
  return new SamvaCliError({
62164
62416
  message: `${prefix}: mailboxes are not enabled for this organization.`,
62165
62417
  api: { reason: "FlagDisabledError", status: 404, details: {}, next: GATED_NEXT }
62166
62418
  });
62167
62419
  const failure = toCliApiError(prefix, error);
62420
+ const flag = failure.api?.details.flag;
62421
+ if (failure.api?.reason === "FlagDisabledError" && (flag === "whatsapp" || flag === "sms"))
62422
+ return new SamvaCliError({
62423
+ message: failure.message,
62424
+ api: {
62425
+ ...failure.api,
62426
+ next: `${flag === "sms" ? "SMS" : "WhatsApp"} is not enabled for this organization. Mailboxes work on email until it is.`
62427
+ }
62428
+ });
62168
62429
  if (options.personOnly !== undefined && failure.api?.reason === "ForbiddenError")
62169
62430
  return new SamvaCliError({
62170
62431
  message: failure.message,
@@ -64332,10 +64593,10 @@ var MailboxesCreateRequestJson = /* @__PURE__ */ Struct({
64332
64593
  var MailboxesCreate201 = Mailbox2;
64333
64594
  var MailboxesCreate401 = UnauthorizedError2;
64334
64595
  var MailboxesCreate402 = PaymentRequiredError2;
64335
- var MailboxesCreate403 = ForbiddenError2;
64596
+ var MailboxesCreate403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
64336
64597
  var MailboxesCreate404 = ResourceNotFoundError2;
64337
64598
  var MailboxesCreate409 = ConflictError2;
64338
- var MailboxesCreate422 = /* @__PURE__ */ Union2([ValidationError2, MailboxChannelUnsupportedError2]);
64599
+ var MailboxesCreate422 = ValidationError2;
64339
64600
  var MailboxesCreate500 = InternalError2;
64340
64601
  var MailboxesCreate502 = BillingProviderError;
64341
64602
  var MailboxesCreate504 = GatewayTimeoutError2;
@@ -64419,13 +64680,14 @@ var MailboxesApproveAction202 = MailboxPendingAction;
64419
64680
  var MailboxesApproveAction401 = UnauthorizedError2;
64420
64681
  var MailboxesApproveAction402 = PaymentRequiredError2;
64421
64682
  var MailboxesApproveAction403 = /* @__PURE__ */ Union2([
64683
+ FlagDisabledError,
64422
64684
  MailboxSendRefusedError2,
64423
64685
  OnboardingReviewRequiredError2,
64424
64686
  ForbiddenError2
64425
64687
  ]);
64426
64688
  var MailboxesApproveAction404 = ResourceNotFoundError2;
64427
64689
  var MailboxesApproveAction409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64428
- var MailboxesApproveAction422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64690
+ var MailboxesApproveAction422 = ValidationError2;
64429
64691
  var MailboxesApproveAction429 = RateLimitedError2;
64430
64692
  var MailboxesApproveAction500 = InternalError2;
64431
64693
  var MailboxesApproveAction502 = BillingProviderError;
@@ -64440,13 +64702,14 @@ var MailboxesCancelAction202 = MailboxPendingSendReceipt;
64440
64702
  var MailboxesCancelAction401 = UnauthorizedError2;
64441
64703
  var MailboxesCancelAction402 = PaymentRequiredError2;
64442
64704
  var MailboxesCancelAction403 = /* @__PURE__ */ Union2([
64705
+ FlagDisabledError,
64443
64706
  MailboxSendRefusedError2,
64444
64707
  OnboardingReviewRequiredError2,
64445
64708
  ForbiddenError2
64446
64709
  ]);
64447
64710
  var MailboxesCancelAction404 = ResourceNotFoundError2;
64448
64711
  var MailboxesCancelAction409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64449
- var MailboxesCancelAction422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64712
+ var MailboxesCancelAction422 = ValidationError2;
64450
64713
  var MailboxesCancelAction429 = RateLimitedError2;
64451
64714
  var MailboxesCancelAction500 = InternalError2;
64452
64715
  var MailboxesCancelAction502 = BillingProviderError;
@@ -64474,13 +64737,14 @@ var MailboxesRetryAction202 = MailboxPendingSendReceipt;
64474
64737
  var MailboxesRetryAction401 = UnauthorizedError2;
64475
64738
  var MailboxesRetryAction402 = PaymentRequiredError2;
64476
64739
  var MailboxesRetryAction403 = /* @__PURE__ */ Union2([
64740
+ FlagDisabledError,
64477
64741
  MailboxSendRefusedError2,
64478
64742
  OnboardingReviewRequiredError2,
64479
64743
  ForbiddenError2
64480
64744
  ]);
64481
64745
  var MailboxesRetryAction404 = ResourceNotFoundError2;
64482
64746
  var MailboxesRetryAction409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64483
- var MailboxesRetryAction422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64747
+ var MailboxesRetryAction422 = ValidationError2;
64484
64748
  var MailboxesRetryAction429 = RateLimitedError2;
64485
64749
  var MailboxesRetryAction500 = InternalError2;
64486
64750
  var MailboxesRetryAction502 = BillingProviderError;
@@ -64529,7 +64793,7 @@ var MailboxesCreateDraft201 = MailboxDraft;
64529
64793
  var MailboxesCreateDraft401 = UnauthorizedError2;
64530
64794
  var MailboxesCreateDraft403 = ForbiddenError2;
64531
64795
  var MailboxesCreateDraft404 = ResourceNotFoundError2;
64532
- var MailboxesCreateDraft422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64796
+ var MailboxesCreateDraft422 = ValidationError2;
64533
64797
  var MailboxesCreateDraft500 = InternalError2;
64534
64798
  var MailboxesCreateDraft504 = GatewayTimeoutError2;
64535
64799
  var MailboxesGetDraftPathParams = /* @__PURE__ */ Struct({
@@ -64586,13 +64850,14 @@ var MailboxesSendDraft202 = MailboxPendingSendReceipt;
64586
64850
  var MailboxesSendDraft401 = UnauthorizedError2;
64587
64851
  var MailboxesSendDraft402 = PaymentRequiredError2;
64588
64852
  var MailboxesSendDraft403 = /* @__PURE__ */ Union2([
64853
+ FlagDisabledError,
64589
64854
  MailboxSendRefusedError2,
64590
64855
  OnboardingReviewRequiredError2,
64591
64856
  ForbiddenError2
64592
64857
  ]);
64593
64858
  var MailboxesSendDraft404 = ResourceNotFoundError2;
64594
64859
  var MailboxesSendDraft409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64595
- var MailboxesSendDraft422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
64860
+ var MailboxesSendDraft422 = ValidationError2;
64596
64861
  var MailboxesSendDraft429 = RateLimitedError2;
64597
64862
  var MailboxesSendDraft500 = InternalError2;
64598
64863
  var MailboxesSendDraft502 = BillingProviderError;
@@ -64606,10 +64871,10 @@ var MailboxesCreateEndpointRequestJson = /* @__PURE__ */ Struct({
64606
64871
  });
64607
64872
  var MailboxesCreateEndpoint201 = Mailbox2;
64608
64873
  var MailboxesCreateEndpoint401 = UnauthorizedError2;
64609
- var MailboxesCreateEndpoint403 = ForbiddenError2;
64874
+ var MailboxesCreateEndpoint403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
64610
64875
  var MailboxesCreateEndpoint404 = ResourceNotFoundError2;
64611
64876
  var MailboxesCreateEndpoint409 = ConflictError2;
64612
- var MailboxesCreateEndpoint422 = /* @__PURE__ */ Union2([ValidationError2, MailboxChannelUnsupportedError2]);
64877
+ var MailboxesCreateEndpoint422 = ValidationError2;
64613
64878
  var MailboxesCreateEndpoint500 = InternalError2;
64614
64879
  var MailboxesCreateEndpoint504 = GatewayTimeoutError2;
64615
64880
  var MailboxesRemoveEndpointPathParams = /* @__PURE__ */ Struct({
@@ -64794,13 +65059,14 @@ var MailboxesSendMessage202 = MailboxPendingSendReceipt;
64794
65059
  var MailboxesSendMessage401 = UnauthorizedError2;
64795
65060
  var MailboxesSendMessage402 = PaymentRequiredError2;
64796
65061
  var MailboxesSendMessage403 = /* @__PURE__ */ Union2([
65062
+ FlagDisabledError,
64797
65063
  MailboxSendRefusedError2,
64798
65064
  OnboardingReviewRequiredError2,
64799
65065
  ForbiddenError2
64800
65066
  ]);
64801
65067
  var MailboxesSendMessage404 = ResourceNotFoundError2;
64802
65068
  var MailboxesSendMessage409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64803
- var MailboxesSendMessage422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65069
+ var MailboxesSendMessage422 = ValidationError2;
64804
65070
  var MailboxesSendMessage429 = RateLimitedError2;
64805
65071
  var MailboxesSendMessage500 = InternalError2;
64806
65072
  var MailboxesSendMessage502 = BillingProviderError;
@@ -64873,13 +65139,14 @@ var MailboxesForward202 = MailboxPendingSendReceipt;
64873
65139
  var MailboxesForward401 = UnauthorizedError2;
64874
65140
  var MailboxesForward402 = PaymentRequiredError2;
64875
65141
  var MailboxesForward403 = /* @__PURE__ */ Union2([
65142
+ FlagDisabledError,
64876
65143
  MailboxSendRefusedError2,
64877
65144
  OnboardingReviewRequiredError2,
64878
65145
  ForbiddenError2
64879
65146
  ]);
64880
65147
  var MailboxesForward404 = ResourceNotFoundError2;
64881
65148
  var MailboxesForward409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64882
- var MailboxesForward422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65149
+ var MailboxesForward422 = ValidationError2;
64883
65150
  var MailboxesForward429 = RateLimitedError2;
64884
65151
  var MailboxesForward500 = InternalError2;
64885
65152
  var MailboxesForward502 = BillingProviderError;
@@ -64926,13 +65193,14 @@ var MailboxesReply202 = MailboxPendingSendReceipt;
64926
65193
  var MailboxesReply401 = UnauthorizedError2;
64927
65194
  var MailboxesReply402 = PaymentRequiredError2;
64928
65195
  var MailboxesReply403 = /* @__PURE__ */ Union2([
65196
+ FlagDisabledError,
64929
65197
  MailboxSendRefusedError2,
64930
65198
  OnboardingReviewRequiredError2,
64931
65199
  ForbiddenError2
64932
65200
  ]);
64933
65201
  var MailboxesReply404 = ResourceNotFoundError2;
64934
65202
  var MailboxesReply409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64935
- var MailboxesReply422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65203
+ var MailboxesReply422 = ValidationError2;
64936
65204
  var MailboxesReply429 = RateLimitedError2;
64937
65205
  var MailboxesReply500 = InternalError2;
64938
65206
  var MailboxesReply502 = BillingProviderError;
@@ -64956,13 +65224,14 @@ var MailboxesReplyAll202 = MailboxPendingSendReceipt;
64956
65224
  var MailboxesReplyAll401 = UnauthorizedError2;
64957
65225
  var MailboxesReplyAll402 = PaymentRequiredError2;
64958
65226
  var MailboxesReplyAll403 = /* @__PURE__ */ Union2([
65227
+ FlagDisabledError,
64959
65228
  MailboxSendRefusedError2,
64960
65229
  OnboardingReviewRequiredError2,
64961
65230
  ForbiddenError2
64962
65231
  ]);
64963
65232
  var MailboxesReplyAll404 = ResourceNotFoundError2;
64964
65233
  var MailboxesReplyAll409 = /* @__PURE__ */ Union2([MailboxSendConflictError2, ConflictError2]);
64965
- var MailboxesReplyAll422 = /* @__PURE__ */ Union2([MailboxChannelUnsupportedError2, ValidationError2]);
65234
+ var MailboxesReplyAll422 = ValidationError2;
64966
65235
  var MailboxesReplyAll429 = RateLimitedError2;
64967
65236
  var MailboxesReplyAll500 = InternalError2;
64968
65237
  var MailboxesReplyAll502 = BillingProviderError;
@@ -65247,7 +65516,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65247
65516
  MailboxesCreate502.pipe(status(502)),
65248
65517
  MailboxesCreate504.pipe(status(504))
65249
65518
  ]
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", {
65519
+ }).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
65520
  params: MailboxesGetPathParams,
65252
65521
  success: MailboxesGet200,
65253
65522
  error: [
@@ -65402,7 +65671,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65402
65671
  MailboxesCreateDraft500,
65403
65672
  MailboxesCreateDraft504.pipe(status(504))
65404
65673
  ]
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", {
65674
+ }).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
65675
  params: MailboxesGetDraftPathParams,
65407
65676
  success: MailboxesGetDraft200,
65408
65677
  error: [
@@ -65467,7 +65736,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65467
65736
  MailboxesCreateEndpoint500,
65468
65737
  MailboxesCreateEndpoint504.pipe(status(504))
65469
65738
  ]
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", {
65739
+ }).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
65740
  params: MailboxesRemoveEndpointPathParams,
65472
65741
  success: MailboxesRemoveEndpoint200,
65473
65742
  error: [
@@ -65628,7 +65897,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65628
65897
  MailboxesSendMessage503.pipe(status(503)),
65629
65898
  MailboxesSendMessage504.pipe(status(504))
65630
65899
  ]
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", {
65900
+ }).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
65901
  params: MailboxesGetMessagePathParams,
65633
65902
  success: MailboxesGetMessage200,
65634
65903
  error: [
@@ -65734,7 +66003,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65734
66003
  MailboxesReply503.pipe(status(503)),
65735
66004
  MailboxesReply504.pipe(status(504))
65736
66005
  ]
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", {
66006
+ }).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
66007
  params: MailboxesReplyAllPathParams,
65739
66008
  headers: MailboxesReplyAllHeaders,
65740
66009
  payload: MailboxesReplyAllRequestJson,
@@ -65752,7 +66021,7 @@ var MailboxesGroup = class extends make37("Mailboxes").add(get5("mailboxesList",
65752
66021
  MailboxesReplyAll503.pipe(status(503)),
65753
66022
  MailboxesReplyAll504.pipe(status(504))
65754
66023
  ]
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", {
66024
+ }).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
66025
  params: MailboxesPausePathParams,
65757
66026
  success: MailboxesPause200,
65758
66027
  error: [
@@ -66553,17 +66822,36 @@ var HumanProfile = Struct({
66553
66822
  source: optional2(Literals(["api", "import", "manual", "form"]))
66554
66823
  });
66555
66824
 
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;
66825
+ // ../core/src/whatsapp/template-dispatch.ts
66826
+ var CONTACT_BINDING_FIELDS = [
66827
+ "id",
66828
+ "name",
66829
+ "displayName",
66830
+ "externalId",
66831
+ "phone",
66832
+ "email",
66833
+ "firstName",
66834
+ "lastName",
66835
+ "company",
66836
+ "jobTitle"
66837
+ ];
66838
+ var WhatsAppTemplateBinding = Union2([
66839
+ Struct({ contact: Literals(CONTACT_BINDING_FIELDS) }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppTemplateContactBinding" }),
66840
+ Struct({ customField: NonEmptyString }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppTemplateCustomFieldBinding" })
66841
+ ]).annotate({ identifier: "WhatsAppTemplateBinding" });
66842
+ var WhatsAppTemplateBindings = Record(NonEmptyString, WhatsAppTemplateBinding).annotate({
66843
+ identifier: "WhatsAppTemplateBindings",
66844
+ description: "Template parameters filled per recipient: parameter name to the contact field it reads."
66845
+ });
66846
+ var WhatsAppTemplateDispatch = Struct({
66847
+ template: TemplateRef,
66848
+ templateData: optionalKey2(TemplateVariableValues).annotate({
66849
+ identifier: "WhatsAppTemplateDispatchData"
66850
+ }),
66851
+ bindings: optionalKey2(WhatsAppTemplateBindings),
66852
+ businessAccountId: optionalKey2(WhatsAppBusinessAccountId)
66853
+ }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppTemplateDispatch" });
66854
+ var BoundTemplateData = taggedEnum();
66567
66855
  // ../core/src/organizations/reserved-hostnames.ts
66568
66856
  var RESERVED_HOSTNAMES = new Set([
66569
66857
  "apex",
@@ -66690,6 +66978,9 @@ class AnyGrant extends Service()("samva/ResourcePermission/AnyGrant") {
66690
66978
 
66691
66979
  class Unscoped extends Service()("samva/ResourcePermission/Unscoped") {
66692
66980
  }
66981
+
66982
+ class NamespaceScoped extends Service()("samva/ResourcePermission/NamespaceScoped") {
66983
+ }
66693
66984
  function sendGrants(channel) {
66694
66985
  return [
66695
66986
  { resource: "messages", action: "create" },
@@ -66928,7 +67219,7 @@ var ContactEventReference2 = Union2([
66928
67219
  var CreateEventPayload2 = Struct({
66929
67220
  contact: ContactEventReference2,
66930
67221
  name: NonEmptyString.check(isMaxLength(EVENT_NAME_MAX_LENGTH), isPattern2(EVENT_NAME_PATTERN)),
66931
- properties: optional2(JsonObject2),
67222
+ properties: optional2(JsonObject),
66932
67223
  occurredAt: optional2(DateFromString),
66933
67224
  idempotencyKey: optional2(NonEmptyString.check(isMaxLength(EVENT_IDEMPOTENCY_KEY_MAX_LENGTH)))
66934
67225
  }).annotate({ identifier: "CreateEventPayload" });
@@ -66937,7 +67228,7 @@ var ContactEvent2 = Struct({
66937
67228
  contactId: ContactId,
66938
67229
  name: String4,
66939
67230
  source: Literals(["api", "samva"]),
66940
- properties: JsonObject2,
67231
+ properties: JsonObject,
66941
67232
  occurredAt: DateFromString,
66942
67233
  recordedAt: DateFromString
66943
67234
  }).annotate({ identifier: "ContactEvent" });
@@ -66980,7 +67271,7 @@ class EventsGroup2 extends make37("events").add(post("create", "/", {
66980
67271
  }).annotateMerge(annotations({
66981
67272
  summary: "Record contact events in a batch",
66982
67273
  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" })) {
67274
+ }))).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
67275
  }
66985
67276
 
66986
67277
  class ContactEventsGroup2 extends make37("contactEvents").add(get5("listEvents", "/:id/events", {
@@ -66991,7 +67282,7 @@ class ContactEventsGroup2 extends make37("contactEvents").add(get5("listEvents",
66991
67282
  }).annotateMerge(annotations({
66992
67283
  summary: "List contact events",
66993
67284
  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({
67285
+ }))).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
67286
  title: "Contact events",
66996
67287
  description: "A contact's custom and lifecycle event timeline"
66997
67288
  })) {
@@ -67116,7 +67407,7 @@ var JourneyUpdateTagsConfig2 = Struct({
67116
67407
  });
67117
67408
  return issues;
67118
67409
  })).pipe(rejectExcessProperties).annotate({ identifier: "JourneyUpdateTagsConfig" });
67119
- var JourneyWebhookConfig2 = Struct({ data: optionalKey2(JsonObject2) }).pipe(rejectExcessProperties).annotate({ identifier: "JourneyWebhookConfig" });
67410
+ var JourneyWebhookConfig2 = Struct({ data: optionalKey2(JsonObject) }).pipe(rejectExcessProperties).annotate({ identifier: "JourneyWebhookConfig" });
67120
67411
  var JourneyEmptyConfig2 = Record(String4, Never2).annotate({
67121
67412
  identifier: "JourneyEmptyConfig"
67122
67413
  });
@@ -67138,6 +67429,11 @@ var JourneyNode2 = Union2([
67138
67429
  config: JourneySendEmailConfig2,
67139
67430
  next: nextNode
67140
67431
  }).pipe(rejectExcessProperties).annotate({ identifier: "JourneySendEmailNode" }),
67432
+ Struct({
67433
+ type: Literal2("send_whatsapp"),
67434
+ config: WhatsAppTemplateDispatch,
67435
+ next: nextNode
67436
+ }).pipe(rejectExcessProperties).annotate({ identifier: "WhatsAppJourneySendNode" }),
67141
67437
  Struct({ type: Literal2("wait"), config: JourneyWaitConfig2, next: nextNode }).pipe(rejectExcessProperties).annotate({ identifier: "JourneyWaitNode" }),
67142
67438
  Struct({
67143
67439
  type: Literal2("wait_for_event"),
@@ -67261,7 +67557,7 @@ var JourneyRunCounts = /* @__PURE__ */ Struct({
67261
67557
  var JourneyRunTrigger = /* @__PURE__ */ Struct({
67262
67558
  eventId: String4,
67263
67559
  eventName: String4,
67264
- properties: JsonObject
67560
+ properties: JsonObject2
67265
67561
  }).annotate({ identifier: "JourneyRunTrigger" });
67266
67562
  var JourneyListItem = /* @__PURE__ */ Struct({
67267
67563
  id: JourneyId2,
@@ -67367,7 +67663,7 @@ var JourneysCreateRequestJson = /* @__PURE__ */ Struct({
67367
67663
  var JourneysCreate201 = Journey;
67368
67664
  var JourneysCreate401 = UnauthorizedError2;
67369
67665
  var JourneysCreate402 = PaymentRequiredError2;
67370
- var JourneysCreate403 = ForbiddenError2;
67666
+ var JourneysCreate403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67371
67667
  var JourneysCreate404 = ResourceNotFoundError2;
67372
67668
  var JourneysCreate409 = ConflictError2;
67373
67669
  var JourneysCreate422 = ValidationError2;
@@ -67417,7 +67713,7 @@ var JourneysReplaceDraftRequestJson = /* @__PURE__ */ Struct({
67417
67713
  var JourneysReplaceDraft200 = Journey;
67418
67714
  var JourneysReplaceDraft401 = UnauthorizedError2;
67419
67715
  var JourneysReplaceDraft402 = PaymentRequiredError2;
67420
- var JourneysReplaceDraft403 = ForbiddenError2;
67716
+ var JourneysReplaceDraft403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67421
67717
  var JourneysReplaceDraft404 = ResourceNotFoundError2;
67422
67718
  var JourneysReplaceDraft409 = ConflictError2;
67423
67719
  var JourneysReplaceDraft422 = ValidationError2;
@@ -67438,7 +67734,7 @@ var JourneysPublishRequestJson = /* @__PURE__ */ Struct({ revision: String4.chec
67438
67734
  var JourneysPublish200 = Journey;
67439
67735
  var JourneysPublish401 = UnauthorizedError2;
67440
67736
  var JourneysPublish402 = PaymentRequiredError2;
67441
- var JourneysPublish403 = ForbiddenError2;
67737
+ var JourneysPublish403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67442
67738
  var JourneysPublish404 = ResourceNotFoundError2;
67443
67739
  var JourneysPublish409 = ConflictError2;
67444
67740
  var JourneysPublish422 = ValidationError2;
@@ -67449,7 +67745,7 @@ var JourneysResumePathParams = /* @__PURE__ */ Struct({ id: JourneyId2 });
67449
67745
  var JourneysResume200 = Journey;
67450
67746
  var JourneysResume401 = UnauthorizedError2;
67451
67747
  var JourneysResume402 = PaymentRequiredError2;
67452
- var JourneysResume403 = ForbiddenError2;
67748
+ var JourneysResume403 = /* @__PURE__ */ Union2([FlagDisabledError, ForbiddenError2]);
67453
67749
  var JourneysResume404 = ResourceNotFoundError2;
67454
67750
  var JourneysResume409 = ConflictError2;
67455
67751
  var JourneysResume422 = ValidationError2;
@@ -70910,10 +71206,15 @@ var MailboxThreadState2 = Struct({
70910
71206
  var MailboxThreadSummary2 = Struct(threadSummaryFields).annotate({
70911
71207
  identifier: "MailboxThreadSummary"
70912
71208
  });
71209
+ var MailboxWhatsAppServiceWindow = Struct({
71210
+ open: Boolean3,
71211
+ expiresAt: NullOr(DateFromString)
71212
+ }).annotate({ identifier: "MailboxWhatsAppServiceWindow" });
70913
71213
  var MailboxThread2 = Struct({
70914
71214
  ...threadSummaryFields,
70915
71215
  conversationId: ConversationId,
70916
71216
  participants: ArraySchema(MailboxThreadParticipantSchema),
71217
+ whatsappServiceWindow: NullOr(MailboxWhatsAppServiceWindow),
70917
71218
  createdAt: DateFromString
70918
71219
  }).annotate({ identifier: "MailboxThread" });
70919
71220
  var MailboxMessageAuthentication2 = Struct({
@@ -70960,18 +71261,23 @@ var MailboxEmailMessage = Struct({
70960
71261
  attachments: ArraySchema(MailboxMessageAttachmentSchema)
70961
71262
  }).annotate({ identifier: "MailboxEmailMessage" });
70962
71263
  var MailboxChatMedia = Struct({
70963
- id: AttachmentId,
70964
- contentType: String4,
71264
+ type: String4,
71265
+ contentType: NullOr(String4),
70965
71266
  filename: NullOr(String4),
70966
- size: NullOr(Count),
70967
71267
  caption: NullOr(String4)
70968
71268
  }).annotate({ identifier: "MailboxChatMedia" });
71269
+ var MailboxChatMessageTemplate = Struct({
71270
+ name: String4,
71271
+ language: String4
71272
+ }).annotate({ identifier: "MailboxChatMessageTemplate" });
70969
71273
  var MailboxChatMessage = Struct({
70970
71274
  ...messageFields,
70971
71275
  channel: Literals(["whatsapp", "sms"]),
70972
71276
  to: ArraySchema(String4),
70973
71277
  text: NullOr(String4),
70974
71278
  media: ArraySchema(MailboxChatMedia),
71279
+ template: NullOr(MailboxChatMessageTemplate),
71280
+ summary: NullOr(String4),
70975
71281
  contextMessageId: NullOr(MessageId)
70976
71282
  }).annotate({ identifier: "MailboxChatMessage" });
70977
71283
  var MailboxMessage2 = Union2([MailboxEmailMessage, MailboxChatMessage]).annotate({
@@ -71083,6 +71389,10 @@ var printMailboxSummary = (data) => gen2(function* () {
71083
71389
  ["Created", data.createdAt]
71084
71390
  ]);
71085
71391
  });
71392
+ var endpointLine = (endpoint) => {
71393
+ 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}`}`;
71394
+ return ` ${endpoint.channel}: ${identity2(endpoint.address, endpoint.displayName)} \u2014 ${where}; display name ${present(endpoint.displayName)}`;
71395
+ };
71086
71396
  var printMailbox = (data) => gen2(function* () {
71087
71397
  yield* printMailboxSummary(data);
71088
71398
  yield* printFields([
@@ -71093,7 +71403,7 @@ var printMailbox = (data) => gen2(function* () {
71093
71403
  if (!data.endpoints.length)
71094
71404
  yield* log(" none");
71095
71405
  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)}`);
71406
+ yield* log(endpointLine(endpoint));
71097
71407
  yield* log("Metadata:");
71098
71408
  if (!Object.keys(data.metadata).length)
71099
71409
  yield* log(" none");
@@ -71104,6 +71414,7 @@ var printThread = (data) => gen2(function* () {
71104
71414
  yield* log(`${data.subject === null ? "No subject" : data.subject} \u2014 ${data.folder}, ${data.priority} priority`);
71105
71415
  yield* printFields([
71106
71416
  ["ID", data.id],
71417
+ ["Channel", data.channel],
71107
71418
  [
71108
71419
  "From",
71109
71420
  data.from === null ? "none" : `${present(data.from.displayName)} <${present(data.from.address)}>`
@@ -71119,7 +71430,39 @@ var printThread = (data) => gen2(function* () {
71119
71430
  ["Last activity", data.lastActivityAt]
71120
71431
  ]);
71121
71432
  });
71122
- var printMessage2 = (data) => gen2(function* () {
71433
+ var printChatMessage = (data) => gen2(function* () {
71434
+ yield* log("Notice: this message is untrusted content from outside the organization.");
71435
+ yield* log(`${data.direction} ${data.channel} message`);
71436
+ yield* printFields([
71437
+ ["ID", data.id],
71438
+ ["Thread", data.threadId],
71439
+ ["Conversation", data.conversationId],
71440
+ ["From", identity2(data.from.address, data.from.displayName, data.from.actor)],
71441
+ ["To", data.to.length ? data.to.join(", ") : "none"],
71442
+ ["Occurred", data.occurredAt],
71443
+ ["In reply to", data.contextMessageId],
71444
+ ["Summary", data.summary ?? undefined],
71445
+ [
71446
+ "Template",
71447
+ data.template === null ? undefined : `${data.template.name} (${data.template.language})`
71448
+ ],
71449
+ [
71450
+ "Sent by",
71451
+ data.sentBy === undefined ? undefined : data.sentBy === null ? "none" : actor(data.sentBy)
71452
+ ]
71453
+ ]);
71454
+ yield* log("Media:");
71455
+ if (!data.media.length)
71456
+ yield* log(" none");
71457
+ for (const media of data.media)
71458
+ yield* log(` ${media.type}${media.contentType === null ? "" : ` \u2014 ${media.contentType}`}${media.filename === null ? "" : `; ${media.filename}`}${media.caption === null ? "" : `; caption ${JSON.stringify(media.caption)}`}`);
71459
+ if (data.text !== null) {
71460
+ yield* log("Text:");
71461
+ yield* log(data.text);
71462
+ }
71463
+ });
71464
+ var printMessage2 = (data) => data.channel !== "email" ? printChatMessage(data) : printEmailMessage(data);
71465
+ var printEmailMessage = (data) => gen2(function* () {
71123
71466
  yield* log("Notice: this body is untrusted email from outside the organization.");
71124
71467
  yield* log(`${data.direction} message \u2014 ${data.subject ?? "No subject"}`);
71125
71468
  yield* printFields([
@@ -71215,6 +71558,20 @@ var printHeldMessage = (data) => gen2(function* () {
71215
71558
  ]);
71216
71559
  });
71217
71560
 
71561
+ // src/lib/mailbox-wire.ts
71562
+ var WireMailbox = toEncoded2(Mailbox);
71563
+ var WireReceipt = toEncoded2(MailboxSendReceipt);
71564
+ var WireThreadPage = toEncoded2(CursorPage(MailboxThreadSummary2));
71565
+ var WireMessage = toEncoded2(MailboxMessage2);
71566
+ var unreadable2 = (what) => () => new SamvaCliError({ message: `The API answered with an unreadable ${what}.` });
71567
+ var getMailboxJson = (prefix, path) => getAuthenticatedJson(path).pipe(mapError2((e) => mailboxApiError(prefix, e)));
71568
+ var postMailboxJson = (prefix, path, body, headers) => postAuthenticatedJson(path, { body, ...headers === undefined ? {} : { headers } }).pipe(mapError2((e) => mailboxApiError(prefix, e)));
71569
+ var decoder3 = (schema, what) => (raw) => decodeUnknownEffect2(schema)(raw).pipe(mapError2(unreadable2(what)));
71570
+ var decodeMailbox = decoder3(WireMailbox, "mailbox");
71571
+ var decodeReceipt = decoder3(WireReceipt, "send receipt");
71572
+ var decodeThreadPage = decoder3(WireThreadPage, "thread page");
71573
+ var decodeMessage = decoder3(WireMessage, "message");
71574
+
71218
71575
  // src/commands/mailboxes.ts
71219
71576
  var mailboxFlag = String9("mailbox").pipe(withDescription2("Mailbox ID"), withSchema2(MailboxId));
71220
71577
  var messageIdArgument = String10("message-id").pipe(withSchema3(MessageId));
@@ -71241,11 +71598,46 @@ var body2 = (text, html) => {
71241
71598
  ...isSome2(html) ? { html: html.value } : {}
71242
71599
  });
71243
71600
  };
71601
+ var channelFlag2 = Literals3("channel", ["email", "whatsapp", "sms"]).pipe(withDescription2("The channel: email, or a connected whatsapp or sms number"), withDefault5("email"));
71602
+ var chatOnlyFlags = {
71603
+ template: String9("template").pipe(withDescription2("WhatsApp only: send this approved template (tmpl_\u2026) instead of --text"), optional4),
71604
+ data: String9("data").pipe(withDescription2("WhatsApp only: the template's variables as a JSON object"), optional4)
71605
+ };
71606
+ var usage2 = (code, message) => new CliUsageError({ code, message });
71607
+ var chatContent = (channel, flags) => gen2(function* () {
71608
+ if (isSome2(flags.html))
71609
+ return yield* usage2("mailbox_chat_html", `--html is for email; a ${channel} message is text.`);
71610
+ if (isSome2(flags.text) === isSome2(flags.template))
71611
+ return yield* usage2("mailbox_chat_content_required", channel === "whatsapp" ? "Provide exactly one of --text or --template." : "Provide --text; a template sends on WhatsApp only.");
71612
+ if (isNone2(flags.template)) {
71613
+ if (isSome2(flags.data))
71614
+ return yield* usage2("mailbox_chat_data", "--data needs --template.");
71615
+ return isSome2(flags.text) ? { text: flags.text.value } : {};
71616
+ }
71617
+ if (channel !== "whatsapp")
71618
+ return yield* usage2("mailbox_chat_template", "A template sends on WhatsApp only.");
71619
+ const templateId = yield* decodeUnknownEffect2(TemplateId)(flags.template.value).pipe(mapError2(() => usage2("mailbox_chat_template", "--template must be an approved template id (tmpl_\u2026).")));
71620
+ const dataText = getOrUndefined(flags.data);
71621
+ if (dataText === undefined)
71622
+ return { templateId };
71623
+ const raw = yield* try_3({
71624
+ try: () => JSON.parse(dataText),
71625
+ catch: () => usage2("mailbox_chat_data", "--data must be valid JSON.")
71626
+ });
71627
+ if (!isObject(raw) || Array.isArray(raw))
71628
+ return yield* usage2("mailbox_chat_data", "--data must be a JSON object.");
71629
+ return { templateId, templateData: raw };
71630
+ });
71631
+ var keyHeader = (key) => isSome2(key) ? { "idempotency-key": key.value } : undefined;
71244
71632
  var checkCursor = (cursor) => cursor === undefined ? succeed6(undefined) : decodeEffect2(Cursor2)(cursor).pipe(as2(cursor), mapError2(() => new CliUsageError({
71245
71633
  code: "mailbox_cursor_invalid",
71246
71634
  message: "The cursor is not a nextCursor this command printed."
71247
71635
  })));
71248
71636
  var pageLimit = (limit) => getOrUndefined(limit)?.toString();
71637
+ var searchParams = (values) => {
71638
+ const query = new URLSearchParams(Object.entries(values).filter((entry) => entry[1] !== undefined)).toString();
71639
+ return query === "" ? "" : `?${query}`;
71640
+ };
71249
71641
  var followPages = (options) => gen2(function* () {
71250
71642
  if (options.all && !isJsonLinesRequested())
71251
71643
  return yield* new CliUsageError({
@@ -71305,16 +71697,32 @@ var list19 = make29("list", {
71305
71697
  });
71306
71698
  })));
71307
71699
  var create9 = make29("create", {
71308
- address: String9("address").pipe(withDescription2("The mailbox's email address, such as support@acme.samva.email")),
71700
+ channel: channelFlag2,
71701
+ 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
71702
  name: String9("name"),
71310
- slug: String9("slug").pipe(withDescription2("Defaults to the address's local part"), optional4),
71703
+ slug: String9("slug").pipe(withDescription2("Defaults to the address's local part, or a phone number's digits"), optional4),
71311
71704
  namespace: String9("namespace").pipe(withSchema2(NamespaceId), optional4),
71312
71705
  json: jsonFlag
71313
- }).pipe(withDescription3("Create a mailbox with one email endpoint"), withExamples([
71706
+ }).pipe(withDescription3("Create a mailbox with one endpoint on a channel (email by default)"), withExamples([
71314
71707
  {
71315
71708
  command: "samva mailboxes create --address support@acme.samva.email --name Support"
71709
+ },
71710
+ {
71711
+ command: "samva mailboxes create --channel whatsapp --address +14155550123 --name Concierge",
71712
+ description: "A mailbox on a connected WhatsApp number"
71713
+ }
71714
+ ]), withHandler(({ channel, address, name, slug, namespace, json }) => gen2(function* () {
71715
+ if (channel !== "email") {
71716
+ const raw = yield* postMailboxJson("Could not create mailbox", "/v1/mailboxes", {
71717
+ endpoint: { channel, address },
71718
+ name,
71719
+ ...isSome2(slug) ? { slug: slug.value } : {},
71720
+ ...isSome2(namespace) ? { namespaceId: namespace.value } : {}
71721
+ });
71722
+ if (json)
71723
+ return yield* printJson(raw);
71724
+ return yield* printMailbox(yield* decodeMailbox(raw));
71316
71725
  }
71317
- ]), withHandler(({ address, name, slug, namespace, json }) => gen2(function* () {
71318
71726
  const client = yield* getClientProvider;
71319
71727
  const data = yield* create6({
71320
71728
  endpoint: { channel: "email", address },
@@ -71328,9 +71736,9 @@ var create9 = make29("create", {
71328
71736
  })));
71329
71737
  var mailboxIdArgument = String10("mailbox-id").pipe(withSchema3(MailboxId));
71330
71738
  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);
71739
+ const raw = yield* getMailboxJson("Could not read mailbox", `/v1/mailboxes/${id}`);
71740
+ const result = yield* decodeMailbox(raw);
71741
+ yield* json ? printJson(raw) : printMailbox(result);
71334
71742
  })));
71335
71743
  var update9 = make29("update", {
71336
71744
  id: mailboxIdArgument,
@@ -71386,17 +71794,22 @@ var update9 = make29("update", {
71386
71794
  })));
71387
71795
  var endpointAdd = make29("add", {
71388
71796
  mailbox: mailboxFlag,
71389
- address: String9("address").pipe(withDescription2("The email address to add, such as billing@acme.samva.email")),
71797
+ channel: channelFlag2,
71798
+ 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
71799
  displayName: String9("display-name").pipe(withDescription2("The sender name messages from this endpoint carry"), optional4),
71391
71800
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
71392
71801
  json: jsonFlag
71393
- }).pipe(withDescription3("Add an email endpoint to a mailbox"), withExamples([
71802
+ }).pipe(withDescription3("Add an endpoint on a channel (email by default) to a mailbox"), withExamples([
71394
71803
  {
71395
71804
  command: "samva mailboxes endpoints add --mailbox mbx_1234567890123456 --address billing@acme.samva.email"
71805
+ },
71806
+ {
71807
+ command: "samva mailboxes endpoints add --mailbox mbx_1234567890123456 --channel whatsapp --address +14155550123",
71808
+ description: "Add a connected WhatsApp number"
71396
71809
  }
71397
- ]), withHandler(({ mailbox, address, displayName, dryRun, json }) => gen2(function* () {
71810
+ ]), withHandler(({ mailbox, channel, address, displayName, dryRun, json }) => gen2(function* () {
71398
71811
  const payload = {
71399
- channel: "email",
71812
+ channel,
71400
71813
  address,
71401
71814
  displayName: getOrUndefined(displayName)
71402
71815
  };
@@ -71407,8 +71820,18 @@ var endpointAdd = make29("add", {
71407
71820
  id: mailbox,
71408
71821
  request: payload
71409
71822
  }) : log(`[dry-run] Would add ${address} to mailbox ${mailbox}.`);
71823
+ if (channel !== "email") {
71824
+ const raw = yield* postMailboxJson("Could not add the endpoint", `/v1/mailboxes/${mailbox}/endpoints`, payload);
71825
+ if (json)
71826
+ return yield* printJson(raw);
71827
+ return yield* printMailbox(yield* decodeMailbox(raw));
71828
+ }
71410
71829
  const client = yield* getClientProvider;
71411
- const result = yield* createEndpoint({ id: mailbox, ...payload }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not add the endpoint", e)));
71830
+ const result = yield* createEndpoint({
71831
+ id: mailbox,
71832
+ ...payload,
71833
+ channel: "email"
71834
+ }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not add the endpoint", e)));
71412
71835
  yield* json ? printJson(result) : printMailbox(result);
71413
71836
  })));
71414
71837
  var endpointIdArgument = String10("endpoint-id").pipe(withSchema3(MailboxEndpointId));
@@ -71593,13 +72016,11 @@ var threads = make29("threads", {
71593
72016
  },
71594
72017
  { command: "samva mailboxes threads --mailbox mbx_1234567890123456 --all --jsonl" }
71595
72018
  ]), withHandler(({ mailbox, limit, cursor, all, query, folder, label, unread, starred, after, before, json }) => gen2(function* () {
71596
- const client = yield* getClientProvider;
71597
72019
  yield* followPages({
71598
72020
  all,
71599
72021
  json,
71600
72022
  cursor,
71601
- page: (pageCursor) => listThreads({
71602
- id: mailbox,
72023
+ page: (pageCursor) => getMailboxJson("Could not list threads", `/v1/mailboxes/${mailbox}/threads${searchParams({
71603
72024
  cursor: pageCursor,
71604
72025
  limit: pageLimit(limit),
71605
72026
  q: getOrUndefined(query),
@@ -71609,7 +72030,7 @@ var threads = make29("threads", {
71609
72030
  starred: starred ? "true" : undefined,
71610
72031
  after: getOrUndefined(after),
71611
72032
  before: getOrUndefined(before)
71612
- }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not list threads", e))),
72033
+ })}`).pipe(flatMap3(decodeThreadPage)),
71613
72034
  empty: "No threads found.",
71614
72035
  human: printThread
71615
72036
  });
@@ -71621,68 +72042,119 @@ var read2 = make29("read", {
71621
72042
  }).pipe(withDescription3("Read a mailbox message"), withExamples([
71622
72043
  { command: "samva mailboxes read msg_1234567890123456 --mailbox mbx_1234567890123456 --json" }
71623
72044
  ]), 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)));
72045
+ const raw = yield* getMailboxJson("Could not read message", `/v1/mailboxes/${mailbox}/messages/${messageId}`);
72046
+ const data = yield* decodeMessage(raw);
71626
72047
  if (json)
71627
- return yield* printJson(data);
72048
+ return yield* printJson(raw);
71628
72049
  yield* printMessage2(data);
71629
72050
  })));
71630
72051
  var send7 = make29("send", {
71631
72052
  mailbox: mailboxFlag,
71632
- to: String9("to").pipe(atLeast2(1)),
71633
- subject: String9("subject"),
72053
+ channel: channelFlag2,
72054
+ to: String9("to").pipe(withDescription2("Recipient email address (repeatable), or one phone number in E.164 form"), atLeast2(1)),
72055
+ subject: String9("subject").pipe(withDescription2("Email only"), optional4),
71634
72056
  cc: String9("cc").pipe(atLeast2(0)),
71635
72057
  bcc: String9("bcc").pipe(atLeast2(0)),
71636
72058
  ...bodyFlags,
72059
+ ...chatOnlyFlags,
71637
72060
  json: jsonFlag
71638
- }).pipe(withDescription3("Send a message from a mailbox"), withExamples([
72061
+ }).pipe(withDescription3("Send a message from a mailbox: email by default, or to one phone number with --channel whatsapp or sms"), withExamples([
71639
72062
  {
71640
72063
  command: 'samva mailboxes send --mailbox mbx_1234567890123456 --to recipient@example.com --subject Hello --text "Hello"'
72064
+ },
72065
+ {
72066
+ command: `samva mailboxes send --mailbox mbx_1234567890123456 --channel whatsapp --to +14155550123 --template tmpl_1234567890123456 --data '{"name":"Ada"}'`,
72067
+ description: "Open a WhatsApp conversation with an approved template"
72068
+ },
72069
+ {
72070
+ command: 'samva mailboxes send --mailbox mbx_1234567890123456 --channel sms --to +14155550123 --text "Your order shipped."'
71641
72071
  }
71642
- ]), withHandler(({ mailbox, to, subject, cc, bcc, text, html, idempotencyKey, json }) => gen2(function* () {
71643
- const content = yield* body2(text, html);
72072
+ ]), withHandler(({
72073
+ mailbox,
72074
+ channel,
72075
+ to,
72076
+ subject,
72077
+ cc,
72078
+ bcc,
72079
+ text,
72080
+ html,
72081
+ template,
72082
+ data,
72083
+ idempotencyKey,
72084
+ json
72085
+ }) => gen2(function* () {
71644
72086
  const [first, ...rest] = to;
71645
72087
  if (first === undefined)
71646
72088
  return yield* new CliUsageError({
71647
72089
  code: "mailbox_recipient_required",
71648
72090
  message: "Provide --to."
71649
72091
  });
72092
+ if (channel !== "email") {
72093
+ if (rest.length > 0 || cc.length > 0 || bcc.length > 0 || isSome2(subject))
72094
+ return yield* usage2("mailbox_chat_recipient", `A ${channel} message goes to one --to number; --subject, --cc, and --bcc are for email.`);
72095
+ const content = yield* chatContent(channel, { text, html, template, data });
72096
+ const raw = yield* postMailboxJson("Could not send message", `/v1/mailboxes/${mailbox}/messages`, { channel, to: first, ...content }, keyHeader(idempotencyKey));
72097
+ if (json)
72098
+ return yield* printJson(raw);
72099
+ return yield* printReceipt(yield* decodeReceipt(raw));
72100
+ }
72101
+ if (isSome2(template) || isSome2(data))
72102
+ return yield* usage2("mailbox_template_channel", "--template sends on WhatsApp only.");
72103
+ if (isNone2(subject))
72104
+ return yield* usage2("mailbox_subject_required", "An email needs --subject.");
72105
+ const content = yield* body2(text, html);
71650
72106
  const client = yield* getClientProvider;
71651
- const data = yield* sendMessage2({
72107
+ const result = yield* sendMessage2({
71652
72108
  id: mailbox,
71653
72109
  idempotencyKey: getOrUndefined(idempotencyKey),
71654
72110
  to: [first, ...rest],
71655
- subject,
72111
+ subject: subject.value,
71656
72112
  ...cc.length ? { cc } : {},
71657
72113
  ...bcc.length ? { bcc } : {},
71658
72114
  ...content
71659
72115
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not send message", e)));
71660
72116
  if (json)
71661
- return yield* printJson(data);
71662
- yield* printReceipt(data);
72117
+ return yield* printJson(result);
72118
+ yield* printReceipt(result);
71663
72119
  })));
72120
+ 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
72121
  var reply2 = make29("reply", {
71665
72122
  messageId: messageIdArgument,
71666
72123
  mailbox: mailboxFlag,
71667
72124
  ...bodyFlags,
72125
+ ...chatOnlyFlags,
71668
72126
  all: Boolean6("all").pipe(withDefault5(false)),
71669
72127
  json: jsonFlag
71670
- }).pipe(withDescription3("Reply to a message; --all includes the other recipients"), withExamples([
72128
+ }).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
72129
  {
71672
72130
  command: 'samva mailboxes reply msg_1234567890123456 --mailbox mbx_1234567890123456 --text "Thanks" --all'
72131
+ },
72132
+ {
72133
+ command: "samva mailboxes reply msg_1234567890123456 --mailbox mbx_1234567890123456 --template tmpl_1234567890123456",
72134
+ description: "Answer a WhatsApp thread whose 24-hour service window has closed"
72135
+ }
72136
+ ]), withHandler(({ messageId, mailbox, text, html, template, data, idempotencyKey, all, json }) => gen2(function* () {
72137
+ const channel = isSome2(template) || isSome2(data) ? "whatsapp" : isSome2(html) || all || isNone2(text) ? "email" : yield* messageChannel(mailbox, messageId);
72138
+ if (channel !== "email") {
72139
+ if (all)
72140
+ return yield* usage2("mailbox_chat_all", "--all is for email; a chat reply has one recipient.");
72141
+ const content = yield* chatContent(channel, { text, html, template, data });
72142
+ const raw = yield* postMailboxJson("Could not reply", `/v1/mailboxes/${mailbox}/messages/${messageId}/reply`, { channel, ...content }, keyHeader(idempotencyKey));
72143
+ if (json)
72144
+ return yield* printJson(raw);
72145
+ return yield* printReceipt(yield* decodeReceipt(raw));
71673
72146
  }
71674
- ]), withHandler(({ messageId, mailbox, text, html, idempotencyKey, all, json }) => gen2(function* () {
71675
72147
  const payload = yield* body2(text, html);
71676
72148
  const client = yield* getClientProvider;
71677
- const data = yield* (all ? replyAll : reply)({
72149
+ const result = yield* (all ? replyAll : reply)({
71678
72150
  id: mailbox,
71679
72151
  messageId,
71680
72152
  idempotencyKey: getOrUndefined(idempotencyKey),
71681
72153
  ...payload
71682
72154
  }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not reply", e)));
71683
72155
  if (json)
71684
- return yield* printJson(data);
71685
- yield* printReceipt(data);
72156
+ return yield* printJson(result);
72157
+ yield* printReceipt(result);
71686
72158
  })));
71687
72159
  var actionIdArgument = String10("action-id").pipe(withSchema3(MailboxActionId));
71688
72160
  var actionGet = make29("get", {
@@ -71822,6 +72294,519 @@ var mailboxesCommand = make29("mailboxes").pipe(withDescription3("Mailbox readin
71822
72294
  make29("quarantine").pipe(withSubcommands([quarantineList, release2, discard]))
71823
72295
  ]));
71824
72296
 
72297
+ // ../sdk/dist/effect/generated/namespaces.js
72298
+ var NamespaceSummary = /* @__PURE__ */ Struct({
72299
+ id: NamespaceId2,
72300
+ name: String4,
72301
+ createdAt: String4
72302
+ }).annotate({ identifier: "NamespaceSummary" });
72303
+ var NamespaceUsage = /* @__PURE__ */ Struct({
72304
+ namespaceId: NamespaceId2,
72305
+ periodStart: String4,
72306
+ periodEnd: String4,
72307
+ emailCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
72308
+ totalMessages: Finite.check(isFinite4().annotate({ expected: "a finite number" }))
72309
+ }).annotate({ identifier: "NamespaceUsage" });
72310
+ var Namespace = /* @__PURE__ */ Struct({
72311
+ id: NamespaceId2,
72312
+ name: String4,
72313
+ createdAt: String4,
72314
+ metadata: NamespaceMetadata,
72315
+ updatedAt: String4
72316
+ }).annotate({ identifier: "Namespace" });
72317
+ var NamespaceResource = /* @__PURE__ */ Struct({
72318
+ type: NamespaceResourceType,
72319
+ id: String4,
72320
+ namespaceId: Union2([NamespaceId2, Null2])
72321
+ }).annotate({ identifier: "NamespaceResource" });
72322
+ var NamespacePage = /* @__PURE__ */ Struct({
72323
+ items: ArraySchema(NamespaceSummary),
72324
+ nextCursor: Union2([String4, Null2])
72325
+ }).annotate({ identifier: "NamespacePage" });
72326
+ var NamespacesListQuery = /* @__PURE__ */ Struct({
72327
+ limit: optionalKey2(Union2([String4, Null2])),
72328
+ cursor: optionalKey2(Union2([Cursor, Null2])),
72329
+ after: optionalKey2(Union2([String4, Null2])),
72330
+ before: optionalKey2(Union2([String4, Null2]))
72331
+ });
72332
+ var NamespacesList200 = NamespacePage;
72333
+ var NamespacesList401 = UnauthorizedError2;
72334
+ var NamespacesList403 = ForbiddenError2;
72335
+ var NamespacesList422 = ValidationError2;
72336
+ var NamespacesList500 = InternalError2;
72337
+ var NamespacesList504 = GatewayTimeoutError2;
72338
+ var NamespacesCreateRequestJson = /* @__PURE__ */ Struct({
72339
+ 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" })),
72340
+ metadata: optionalKey2(Union2([NamespaceMetadata, Null2]))
72341
+ });
72342
+ var NamespacesCreate201 = Namespace;
72343
+ var NamespacesCreate401 = UnauthorizedError2;
72344
+ var NamespacesCreate403 = ForbiddenError2;
72345
+ var NamespacesCreate409 = ConflictError2;
72346
+ var NamespacesCreate422 = ValidationError2;
72347
+ var NamespacesCreate500 = InternalError2;
72348
+ var NamespacesCreate504 = GatewayTimeoutError2;
72349
+ var NamespacesGetPathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72350
+ var NamespacesGet200 = Namespace;
72351
+ var NamespacesGet401 = UnauthorizedError2;
72352
+ var NamespacesGet403 = ForbiddenError2;
72353
+ var NamespacesGet404 = ResourceNotFoundError2;
72354
+ var NamespacesGet422 = ValidationError2;
72355
+ var NamespacesGet500 = InternalError2;
72356
+ var NamespacesGet504 = GatewayTimeoutError2;
72357
+ var NamespacesRemovePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72358
+ var NamespacesRemove200 = SuccessResponse2;
72359
+ var NamespacesRemove401 = UnauthorizedError2;
72360
+ var NamespacesRemove403 = ForbiddenError2;
72361
+ var NamespacesRemove404 = ResourceNotFoundError2;
72362
+ var NamespacesRemove409 = ConflictError2;
72363
+ var NamespacesRemove422 = ValidationError2;
72364
+ var NamespacesRemove500 = InternalError2;
72365
+ var NamespacesRemove504 = GatewayTimeoutError2;
72366
+ var NamespacesUpdatePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72367
+ var NamespacesUpdateRequestJson = /* @__PURE__ */ Struct({
72368
+ 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])),
72369
+ metadata: optionalKey2(Union2([Record(String4, Union2([String4, Null2])), Null2]))
72370
+ });
72371
+ var NamespacesUpdate200 = Namespace;
72372
+ var NamespacesUpdate401 = UnauthorizedError2;
72373
+ var NamespacesUpdate403 = ForbiddenError2;
72374
+ var NamespacesUpdate404 = ResourceNotFoundError2;
72375
+ var NamespacesUpdate409 = ConflictError2;
72376
+ var NamespacesUpdate422 = ValidationError2;
72377
+ var NamespacesUpdate500 = InternalError2;
72378
+ var NamespacesUpdate504 = GatewayTimeoutError2;
72379
+ var NamespacesAssignResourcePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72380
+ var NamespacesAssignResourceRequestJson = /* @__PURE__ */ Struct({
72381
+ type: NamespaceResourceType,
72382
+ resourceId: String4.annotate({ description: "The resource's id, such as `dom_...` for a domain." })
72383
+ });
72384
+ var NamespacesAssignResource200 = NamespaceResource;
72385
+ var NamespacesAssignResource401 = UnauthorizedError2;
72386
+ var NamespacesAssignResource403 = ForbiddenError2;
72387
+ var NamespacesAssignResource404 = ResourceNotFoundError2;
72388
+ var NamespacesAssignResource409 = ConflictError2;
72389
+ var NamespacesAssignResource422 = ValidationError2;
72390
+ var NamespacesAssignResource500 = InternalError2;
72391
+ var NamespacesAssignResource504 = GatewayTimeoutError2;
72392
+ var NamespacesRemoveResourcePathParams = /* @__PURE__ */ Struct({
72393
+ id: NamespaceId2,
72394
+ type: NamespaceResourceType,
72395
+ resourceId: String4
72396
+ });
72397
+ var NamespacesRemoveResource200 = NamespaceResource;
72398
+ var NamespacesRemoveResource401 = UnauthorizedError2;
72399
+ var NamespacesRemoveResource403 = ForbiddenError2;
72400
+ var NamespacesRemoveResource404 = ResourceNotFoundError2;
72401
+ var NamespacesRemoveResource409 = ConflictError2;
72402
+ var NamespacesRemoveResource422 = ValidationError2;
72403
+ var NamespacesRemoveResource500 = InternalError2;
72404
+ var NamespacesRemoveResource504 = GatewayTimeoutError2;
72405
+ var NamespacesGetUsagePathParams = /* @__PURE__ */ Struct({ id: NamespaceId2 });
72406
+ var NamespacesGetUsageQuery = /* @__PURE__ */ Struct({
72407
+ after: optionalKey2(Union2([String4, Null2])),
72408
+ before: optionalKey2(Union2([String4, Null2]))
72409
+ });
72410
+ var NamespacesGetUsage200 = NamespaceUsage;
72411
+ var NamespacesGetUsage401 = UnauthorizedError2;
72412
+ var NamespacesGetUsage403 = ForbiddenError2;
72413
+ var NamespacesGetUsage404 = ResourceNotFoundError2;
72414
+ var NamespacesGetUsage422 = ValidationError2;
72415
+ var NamespacesGetUsage500 = InternalError2;
72416
+ var NamespacesGetUsage504 = GatewayTimeoutError2;
72417
+ var NamespacesGroup = class extends make37("Namespaces").add(get5("namespacesList", "/v1/namespaces", {
72418
+ query: NamespacesListQuery,
72419
+ success: NamespacesList200,
72420
+ error: [
72421
+ NamespacesList401.pipe(status(401)),
72422
+ NamespacesList403.pipe(status(403)),
72423
+ NamespacesList422.pipe(status(422)),
72424
+ NamespacesList500,
72425
+ NamespacesList504.pipe(status(504))
72426
+ ]
72427
+ }).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", {
72428
+ payload: NamespacesCreateRequestJson,
72429
+ success: NamespacesCreate201.pipe(status(201)),
72430
+ error: [
72431
+ NamespacesCreate401.pipe(status(401)),
72432
+ NamespacesCreate403.pipe(status(403)),
72433
+ NamespacesCreate409.pipe(status(409)),
72434
+ NamespacesCreate422.pipe(status(422)),
72435
+ NamespacesCreate500,
72436
+ NamespacesCreate504.pipe(status(504))
72437
+ ]
72438
+ }).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", {
72439
+ params: NamespacesGetPathParams,
72440
+ success: NamespacesGet200,
72441
+ error: [
72442
+ NamespacesGet401.pipe(status(401)),
72443
+ NamespacesGet403.pipe(status(403)),
72444
+ NamespacesGet404.pipe(status(404)),
72445
+ NamespacesGet422.pipe(status(422)),
72446
+ NamespacesGet500,
72447
+ NamespacesGet504.pipe(status(504))
72448
+ ]
72449
+ }).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "namespaces.get").annotate(Summary, "Get a namespace").annotate(Description, "Returns one namespace."), del("namespacesRemove", "/v1/namespaces/:id", {
72450
+ params: NamespacesRemovePathParams,
72451
+ success: NamespacesRemove200,
72452
+ error: [
72453
+ NamespacesRemove401.pipe(status(401)),
72454
+ NamespacesRemove403.pipe(status(403)),
72455
+ NamespacesRemove404.pipe(status(404)),
72456
+ NamespacesRemove409.pipe(status(409)),
72457
+ NamespacesRemove422.pipe(status(422)),
72458
+ NamespacesRemove500,
72459
+ NamespacesRemove504.pipe(status(504))
72460
+ ]
72461
+ }).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", {
72462
+ params: NamespacesUpdatePathParams,
72463
+ payload: NamespacesUpdateRequestJson,
72464
+ success: NamespacesUpdate200,
72465
+ error: [
72466
+ NamespacesUpdate401.pipe(status(401)),
72467
+ NamespacesUpdate403.pipe(status(403)),
72468
+ NamespacesUpdate404.pipe(status(404)),
72469
+ NamespacesUpdate409.pipe(status(409)),
72470
+ NamespacesUpdate422.pipe(status(422)),
72471
+ NamespacesUpdate500,
72472
+ NamespacesUpdate504.pipe(status(504))
72473
+ ]
72474
+ }).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", {
72475
+ params: NamespacesAssignResourcePathParams,
72476
+ payload: NamespacesAssignResourceRequestJson,
72477
+ success: NamespacesAssignResource200,
72478
+ error: [
72479
+ NamespacesAssignResource401.pipe(status(401)),
72480
+ NamespacesAssignResource403.pipe(status(403)),
72481
+ NamespacesAssignResource404.pipe(status(404)),
72482
+ NamespacesAssignResource409.pipe(status(409)),
72483
+ NamespacesAssignResource422.pipe(status(422)),
72484
+ NamespacesAssignResource500,
72485
+ NamespacesAssignResource504.pipe(status(504))
72486
+ ]
72487
+ }).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", {
72488
+ params: NamespacesRemoveResourcePathParams,
72489
+ success: NamespacesRemoveResource200,
72490
+ error: [
72491
+ NamespacesRemoveResource401.pipe(status(401)),
72492
+ NamespacesRemoveResource403.pipe(status(403)),
72493
+ NamespacesRemoveResource404.pipe(status(404)),
72494
+ NamespacesRemoveResource409.pipe(status(409)),
72495
+ NamespacesRemoveResource422.pipe(status(422)),
72496
+ NamespacesRemoveResource500,
72497
+ NamespacesRemoveResource504.pipe(status(504))
72498
+ ]
72499
+ }).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", {
72500
+ params: NamespacesGetUsagePathParams,
72501
+ query: NamespacesGetUsageQuery,
72502
+ success: NamespacesGetUsage200,
72503
+ error: [
72504
+ NamespacesGetUsage401.pipe(status(401)),
72505
+ NamespacesGetUsage403.pipe(status(403)),
72506
+ NamespacesGetUsage404.pipe(status(404)),
72507
+ NamespacesGetUsage422.pipe(status(422)),
72508
+ NamespacesGetUsage500,
72509
+ NamespacesGetUsage504.pipe(status(504))
72510
+ ]
72511
+ }).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") {
72512
+ };
72513
+
72514
+ // ../sdk/dist/effect/namespaces.js
72515
+ var make52 = /* @__PURE__ */ forGroup(NamespacesGroup);
72516
+ var list20 = /* @__PURE__ */ make52("namespacesList");
72517
+ var create10 = /* @__PURE__ */ make52("namespacesCreate");
72518
+ var get23 = /* @__PURE__ */ make52("namespacesGet");
72519
+ var update10 = /* @__PURE__ */ make52("namespacesUpdate");
72520
+ var remove10 = /* @__PURE__ */ make52("namespacesRemove");
72521
+ var assignResource = /* @__PURE__ */ make52("namespacesAssignResource");
72522
+ var removeResource = /* @__PURE__ */ make52("namespacesRemoveResource");
72523
+ var getUsage2 = /* @__PURE__ */ make52("namespacesGetUsage");
72524
+
72525
+ // src/commands/namespaces.ts
72526
+ var idArgument3 = String10("id").pipe(withDescription4("Namespace id (ns_...)"));
72527
+ var optionalString2 = (name, description) => String9(name).pipe(withDescription2(description), optional4);
72528
+ var dryRunFlag4 = Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false));
72529
+ var RESOURCE_FLAGS = ["domain", "sender", "contact", "template"];
72530
+ var resourceFlags = {
72531
+ domain: optionalString2("domain", "Domain id (dom_...)"),
72532
+ sender: optionalString2("sender", "Sender id"),
72533
+ contact: optionalString2("contact", "Contact id"),
72534
+ template: optionalString2("template", "Template id; its whole project moves with it")
72535
+ };
72536
+ var chosenResource = (flags) => {
72537
+ const chosen = RESOURCE_FLAGS.flatMap((type) => {
72538
+ const id = flags[type];
72539
+ return isSome2(id) ? [{ type, id: id.value }] : [];
72540
+ });
72541
+ if (chosen.length !== 1) {
72542
+ return new CliUsageError({
72543
+ code: "resource_flag_required",
72544
+ message: `Pass exactly one resource: ${RESOURCE_FLAGS.map((type) => `--${type} <id>`).join(", ")}.`
72545
+ });
72546
+ }
72547
+ return chosen[0];
72548
+ };
72549
+ var parsePairs = (flag, raw) => gen2(function* () {
72550
+ const metadata = {};
72551
+ for (const pair of raw) {
72552
+ const at = pair.indexOf("=");
72553
+ if (at <= 0) {
72554
+ return yield* new CliUsageError({
72555
+ code: "invalid_metadata",
72556
+ message: `${flag} must be key=value, got "${pair}".`
72557
+ });
72558
+ }
72559
+ metadata[pair.slice(0, at)] = pair.slice(at + 1);
72560
+ }
72561
+ return metadata;
72562
+ });
72563
+ var metadataRows = (metadata) => Object.entries(metadata).map(([key, value]) => [`Metadata ${key}`, value]);
72564
+ var list21 = make29("list", {
72565
+ cursor: optionalString2("cursor", "Resume after this nextCursor from a previous page"),
72566
+ limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
72567
+ after: optionalString2("after", "Only namespaces created after this ISO 8601 instant"),
72568
+ before: optionalString2("before", "Only namespaces created before this ISO 8601 instant"),
72569
+ all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
72570
+ json: jsonFlag
72571
+ }).pipe(withDescription3("List namespaces, newest first"), withExamples([
72572
+ { command: "samva namespaces list" },
72573
+ { command: "samva namespaces list --all --jsonl", description: "Stream every page as JSONL" }
72574
+ ]), withHandler(({ cursor, limit, after, before, all, json }) => gen2(function* () {
72575
+ if (all && !isJsonLinesRequested())
72576
+ return yield* new CliUsageError({
72577
+ code: "all_requires_jsonl",
72578
+ message: "--all is an unbounded traversal and requires --jsonl."
72579
+ });
72580
+ const client = yield* getClientProvider;
72581
+ const query = {
72582
+ limit: getOrUndefined(limit)?.toString(),
72583
+ after: getOrUndefined(after),
72584
+ before: getOrUndefined(before)
72585
+ };
72586
+ const page = (pageCursor) => list20({ ...query, cursor: pageCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list namespaces", error, { cursor: pageCursor ?? null })));
72587
+ let nextCursor = getOrUndefined(cursor);
72588
+ for (;; ) {
72589
+ const data = yield* page(nextCursor);
72590
+ if (isJsonLinesRequested()) {
72591
+ for (const item of data.items)
72592
+ yield* printJsonLine(item);
72593
+ } else if (json) {
72594
+ return yield* printJson(data);
72595
+ } else {
72596
+ if (data.items.length === 0) {
72597
+ return yield* log(`No namespaces yet. Create one with \`samva namespaces create "Acme"\`.`);
72598
+ }
72599
+ for (const item of data.items) {
72600
+ yield* printFields([
72601
+ ["ID", item.id],
72602
+ ["Name", item.name],
72603
+ ["Created", item.createdAt]
72604
+ ]);
72605
+ yield* log("");
72606
+ }
72607
+ if (data.nextCursor !== null)
72608
+ yield* printFields([["Next cursor", data.nextCursor]]);
72609
+ }
72610
+ if (!all || data.nextCursor === null)
72611
+ return;
72612
+ nextCursor = data.nextCursor;
72613
+ }
72614
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72615
+ var create11 = make29("create", {
72616
+ name: String10("name").pipe(withDescription4("Namespace name")),
72617
+ metadata: String9("metadata").pipe(withDescription2("Your own label, key=value (repeatable); Samva stores and never reads it"), atLeast2(0)),
72618
+ dryRun: dryRunFlag4,
72619
+ json: jsonFlag
72620
+ }).pipe(withDescription3("Create a namespace, a sub-tenant for one of your customers"), withExamples([
72621
+ { command: "samva namespaces create Acme --metadata customerId=cus_123" },
72622
+ { command: "samva namespaces create Acme --dry-run --json" }
72623
+ ]), withHandler(({ name, metadata, dryRun, json }) => gen2(function* () {
72624
+ const labels = yield* parsePairs("--metadata", metadata);
72625
+ const request = { name, ...metadata.length === 0 ? {} : { metadata: labels } };
72626
+ if (dryRun)
72627
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.create", request }) : printFields([["Action", "namespaces.create"], ["Name", name], ...metadataRows(labels)]);
72628
+ const client = yield* getClientProvider;
72629
+ const created = yield* create10(request).pipe(client.provide, mapError2((error) => toCliApiError("Could not create namespace", error)));
72630
+ if (json)
72631
+ return yield* printJson(created);
72632
+ yield* printFields([
72633
+ ["ID", created.id],
72634
+ ["Name", created.name],
72635
+ ...metadataRows(created.metadata),
72636
+ ["Created", created.createdAt]
72637
+ ]);
72638
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72639
+ 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* () {
72640
+ const client = yield* getClientProvider;
72641
+ const namespace = yield* get23({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get namespace", error)));
72642
+ if (json)
72643
+ return yield* printJson(namespace);
72644
+ yield* printFields([
72645
+ ["ID", namespace.id],
72646
+ ["Name", namespace.name],
72647
+ ...metadataRows(namespace.metadata),
72648
+ ["Created", namespace.createdAt],
72649
+ ["Updated", namespace.updatedAt]
72650
+ ]);
72651
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72652
+ var update11 = make29("update", {
72653
+ id: idArgument3,
72654
+ name: optionalString2("name", "New name"),
72655
+ metadata: String9("metadata").pipe(withDescription2("Set a metadata label, key=value (repeatable); other keys are kept"), atLeast2(0)),
72656
+ unsetMetadata: String9("unset-metadata").pipe(withDescription2("Delete a metadata key (repeatable)"), atLeast2(0)),
72657
+ dryRun: dryRunFlag4,
72658
+ json: jsonFlag
72659
+ }).pipe(withDescription3("Rename a namespace or change its metadata"), withExamples([
72660
+ { command: "samva namespaces update ns_7q2xk9mvt4znw8rh --name Acme --metadata plan=pro" },
72661
+ { command: "samva namespaces update ns_7q2xk9mvt4znw8rh --unset-metadata plan" }
72662
+ ]), withHandler(({ id, name, metadata, unsetMetadata, dryRun, json }) => gen2(function* () {
72663
+ const labels = yield* parsePairs("--metadata", metadata);
72664
+ const conflicting = unsetMetadata.filter((key) => (key in labels));
72665
+ if (conflicting.length > 0) {
72666
+ return yield* new CliUsageError({
72667
+ code: "metadata_conflict",
72668
+ message: `--metadata and --unset-metadata both name ${conflicting.join(", ")}.`
72669
+ });
72670
+ }
72671
+ if (isNone2(name) && metadata.length === 0 && unsetMetadata.length === 0) {
72672
+ return yield* new CliUsageError({
72673
+ code: "nothing_to_update",
72674
+ message: "Pass --name, --metadata key=value, or --unset-metadata key."
72675
+ });
72676
+ }
72677
+ const merged = {
72678
+ ...labels,
72679
+ ...Object.fromEntries(unsetMetadata.map((key) => [key, null]))
72680
+ };
72681
+ const request = {
72682
+ ...match(name, { onNone: () => ({}), onSome: (value) => ({ name: value }) }),
72683
+ ...metadata.length === 0 && unsetMetadata.length === 0 ? {} : { metadata: merged }
72684
+ };
72685
+ if (dryRun)
72686
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.update", id, request }) : printFields([
72687
+ ["Action", "namespaces.update"],
72688
+ ["Namespace", id],
72689
+ ["Name", getOrUndefined(name)],
72690
+ ...metadataRows(labels),
72691
+ ...unsetMetadata.map((key) => [`Unset ${key}`, "yes"])
72692
+ ]);
72693
+ const client = yield* getClientProvider;
72694
+ const updated = yield* update10({ id, ...request }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update namespace", error)));
72695
+ if (json)
72696
+ return yield* printJson(updated);
72697
+ yield* printFields([
72698
+ ["ID", updated.id],
72699
+ ["Name", updated.name],
72700
+ ...metadataRows(updated.metadata),
72701
+ ["Updated", updated.updatedAt]
72702
+ ]);
72703
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72704
+ var remove11 = make29("delete", {
72705
+ id: idArgument3,
72706
+ dryRun: dryRunFlag4,
72707
+ yes: Boolean6("yes").pipe(withDefault5(false)),
72708
+ json: jsonFlag
72709
+ }).pipe(withDescription3("Delete an empty namespace; one that still holds anything is refused with a count of what remains"), withExamples([
72710
+ { command: "samva namespaces delete ns_7q2xk9mvt4znw8rh --dry-run" },
72711
+ { command: "samva namespaces delete ns_7q2xk9mvt4znw8rh --yes" }
72712
+ ]), withHandler(({ id, dryRun, yes, json }) => gen2(function* () {
72713
+ if (dryRun)
72714
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.delete", id }) : log(`[dry-run] Would delete namespace ${id}.`);
72715
+ yield* confirmDestructive({
72716
+ yes,
72717
+ json,
72718
+ message: `Delete namespace ${id}?`,
72719
+ nonInteractiveMessage: "Namespace deletion requires --yes in non-interactive mode. Preview with --dry-run."
72720
+ });
72721
+ const client = yield* getClientProvider;
72722
+ const result = yield* remove10({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not delete namespace", error)));
72723
+ if (json)
72724
+ return yield* printJson(result);
72725
+ yield* log(`Deleted namespace ${id}.`);
72726
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72727
+ var assign2 = make29("assign", {
72728
+ id: idArgument3,
72729
+ ...resourceFlags,
72730
+ dryRun: dryRunFlag4,
72731
+ json: jsonFlag
72732
+ }).pipe(withDescription3("Move a domain, sender, contact, or template into a namespace; pass exactly one resource flag"), withExamples([
72733
+ { command: "samva namespaces assign ns_7q2xk9mvt4znw8rh --domain dom_xyz789" },
72734
+ {
72735
+ command: "samva namespaces assign ns_7q2xk9mvt4znw8rh --contact contact_7q2xk9mvt4znw8rh --dry-run"
72736
+ }
72737
+ ]), withHandler(({ id, domain, sender, contact, template, dryRun, json }) => gen2(function* () {
72738
+ const resource = chosenResource({ domain, sender, contact, template });
72739
+ if (resource instanceof CliUsageError)
72740
+ return yield* resource;
72741
+ if (dryRun)
72742
+ return yield* json ? printJson({ dryRun: true, action: "namespaces.assign", id, request: resource }) : log(`[dry-run] Would move ${resource.type} ${resource.id} into ${id}.`);
72743
+ const client = yield* getClientProvider;
72744
+ const moved = yield* assignResource({
72745
+ id,
72746
+ type: resource.type,
72747
+ resourceId: resource.id
72748
+ }).pipe(client.provide, mapError2((error) => toCliApiError("Could not assign resource", error)));
72749
+ if (json)
72750
+ return yield* printJson(moved);
72751
+ yield* printFields([
72752
+ ["Type", moved.type],
72753
+ ["ID", moved.id],
72754
+ ["Namespace", moved.namespaceId]
72755
+ ]);
72756
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72757
+ var unassign = make29("unassign", {
72758
+ id: idArgument3,
72759
+ ...resourceFlags,
72760
+ dryRun: dryRunFlag4,
72761
+ json: jsonFlag
72762
+ }).pipe(withDescription3("Return a domain, sender, contact, or template to organization level; pass exactly one resource flag"), withExamples([
72763
+ { command: "samva namespaces unassign ns_7q2xk9mvt4znw8rh --domain dom_xyz789" }
72764
+ ]), withHandler(({ id, domain, sender, contact, template, dryRun, json }) => gen2(function* () {
72765
+ const resource = chosenResource({ domain, sender, contact, template });
72766
+ if (resource instanceof CliUsageError)
72767
+ return yield* resource;
72768
+ if (dryRun)
72769
+ 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.`);
72770
+ const client = yield* getClientProvider;
72771
+ const moved = yield* removeResource({
72772
+ id,
72773
+ type: resource.type,
72774
+ resourceId: resource.id
72775
+ }).pipe(client.provide, mapError2((error) => toCliApiError("Could not unassign resource", error)));
72776
+ if (json)
72777
+ return yield* printJson(moved);
72778
+ yield* printFields([
72779
+ ["Type", moved.type],
72780
+ ["ID", moved.id],
72781
+ ["Namespace", moved.namespaceId ?? "organization"]
72782
+ ]);
72783
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72784
+ var usage3 = make29("usage", {
72785
+ id: idArgument3,
72786
+ after: optionalString2("after", "Start of the window, an ISO 8601 instant"),
72787
+ before: optionalString2("before", "End of the window, an ISO 8601 instant"),
72788
+ json: jsonFlag
72789
+ }).pipe(withDescription3("Count the messages a namespace sent and received in a window"), withExamples([
72790
+ { command: "samva namespaces usage ns_7q2xk9mvt4znw8rh --after 2026-10-01T00:00:00Z --json" }
72791
+ ]), withHandler(({ id, after, before, json }) => gen2(function* () {
72792
+ const client = yield* getClientProvider;
72793
+ const data = yield* getUsage2({
72794
+ id,
72795
+ after: getOrUndefined(after),
72796
+ before: getOrUndefined(before)
72797
+ }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get namespace usage", error)));
72798
+ if (json)
72799
+ return yield* printJson(data);
72800
+ yield* printFields([
72801
+ ["Namespace", data.namespaceId],
72802
+ ["Period start", data.periodStart],
72803
+ ["Period end", data.periodEnd],
72804
+ ["Email", data.emailCount],
72805
+ ["Total", data.totalMessages]
72806
+ ]);
72807
+ }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72808
+ 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]));
72809
+
71825
72810
  // ../sdk/dist/effect/generated/whoami.js
71826
72811
  var WhoamiUser = /* @__PURE__ */ Struct({
71827
72812
  id: String4,
@@ -71872,7 +72857,7 @@ var WhoamiGroup = class extends make37("Whoami").add(get5("whoamiGet", "/v1/whoa
71872
72857
  };
71873
72858
 
71874
72859
  // ../sdk/dist/effect/whoami.js
71875
- var get23 = /* @__PURE__ */ (/* @__PURE__ */ forGroup(WhoamiGroup))("whoamiGet");
72860
+ var get25 = /* @__PURE__ */ (/* @__PURE__ */ forGroup(WhoamiGroup))("whoamiGet");
71876
72861
 
71877
72862
  // src/commands/usage.ts
71878
72863
  var afterFlag2 = String9("after").pipe(withDescription2("Start of the window, an ISO 8601 instant (default: the start of this calendar month)"), optional4);
@@ -71909,7 +72894,7 @@ var usageCommand = make29("usage", {
71909
72894
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
71910
72895
 
71911
72896
  // 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([
72897
+ 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
72898
  {
71914
72899
  command: "samva org list",
71915
72900
  description: "List orgs (OAuth) or show API-key org"
@@ -71973,7 +72958,7 @@ var use = make29("use", { slug: String10("slug") }).pipe(withDescription3("Set t
71973
72958
  })));
71974
72959
  var currentForApiKey = gen2(function* () {
71975
72960
  const client = yield* getClientProvider;
71976
- return yield* get23().pipe(client.provide, mapError2((error) => {
72961
+ return yield* get25().pipe(client.provide, mapError2((error) => {
71977
72962
  const failure = toCliApiError("Could not look up the organization", error);
71978
72963
  return new SamvaCliError({
71979
72964
  message: `Could not look up the organization for SAMVA_API_KEY. ${failure.message}`,
@@ -72014,10 +72999,10 @@ var current = make29("current", { json: jsonFlag }).pipe(withDescription3("Show
72014
72999
  var orgCommand = make29("org").pipe(withDescription3(`Manage organizations. ${AGENT_AUTH_HINT}`), withExamples([
72015
73000
  { command: "samva org list", description: "List accessible organizations" },
72016
73001
  { command: "samva org use my-org-slug", description: "Set active org (OAuth)" }
72017
- ]), withSubcommands([list20, use, current, usageCommand]));
73002
+ ]), withSubcommands([list22, use, current, usageCommand]));
72018
73003
 
72019
73004
  // src/commands/profile.ts
72020
- var list21 = make29("list").pipe(withDescription3("List user-level execution profiles"), withHandler(fnUntraced2(function* () {
73005
+ var list23 = make29("list").pipe(withDescription3("List user-level execution profiles"), withHandler(fnUntraced2(function* () {
72021
73006
  const config = yield* readConfig;
72022
73007
  if ((yield* Json3) || (yield* JsonLines)) {
72023
73008
  return yield* printJson({
@@ -72051,7 +73036,7 @@ var show = make29("show", { name: String10("name").pipe(optional5) }).pipe(withD
72051
73036
  return yield* printJson(output);
72052
73037
  yield* log(`${output.name}${output.orgSlug ? ` ${output.orgSlug}` : ""}`);
72053
73038
  })));
72054
- var create10 = make29("create", {
73039
+ var create12 = make29("create", {
72055
73040
  name: String10("name"),
72056
73041
  org: String9("org").pipe(optional4)
72057
73042
  }).pipe(withDescription3("Create a non-secret execution profile"), withHandler(fnUntraced2(function* ({ name, org }) {
@@ -72081,7 +73066,7 @@ var use2 = make29("use", { name: String10("name") }).pipe(withDescription3("Sele
72081
73066
  yield* writeConfig({ ...config, activeProfile: name });
72082
73067
  yield* printResult({ action: "profile.use", name }, `Active profile set to ${name}.`);
72083
73068
  })));
72084
- var remove10 = make29("delete", {
73069
+ var remove12 = make29("delete", {
72085
73070
  name: String10("name"),
72086
73071
  yes: Boolean6("yes").pipe(withDefault5(false))
72087
73072
  }).pipe(withDescription3("Delete a profile and its OS-keyring credential"), withHandler(fnUntraced2(function* ({ name, yes }) {
@@ -72106,7 +73091,7 @@ var remove10 = make29("delete", {
72106
73091
  yield* (yield* Service4).clear(name);
72107
73092
  yield* printResult({ action: "profile.delete", name }, `Deleted profile ${name}.`);
72108
73093
  })));
72109
- var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list21, show, create10, use2, remove10]));
73094
+ var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list23, show, create12, use2, remove12]));
72110
73095
 
72111
73096
  // ../sdk/dist/effect/generated/scheduled-messages.js
72112
73097
  var ScheduledMessageId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new RegExp("^sched_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
@@ -72293,12 +73278,12 @@ var ScheduledMessagesGroup = class extends make37("Scheduled Messages").add(get5
72293
73278
  };
72294
73279
 
72295
73280
  // ../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");
73281
+ var make53 = /* @__PURE__ */ forGroup(ScheduledMessagesGroup);
73282
+ var list24 = /* @__PURE__ */ make53("scheduledMessagesList");
73283
+ var create13 = /* @__PURE__ */ make53("scheduledMessagesCreate");
73284
+ var get26 = /* @__PURE__ */ make53("scheduledMessagesGet");
73285
+ var cancel = /* @__PURE__ */ make53("scheduledMessagesCancel");
73286
+ var resume4 = /* @__PURE__ */ make53("scheduledMessagesResume");
72302
73287
 
72303
73288
  // src/commands/scheduled.ts
72304
73289
  var SCHEDULED_STATUSES = [
@@ -72363,14 +73348,14 @@ var atFlag2 = String9("at").pipe(withDescription2("Absolute send instant as an I
72363
73348
  var timezoneFlag = String9("timezone").pipe(withDescription2("IANA timezone for the schedule, e.g. America/New_York"), optional4);
72364
73349
  var idempotencyKeyFlag3 = String9("idempotency-key").pipe(withDescription2("Idempotency key so retries do not schedule duplicates"), optional4);
72365
73350
  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));
73351
+ var dryRunFlag5 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
72367
73352
  var trackOpensFlag3 = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for this scheduled send; recipient opt-out wins"), optional4);
72368
73353
  var trackClicksFlag3 = Literals3("track-clicks", ["on", "off"]).pipe(withDescription2("Override click tracking for this scheduled send; recipient opt-out wins"), optional4);
72369
73354
  var statusFlag2 = Literals3("status", SCHEDULED_STATUSES).pipe(withDescription2("Filter by status"), optional4);
72370
73355
  var cursorFlag4 = String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4);
72371
73356
  var limitFlag4 = Int5("limit").pipe(withDescription2("Items per page"), optional4);
72372
73357
  var allFlag4 = Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false));
72373
- var create12 = make29("create", {
73358
+ var create14 = make29("create", {
72374
73359
  to: toFlag2,
72375
73360
  cc: ccFlag2,
72376
73361
  bcc: bccFlag2,
@@ -72388,7 +73373,7 @@ var create12 = make29("create", {
72388
73373
  referenceId: referenceIdFlag,
72389
73374
  trackOpens: trackOpensFlag3,
72390
73375
  trackClicks: trackClicksFlag3,
72391
- dryRun: dryRunFlag4,
73376
+ dryRun: dryRunFlag5,
72392
73377
  json: jsonFlag
72393
73378
  }).pipe(withDescription3("Schedule an email to send at a future time"), withExamples([
72394
73379
  {
@@ -72497,7 +73482,7 @@ Payload:
72497
73482
  ${truncateForDisplay(JSON.stringify(payload, null, 2))}`);
72498
73483
  }
72499
73484
  const client = yield* getClientProvider;
72500
- const data = yield* create11(payload).pipe(client.provide, mapError2((error) => toCliApiError("Failed to schedule message", error)));
73485
+ const data = yield* create13(payload).pipe(client.provide, mapError2((error) => toCliApiError("Failed to schedule message", error)));
72501
73486
  if (json)
72502
73487
  return yield* printJson(data);
72503
73488
  yield* logInfo(`Message scheduled.
@@ -72511,7 +73496,7 @@ ${truncateForDisplay(JSON.stringify(payload, null, 2))}`);
72511
73496
  yield* logInfo(`
72512
73497
  Inspect it: samva scheduled-messages get ${data.id}`);
72513
73498
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
72514
- var list23 = make29("list", {
73499
+ var list25 = make29("list", {
72515
73500
  status: statusFlag2,
72516
73501
  cursor: cursorFlag4,
72517
73502
  limit: limitFlag4,
@@ -72546,7 +73531,7 @@ var list23 = make29("list", {
72546
73531
  if (all) {
72547
73532
  let nextCursor = cursorValue;
72548
73533
  for (;; ) {
72549
- const data = yield* list22({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
73534
+ const data = yield* list24({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
72550
73535
  for (const item of data.items)
72551
73536
  yield* printJsonLine(item);
72552
73537
  if (data.nextCursor === null)
@@ -72554,7 +73539,7 @@ var list23 = make29("list", {
72554
73539
  nextCursor = data.nextCursor;
72555
73540
  }
72556
73541
  }
72557
- const data = yield* list22(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
73542
+ const data = yield* list24(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list scheduled messages", error)));
72558
73543
  if (isJsonLinesRequested()) {
72559
73544
  for (const item of data.items)
72560
73545
  yield* printJsonLine(item);
@@ -72578,9 +73563,9 @@ var list23 = make29("list", {
72578
73563
  if (data.nextCursor !== null)
72579
73564
  yield* printFields([["Next cursor", data.nextCursor]]);
72580
73565
  }).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* () {
73566
+ 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
73567
  const client = yield* getClientProvider;
72583
- const data = yield* get24({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not fetch scheduled message", error)));
73568
+ const data = yield* get26({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not fetch scheduled message", error)));
72584
73569
  if (json)
72585
73570
  return yield* printJson(data);
72586
73571
  yield* printFields([
@@ -72661,7 +73646,7 @@ var scheduledMessagesCommand = make29("scheduled-messages").pipe(withDescription
72661
73646
  description: "Schedule an email"
72662
73647
  },
72663
73648
  { command: "samva scheduled-messages list", description: "List scheduled messages" }
72664
- ]), withSubcommands([create12, list23, get25, cancel2, resume5]));
73649
+ ]), withSubcommands([create14, list25, get27, cancel2, resume5]));
72665
73650
 
72666
73651
  // ../sdk/dist/effect/generated/subscriptions.js
72667
73652
  var SubscribeResult = /* @__PURE__ */ Struct({
@@ -72830,6 +73815,7 @@ var TemplateSummary = /* @__PURE__ */ Struct({
72830
73815
  name: String4,
72831
73816
  channel: Literal2("email"),
72832
73817
  projectId: TemplateProjectId2,
73818
+ 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
73819
  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
73820
  status: Union2([
72835
73821
  Literal2("draft"),
@@ -72854,6 +73840,7 @@ var Template = /* @__PURE__ */ Struct({
72854
73840
  name: String4,
72855
73841
  channel: Literal2("email"),
72856
73842
  projectId: TemplateProjectId2,
73843
+ 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
73844
  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
73845
  status: Union2([
72859
73846
  Literal2("draft"),
@@ -72937,7 +73924,8 @@ var TemplatesListQuery = /* @__PURE__ */ Struct({
72937
73924
  Literal2("archived")
72938
73925
  ]), Null2])),
72939
73926
  search: optionalKey2(Union2([String4, Null2])),
72940
- projectId: optionalKey2(Union2([TemplateProjectId2, Null2]))
73927
+ projectId: optionalKey2(Union2([TemplateProjectId2, Null2])),
73928
+ namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Only templates in this namespace. A namespace-scoped key lists its own namespace's templates only." }))
72941
73929
  });
72942
73930
  var TemplatesList200 = TemplatePage;
72943
73931
  var TemplatesList401 = UnauthorizedError2;
@@ -72962,11 +73950,13 @@ var TemplatesCreateRequestJson = /* @__PURE__ */ Struct({
72962
73950
  Literal2("alert")
72963
73951
  ]), Null2]), Null2])),
72964
73952
  isActive: optionalKey2(Union2([Boolean3, Null2])),
73953
+ 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
73954
  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
73955
  });
72967
73956
  var TemplatesCreate201 = Template;
72968
73957
  var TemplatesCreate401 = UnauthorizedError2;
72969
73958
  var TemplatesCreate403 = ForbiddenError2;
73959
+ var TemplatesCreate404 = ResourceNotFoundError2;
72970
73960
  var TemplatesCreate409 = ConflictError2;
72971
73961
  var TemplatesCreate422 = ValidationError2;
72972
73962
  var TemplatesCreate500 = InternalError2;
@@ -74592,6 +75582,7 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
74592
75582
  error: [
74593
75583
  TemplatesCreate401.pipe(status(401)),
74594
75584
  TemplatesCreate403.pipe(status(403)),
75585
+ TemplatesCreate404.pipe(status(404)),
74595
75586
  TemplatesCreate409.pipe(status(409)),
74596
75587
  TemplatesCreate422.pipe(status(422)),
74597
75588
  TemplatesCreate500,
@@ -74980,24 +75971,24 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
74980
75971
  };
74981
75972
 
74982
75973
  // ../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");
75974
+ var make54 = /* @__PURE__ */ forGroup(TemplatesGroup);
75975
+ var list26 = /* @__PURE__ */ make54("templatesList");
75976
+ var create15 = /* @__PURE__ */ make54("templatesCreate");
75977
+ var addEntry = /* @__PURE__ */ make54("templatesAddEntry");
75978
+ var getById = /* @__PURE__ */ make54("templatesGetById");
75979
+ var remove13 = /* @__PURE__ */ make54("templatesRemove");
75980
+ var update12 = /* @__PURE__ */ make54("templatesUpdate");
75981
+ var openWorkspace = /* @__PURE__ */ make54("templatesOpenWorkspace");
75982
+ var getGitRepository = /* @__PURE__ */ make54("templatesGetGitRepository");
75983
+ var issueGitCredential = /* @__PURE__ */ make54("templatesIssueGitCredential");
75984
+ var patchWorkspace = /* @__PURE__ */ make54("templatesPatchWorkspace");
75985
+ var putWorkspaceAsset = /* @__PURE__ */ make54("templatesPutWorkspaceAsset");
75986
+ var saveWorkspace = /* @__PURE__ */ make54("templatesSaveWorkspace");
75987
+ var checkWorkspace = /* @__PURE__ */ make54("templatesCheckWorkspace");
75988
+ var renderWorkspaceFixture = /* @__PURE__ */ make54("templatesRenderWorkspaceFixture");
75989
+ var publish5 = /* @__PURE__ */ make54("templatesPublish");
75990
+ var diffWorkspace = /* @__PURE__ */ make54("templatesDiffWorkspace");
75991
+ var workspaceHistory = /* @__PURE__ */ make54("templatesWorkspaceHistory");
75001
75992
 
75002
75993
  // src/commands/templates/dev-command.ts
75003
75994
  import { resolve as resolve8 } from "path";
@@ -75659,7 +76650,7 @@ var listProjectTemplates = fn2("Templates.listProjectTemplates")(function* (proj
75659
76650
  const templates = [];
75660
76651
  let cursor;
75661
76652
  for (;; ) {
75662
- const data = yield* list24({
76653
+ const data = yield* list26({
75663
76654
  projectId,
75664
76655
  cursor,
75665
76656
  limit: PROJECT_PAGE_SIZE.toString()
@@ -75818,7 +76809,7 @@ ${starter.value}` : ""}`))).slice(0, 48)}`
75818
76809
  }
75819
76810
  }
75820
76811
  const client = yield* getClientProvider;
75821
- const created = yield* create13(request).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template project", error)));
76812
+ const created = yield* create15(request).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template project", error)));
75822
76813
  const result = yield* cloneProject({ id: created.id, dir: root });
75823
76814
  const payload = { ...result, action: "templates.init" };
75824
76815
  if (json)
@@ -75988,7 +76979,7 @@ var move = make29("move", {
75988
76979
  });
75989
76980
  }
75990
76981
  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)));
76982
+ const moved = yield* update12({ id: template.id, data: { entryPath: to } }).pipe(client.provide, mapError2((error) => toCliApiError("Could not move template entry", error)));
75992
76983
  if (json)
75993
76984
  return yield* printJson(moved);
75994
76985
  yield* printFields([
@@ -77019,7 +78010,7 @@ var readCatalog = fn2("templates.types.readCatalog")(function* () {
77019
78010
  const ids = [];
77020
78011
  let cursor;
77021
78012
  for (;; ) {
77022
- const data = yield* list24({
78013
+ const data = yield* list26({
77023
78014
  cursor,
77024
78015
  limit: CATALOG_PAGE_SIZE.toString()
77025
78016
  }).pipe(client.provide, mapError2(catalogError));
@@ -77343,7 +78334,7 @@ var workspaceCommand = make29("workspace").pipe(withDescription3("Author a templ
77343
78334
 
77344
78335
  // src/commands/templates.ts
77345
78336
  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));
78337
+ var dryRunFlag6 = Boolean6("dry-run").pipe(withDescription2("Show the request without calling the API"), withDefault5(false));
77347
78338
  var templateIdArgument2 = String10("id").pipe(withDescription4("Remote template id"));
77348
78339
  var parseObject = (raw, flag) => try_3({
77349
78340
  try: () => JSON.parse(raw),
@@ -77709,9 +78700,10 @@ var build3 = make29("build", {
77709
78700
  var listRemote = make29("list", {
77710
78701
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
77711
78702
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
78703
+ namespace: namespaceFlag("list"),
77712
78704
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
77713
78705
  json: jsonFlag
77714
- }).pipe(withDescription3("List remote templates"), withExamples([{ command: "samva templates list --json" }]), withHandler(({ cursor, limit, all, json }) => gen2(function* () {
78706
+ }).pipe(withDescription3("List remote templates"), withExamples([{ command: "samva templates list --json" }]), withHandler(({ cursor, limit, namespace, all, json }) => gen2(function* () {
77715
78707
  if (all && !isJsonLinesRequested())
77716
78708
  return yield* new CliUsageError({
77717
78709
  code: "all_requires_jsonl",
@@ -77720,11 +78712,15 @@ var listRemote = make29("list", {
77720
78712
  const client = yield* getClientProvider;
77721
78713
  const cursorValue = getOrUndefined(cursor);
77722
78714
  const limitValue = getOrUndefined(limit);
77723
- const query = { cursor: cursorValue, limit: limitValue?.toString() };
78715
+ const query = {
78716
+ cursor: cursorValue,
78717
+ limit: limitValue?.toString(),
78718
+ ...namespaceField(namespace)
78719
+ };
77724
78720
  if (all) {
77725
78721
  let nextCursor = cursorValue;
77726
78722
  for (;; ) {
77727
- const data = yield* list24({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
78723
+ const data = yield* list26({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
77728
78724
  for (const item of data.items)
77729
78725
  yield* printJsonLine(item);
77730
78726
  if (data.nextCursor === null)
@@ -77732,7 +78728,7 @@ var listRemote = make29("list", {
77732
78728
  nextCursor = data.nextCursor;
77733
78729
  }
77734
78730
  }
77735
- const data = yield* list24(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
78731
+ const data = yield* list26(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list templates", error)));
77736
78732
  if (isJsonLinesRequested()) {
77737
78733
  for (const item of data.items)
77738
78734
  yield* printJsonLine(item);
@@ -77745,7 +78741,8 @@ var listRemote = make29("list", {
77745
78741
  ["ID", item.id],
77746
78742
  ["Name", item.name],
77747
78743
  ["Slug", item.slug],
77748
- ["Status", item.status]
78744
+ ["Status", item.status],
78745
+ ["Namespace", item.namespaceId ?? "organization"]
77749
78746
  ]);
77750
78747
  if (data.nextCursor !== null)
77751
78748
  yield* printFields([["Next cursor", data.nextCursor]]);
@@ -77759,21 +78756,28 @@ var getRemote = make29("get", { id: templateIdArgument2, json: jsonFlag }).pipe(
77759
78756
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
77760
78757
  var createRemote = make29("create", {
77761
78758
  data: String9("data").pipe(withDescription2("Complete template JSON payload")),
77762
- dryRun: dryRunFlag5,
78759
+ namespace: namespaceFlag("create"),
78760
+ dryRun: dryRunFlag6,
77763
78761
  json: jsonFlag
77764
78762
  }).pipe(withDescription3("Create a remote template from JSON"), withExamples([
77765
78763
  {
77766
78764
  command: `samva templates create --data '{"name":"Welcome","projectName":"welcome-email","idempotencyKey":"welcome-email-v1"}' --dry-run`
77767
78765
  }
77768
- ]), withHandler(({ data, dryRun, json }) => gen2(function* () {
77769
- const payload = yield* decodePayload(data, "--data", CreateTemplatePayload);
78766
+ ]), withHandler(({ data, namespace, dryRun, json }) => gen2(function* () {
78767
+ const decoded = yield* decodePayload(data, "--data", CreateTemplatePayload);
78768
+ if (isSome2(namespace) && decoded.namespaceId != null && decoded.namespaceId !== namespace.value)
78769
+ return yield* new CliUsageError({
78770
+ code: "namespace_conflict",
78771
+ message: "--namespace and the namespaceId in --data name different namespaces."
78772
+ });
78773
+ const payload = { ...decoded, ...namespaceField(namespace) };
77770
78774
  if (dryRun)
77771
78775
  return yield* json ? printJson({ dryRun: true, action: "templates.create", request: payload }) : printFields([
77772
78776
  ["Action", "templates.create"],
77773
78777
  ...objectRows(payload, { explicit: true })
77774
78778
  ]);
77775
78779
  const client = yield* getClientProvider;
77776
- const result = yield* create13(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template", error)));
78780
+ const result = yield* create15(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create template", error)));
77777
78781
  if (json)
77778
78782
  return yield* printJson(result);
77779
78783
  yield* printFields(objectRows(result));
@@ -77781,7 +78785,7 @@ var createRemote = make29("create", {
77781
78785
  var updateRemote = make29("update", {
77782
78786
  id: templateIdArgument2,
77783
78787
  data: String9("data").pipe(withDescription2("JSON object of template fields to update")),
77784
- dryRun: dryRunFlag5,
78788
+ dryRun: dryRunFlag6,
77785
78789
  json: jsonFlag
77786
78790
  }).pipe(withDescription3("Update a remote template from JSON"), withExamples([
77787
78791
  {
@@ -77797,14 +78801,14 @@ var updateRemote = make29("update", {
77797
78801
  ...objectRows(payload, { explicit: true })
77798
78802
  ]);
77799
78803
  const client = yield* getClientProvider;
77800
- const result = yield* update10({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update template", error)));
78804
+ const result = yield* update12({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update template", error)));
77801
78805
  if (json)
77802
78806
  return yield* printJson(result);
77803
78807
  yield* printFields(objectRows(result));
77804
78808
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
77805
78809
  var removeRemote = make29("remove", {
77806
78810
  id: templateIdArgument2,
77807
- dryRun: dryRunFlag5,
78811
+ dryRun: dryRunFlag6,
77808
78812
  yes: Boolean6("yes").pipe(withDescription2("Confirm destructive state change"), withDefault5(false)),
77809
78813
  json: jsonFlag
77810
78814
  }).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 +78821,7 @@ var removeRemote = make29("remove", {
77817
78821
  nonInteractiveMessage: "remove requires --yes in non-interactive mode. Preview with --dry-run."
77818
78822
  });
77819
78823
  const client = yield* getClientProvider;
77820
- const result = yield* remove11({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove template", error)));
78824
+ const result = yield* remove13({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove template", error)));
77821
78825
  if (json)
77822
78826
  return yield* printJson(result);
77823
78827
  yield* printFields([
@@ -78453,20 +79457,20 @@ var WebhooksGroup = class extends make37("Webhooks").add(get5("webhooksList", "/
78453
79457
  };
78454
79458
 
78455
79459
  // ../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");
79460
+ var make55 = /* @__PURE__ */ forGroup(WebhooksGroup);
79461
+ var list27 = /* @__PURE__ */ make55("webhooksList");
79462
+ var create16 = /* @__PURE__ */ make55("webhooksCreate");
79463
+ var get28 = /* @__PURE__ */ make55("webhooksGet");
79464
+ var remove14 = /* @__PURE__ */ make55("webhooksRemove");
79465
+ var update13 = /* @__PURE__ */ make55("webhooksUpdate");
79466
+ var test = /* @__PURE__ */ make55("webhooksTest");
79467
+ var getLogs = /* @__PURE__ */ make55("webhooksGetLogs");
79468
+ var getStats = /* @__PURE__ */ make55("webhooksGetStats");
79469
+ var retryDelivery = /* @__PURE__ */ make55("webhooksRetryDelivery");
79470
+ var regenerateSecret = /* @__PURE__ */ make55("webhooksRegenerateSecret");
78467
79471
 
78468
79472
  // src/commands/webhooks.ts
78469
- var idArgument3 = String10("id").pipe(withDescription4("Webhook id"));
79473
+ var idArgument4 = String10("id").pipe(withDescription4("Webhook id"));
78470
79474
  var parseObject2 = (raw, flag) => try_3({
78471
79475
  try: () => JSON.parse(raw),
78472
79476
  catch: () => new SamvaCliError({ message: `${flag} must be a valid JSON object.` })
@@ -78487,7 +79491,7 @@ var readData = (raw) => {
78487
79491
  message: `Could not read webhook test data from ${path}.`
78488
79492
  })));
78489
79493
  };
78490
- var list26 = make29("list", {
79494
+ var list28 = make29("list", {
78491
79495
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
78492
79496
  limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
78493
79497
  all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
@@ -78505,7 +79509,7 @@ var list26 = make29("list", {
78505
79509
  if (all) {
78506
79510
  let nextCursor = cursorValue;
78507
79511
  for (;; ) {
78508
- const data = yield* list25({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
79512
+ const data = yield* list27({ ...query, cursor: nextCursor }).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
78509
79513
  for (const item of data.items)
78510
79514
  yield* printJsonLine(item);
78511
79515
  if (data.nextCursor === null)
@@ -78513,7 +79517,7 @@ var list26 = make29("list", {
78513
79517
  nextCursor = data.nextCursor;
78514
79518
  }
78515
79519
  }
78516
- const data = yield* list25(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
79520
+ const data = yield* list27(query).pipe(client.provide, mapError2((error) => toCliApiError("Could not list webhooks", error)));
78517
79521
  if (isJsonLinesRequested()) {
78518
79522
  for (const item of data.items)
78519
79523
  yield* printJsonLine(item);
@@ -78533,9 +79537,9 @@ var list26 = make29("list", {
78533
79537
  if (data.nextCursor !== null)
78534
79538
  yield* printFields([["Next cursor", data.nextCursor]]);
78535
79539
  }).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* () {
79540
+ 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
79541
  const client = yield* getClientProvider;
78538
- const data = yield* get26({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get webhook", error)));
79542
+ const data = yield* get28({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not get webhook", error)));
78539
79543
  if (json)
78540
79544
  return yield* printJson(data);
78541
79545
  yield* printFields([
@@ -78546,7 +79550,7 @@ var get27 = make29("get", { id: idArgument3, json: jsonFlag }).pipe(withDescript
78546
79550
  ]);
78547
79551
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78548
79552
  var logs = make29("logs", {
78549
- id: idArgument3,
79553
+ id: idArgument4,
78550
79554
  limit: Int5("limit").pipe(optional4),
78551
79555
  cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
78552
79556
  json: jsonFlag
@@ -78609,7 +79613,7 @@ var logs = make29("logs", {
78609
79613
  var statsAfterFlag = String9("after").pipe(withDescription2("Start of the daily series, an ISO 8601 instant (default: 30 days back)"), optional4);
78610
79614
  var statsBeforeFlag = String9("before").pipe(withDescription2("End of the daily series, an ISO 8601 instant (default: end of today)"), optional4);
78611
79615
  var stats3 = make29("stats", {
78612
- id: idArgument3,
79616
+ id: idArgument4,
78613
79617
  after: statsAfterFlag,
78614
79618
  before: statsBeforeFlag,
78615
79619
  json: jsonFlag
@@ -78637,7 +79641,7 @@ var stats3 = make29("stats", {
78637
79641
  ]);
78638
79642
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78639
79643
  var test2 = make29("test", {
78640
- id: idArgument3,
79644
+ id: idArgument4,
78641
79645
  data: String9("data").pipe(withDescription2("JSON object or @file to send as the signed test payload"), optional4),
78642
79646
  dryRun: Boolean6("dry-run").pipe(withDescription2("Validate and preview without sending a request"), withDefault5(false)),
78643
79647
  json: jsonFlag
@@ -78669,7 +79673,7 @@ var test2 = make29("test", {
78669
79673
  ]);
78670
79674
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78671
79675
  var retry4 = make29("retry", {
78672
- id: idArgument3,
79676
+ id: idArgument4,
78673
79677
  deliveryId: String10("delivery-id").pipe(withDescription4("Webhook delivery id")),
78674
79678
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78675
79679
  json: jsonFlag
@@ -78689,7 +79693,7 @@ var retry4 = make29("retry", {
78689
79693
  ]);
78690
79694
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78691
79695
  var rotate3 = make29("rotate-secret", {
78692
- id: idArgument3,
79696
+ id: idArgument4,
78693
79697
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78694
79698
  yes: Boolean6("yes").pipe(withDefault5(false)),
78695
79699
  json: jsonFlag
@@ -78714,7 +79718,7 @@ var rotate3 = make29("rotate-secret", {
78714
79718
  yield* error(`WARNING: ${warning}`);
78715
79719
  yield* log(secret);
78716
79720
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78717
- var create15 = make29("create", {
79721
+ var create17 = make29("create", {
78718
79722
  data: String9("data").pipe(withDescription2("Webhook JSON: name, url, eventTypes, and optional retry settings")),
78719
79723
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78720
79724
  json: jsonFlag
@@ -78730,7 +79734,7 @@ var create15 = make29("create", {
78730
79734
  ...objectRows(payload, { explicit: true })
78731
79735
  ]);
78732
79736
  const client = yield* getClientProvider;
78733
- const result = yield* create14(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create webhook", error)));
79737
+ const result = yield* create16(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create webhook", error)));
78734
79738
  const warning = "This signing secret is shown once. Store it now; `samva webhooks rotate-secret` issues a new one.";
78735
79739
  const secret = value2(result.secret);
78736
79740
  if (json)
@@ -78744,8 +79748,8 @@ var create15 = make29("create", {
78744
79748
  ["Signing secret", secret]
78745
79749
  ]);
78746
79750
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78747
- var update12 = make29("update", {
78748
- id: idArgument3,
79751
+ var update14 = make29("update", {
79752
+ id: idArgument4,
78749
79753
  data: String9("data").pipe(withDescription2("JSON object of webhook fields to update")),
78750
79754
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78751
79755
  json: jsonFlag
@@ -78762,13 +79766,13 @@ var update12 = make29("update", {
78762
79766
  ...objectRows(payload, { explicit: true })
78763
79767
  ]);
78764
79768
  const client = yield* getClientProvider;
78765
- const result = yield* update11({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update webhook", error)));
79769
+ const result = yield* update13({ id, ...payload }).pipe(client.provide, mapError2((error) => toCliApiError("Could not update webhook", error)));
78766
79770
  if (json)
78767
79771
  return yield* printJson(result);
78768
79772
  yield* printFields(objectRows(result));
78769
79773
  }).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
78770
- var remove13 = make29("remove", {
78771
- id: idArgument3,
79774
+ var remove15 = make29("remove", {
79775
+ id: idArgument4,
78772
79776
  dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
78773
79777
  yes: Boolean6("yes").pipe(withDefault5(false)),
78774
79778
  json: jsonFlag
@@ -78785,12 +79789,12 @@ var remove13 = make29("remove", {
78785
79789
  nonInteractiveMessage: "Permanent webhook deletion requires --yes in non-interactive mode. Preview with --dry-run."
78786
79790
  });
78787
79791
  const client = yield* getClientProvider;
78788
- const result = yield* remove12({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove webhook", error)));
79792
+ const result = yield* remove14({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove webhook", error)));
78789
79793
  if (json)
78790
79794
  return yield* printJson(result);
78791
79795
  yield* log(`Removed webhook ${id}.`);
78792
79796
  }).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]));
79797
+ 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
79798
 
78795
79799
  // src/lib/root-commands.ts
78796
79800
  var rootCommands = [
@@ -78808,6 +79812,7 @@ var rootCommands = [
78808
79812
  templatesCommand,
78809
79813
  brandsCommand,
78810
79814
  mailboxesCommand,
79815
+ namespacesCommand,
78811
79816
  extensionsCommand,
78812
79817
  webhooksCommand,
78813
79818
  apiCommand,