@openclaw/discord 2026.5.7 → 2026.5.10-beta.1

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 (110) hide show
  1. package/dist/{access-CHY9FK3X.js → access-R4X7pYt4.js} +1 -1
  2. package/dist/action-runtime-api.js +1 -1
  3. package/dist/{allow-list-ek-1hMKN.js → allow-list-4wnZg5P9.js} +2 -6
  4. package/dist/api.js +18 -16
  5. package/dist/{approval-handler.runtime-BBZRYAGs.js → approval-handler.runtime-B5BCBw4D.js} +3 -4
  6. package/dist/{approval-native-CBdZsAR7.js → approval-native-CrCc3b4u.js} +2 -2
  7. package/dist/{approval-shared-Ck6TxKgo.js → approval-shared-Ckk65xSG.js} +1 -1
  8. package/dist/{audit-CCJ0h49k.js → audit-BRBe8xFv.js} +4 -4
  9. package/dist/{channel-UXGa9PGc.js → channel-DTBEGHsT.js} +53 -31
  10. package/dist/{channel-actions-Br29_1nE.js → channel-actions-CHgoSpPF.js} +27 -1
  11. package/dist/{channel-actions.runtime-ChmNUig1.js → channel-actions.runtime-E5Plubuu.js} +5 -5
  12. package/dist/channel-config-api.js +1 -1
  13. package/dist/channel-plugin-api.js +1 -1
  14. package/dist/{channel.setup-D_xyQu_h.js → channel.setup-EQXuueIk.js} +3 -3
  15. package/dist/chunk-DYl-_5RL.js +179 -0
  16. package/dist/{components-D5LnN7ZQ.js → components-BJOShoIU.js} +2 -3
  17. package/dist/{config-schema-Cc953rAs.js → config-schema-BGn5I3_3.js} +46 -1
  18. package/dist/contract-api.js +7 -7
  19. package/dist/{conversation-identity-DHhS0ez3.js → conversation-identity-BPQm_uhV.js} +1 -1
  20. package/dist/{directory-config-DoETeOOx.js → directory-config-JBaFwbAQ.js} +1 -1
  21. package/dist/directory-contract-api.js +1 -1
  22. package/dist/{directory-live-DJ0V5asB.js → directory-live-B4kW11z5.js} +2 -2
  23. package/dist/{discord-eZlimVfW.js → discord-DtHMmZqJ.js} +58 -15
  24. package/dist/{doctor-Bo-yifB3.js → doctor-CPV4Ch3V.js} +3 -3
  25. package/dist/{doctor-contract-Bso46EOQ.js → doctor-contract-BGjjFBdq.js} +1 -1
  26. package/dist/doctor-contract-api.js +1 -1
  27. package/dist/{handle-action.guild-admin-sJiQymg8.js → handle-action.guild-admin-DSeMCHvR.js} +6 -3
  28. package/dist/{inbound-context-CRylwjg0.js → inbound-context-BAwOn5Iq.js} +1 -1
  29. package/dist/manager.runtime-DGvCDWI5.js +2082 -0
  30. package/dist/{message-handler-C9Ohf-ea.js → message-handler-BWHSteQf.js} +7 -7
  31. package/dist/{message-handler.preflight-BrvazsYn.js → message-handler.preflight-q7ose9Ta.js} +31 -42
  32. package/dist/{message-handler.process-CEnzuLiN.js → message-handler.process-BN8bE7AE.js} +81 -64
  33. package/dist/{message-utils-9kaGF59d.js → message-utils-DEjCwCRz.js} +2 -2
  34. package/dist/normalize-Cu94FOqy.js +58 -0
  35. package/dist/{outbound-adapter-DNsTVJfH.js → outbound-adapter-Bt8FL3yO.js} +78 -17
  36. package/dist/{outbound-session-route-DK9qkPgP.js → outbound-session-route-BaJRt05p.js} +1 -1
  37. package/dist/{pluralkit-OFss_pIy.js → pluralkit-CUfobeQu.js} +1 -1
  38. package/dist/{preflight-audio-CRmUxxuM.js → preflight-audio-BcsH127L.js} +1 -1
  39. package/dist/{preview-streaming-Cc_oeIPP.js → preview-streaming-DCPAe24T.js} +1 -0
  40. package/dist/{probe.runtime-CMgUDax3.js → probe.runtime-4Q9GD7FG.js} +1 -1
  41. package/dist/{provider-CuOh6z_b.js → provider-DBvvDP9A.js} +185 -225
  42. package/dist/{provider-session.runtime-CCESIHVo.js → provider-session.runtime-DepAOR1U.js} +3 -3
  43. package/dist/provider.runtime-BlbOt97W.js +2 -0
  44. package/dist/{reply-delivery-D9aKHtDH.js → reply-delivery-vHSqaKKo.js} +9 -6
  45. package/dist/{resolve-allowlist-common-_e1cWOb3.js → resolve-allowlist-common-ZcVU4OMA.js} +1 -1
  46. package/dist/{resolve-channels-kyuvrXJg.js → resolve-channels-D9Dubj_y.js} +3 -3
  47. package/dist/{resolve-users-CAwh4EBq.js → resolve-users-DlzKsLQe.js} +2 -2
  48. package/dist/route-resolution-foWW8_D1.js +268 -0
  49. package/dist/runtime-api.actions.js +2 -2
  50. package/dist/runtime-api.js +25 -25
  51. package/dist/runtime-api.lookup.js +6 -6
  52. package/dist/runtime-api.monitor-CsetE9pd.js +6 -0
  53. package/dist/runtime-api.monitor.js +7 -7
  54. package/dist/runtime-api.send.js +5 -5
  55. package/dist/runtime-api.threads.js +5 -5
  56. package/dist/{runtime-D8alY00g.js → runtime-oXRGbcb5.js} +7 -7
  57. package/dist/runtime-setter-api.js +1 -1
  58. package/dist/secret-contract-api.js +1 -1
  59. package/dist/{security-audit-BtRd_VhN.js → security-audit-BQ_sGK3J.js} +1 -1
  60. package/dist/security-audit-contract-api.js +1 -1
  61. package/dist/{security-audit.runtime-Dm1LW9KX.js → security-audit.runtime-B7Gmz2DX.js} +1 -1
  62. package/dist/security-contract-api.js +1 -1
  63. package/dist/{send-8S_HKJpQ.js → send-BSBMchf8.js} +83 -57
  64. package/dist/{send.components-A42c_5tQ.js → send.components-BoEhxys4.js} +22 -15
  65. package/dist/{send.outbound-D3tonSz8.js → send.outbound-B2DK2loZ.js} +22 -11
  66. package/dist/send.receipt-BAZw2Zsz.js +35 -0
  67. package/dist/{send.shared-BQGiUPvZ.js → send.shared-DzwpAEMP.js} +26 -7
  68. package/dist/session-key-api.js +1 -1
  69. package/dist/setup-plugin-api.js +1 -1
  70. package/dist/{shared-BEW4H3bj.js → shared-CBsrEG5q.js} +8 -8
  71. package/dist/{shared-interactive-KgJjCqnB.js → shared-interactive-D39V9Wtn.js} +3 -3
  72. package/dist/{subagent-hooks-T0LPLh4H.js → subagent-hooks-BDy1pJD5.js} +2 -2
  73. package/dist/subagent-hooks-api.js +1 -1
  74. package/dist/{system-events-_fzSG--3.js → system-events-BeVImqnV.js} +1 -1
  75. package/dist/target-parsing-D-H7nnh2.js +51 -0
  76. package/dist/target-resolver-DzOelJEt.js +85 -0
  77. package/dist/targets-Dj-qyUaE.js +3 -0
  78. package/dist/test-api.js +4 -4
  79. package/dist/{thread-bindings-CMpZjP50.js → thread-bindings-DUzBL8jL.js} +7 -7
  80. package/dist/{thread-bindings.discord-api-CwWGoyei.js → thread-bindings.discord-api-dpSDYFKX.js} +7 -7
  81. package/dist/{thread-bindings.manager-BtxfLfWf.js → thread-bindings.manager-DTuwm8Tk.js} +5 -6
  82. package/dist/{thread-bindings.session-updates-jcZSiRPI.js → thread-bindings.session-updates-BhcGQTJb.js} +1 -1
  83. package/dist/{threading-BMmpA2JR.js → threading-CTUnZtNi.js} +4 -5
  84. package/dist/timeouts.js +1 -1
  85. package/dist/{typing-Bw6NKWLZ.js → typing-BYeVSviE.js} +2 -3
  86. package/openclaw.plugin.json +222 -1
  87. package/package.json +5 -5
  88. package/dist/manager.runtime-Cug1PoeZ.js +0 -1025
  89. package/dist/provider.runtime-B68g3qLv.js +0 -2
  90. package/dist/rolldown-runtime-C3SqQTfK.js +0 -28
  91. package/dist/route-resolution-BWErj5Cn.js +0 -236
  92. package/dist/runtime-api.monitor-DzkCxeBL.js +0 -6
  93. package/dist/target-resolver-DA84_xbt.js +0 -365
  94. package/dist/targets-FwL1BPTU.js +0 -2
  95. /package/dist/{agent-components.runtime-Dof1YMSz.js → agent-components.runtime-zT8qPsnM.js} +0 -0
  96. /package/dist/{audit-core-CejGc3hO.js → audit-core-CG37TsZm.js} +0 -0
  97. /package/dist/{channel-access-DFIQqbYm.js → channel-access-BL-wemES.js} +0 -0
  98. /package/dist/{doctor-shared-Cqvfgv9m.js → doctor-shared-D_QLzu30.js} +0 -0
  99. /package/dist/{mentions-BPZUaFk7.js → mentions-f806C7MB.js} +0 -0
  100. /package/dist/{preflight-audio.runtime-DPVbpZid.js → preflight-audio.runtime-fXnUxxBa.js} +0 -0
  101. /package/dist/{probe-E80IMT1X.js → probe-CjO53qsc.js} +0 -0
  102. /package/dist/{runtime-K9RT6Egn.js → runtime-BqCoo-zp.js} +0 -0
  103. /package/dist/{secret-config-contract-5S9U9pjx.js → secret-config-contract-BCQNNS7N.js} +0 -0
  104. /package/dist/{security-contract-BE8rsdPq.js → security-contract-DrbQqyyW.js} +0 -0
  105. /package/dist/{security-doctor-DiilN216.js → security-doctor-BJH5YIGL.js} +0 -0
  106. /package/dist/{sender-identity-BGUfyvOC.js → sender-identity-CDOVm5Dk.js} +0 -0
  107. /package/dist/{session-contract-CuW9Nlxg.js → session-contract-D871HDFG.js} +0 -0
  108. /package/dist/{session-key-normalization-B5La-jFM.js → session-key-normalization-BQNCS1gu.js} +0 -0
  109. /package/dist/{thread-bindings.state-WU4duXKY.js → thread-bindings.state-DwgDYzBM.js} +0 -0
  110. /package/dist/{timeouts-CdsmBWWs.js → timeouts-C3FYXWJX.js} +0 -0
@@ -1,8 +1,8 @@
1
- import { j as createDiscordRestClient } from "./send.shared-BQGiUPvZ.js";
2
- import { a as resolveDiscordChannelParentSafe, n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-DFIQqbYm.js";
3
- import { a as mergeAbortSignals } from "./timeouts-CdsmBWWs.js";
4
- import { l as resolveDiscordMessageChannelId, r as resolveDiscordMessageText, s as hasDiscordMessageStickers } from "./message-utils-9kaGF59d.js";
5
- import { t as sendTyping } from "./typing-Bw6NKWLZ.js";
1
+ import { j as createDiscordRestClient } from "./send.shared-DzwpAEMP.js";
2
+ import { a as resolveDiscordChannelParentSafe, n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe, t as resolveDiscordChannelIdSafe } from "./channel-access-BL-wemES.js";
3
+ import { a as mergeAbortSignals } from "./timeouts-C3FYXWJX.js";
4
+ import { l as resolveDiscordMessageChannelId, r as resolveDiscordMessageText, s as hasDiscordMessageStickers } from "./message-utils-DEjCwCRz.js";
5
+ import { t as sendTyping } from "./typing-BYeVSviE.js";
6
6
  import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
7
7
  import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
8
8
  import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
@@ -121,7 +121,7 @@ function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
121
121
  //#region extensions/discord/src/monitor/message-run-queue.ts
122
122
  let messageProcessRuntimePromise;
123
123
  async function loadMessageProcessRuntime() {
124
- messageProcessRuntimePromise ??= import("./message-handler.process-CEnzuLiN.js");
124
+ messageProcessRuntimePromise ??= import("./message-handler.process-BN8bE7AE.js");
125
125
  return await messageProcessRuntimePromise;
126
126
  }
127
127
  async function processDiscordQueuedMessage(params) {
@@ -173,7 +173,7 @@ function createDiscordMessageRunQueue(params) {
173
173
  //#region extensions/discord/src/monitor/message-handler.ts
174
174
  let messagePreflightRuntimePromise;
175
175
  async function loadMessagePreflightRuntime() {
176
- messagePreflightRuntimePromise ??= import("./message-handler.preflight-BrvazsYn.js");
176
+ messagePreflightRuntimePromise ??= import("./message-handler.preflight-q7ose9Ta.js");
177
177
  return await messagePreflightRuntimePromise;
178
178
  }
179
179
  function isNonEmptyString(value) {
@@ -1,14 +1,14 @@
1
+ import { S as Message, ot as getChannelMessage, t as discord_exports } from "./discord-DtHMmZqJ.js";
1
2
  import { o as resolveDefaultDiscordAccountId } from "./accounts-CaHGiVB4.js";
2
- import { S as Message, ot as getChannelMessage, t as discord_exports } from "./discord-eZlimVfW.js";
3
3
  import { i as resolveTimestampMs, n as formatDiscordUserTag, r as resolveDiscordSystemLocation } from "./format-D8TsaXxW.js";
4
- import { _ as resolveGroupDmAllow, a as normalizeDiscordSlug, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, f as resolveDiscordMemberAccessState, g as resolveDiscordShouldRequireMention, i as normalizeDiscordDisplaySlug, m as resolveDiscordOwnerAccess, n as isDiscordGroupAllowedByPolicy } from "./allow-list-ek-1hMKN.js";
5
- import { t as resolveDiscordConversationIdentity } from "./conversation-identity-DHhS0ez3.js";
6
- import { l as isRecentlyUnboundThreadWebhookMessage } from "./thread-bindings.state-WU4duXKY.js";
7
- import "./thread-bindings-CMpZjP50.js";
8
- import { n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe } from "./channel-access-DFIQqbYm.js";
9
- import { c as resolveDiscordChannelInfo, l as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-9kaGF59d.js";
10
- import { a as shouldIgnoreStaleDiscordRouteBinding, i as resolveDiscordEffectiveRoute, o as handleDiscordDmCommandDecision, r as resolveDiscordConversationRoute, s as resolveDiscordDmCommandAccess, t as buildDiscordRoutePeer } from "./route-resolution-BWErj5Cn.js";
11
- import { n as resolveDiscordWebhookId, t as resolveDiscordSenderIdentity } from "./sender-identity-BGUfyvOC.js";
4
+ import { _ as resolveGroupDmAllow, a as normalizeDiscordSlug, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordGuildEntry, f as resolveDiscordMemberAccessState, g as resolveDiscordShouldRequireMention, i as normalizeDiscordDisplaySlug, n as isDiscordGroupAllowedByPolicy } from "./allow-list-4wnZg5P9.js";
5
+ import { t as resolveDiscordConversationIdentity } from "./conversation-identity-BPQm_uhV.js";
6
+ import { l as isRecentlyUnboundThreadWebhookMessage } from "./thread-bindings.state-DwgDYzBM.js";
7
+ import "./thread-bindings-DUzBL8jL.js";
8
+ import { n as resolveDiscordChannelInfoSafe, r as resolveDiscordChannelNameSafe } from "./channel-access-BL-wemES.js";
9
+ import { a as shouldIgnoreStaleDiscordRouteBinding, c as resolveDiscordTextCommandAccess, i as resolveDiscordEffectiveRoute, o as handleDiscordDmCommandDecision, r as resolveDiscordConversationRoute, s as resolveDiscordDmCommandAccess, t as buildDiscordRoutePeer } from "./route-resolution-foWW8_D1.js";
10
+ import { c as resolveDiscordChannelInfo, l as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-DEjCwCRz.js";
11
+ import { n as resolveDiscordWebhookId, t as resolveDiscordSenderIdentity } from "./sender-identity-CDOVm5Dk.js";
12
12
  import { logDebug, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
13
13
  import { getChildLogger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
14
14
  import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
@@ -16,7 +16,6 @@ import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
16
16
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
17
17
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
18
18
  import { buildMentionRegexes, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
19
- import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth-native";
20
19
  import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
21
20
  import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
22
21
  import { recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
@@ -28,7 +27,7 @@ async function loadConversationRuntime$1() {
28
27
  return await conversationRuntimePromise$1;
29
28
  }
30
29
  async function loadDiscordSendRuntime() {
31
- discordSendRuntimePromise ??= import("./send-8S_HKJpQ.js").then((n) => n.t);
30
+ discordSendRuntimePromise ??= import("./send-BSBMchf8.js").then((n) => n.t);
32
31
  return await discordSendRuntimePromise;
33
32
  }
34
33
  async function resolveDiscordDmPreflightAccess(params) {
@@ -55,20 +54,18 @@ async function resolveDiscordDmPreflightAccess(params) {
55
54
  tag: params.sender.tag
56
55
  },
57
56
  allowNameMatching: params.allowNameMatching,
58
- useAccessGroups: params.useAccessGroups,
59
57
  cfg: params.preflight.cfg,
60
58
  token: params.preflight.token,
61
59
  rest: params.preflight.client.rest
62
60
  });
63
- const commandAuthorized = dmAccess.commandAuthorized || directBindingRecord != null;
64
- if (dmAccess.decision === "allow") return { commandAuthorized };
61
+ const commandAuthorized = dmAccess.senderAccess.allowed && dmAccess.commandAccess.authorized || directBindingRecord != null;
62
+ if (dmAccess.senderAccess.decision === "allow") return { commandAuthorized };
65
63
  if (directBindingRecord) {
66
64
  logVerbose(`discord: allow bound DM conversation ${directBindingConversationId} despite dmPolicy=${params.dmPolicy}`);
67
65
  return { commandAuthorized };
68
66
  }
69
- const allowMatchMeta = formatAllowlistMatchMeta(dmAccess.allowMatch.allowed ? dmAccess.allowMatch : void 0);
70
67
  await handleDiscordDmCommandDecision({
71
- dmAccess,
68
+ senderAccess: dmAccess.senderAccess,
72
69
  accountId: params.resolvedAccountId,
73
70
  sender: {
74
71
  id: params.author.id,
@@ -76,7 +73,7 @@ async function resolveDiscordDmPreflightAccess(params) {
76
73
  name: params.author.username ?? void 0
77
74
  },
78
75
  onPairingCreated: async (code) => {
79
- logVerbose(`discord pairing request sender=${params.author.id} tag=${formatDiscordUserTag(params.author)} (${allowMatchMeta})`);
76
+ logVerbose(`discord pairing request sender=${params.author.id} tag=${formatDiscordUserTag(params.author)} reason=${dmAccess.senderAccess.reasonCode}`);
80
77
  try {
81
78
  const conversationRuntime = await loadConversationRuntime$1();
82
79
  const { sendMessageDiscord } = await loadDiscordSendRuntime();
@@ -95,7 +92,7 @@ async function resolveDiscordDmPreflightAccess(params) {
95
92
  }
96
93
  },
97
94
  onUnauthorized: async () => {
98
- logVerbose(`Blocked unauthorized discord sender ${params.sender.id} (dmPolicy=${params.dmPolicy}, ${allowMatchMeta})`);
95
+ logVerbose(`Blocked unauthorized discord sender ${params.sender.id} (dmPolicy=${params.dmPolicy}, reason=${dmAccess.senderAccess.reasonCode})`);
99
96
  }
100
97
  });
101
98
  return null;
@@ -428,19 +425,19 @@ let preflightAudioRuntimePromise;
428
425
  let systemEventsRuntimePromise;
429
426
  let discordThreadingRuntimePromise;
430
427
  async function loadPluralKitRuntime() {
431
- pluralkitRuntimePromise ??= import("./pluralkit-OFss_pIy.js").then((n) => n.n);
428
+ pluralkitRuntimePromise ??= import("./pluralkit-CUfobeQu.js").then((n) => n.n);
432
429
  return await pluralkitRuntimePromise;
433
430
  }
434
431
  async function loadPreflightAudioRuntime() {
435
- preflightAudioRuntimePromise ??= import("./preflight-audio-CRmUxxuM.js");
432
+ preflightAudioRuntimePromise ??= import("./preflight-audio-BcsH127L.js");
436
433
  return await preflightAudioRuntimePromise;
437
434
  }
438
435
  async function loadSystemEventsRuntime() {
439
- systemEventsRuntimePromise ??= import("./system-events-_fzSG--3.js");
436
+ systemEventsRuntimePromise ??= import("./system-events-BeVImqnV.js");
440
437
  return await systemEventsRuntimePromise;
441
438
  }
442
439
  async function loadDiscordThreadingRuntime() {
443
- discordThreadingRuntimePromise ??= import("./threading-BMmpA2JR.js").then((n) => n.t);
440
+ discordThreadingRuntimePromise ??= import("./threading-CTUnZtNi.js").then((n) => n.t);
444
441
  return await discordThreadingRuntimePromise;
445
442
  }
446
443
  function isPreflightAborted(abortSignal) {
@@ -659,7 +656,6 @@ async function preflightDiscordMessage(params) {
659
656
  return null;
660
657
  }
661
658
  const dmPolicy = params.dmPolicy;
662
- const useAccessGroups = params.cfg.commands?.useAccessGroups !== false;
663
659
  const resolvedAccountId = params.accountId ?? resolveDefaultDiscordAccountId(params.cfg);
664
660
  const allowNameMatching = isDangerousNameMatchingEnabled(params.discordConfig);
665
661
  let commandAuthorized = true;
@@ -670,8 +666,7 @@ async function preflightDiscordMessage(params) {
670
666
  sender,
671
667
  dmPolicy,
672
668
  resolvedAccountId,
673
- allowNameMatching,
674
- useAccessGroups
669
+ allowNameMatching
675
670
  });
676
671
  if (isPreflightAborted(params.abortSignal)) return null;
677
672
  if (!access) return null;
@@ -847,30 +842,23 @@ async function preflightDiscordMessage(params) {
847
842
  });
848
843
  const hasControlCommandInMessage = hasControlCommand(baseText, params.cfg);
849
844
  if (!isDirectMessage) {
850
- const { ownerAllowList, ownerAllowed: ownerOk } = resolveDiscordOwnerAccess({
851
- allowFrom: params.allowFrom,
845
+ const commandAccess = await resolveDiscordTextCommandAccess({
846
+ accountId: params.accountId,
847
+ cfg: params.cfg,
848
+ ownerAllowFrom: params.allowFrom,
852
849
  sender: {
853
850
  id: sender.id,
854
851
  name: sender.name,
855
852
  tag: sender.tag
856
853
  },
857
- allowNameMatching
858
- });
859
- const commandGate = resolveControlCommandGate({
860
- useAccessGroups,
861
- authorizers: [{
862
- configured: ownerAllowList != null,
863
- allowed: ownerOk
864
- }, {
865
- configured: hasAccessRestrictions,
866
- allowed: memberAllowed
867
- }],
868
- modeWhenAccessGroupsOff: "configured",
854
+ memberAccessConfigured: hasAccessRestrictions,
855
+ memberAllowed,
856
+ allowNameMatching,
869
857
  allowTextCommands,
870
858
  hasControlCommand: hasControlCommandInMessage
871
859
  });
872
- commandAuthorized = commandGate.commandAuthorized;
873
- if (commandGate.shouldBlock) {
860
+ commandAuthorized = commandAccess.authorized;
861
+ if (commandAccess.shouldBlockControlCommand) {
874
862
  logInboundDrop({
875
863
  log: logVerbose,
876
864
  channel: "discord",
@@ -946,7 +934,8 @@ async function preflightDiscordMessage(params) {
946
934
  logDebug(`[discord-preflight] drop: system event`);
947
935
  enqueueSystemEvent(systemText, {
948
936
  sessionKey: effectiveRoute.sessionKey,
949
- contextKey: `discord:system:${messageChannelId}:${message.id}`
937
+ contextKey: `discord:system:${messageChannelId}:${message.id}`,
938
+ trusted: false
950
939
  });
951
940
  return null;
952
941
  }
@@ -1,37 +1,38 @@
1
+ import { $ as createChannelMessage, it as editChannelMessage, nt as deleteChannelMessage, t as discord_exports } from "./discord-DtHMmZqJ.js";
1
2
  import { f as resolveDiscordMaxLinesPerMessage } from "./accounts-CaHGiVB4.js";
2
- import { l as resolveDiscordChannelId, s as chunkDiscordTextWithMode } from "./target-resolver-DA84_xbt.js";
3
- import { $ as createChannelMessage, it as editChannelMessage, nt as deleteChannelMessage, t as discord_exports } from "./discord-eZlimVfW.js";
4
- import { M as createDiscordRuntimeAccountContext, d as resolveDiscordTargetChannelId, j as createDiscordRestClient } from "./send.shared-BQGiUPvZ.js";
3
+ import { n as resolveDiscordChannelId } from "./target-parsing-D-H7nnh2.js";
4
+ import { t as chunkDiscordTextWithMode } from "./chunk-DYl-_5RL.js";
5
+ import { M as createDiscordRuntimeAccountContext, d as resolveDiscordTargetChannelId, j as createDiscordRestClient } from "./send.shared-DzwpAEMP.js";
5
6
  import { i as resolveTimestampMs } from "./format-D8TsaXxW.js";
6
- import { a as normalizeDiscordSlug, r as normalizeDiscordAllowList } from "./allow-list-ek-1hMKN.js";
7
- import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-8S_HKJpQ.js";
8
- import "./targets-FwL1BPTU.js";
9
- import { t as resolveDiscordConversationIdentity } from "./conversation-identity-DHhS0ez3.js";
10
- import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-DNsTVJfH.js";
11
- import { t as resolveDiscordPreviewStreamMode } from "./preview-streaming-Cc_oeIPP.js";
12
- import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-CdsmBWWs.js";
13
- import { a as resolveForwardedMediaList, i as buildDiscordMediaPayload, o as resolveMediaList, r as resolveDiscordMessageText } from "./message-utils-9kaGF59d.js";
14
- import { a as resolveDiscordThreadStarter, n as resolveDiscordAutoThreadReplyPlan } from "./threading-BMmpA2JR.js";
15
- import { t as sendTyping } from "./typing-Bw6NKWLZ.js";
16
- import { n as buildDiscordInboundAccessContext, r as createDiscordSupplementalContextAccessChecker } from "./inbound-context-CRylwjg0.js";
17
- import { i as resolveReplyContext, n as buildDirectLabel, r as buildGuildLabel, t as deliverDiscordReply } from "./reply-delivery-D9aKHtDH.js";
7
+ import { a as normalizeDiscordSlug, r as normalizeDiscordAllowList } from "./allow-list-4wnZg5P9.js";
8
+ import { a as removeReactionDiscord, f as editMessageDiscord, r as reactMessageDiscord } from "./send-BSBMchf8.js";
9
+ import "./targets-Dj-qyUaE.js";
10
+ import { t as resolveDiscordConversationIdentity } from "./conversation-identity-BPQm_uhV.js";
11
+ import { t as DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter-Bt8FL3yO.js";
12
+ import { t as resolveDiscordPreviewStreamMode } from "./preview-streaming-DCPAe24T.js";
13
+ import { n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-C3FYXWJX.js";
14
+ import { a as resolveForwardedMediaList, i as buildDiscordMediaPayload, o as resolveMediaList, r as resolveDiscordMessageText } from "./message-utils-DEjCwCRz.js";
15
+ import { a as resolveDiscordThreadStarter, n as resolveDiscordAutoThreadReplyPlan } from "./threading-CTUnZtNi.js";
16
+ import { t as sendTyping } from "./typing-BYeVSviE.js";
17
+ import { n as buildDiscordInboundAccessContext, r as createDiscordSupplementalContextAccessChecker } from "./inbound-context-BAwOn5Iq.js";
18
+ import { i as resolveReplyContext, n as buildDirectLabel, r as buildGuildLabel, t as deliverDiscordReply } from "./reply-delivery-vHSqaKKo.js";
18
19
  import { convertMarkdownTables, stripInlineDirectiveTagsForDelivery, stripReasoningTagsFromText, truncateUtf16Safe } from "openclaw/plugin-sdk/text-runtime";
19
20
  import { buildAgentSessionKey, normalizeAccountId, resolveAccountEntry, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
21
+ import { evaluateSupplementalContextVisibility } from "openclaw/plugin-sdk/security-runtime";
20
22
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
21
23
  import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
22
24
  import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
23
25
  import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
24
26
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
25
27
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
26
- import { createChannelProgressDraftGate, formatChannelProgressDraftLine, formatChannelProgressDraftLineForEntry, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, resolveChannelProgressDraftMaxLines, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewChunk, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-streaming";
28
+ import { createChannelMessageReplyPipeline, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-message";
29
+ import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, resolveChannelProgressDraftMaxLines, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewChunk, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-streaming";
27
30
  import { recordInboundSession, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/conversation-runtime";
28
- import { EmbeddedBlockChunker, resolveAckReaction, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
31
+ import { EmbeddedBlockChunker, formatReasoningMessage, resolveAckReaction, resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
29
32
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
30
- import { evaluateSupplementalContextVisibility } from "openclaw/plugin-sdk/security-runtime";
31
33
  import { readSessionUpdatedAt, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
32
34
  import { formatInboundEnvelope, resolveEnvelopeFormatOptions } from "openclaw/plugin-sdk/channel-inbound";
33
- import { createFinalizableDraftLifecycle, deliverFinalizableDraftPreview } from "openclaw/plugin-sdk/channel-lifecycle";
34
- import { createChannelReplyPipeline, resolveChannelSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-reply-pipeline";
35
+ import { createFinalizableDraftLifecycle } from "openclaw/plugin-sdk/channel-lifecycle";
35
36
  import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-dispatch-runtime";
36
37
  import { hasFinalInboundReplyDispatch, runInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";
37
38
  import { buildPendingHistoryContextFromMap } from "openclaw/plugin-sdk/reply-history";
@@ -557,12 +558,14 @@ function createDiscordDraftPreviewController(params) {
557
558
  async pushToolProgress(line, options) {
558
559
  if (!draftStream) return;
559
560
  if (options?.toolName !== void 0 && !isChannelProgressDraftWorkToolName(options.toolName)) return;
560
- const normalized = line?.replace(/\s+/g, " ").trim();
561
+ if (isEmptyDiscordProgressLine(line)) return;
562
+ const normalized = normalizeProgressLineIdentity(line);
561
563
  if (!normalized) return;
564
+ const progressLine = typeof line === "object" && line !== void 0 ? line : normalized;
562
565
  if (discordStreamMode !== "progress") {
563
566
  if (!previewToolProgressEnabled || previewToolProgressSuppressed) return;
564
- if (previewToolProgressLines.at(-1) === normalized) return;
565
- previewToolProgressLines = [...previewToolProgressLines, normalized].slice(-resolveChannelProgressDraftMaxLines(params.discordConfig));
567
+ if (normalizeProgressLineIdentity(previewToolProgressLines.at(-1)) === normalized) return;
568
+ previewToolProgressLines = [...previewToolProgressLines, progressLine].slice(-resolveChannelProgressDraftMaxLines(params.discordConfig));
566
569
  const previewText = formatChannelProgressDraftText({
567
570
  entry: params.discordConfig,
568
571
  lines: previewToolProgressLines,
@@ -576,10 +579,11 @@ function createDiscordDraftPreviewController(params) {
576
579
  return;
577
580
  }
578
581
  if (previewToolProgressEnabled && !previewToolProgressSuppressed && normalized) {
579
- if (previewToolProgressLines.at(-1) !== normalized) previewToolProgressLines = [...previewToolProgressLines, normalized].slice(-resolveChannelProgressDraftMaxLines(params.discordConfig));
582
+ if (normalizeProgressLineIdentity(previewToolProgressLines.at(-1)) !== normalized) previewToolProgressLines = [...previewToolProgressLines, progressLine].slice(-resolveChannelProgressDraftMaxLines(params.discordConfig));
580
583
  }
581
584
  const alreadyStarted = progressDraftGate.hasStarted;
582
- await progressDraftGate.noteWork();
585
+ if (shouldStartDiscordProgressDraftNow(line)) await progressDraftGate.startNow();
586
+ else await progressDraftGate.noteWork();
583
587
  if (alreadyStarted && progressDraftGate.hasStarted) await renderProgressDraft();
584
588
  },
585
589
  async pushReasoningProgress(text) {
@@ -698,6 +702,16 @@ function mergeReasoningProgressText(current, incoming) {
698
702
  function isReasoningSnapshotText(text) {
699
703
  return /^\s*(?:>\s*)?Reasoning:\s*/i.test(text);
700
704
  }
705
+ function normalizeProgressLineIdentity(line) {
706
+ return (typeof line === "string" ? line : line?.text)?.replace(/\s+/g, " ").trim() ?? "";
707
+ }
708
+ function isEmptyDiscordProgressLine(line) {
709
+ if (!line || typeof line === "string") return false;
710
+ return line.toolName === "apply_patch" && !line.detail && !line.status;
711
+ }
712
+ function shouldStartDiscordProgressDraftNow(line) {
713
+ return typeof line === "object" && line?.kind === "patch" && Boolean(line.detail);
714
+ }
701
715
  //#endregion
702
716
  //#region extensions/discord/src/monitor/message-handler.process.ts
703
717
  function sleep(ms) {
@@ -748,7 +762,7 @@ async function processDiscordMessage(ctx, observer) {
748
762
  const boundThreadId = ctx.threadBinding?.conversation?.conversationId?.trim();
749
763
  if (boundThreadId && typeof threadBindings.touchThread === "function") threadBindings.touchThread({ threadId: boundThreadId });
750
764
  const { createReplyDispatcherWithTyping, dispatchInboundMessage, settleReplyDispatcher } = await loadReplyRuntime();
751
- const sourceReplyDeliveryMode = resolveChannelSourceReplyDeliveryMode({
765
+ const sourceReplyDeliveryMode = resolveChannelMessageSourceReplyDeliveryMode({
752
766
  cfg,
753
767
  ctx: { ChatType: isGuildMessage ? "channel" : void 0 }
754
768
  });
@@ -887,7 +901,7 @@ async function processDiscordMessage(ctx, observer) {
887
901
  sessionKey: persistedSessionKey
888
902
  });
889
903
  const typingChannelId = deliverTarget.startsWith("channel:") ? deliverTarget.slice(8) : messageChannelId;
890
- const { onModelSelected, ...replyPipeline } = createChannelReplyPipeline({
904
+ const { onModelSelected, ...replyPipeline } = createChannelMessageReplyPipeline({
891
905
  cfg,
892
906
  agentId: route.agentId,
893
907
  channel: "discord",
@@ -957,29 +971,39 @@ async function processDiscordMessage(ctx, observer) {
957
971
  const finalText = payload.text;
958
972
  const previewFinalText = draftPreview.resolvePreviewFinalText(finalText);
959
973
  const hasExplicitReplyDirective = Boolean(payload.replyToTag || payload.replyToCurrent) || typeof finalText === "string" && /\[\[\s*reply_to(?:_current|\s*:)/i.test(finalText);
960
- if (await deliverFinalizableDraftPreview({
974
+ if ((await deliverWithFinalizableLivePreviewAdapter({
961
975
  kind: info.kind,
962
976
  payload,
963
- draft: {
964
- flush: () => draftPreview.flush(),
965
- clear: () => draftStream.clear(),
966
- discardPending: () => draftStream.discardPending(),
967
- seal: () => draftStream.seal(),
968
- id: draftStream.messageId
969
- },
970
- buildFinalEdit: () => {
971
- if (draftPreview.finalizedViaPreviewMessage || hasMedia || typeof previewFinalText !== "string" || hasExplicitReplyDirective || payload.isError) return;
972
- return { content: previewFinalText };
973
- },
974
- editFinal: async (previewMessageId, edit) => {
975
- if (isProcessAborted(abortSignal)) throw new Error("process aborted");
976
- notifyFinalReplyStart();
977
- await editMessageDiscord(deliverChannelId, previewMessageId, edit, {
978
- cfg,
979
- accountId,
980
- rest: deliveryRest
981
- });
982
- },
977
+ adapter: defineFinalizableLivePreviewAdapter({
978
+ draft: {
979
+ flush: () => draftPreview.flush(),
980
+ clear: () => draftStream.clear(),
981
+ discardPending: () => draftStream.discardPending(),
982
+ seal: () => draftStream.seal(),
983
+ id: draftStream.messageId
984
+ },
985
+ buildFinalEdit: () => {
986
+ if (draftPreview.finalizedViaPreviewMessage || hasMedia || typeof previewFinalText !== "string" || hasExplicitReplyDirective || payload.isError) return;
987
+ return { content: previewFinalText };
988
+ },
989
+ editFinal: async (previewMessageId, edit) => {
990
+ if (isProcessAborted(abortSignal)) throw new Error("process aborted");
991
+ notifyFinalReplyStart();
992
+ await editMessageDiscord(deliverChannelId, previewMessageId, edit, {
993
+ cfg,
994
+ accountId,
995
+ rest: deliveryRest
996
+ });
997
+ },
998
+ onPreviewFinalized: () => {
999
+ draftPreview.markPreviewFinalized();
1000
+ replyReference.markSent();
1001
+ observer?.onFinalReplyDelivered?.();
1002
+ },
1003
+ logPreviewEditFailure: (err) => {
1004
+ logVerbose(`discord: preview final edit failed; falling back to standard send (${String(err)})`);
1005
+ }
1006
+ }),
983
1007
  deliverNormally: async () => {
984
1008
  if (isProcessAborted(abortSignal)) return false;
985
1009
  const replyToId = replyReference.use();
@@ -1005,16 +1029,8 @@ async function processDiscordMessage(ctx, observer) {
1005
1029
  replyReference.markSent();
1006
1030
  observer?.onFinalReplyDelivered?.();
1007
1031
  return true;
1008
- },
1009
- onPreviewFinalized: () => {
1010
- draftPreview.markPreviewFinalized();
1011
- replyReference.markSent();
1012
- observer?.onFinalReplyDelivered?.();
1013
- },
1014
- logPreviewEditFailure: (err) => {
1015
- logVerbose(`discord: preview final edit failed; falling back to standard send (${String(err)})`);
1016
1032
  }
1017
- }) !== "normal-skipped") return;
1033
+ })).kind !== "normal-skipped") return;
1018
1034
  }
1019
1035
  if (isProcessAborted(abortSignal)) return;
1020
1036
  const replyToId = replyReference.use();
@@ -1121,13 +1137,14 @@ async function processDiscordMessage(ctx, observer) {
1121
1137
  suppressDefaultToolProgressMessages: draftPreview.suppressDefaultToolProgressMessages ? true : void 0,
1122
1138
  onReasoningStream: async (payload) => {
1123
1139
  await statusReactions.setThinking();
1124
- await draftPreview.pushReasoningProgress(payload?.text);
1140
+ const formattedText = payload?.text ? formatReasoningMessage(payload.text) : void 0;
1141
+ await draftPreview.pushReasoningProgress(formattedText);
1125
1142
  },
1126
1143
  onToolStart: async (payload) => {
1127
1144
  if (isProcessAborted(abortSignal)) return;
1128
1145
  await maybeBindStatusReactionsToToolReaction(payload);
1129
1146
  await statusReactions.setTool(payload.name);
1130
- await draftPreview.pushToolProgress(formatChannelProgressDraftLineForEntry(discordConfig, {
1147
+ await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
1131
1148
  event: "tool",
1132
1149
  name: payload.name,
1133
1150
  phase: payload.phase,
@@ -1135,7 +1152,7 @@ async function processDiscordMessage(ctx, observer) {
1135
1152
  }, payload.detailMode ? { detailMode: payload.detailMode } : void 0), { toolName: payload.name });
1136
1153
  },
1137
1154
  onItemEvent: async (payload) => {
1138
- await draftPreview.pushToolProgress(formatChannelProgressDraftLineForEntry(discordConfig, {
1155
+ await draftPreview.pushToolProgress(buildChannelProgressDraftLineForEntry(discordConfig, {
1139
1156
  event: "item",
1140
1157
  itemKind: payload.kind,
1141
1158
  title: payload.title,
@@ -1149,7 +1166,7 @@ async function processDiscordMessage(ctx, observer) {
1149
1166
  },
1150
1167
  onPlanUpdate: async (payload) => {
1151
1168
  if (payload.phase !== "update") return;
1152
- await draftPreview.pushToolProgress(formatChannelProgressDraftLine({
1169
+ await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1153
1170
  event: "plan",
1154
1171
  phase: payload.phase,
1155
1172
  title: payload.title,
@@ -1159,7 +1176,7 @@ async function processDiscordMessage(ctx, observer) {
1159
1176
  },
1160
1177
  onApprovalEvent: async (payload) => {
1161
1178
  if (payload.phase !== "requested") return;
1162
- await draftPreview.pushToolProgress(formatChannelProgressDraftLine({
1179
+ await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1163
1180
  event: "approval",
1164
1181
  phase: payload.phase,
1165
1182
  title: payload.title,
@@ -1170,7 +1187,7 @@ async function processDiscordMessage(ctx, observer) {
1170
1187
  },
1171
1188
  onCommandOutput: async (payload) => {
1172
1189
  if (payload.phase !== "end") return;
1173
- await draftPreview.pushToolProgress(formatChannelProgressDraftLine({
1190
+ await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1174
1191
  event: "command-output",
1175
1192
  phase: payload.phase,
1176
1193
  title: payload.title,
@@ -1181,7 +1198,7 @@ async function processDiscordMessage(ctx, observer) {
1181
1198
  },
1182
1199
  onPatchSummary: async (payload) => {
1183
1200
  if (payload.phase !== "end") return;
1184
- await draftPreview.pushToolProgress(formatChannelProgressDraftLine({
1201
+ await draftPreview.pushToolProgress(buildChannelProgressDraftLine({
1185
1202
  event: "patch",
1186
1203
  phase: payload.phase,
1187
1204
  title: payload.title,
@@ -1,5 +1,5 @@
1
- import { n as resolveDiscordChannelInfoSafe } from "./channel-access-DFIQqbYm.js";
2
- import { a as mergeAbortSignals } from "./timeouts-CdsmBWWs.js";
1
+ import { n as resolveDiscordChannelInfoSafe } from "./channel-access-BL-wemES.js";
2
+ import { a as mergeAbortSignals } from "./timeouts-C3FYXWJX.js";
3
3
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/text-runtime";
4
4
  import { ComponentType, StickerFormatType } from "discord-api-types/v10";
5
5
  import { fetchRemoteMedia, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
@@ -0,0 +1,58 @@
1
+ import { t as parseDiscordTarget } from "./target-parsing-D-H7nnh2.js";
2
+ //#region extensions/discord/src/normalize.ts
3
+ function normalizeDiscordMessagingTarget(raw) {
4
+ return parseDiscordTarget(raw, { defaultKind: "channel" })?.normalized;
5
+ }
6
+ /**
7
+ * Normalize a Discord outbound target for delivery. Bare numeric IDs are
8
+ * prefixed with "channel:" to avoid the ambiguous-target error in
9
+ * parseDiscordTarget, unless the ID is explicitly configured as an allowed DM
10
+ * sender. All other formats pass through unchanged.
11
+ */
12
+ function normalizeDiscordOutboundTarget(to, allowFrom) {
13
+ const trimmed = to?.trim();
14
+ if (!trimmed) return {
15
+ ok: false,
16
+ error: /* @__PURE__ */ new Error("Discord recipient is required. Use \"channel:<id>\" for channels or \"user:<id>\" for DMs.")
17
+ };
18
+ if (/^\d+$/.test(trimmed)) {
19
+ if (allowFromContainsDiscordUserId(allowFrom, trimmed)) return {
20
+ ok: true,
21
+ to: `user:${trimmed}`
22
+ };
23
+ return {
24
+ ok: true,
25
+ to: `channel:${trimmed}`
26
+ };
27
+ }
28
+ return {
29
+ ok: true,
30
+ to: trimmed
31
+ };
32
+ }
33
+ function allowFromContainsDiscordUserId(allowFrom, userId) {
34
+ const normalizedUserId = userId.trim();
35
+ if (!normalizedUserId) return false;
36
+ return (allowFrom ?? []).some((entry) => normalizeAllowFromDiscordUserId(entry) === normalizedUserId);
37
+ }
38
+ function normalizeAllowFromDiscordUserId(entry) {
39
+ const trimmed = entry.trim().toLowerCase();
40
+ if (!trimmed || trimmed === "*") return;
41
+ const mentionMatch = /^<@!?(\d+)>$/.exec(trimmed);
42
+ if (mentionMatch) return mentionMatch[1];
43
+ const prefixedMatch = /^(?:discord:)?user:(\d+)$/.exec(trimmed);
44
+ if (prefixedMatch) return prefixedMatch[1];
45
+ const discordMatch = /^discord:(\d+)$/.exec(trimmed);
46
+ if (discordMatch) return discordMatch[1];
47
+ return /^\d+$/.test(trimmed) ? trimmed : void 0;
48
+ }
49
+ function looksLikeDiscordTargetId(raw) {
50
+ const trimmed = raw.trim();
51
+ if (!trimmed) return false;
52
+ if (/^<@!?\d+>$/.test(trimmed)) return true;
53
+ if (/^(user|channel|discord):/i.test(trimmed)) return true;
54
+ if (/^\d{6,}$/.test(trimmed)) return true;
55
+ return false;
56
+ }
57
+ //#endregion
58
+ export { normalizeDiscordOutboundTarget as i, looksLikeDiscordTargetId as n, normalizeDiscordMessagingTarget as r, allowFromContainsDiscordUserId as t };