@openclaw/discord 2026.9.8 → 2026.10.1-beta.2

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 (147) hide show
  1. package/README.md +7 -0
  2. package/dist/.setup/{account-inspect-De8hOUxG.mjs → account-inspect-CjKqkDnH.mjs} +2 -2
  3. package/dist/.setup/{accounts-ChaMcixG.mjs → accounts-DXHCL8Zm.mjs} +9 -32
  4. package/dist/.setup/{active-turn-thread-route-fmHl1HNd.mjs → active-turn-thread-route-C4tp9noA.mjs} +5 -9
  5. package/dist/.setup/{activities-api-tvbsU2e3.mjs → activities-api-BL_hJ0JQ.mjs} +15 -18
  6. package/dist/.setup/{api-DVbJwZVt.mjs → api-_oznjffB.mjs} +1 -1
  7. package/dist/.setup/{approval-handler.runtime-DxCK2Rux.mjs → approval-handler.runtime-BilYSrRF.mjs} +22 -61
  8. package/dist/.setup/{approval-message-updates-BKFqavHZ.mjs → approval-message-updates-CgRwc2_Q.mjs} +2 -2
  9. package/dist/.setup/{audit-CLg9I71N.mjs → audit-DtvzxONM.mjs} +4 -4
  10. package/dist/.setup/{channel-access-C12aDZ0p.mjs → channel-access-BRp3Y-rF.mjs} +4 -17
  11. package/dist/.setup/{channel-type-DRCrEMss.mjs → channel-type-D1_b5UhU.mjs} +12 -16
  12. package/dist/.setup/{channel-DxlUVU9t.mjs → channel-z5lQMS_9.mjs} +79 -75
  13. package/dist/.setup/{channel.setup-CRo1GjV7.mjs → channel.setup-DBJtugJO.mjs} +14 -34
  14. package/dist/.setup/{components-Cq1PvIpN.mjs → components-CzXLR3QH.mjs} +56 -72
  15. package/dist/.setup/{config-schema-oxELUSDx.mjs → config-schema-CsemBDpS.mjs} +6 -17
  16. package/dist/.setup/{conversation-binding-route-Caz_XuFH.mjs → conversation-binding-route-Bi62ApSt.mjs} +1 -1
  17. package/dist/.setup/{directory-config-esqNn0Eo.mjs → directory-config-BH1LA-gi.mjs} +1 -1
  18. package/dist/.setup/{directory-live-DtKRHuGV.mjs → directory-live-C9xz7IPm.mjs} +10 -13
  19. package/dist/.setup/{discord-0xJYfdDD.mjs → discord-J7aRzq2Q.mjs} +101 -381
  20. package/dist/.setup/{doctor-BCl1H5tl.mjs → doctor-DxSAngJq.mjs} +31 -70
  21. package/dist/.setup/doctor-contract-Bg3NPAMw.mjs +137 -0
  22. package/dist/.setup/{handle-action-CUvQWnE7.mjs → handle-action-DlmFX-_G.mjs} +10 -11
  23. package/dist/.setup/{handle-action.guild-admin-Df-8gVle.mjs → handle-action.guild-admin-BnyqTczR.mjs} +67 -129
  24. package/dist/.setup/{live-policy-config-8Pv20CHc.mjs → live-policy-config-emmPNyh4.mjs} +1 -1
  25. package/dist/.setup/{message-handler-B-Jk4oDk.mjs → message-handler-BNToPZrx.mjs} +7 -6
  26. package/dist/.setup/{message-handler.preflight-v-__NSDq.mjs → message-handler.preflight-D0BcCyI7.mjs} +13 -23
  27. package/dist/.setup/{message-handler.preflight-pluralkit-CWLUBVcx.mjs → message-handler.preflight-pluralkit-D1g3eq0B.mjs} +5 -8
  28. package/dist/.setup/{message-handler.process-BNFFuChn.mjs → message-handler.process-CThRmCWK.mjs} +57 -96
  29. package/dist/.setup/{outbound-adapter-BobT-kse.mjs → outbound-adapter-BPq0c2wY.mjs} +11 -17
  30. package/dist/.setup/{outbound-session-route-zVGxxceg.mjs → outbound-session-route-DGPPKA0z.mjs} +21 -46
  31. package/dist/.setup/{presence-cache-Di3H3DIU.mjs → presence-cache-Dg3_dADn.mjs} +2 -4
  32. package/dist/.setup/{probe-LYrIHlBF.mjs → probe-DIRY8vh7.mjs} +17 -27
  33. package/dist/.setup/{provider-B_G5hASF.mjs → provider-D2OKMo0f.mjs} +273 -446
  34. package/dist/.setup/{provider-session.runtime-BYlTBFD2.mjs → provider-session.runtime-BupCTZQv.mjs} +3 -3
  35. package/dist/.setup/provider.runtime-BaW_JnfU.mjs +2 -0
  36. package/dist/.setup/{realtime-session.runtime-oUd9DOcz.mjs → realtime-session.runtime-D5RSC8Mm.mjs} +6 -8
  37. package/dist/.setup/{receive-recovery-CHPOsnLc.mjs → receive-recovery-GqF2PUN_.mjs} +1 -4
  38. package/dist/.setup/{resolve-allowlist-common-DPdRggu5.mjs → resolve-allowlist-common-DUYRrrVB.mjs} +5 -9
  39. package/dist/.setup/{resolve-channels-BFPNRmVv.mjs → resolve-channels--MUatisx.mjs} +3 -3
  40. package/dist/.setup/{resolve-users-0-aBuCy3.mjs → resolve-users-CxLcDmM0.mjs} +6 -9
  41. package/dist/.setup/{retry-pz_cSha2.mjs → retry-BKzO25k4.mjs} +27 -51
  42. package/dist/.setup/{runtime-sUksZ--Q.mjs → runtime-CerRBfaa.mjs} +2 -2
  43. package/dist/.setup/{runtime-FN000lxA.mjs → runtime-CwUA0RLr.mjs} +228 -255
  44. package/dist/.setup/{runtime-doctor-migrations-CshUGl36.mjs → runtime-doctor-migrations-BPV-R4G9.mjs} +6 -0
  45. package/dist/.setup/{security-audit-Cdaegq7C.mjs → security-audit-D42cp5N7.mjs} +21 -48
  46. package/dist/.setup/{send-CrfEI6Bs.mjs → send-2X7m2Zmw.mjs} +45 -58
  47. package/dist/.setup/{send.components-DxQAMfES.mjs → send.components-RqvgmCs3.mjs} +44 -90
  48. package/dist/.setup/{send.outbound-BISKnb-a.mjs → send.outbound-B4QHSEzm.mjs} +60 -98
  49. package/dist/.setup/{send.shared-DGFkbkQR.mjs → send.shared-BQIUh6Vn.mjs} +13 -20
  50. package/dist/.setup/{sender-identity-B9X5Vb9R.mjs → sender-identity-CooeYfAn.mjs} +1 -1
  51. package/dist/.setup/{session-key-normalization-wJgsKPNF.mjs → session-key-normalization-CCHGNSQw.mjs} +3 -9
  52. package/dist/.setup/setup-plugin-api-nn_giXvZ.mjs +3 -0
  53. package/dist/.setup/{shared-B3wZ4hN-.mjs → shared-CIJn6AEC.mjs} +7 -7
  54. package/dist/.setup/{subagent-hooks-nlUE9ow7.mjs → subagent-hooks-BYlVnxzy.mjs} +4 -9
  55. package/dist/.setup/{system-events-CdeZnvPV.mjs → system-events-CQ3if_pS.mjs} +2 -2
  56. package/dist/.setup/{target-resolver-BuLapkhy.mjs → target-resolver-Dzxf80Y3.mjs} +5 -13
  57. package/dist/.setup/targets-Lf8D55w-.mjs +3 -0
  58. package/dist/.setup/{thread-bindings-D7TfgjR_.mjs → thread-bindings-yNNlcUWE.mjs} +5 -6
  59. package/dist/.setup/{thread-bindings.manager-DN-NissX.mjs → thread-bindings.manager-plk0zJAW.mjs} +14 -20
  60. package/dist/.setup/{thread-bindings.session-updates-CshfKghV.mjs → thread-bindings.session-updates-C9aKtVs6.mjs} +295 -5
  61. package/dist/.setup/{timeouts-D86uWLt_.mjs → timeouts-pun7VJ02.mjs} +2 -15
  62. package/dist/.setup/{transcripts-source-p8EV179h.mjs → transcripts-source-CNWswry-.mjs} +31 -79
  63. package/dist/.setup/typing-CNlSKY5S.mjs +11 -0
  64. package/dist/.setup/{voice-runtime-B46rcwrG.mjs → voice-runtime-Bc75quiH.mjs} +62 -110
  65. package/dist/account-inspect-api.js +1 -1
  66. package/dist/action-runtime-api.js +1 -1
  67. package/dist/activities-api.js +1 -1
  68. package/dist/api.js +18 -18
  69. package/dist/channel-config-api.js +1 -1
  70. package/dist/channel-plugin-api.js +1 -1
  71. package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +1 -0
  72. package/dist/directory-contract-api.js +1 -1
  73. package/dist/doctor-contract-api.js +19 -128
  74. package/dist/index.js +1 -1
  75. package/dist/runtime-api.js +20 -21
  76. package/dist/security-audit-contract-api.js +1 -1
  77. package/dist/session-key-api.js +1 -1
  78. package/dist/setup-entry.js +1 -1
  79. package/dist/setup-plugin-api.js +1 -1
  80. package/dist/src/voice/audio-worker.runtime.js +6 -8
  81. package/dist/subagent-hooks-api.js +1 -1
  82. package/dist/transcripts-source-api.js +1 -1
  83. package/node_modules/libopus-wasm/CHANGELOG.md +8 -0
  84. package/node_modules/libopus-wasm/dist/discordjs.d.ts.map +1 -1
  85. package/node_modules/libopus-wasm/dist/discordjs.js +14 -2
  86. package/node_modules/libopus-wasm/dist/generated/libopus.generated.mjs +0 -0
  87. package/node_modules/libopus-wasm/dist/index.d.ts.map +1 -1
  88. package/node_modules/libopus-wasm/dist/index.js +55 -100
  89. package/node_modules/libopus-wasm/package.json +5 -5
  90. package/node_modules/undici/README.md +10 -1
  91. package/node_modules/undici/docs/docs/api/Agent.md +8 -8
  92. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
  93. package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
  94. package/node_modules/undici/docs/docs/api/Errors.md +25 -0
  95. package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
  96. package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
  97. package/node_modules/undici/docs/docs/api/Pool.md +5 -6
  98. package/node_modules/undici/docs/docs/index.md +10 -1
  99. package/node_modules/undici/lib/api/readable.js +1 -2
  100. package/node_modules/undici/lib/core/request.js +23 -2
  101. package/node_modules/undici/lib/core/util.js +0 -39
  102. package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
  103. package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
  104. package/node_modules/undici/lib/dispatcher/client.js +6 -1
  105. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
  106. package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
  107. package/node_modules/undici/lib/dispatcher/pool.js +90 -7
  108. package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
  109. package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
  110. package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
  111. package/node_modules/undici/lib/handler/retry-handler.js +72 -13
  112. package/node_modules/undici/lib/interceptor/cache.js +4 -1
  113. package/node_modules/undici/lib/interceptor/decompress.js +236 -69
  114. package/node_modules/undici/lib/web/cache/cache.js +17 -8
  115. package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
  116. package/node_modules/undici/lib/web/cookies/index.js +19 -7
  117. package/node_modules/undici/lib/web/cookies/util.js +3 -1
  118. package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
  119. package/node_modules/undici/lib/web/fetch/body.js +22 -15
  120. package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
  121. package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
  122. package/node_modules/undici/lib/web/fetch/headers.js +34 -31
  123. package/node_modules/undici/lib/web/fetch/index.js +46 -25
  124. package/node_modules/undici/lib/web/fetch/request.js +74 -79
  125. package/node_modules/undici/lib/web/fetch/response.js +43 -44
  126. package/node_modules/undici/lib/web/fetch/util.js +7 -7
  127. package/node_modules/undici/lib/web/infra/index.js +16 -1
  128. package/node_modules/undici/lib/web/webidl/index.js +2 -14
  129. package/node_modules/undici/lib/web/websocket/connection.js +33 -12
  130. package/node_modules/undici/lib/web/websocket/events.js +43 -26
  131. package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
  132. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
  133. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
  134. package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
  135. package/node_modules/undici/package.json +1 -1
  136. package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
  137. package/node_modules/undici/types/interceptors.d.ts +1 -1
  138. package/node_modules/undici/types/webidl.d.ts +13 -7
  139. package/openclaw.plugin.json +6 -0
  140. package/package.json +12 -7
  141. package/dist/.setup/doctor-contract-CvvgwrrG.mjs +0 -409
  142. package/dist/.setup/model-picker-preference-primitives-BHT1LkR_.mjs +0 -37
  143. package/dist/.setup/provider.runtime-CUE3UxER.mjs +0 -2
  144. package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +0 -3
  145. package/dist/.setup/targets-0KUcEIYx.mjs +0 -3
  146. package/dist/.setup/thread-bindings.state-g6v9zAym.mjs +0 -331
  147. package/dist/.setup/typing-BiHCzBRu.mjs +0 -15
@@ -1,21 +1,83 @@
1
- import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-Cq1PvIpN.mjs";
2
- import { l as resolveDiscordChannelConfigWithFallback, o as normalizeDiscordSlug, r as isDiscordGroupAllowedByPolicy, t as isDiscordThreadChannelType, y as resolveGroupDmAllow } from "./channel-type-DRCrEMss.mjs";
3
- import { o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId, t as createDiscordActionGate } from "./accounts-ChaMcixG.mjs";
4
- import { r as sendDiscordComponentMessage } from "./send.components-DxQAMfES.mjs";
5
- import { b as parseDiscordTarget, f as createReusableDiscordReplyReference, m as resolveDiscordReplyReference, x as resolveDiscordChannelId } from "./retry-pz_cSha2.mjs";
6
- import { C as hasAnyChannelPermissionDiscord, H as getGateway, P as createDiscordRuntimeAccountContext, _ as canManageGuildMemberRoleDiscord, b as fetchChannelPermissionsDiscord, n as buildDiscordTextChunks, u as resolveDiscordTargetChannelId, v as canManageGuildRoleDiscord, w as hasAnyGuildPermissionDiscord, y as canViewDiscordGuildChannel } from "./send.shared-DGFkbkQR.mjs";
7
- import { r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-BISKnb-a.mjs";
8
- import { n as getPresence } from "./presence-cache-Di3H3DIU.mjs";
9
- import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, l as DiscordThreadInitialMessageError, m as listPinsDiscord, n as fetchReactionsDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, w as fetchGuildInfoDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-CrfEI6Bs.mjs";
10
- import "./targets-0KUcEIYx.mjs";
1
+ import { h as readDiscordComponentSpec, m as coerceDiscordComponentParam } from "./components-CzXLR3QH.mjs";
2
+ import { b as resolveGroupDmAllow, i as isDiscordGroupAllowedByPolicy, r as hasConfiguredDiscordChannels, s as normalizeDiscordSlug, t as isDiscordThreadChannelType, u as resolveDiscordChannelConfigWithFallback } from "./channel-type-D1_b5UhU.mjs";
3
+ import { o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId, t as createDiscordActionGate } from "./accounts-DXHCL8Zm.mjs";
4
+ import { r as sendDiscordComponentMessage } from "./send.components-RqvgmCs3.mjs";
5
+ import { b as parseDiscordTarget, f as createReusableDiscordReplyReference, m as resolveDiscordReplyReference, x as resolveDiscordChannelId } from "./retry-BKzO25k4.mjs";
6
+ import { C as hasAnyChannelPermissionDiscord, H as getGateway, P as createDiscordRuntimeAccountContext, _ as canManageGuildMemberRoleDiscord, b as fetchChannelPermissionsDiscord, n as buildDiscordTextChunks, u as resolveDiscordTargetChannelId, v as canManageGuildRoleDiscord, w as hasAnyGuildPermissionDiscord, y as canViewDiscordGuildChannel } from "./send.shared-BQIUh6Vn.mjs";
7
+ import { r as sendStickerDiscord, t as sendMessageDiscord } from "./send.outbound-B4QHSEzm.mjs";
8
+ import { n as getPresence } from "./presence-cache-Dg3_dADn.mjs";
9
+ import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, l as DiscordThreadInitialMessageError, m as listPinsDiscord, n as fetchReactionsDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, w as fetchGuildInfoDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./send-2X7m2Zmw.mjs";
10
+ import "./targets-Lf8D55w-.mjs";
11
+ import { asBoolean, asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
11
12
  import { ChannelType, PermissionFlagsBits } from "discord-api-types/v10";
12
13
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
13
- import { asBoolean, asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
14
14
  import { createChannelProgressDraftCompositor } from "openclaw/plugin-sdk/channel-outbound";
15
15
  import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
16
16
  import { assertMediaNotDataUrl, jsonResult, parseAvailableTags, readNonNegativeIntegerParam, readPositiveIntegerParam, readReactionParams, readStringArrayParam, readStringParam, withNormalizedTimestamp } from "openclaw/plugin-sdk/channel-actions";
17
17
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
18
18
  import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
19
+ //#region extensions/discord/src/actions/runtime.messaging.thread-list.ts
20
+ function readDiscordChannelStringField(value, ...keys) {
21
+ if (!value || typeof value !== "object") return;
22
+ const record = value;
23
+ for (const key of keys) {
24
+ const candidate = record[key];
25
+ if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
26
+ }
27
+ }
28
+ function readDiscordChannelType(value) {
29
+ if (!value || typeof value !== "object") return;
30
+ const type = value.type;
31
+ return typeof type === "number" ? type : void 0;
32
+ }
33
+ function isDiscordThreadChannel(value) {
34
+ return isDiscordThreadChannelType(readDiscordChannelType(value));
35
+ }
36
+ function filterDiscordActiveThreadList(params) {
37
+ const response = asOptionalRecord(params.value);
38
+ if (!Array.isArray(response?.threads) || !Array.isArray(response.members)) throw new Error("Unexpected Discord response for active thread list.");
39
+ const { guildId, channelId, parent } = params;
40
+ const parentAncestor = {
41
+ channelId,
42
+ channelSlug: parent.channelSlug,
43
+ ...parent.channelName ? { channelName: parent.channelName } : {}
44
+ };
45
+ const threads = [];
46
+ const threadIds = /* @__PURE__ */ new Set();
47
+ for (const thread of response.threads) {
48
+ const id = readDiscordChannelStringField(thread, "id");
49
+ const parentId = readDiscordChannelStringField(thread, "parent_id");
50
+ const threadGuildId = readDiscordChannelStringField(thread, "guild_id");
51
+ const channelType = readDiscordChannelType(thread);
52
+ if (!id || parentId !== channelId || threadGuildId !== guildId || !isDiscordThreadChannelType(channelType)) continue;
53
+ const channelName = readDiscordChannelStringField(thread, "name");
54
+ const target = {
55
+ channelId: id,
56
+ channelSlug: channelName ? normalizeDiscordSlug(channelName) : id,
57
+ guildId,
58
+ metadataKnown: true,
59
+ ancestryComplete: parent.ancestryComplete,
60
+ ancestors: [parentAncestor, ...parent.ancestors],
61
+ channelType,
62
+ scope: "thread",
63
+ parentId: channelId,
64
+ parentSlug: parent.channelSlug,
65
+ ...channelName ? { channelName } : {},
66
+ ...parent.channelName ? { parentName: parent.channelName } : {}
67
+ };
68
+ if (!params.isAllowed(target)) continue;
69
+ threads.push(thread);
70
+ threadIds.add(id);
71
+ }
72
+ return {
73
+ threads,
74
+ members: response.members.filter((member) => {
75
+ const id = readDiscordChannelStringField(member, "id");
76
+ return id !== void 0 && threadIds.has(id);
77
+ })
78
+ };
79
+ }
80
+ //#endregion
19
81
  //#region extensions/discord/src/actions/runtime.shared.ts
20
82
  /** Discord REST auto_archive_duration allowlist (minutes). */
21
83
  const DISCORD_AUTO_ARCHIVE_MINUTES = /* @__PURE__ */ new Set([
@@ -25,8 +87,7 @@ const DISCORD_AUTO_ARCHIVE_MINUTES = /* @__PURE__ */ new Set([
25
87
  10080
26
88
  ]);
27
89
  function readDiscordParentIdParam(params) {
28
- if (params.clearParent === true) return null;
29
- if (params.parentId === null) return null;
90
+ if (params.clearParent === true || params.parentId === null) return null;
30
91
  return readStringParam(params, "parentId");
31
92
  }
32
93
  /**
@@ -51,10 +112,10 @@ function readDiscordChannelCreateParams(params) {
51
112
  return {
52
113
  guildId: readStringParam(params, "guildId", { required: true }),
53
114
  name: readStringParam(params, "name", { required: true }),
54
- type: readNonNegativeIntegerParam(params, "channelType") ?? readNonNegativeIntegerParam(params, "type") ?? void 0,
115
+ type: readNonNegativeIntegerParam(params, "channelType") ?? readNonNegativeIntegerParam(params, "type"),
55
116
  parentId: parentId ?? void 0,
56
- topic: readStringParam(params, "topic") ?? void 0,
57
- position: readNonNegativeIntegerParam(params, "position") ?? void 0,
117
+ topic: readStringParam(params, "topic"),
118
+ position: readNonNegativeIntegerParam(params, "position"),
58
119
  nsfw: asBoolean(params.nsfw)
59
120
  };
60
121
  }
@@ -62,12 +123,12 @@ function readDiscordChannelEditParams(params) {
62
123
  const parentId = readDiscordParentIdParam(params);
63
124
  return {
64
125
  channelId: readStringParam(params, "channelId", { required: true }),
65
- name: readStringParam(params, "name") ?? void 0,
66
- topic: readStringParam(params, "topic") ?? void 0,
67
- position: readNonNegativeIntegerParam(params, "position") ?? void 0,
68
- parentId: parentId === void 0 ? void 0 : parentId,
126
+ name: readStringParam(params, "name"),
127
+ topic: readStringParam(params, "topic"),
128
+ position: readNonNegativeIntegerParam(params, "position"),
129
+ parentId,
69
130
  nsfw: asBoolean(params.nsfw),
70
- rateLimitPerUser: readNonNegativeIntegerParam(params, "rateLimitPerUser") ?? void 0,
131
+ rateLimitPerUser: readNonNegativeIntegerParam(params, "rateLimitPerUser"),
71
132
  archived: asBoolean(params.archived),
72
133
  locked: asBoolean(params.locked),
73
134
  autoArchiveDuration: readDiscordAutoArchiveDurationParam(params, "autoArchiveDuration"),
@@ -79,15 +140,12 @@ function readDiscordChannelMoveParams(params) {
79
140
  return {
80
141
  guildId: readStringParam(params, "guildId", { required: true }),
81
142
  channelId: readStringParam(params, "channelId", { required: true }),
82
- parentId: parentId === void 0 ? void 0 : parentId,
83
- position: readNonNegativeIntegerParam(params, "position") ?? void 0
143
+ parentId,
144
+ position: readNonNegativeIntegerParam(params, "position")
84
145
  };
85
146
  }
86
147
  //#endregion
87
148
  //#region extensions/discord/src/actions/runtime.messaging.shared.ts
88
- function hasDiscordGuildEntries(guilds) {
89
- return Boolean(guilds && Object.keys(guilds).length > 0);
90
- }
91
149
  function allowsAllDiscordGuildChannels(channels) {
92
150
  const wildcard = channels?.["*"];
93
151
  if (!wildcard || wildcard.enabled === false) return false;
@@ -157,21 +215,34 @@ async function resolveDiscordReadAncestry(params) {
157
215
  complete: !parentId
158
216
  };
159
217
  }
160
- function readDiscordChannelStringField(value, ...keys) {
161
- if (!value || typeof value !== "object") return;
162
- const record = value;
163
- for (const key of keys) {
164
- const candidate = record[key];
165
- if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
218
+ async function buildDiscordReadTarget(params) {
219
+ const channelName = readDiscordChannelStringField(params.channelInfo, "name");
220
+ const channelType = readDiscordChannelType(params.channelInfo);
221
+ const target = {
222
+ channelId: params.channelId,
223
+ channelSlug: channelName ? normalizeDiscordSlug(channelName) : params.fallbackSlug,
224
+ metadataKnown: true,
225
+ ancestryComplete: true,
226
+ ancestors: [],
227
+ ...params.guildId ? { guildId: params.guildId } : {},
228
+ ...channelName ? { channelName } : {},
229
+ ...channelType !== void 0 ? { channelType } : {},
230
+ ...isDiscordThreadChannel(params.channelInfo) ? { scope: "thread" } : {}
231
+ };
232
+ const ancestry = await resolveDiscordReadAncestry({
233
+ channelId: params.channelId,
234
+ parentId: readDiscordChannelStringField(params.channelInfo, "parent_id", "parentId"),
235
+ loadChannel: params.loadChannel
236
+ });
237
+ target.ancestors = ancestry.ancestors;
238
+ target.ancestryComplete = ancestry.complete;
239
+ const immediateParent = target.ancestors[0];
240
+ if (immediateParent) {
241
+ target.parentId = immediateParent.channelId;
242
+ if (immediateParent.channelName) target.parentName = immediateParent.channelName;
243
+ target.parentSlug = immediateParent.channelSlug;
166
244
  }
167
- }
168
- function readDiscordChannelType(value) {
169
- if (!value || typeof value !== "object") return;
170
- const type = value.type;
171
- return typeof type === "number" ? type : void 0;
172
- }
173
- function isDiscordThreadChannel(value) {
174
- return isDiscordThreadChannelType(readDiscordChannelType(value));
245
+ return target;
175
246
  }
176
247
  function isDiscordReadAncestryAllowed(params) {
177
248
  for (const ancestor of params.target.ancestors) {
@@ -192,19 +263,13 @@ function isDiscordReadTargetAllowedInGuild(params) {
192
263
  }
193
264
  if (!isDiscordReadAncestryAllowed(params)) return false;
194
265
  if (resolveDiscordChannelConfigWithFallback({
195
- guildInfo: params.guildInfo,
196
- channelId: params.target.channelId,
197
- channelName: params.target.channelName,
198
- channelSlug: params.target.channelSlug,
199
- parentId: params.target.parentId,
200
- parentName: params.target.parentName,
201
- parentSlug: params.target.parentSlug,
202
- scope: params.target.scope
266
+ ...params.target,
267
+ guildInfo: params.guildInfo
203
268
  })?.allowed === false) return false;
204
269
  return isDiscordGroupAllowedByPolicy({
205
270
  groupPolicy: params.groupPolicy,
206
271
  guildAllowlisted: Boolean(params.guildInfo),
207
- channelAllowlistConfigured: hasDiscordGuildEntries(params.guildInfo?.channels),
272
+ channelAllowlistConfigured: hasConfiguredDiscordChannels(params.guildInfo?.channels),
208
273
  channelAllowed: true
209
274
  });
210
275
  }
@@ -303,23 +368,11 @@ function createDiscordMessagingActionContext(params) {
303
368
  } catch {
304
369
  return fallback;
305
370
  }
306
- const channelName = readDiscordChannelStringField(channelInfo, "name");
307
- const target = {
308
- channelId,
309
- channelSlug: channelName ? normalizeDiscordSlug(channelName) : fallback.channelSlug,
310
- metadataKnown: true,
311
- ancestryComplete: true,
312
- ancestors: []
313
- };
314
- const channelType = readDiscordChannelType(channelInfo);
315
- if (channelType !== void 0) target.channelType = channelType;
316
- const targetGuildId = readDiscordChannelStringField(channelInfo, "guild_id", "guildId");
317
- if (targetGuildId) target.guildId = targetGuildId;
318
- if (channelName) target.channelName = channelName;
319
- if (isDiscordThreadChannel(channelInfo)) target.scope = "thread";
320
- const ancestry = await resolveDiscordReadAncestry({
371
+ return buildDiscordReadTarget({
321
372
  channelId,
322
- parentId: readDiscordChannelStringField(channelInfo, "parent_id", "parentId"),
373
+ channelInfo,
374
+ guildId: readDiscordChannelStringField(channelInfo, "guild_id", "guildId"),
375
+ fallbackSlug: fallback.channelSlug,
323
376
  loadChannel: async (parentId) => {
324
377
  try {
325
378
  return await fetchChannelInfoDiscord(parentId, withOpts());
@@ -328,14 +381,6 @@ function createDiscordMessagingActionContext(params) {
328
381
  }
329
382
  }
330
383
  });
331
- target.ancestors = ancestry.ancestors;
332
- target.ancestryComplete = ancestry.complete;
333
- const immediateParent = target.ancestors[0];
334
- if (!immediateParent) return target;
335
- target.parentId = immediateParent.channelId;
336
- if (immediateParent.channelName) target.parentName = immediateParent.channelName;
337
- target.parentSlug = immediateParent.channelSlug;
338
- return target;
339
384
  };
340
385
  const isExpandedReadTargetEnabled = (guildInfo, target, currentConversation) => {
341
386
  const groupDmEnabled = accountConfig.dm?.groupEnabled === true && (currentConversation || resolveGroupDmAllow({
@@ -356,14 +401,8 @@ function createDiscordMessagingActionContext(params) {
356
401
  target
357
402
  })) return false;
358
403
  const channelConfig = resolveDiscordChannelConfigWithFallback({
359
- guildInfo,
360
- channelId: target.channelId,
361
- channelName: target.channelName,
362
- channelSlug: target.channelSlug,
363
- parentId: target.parentId,
364
- parentName: target.parentName,
365
- parentSlug: target.parentSlug,
366
- scope: target.scope
404
+ ...target,
405
+ guildInfo
367
406
  });
368
407
  return !channelConfig?.matchSource || channelConfig.allowed;
369
408
  };
@@ -376,9 +415,10 @@ function createDiscordMessagingActionContext(params) {
376
415
  options: params.options,
377
416
  accountId,
378
417
  resolveChannelId: () => resolveDiscordChannelId(readStringParam(params.input, "channelId", { required: true })),
379
- assertReadTargetAllowed: async ({ guildId, channelId }) => {
418
+ assertReadTargetAllowed: async ({ guildId, channelId, requireGuildMetadata }) => {
380
419
  const targetChannelId = resolveDiscordChannelId(channelId);
381
420
  const target = await resolveReadTargetContext(targetChannelId);
421
+ if (requireGuildMetadata && (!guildId || !target.metadataKnown || target.guildId !== guildId)) throw new Error("Discord active thread parent metadata is unavailable.");
382
422
  const currentConversation = isCurrentReadTarget(targetChannelId);
383
423
  if (guildId && target.metadataKnown && target.guildId !== guildId) throw new Error("Discord read target channel is not allowed.");
384
424
  const targetGuildId = guildId || target.guildId;
@@ -409,7 +449,23 @@ function createDiscordMessagingActionContext(params) {
409
449
  channelAllowlistConfigured: false,
410
450
  channelAllowed: true
411
451
  })) throw new Error("Discord read target channel is not allowed.");
412
- if (hasDiscordGuildEntries(guildInfo?.channels) && !allowsAllDiscordGuildChannels(guildInfo.channels)) throw new Error(channelTargetRequiredMessage ?? "Discord message search requires channelId or channelIds so each read target can be authorized.");
452
+ if (hasConfiguredDiscordChannels(guildInfo?.channels) && !allowsAllDiscordGuildChannels(guildInfo.channels)) throw new Error(channelTargetRequiredMessage ?? "Discord message search requires channelId or channelIds so each read target can be authorized.");
453
+ },
454
+ filterActiveThreadList: async ({ guildId, channelId, value }) => {
455
+ const parent = await resolveReadTargetContext(channelId);
456
+ if (!parent.metadataKnown || parent.guildId !== guildId) throw new Error("Discord active thread parent metadata is unavailable.");
457
+ const guildInfo = await resolveReadGuildEntry(guildId);
458
+ return filterDiscordActiveThreadList({
459
+ value,
460
+ guildId,
461
+ channelId,
462
+ parent,
463
+ isAllowed: (target) => directOperator && isExpandedReadTargetEnabled(guildInfo, target, false) || isCurrentReadTarget(target.channelId) && isExpandedReadTargetEnabled(guildInfo, target, true) || isDiscordReadTargetAllowedInGuild({
464
+ groupPolicy,
465
+ guildInfo,
466
+ target
467
+ })
468
+ });
413
469
  },
414
470
  filterGuildChannelList: async ({ guildId, channels }) => {
415
471
  if (!directOperator) return channels;
@@ -422,45 +478,20 @@ function createDiscordMessagingActionContext(params) {
422
478
  for (const channel of channels) {
423
479
  const channelId = readDiscordChannelStringField(channel, "id");
424
480
  if (!channelId) continue;
425
- const channelName = readDiscordChannelStringField(channel, "name");
426
- const channelType = readDiscordChannelType(channel);
427
- const target = {
481
+ const target = await buildDiscordReadTarget({
428
482
  channelId,
429
- channelSlug: channelName ? normalizeDiscordSlug(channelName) : channelId,
483
+ channelInfo: channel,
430
484
  guildId,
431
- metadataKnown: true,
432
- ancestryComplete: true,
433
- ancestors: [],
434
- ...channelName ? { channelName } : {},
435
- ...channelType !== void 0 ? { channelType } : {},
436
- ...isDiscordThreadChannel(channel) ? { scope: "thread" } : {}
437
- };
438
- const ancestry = await resolveDiscordReadAncestry({
439
- channelId,
440
- parentId: readDiscordChannelStringField(channel, "parent_id", "parentId"),
485
+ fallbackSlug: channelId,
441
486
  loadChannel: async (parentId) => channelById.get(parentId)
442
487
  });
443
- target.ancestors = ancestry.ancestors;
444
- target.ancestryComplete = ancestry.complete;
445
- const immediateParent = target.ancestors[0];
446
- if (immediateParent) {
447
- target.parentId = immediateParent.channelId;
448
- if (immediateParent.channelName) target.parentName = immediateParent.channelName;
449
- target.parentSlug = immediateParent.channelSlug;
450
- }
451
488
  if (!isDiscordReadAncestryAllowed({
452
489
  guildInfo,
453
490
  target
454
491
  })) continue;
455
492
  const channelConfig = resolveDiscordChannelConfigWithFallback({
456
- guildInfo,
457
- channelId,
458
- channelName,
459
- channelSlug: target.channelSlug,
460
- parentId: target.parentId,
461
- parentName: target.parentName,
462
- parentSlug: target.parentSlug,
463
- scope: target.scope
493
+ ...target,
494
+ guildInfo
464
495
  });
465
496
  if (!channelConfig?.matchSource || channelConfig.allowed) visibleChannels.push(channel);
466
497
  }
@@ -578,7 +609,6 @@ async function resolveGuildIdForGuildAdminAction(params) {
578
609
  return "guild_id" in channel ? channel.guild_id ?? void 0 : void 0;
579
610
  }
580
611
  function readChannelScopedPermissionTargetId(action, values) {
581
- if (action === "eventCreate") return readStringParam(values, "channelId");
582
612
  if (action === "categoryEdit" || action === "categoryDelete") return readStringParam(values, "categoryId");
583
613
  return readStringParam(values, "channelId");
584
614
  }
@@ -690,14 +720,16 @@ async function handleDiscordGuildAction(action, params, isActionEnabled, cfg, op
690
720
  } : {}
691
721
  });
692
722
  }
693
- case "roleInfo": {
694
- if (!isActionEnabled("roleInfo")) throw new Error("Discord role info is disabled.");
723
+ case "roleInfo":
724
+ case "eventList": {
725
+ const roleInfo = action === "roleInfo";
726
+ if (!isActionEnabled(roleInfo ? "roleInfo" : "events")) throw new Error(roleInfo ? "Discord role info is disabled." : "Discord events are disabled.");
695
727
  const guildId = readStringParam(params, "guildId", { required: true });
696
728
  await assertGuildMetadataReadAllowed(guildId);
697
- const roles = await fetchRoleInfoDiscord(guildId, withOpts());
729
+ const read = roleInfo ? fetchRoleInfoDiscord : listScheduledEventsDiscord;
698
730
  return jsonResult({
699
731
  ok: true,
700
- roles
732
+ [roleInfo ? "roles" : "events"]: await read(guildId, withOpts())
701
733
  });
702
734
  }
703
735
  case "emojiList": {
@@ -723,15 +755,15 @@ async function handleDiscordGuildAction(action, params, isActionEnabled, cfg, op
723
755
  });
724
756
  }
725
757
  case "emojiUpload": {
726
- const guildId = readStringParam(params, "guildId", { required: true });
727
- const name = readStringParam(params, "name", { required: true });
728
- const mediaUrl = readStringParam(params, "mediaUrl", { required: true });
729
- const roleIds = readStringArrayParam(params, "roleIds");
758
+ const upload = {
759
+ guildId: readStringParam(params, "guildId", { required: true }),
760
+ name: readStringParam(params, "name", { required: true }),
761
+ mediaUrl: readStringParam(params, "mediaUrl", { required: true }),
762
+ roleIds: readStringArrayParam(params, "roleIds")
763
+ };
730
764
  const emoji = await uploadEmojiDiscord({
731
- guildId,
732
- name,
733
- mediaUrl,
734
- roleIds: roleIds?.length ? roleIds : void 0
765
+ ...upload,
766
+ roleIds: upload.roleIds?.length ? upload.roleIds : void 0
735
767
  }, createDiscordActionOptions({
736
768
  cfg,
737
769
  accountId,
@@ -743,17 +775,12 @@ async function handleDiscordGuildAction(action, params, isActionEnabled, cfg, op
743
775
  });
744
776
  }
745
777
  case "stickerUpload": {
746
- const guildId = readStringParam(params, "guildId", { required: true });
747
- const name = readStringParam(params, "name", { required: true });
748
- const description = readStringParam(params, "description", { required: true });
749
- const tags = readStringParam(params, "tags", { required: true });
750
- const mediaUrl = readStringParam(params, "mediaUrl", { required: true });
751
778
  const sticker = await uploadStickerDiscord({
752
- guildId,
753
- name,
754
- description,
755
- tags,
756
- mediaUrl
779
+ guildId: readStringParam(params, "guildId", { required: true }),
780
+ name: readStringParam(params, "name", { required: true }),
781
+ description: readStringParam(params, "description", { required: true }),
782
+ tags: readStringParam(params, "tags", { required: true }),
783
+ mediaUrl: readStringParam(params, "mediaUrl", { required: true })
757
784
  }, createDiscordActionOptions({
758
785
  cfg,
759
786
  accountId,
@@ -811,16 +838,6 @@ async function handleDiscordGuildAction(action, params, isActionEnabled, cfg, op
811
838
  voice
812
839
  });
813
840
  }
814
- case "eventList": {
815
- if (!isActionEnabled("events")) throw new Error("Discord events are disabled.");
816
- const guildId = readStringParam(params, "guildId", { required: true });
817
- await assertGuildMetadataReadAllowed(guildId);
818
- const events = await listScheduledEventsDiscord(guildId, withOpts());
819
- return jsonResult({
820
- ok: true,
821
- events
822
- });
823
- }
824
841
  case "eventCreate": {
825
842
  const guildId = readStringParam(params, "guildId", { required: true });
826
843
  const name = readStringParam(params, "name", { required: true });
@@ -1001,21 +1018,15 @@ async function handleDiscordMessageManagementAction(ctx) {
1001
1018
  message
1002
1019
  });
1003
1020
  }
1004
- case "deleteMessage": {
1005
- if (!ctx.isActionEnabled("messages")) throw new Error("Discord message deletes are disabled.");
1006
- const channelId = ctx.resolveChannelId();
1007
- const messageId = readStringParam(ctx.params, "messageId", { required: true });
1008
- await ctx.assertReadTargetAllowed({ channelId });
1009
- await deleteMessageDiscord(channelId, messageId, ctx.withOpts());
1010
- return jsonResult({ ok: true });
1011
- }
1021
+ case "deleteMessage":
1012
1022
  case "pinMessage":
1013
1023
  case "unpinMessage": {
1014
- if (!ctx.isActionEnabled("pins")) throw new Error("Discord pins are disabled.");
1024
+ const deleting = ctx.action === "deleteMessage";
1025
+ if (!ctx.isActionEnabled(deleting ? "messages" : "pins")) throw new Error(deleting ? "Discord message deletes are disabled." : "Discord pins are disabled.");
1015
1026
  const channelId = ctx.resolveChannelId();
1016
1027
  const messageId = readStringParam(ctx.params, "messageId", { required: true });
1017
1028
  await ctx.assertReadTargetAllowed({ channelId });
1018
- await (ctx.action === "pinMessage" ? pinMessageDiscord : unpinMessageDiscord)(channelId, messageId, ctx.withOpts());
1029
+ await (deleting ? deleteMessageDiscord : ctx.action === "pinMessage" ? pinMessageDiscord : unpinMessageDiscord)(channelId, messageId, ctx.withOpts());
1019
1030
  return jsonResult({ ok: true });
1020
1031
  }
1021
1032
  case "listPins": {
@@ -1087,13 +1098,6 @@ async function handleDiscordReactionMessagingAction(ctx) {
1087
1098
  const messageId = readStringParam(ctx.params, "messageId", { required: true });
1088
1099
  const { emoji, remove, isEmpty } = readReactionParams(ctx.params, { removeErrorMessage: "Emoji is required to remove a Discord reaction." });
1089
1100
  await ctx.assertReadTargetAllowed({ channelId });
1090
- if (remove) {
1091
- await removeReactionDiscord(channelId, messageId, emoji, ctx.withReactionRuntimeOptions());
1092
- return jsonResult({
1093
- ok: true,
1094
- removed: emoji
1095
- });
1096
- }
1097
1101
  if (isEmpty) {
1098
1102
  const removed = await removeOwnReactionsDiscord(channelId, messageId, ctx.withReactionRuntimeOptions());
1099
1103
  return jsonResult({
@@ -1101,10 +1105,10 @@ async function handleDiscordReactionMessagingAction(ctx) {
1101
1105
  removed: removed.removed
1102
1106
  });
1103
1107
  }
1104
- await reactMessageDiscord(channelId, messageId, emoji, ctx.withReactionRuntimeOptions());
1108
+ await (remove ? removeReactionDiscord : reactMessageDiscord)(channelId, messageId, emoji, ctx.withReactionRuntimeOptions());
1105
1109
  return jsonResult({
1106
1110
  ok: true,
1107
- added: emoji
1111
+ [remove ? "removed" : "added"]: emoji
1108
1112
  });
1109
1113
  }
1110
1114
  case "reactions": {
@@ -1241,6 +1245,15 @@ async function handleDiscordMessageSendAction(ctx) {
1241
1245
  const threadName = readStringParam(ctx.params, "threadName");
1242
1246
  const sessionKey = readStringParam(ctx.params, "__sessionKey");
1243
1247
  const agentId = readStringParam(ctx.params, "__agentId");
1248
+ const sendOptions = {
1249
+ ...ctx.withOpts(),
1250
+ reply: resolveActionReplyReference(ctx, replyTo),
1251
+ silent,
1252
+ mediaAccess: ctx.options?.mediaAccess,
1253
+ mediaLocalRoots: ctx.options?.mediaLocalRoots,
1254
+ mediaReadFile: ctx.options?.mediaReadFile
1255
+ };
1256
+ let result;
1244
1257
  if (componentSpec) {
1245
1258
  if (asVoice) throw new Error("Discord components cannot be sent as voice messages.");
1246
1259
  if (embeds?.length) throw new Error("Discord components cannot include embeds.");
@@ -1249,70 +1262,34 @@ async function handleDiscordMessageSendAction(ctx) {
1249
1262
  ...componentSpec,
1250
1263
  text: normalizedContent
1251
1264
  };
1252
- const result = await sendDiscordComponentMessage(to, payload, {
1253
- ...ctx.withOpts(),
1254
- silent,
1255
- reply: resolveActionReplyReference(ctx, replyTo),
1256
- sessionKey: sessionKey ?? void 0,
1257
- agentId: agentId ?? void 0,
1258
- mediaUrl: mediaUrl ?? void 0,
1259
- filename: filename ?? void 0,
1260
- mediaAccess: ctx.options?.mediaAccess,
1261
- mediaLocalRoots: ctx.options?.mediaLocalRoots,
1262
- mediaReadFile: ctx.options?.mediaReadFile,
1265
+ result = await sendDiscordComponentMessage(to, payload, {
1266
+ ...sendOptions,
1267
+ sessionKey,
1268
+ agentId,
1269
+ mediaUrl,
1270
+ filename,
1263
1271
  ...suppressEmbeds === void 0 ? {} : { suppressEmbeds }
1264
1272
  });
1265
- return jsonResult(await appendDiscordThreadRenameResult(ctx, {
1266
- payload: {
1267
- ok: true,
1268
- result,
1269
- components: true
1270
- },
1271
- target: result.receipt?.threadId ?? to,
1272
- threadName
1273
- }));
1274
- }
1275
- if (asVoice) {
1273
+ } else if (asVoice) {
1276
1274
  if (!mediaUrl) throw new Error("Voice messages require a media file reference (mediaUrl, path, or filePath).");
1277
1275
  if (content && content.trim()) throw new Error("Voice messages cannot include text content (Discord limitation). Remove the content parameter.");
1278
1276
  assertMediaNotDataUrl(mediaUrl);
1279
- const result = await sendVoiceMessageDiscord(to, mediaUrl, {
1280
- ...ctx.withOpts(),
1281
- reply: resolveActionReplyReference(ctx, replyTo),
1282
- silent,
1283
- mediaAccess: ctx.options?.mediaAccess,
1284
- mediaLocalRoots: ctx.options?.mediaLocalRoots,
1285
- mediaReadFile: ctx.options?.mediaReadFile
1286
- });
1287
- return jsonResult(await appendDiscordThreadRenameResult(ctx, {
1288
- payload: {
1289
- ok: true,
1290
- result,
1291
- voiceMessage: true
1292
- },
1293
- target: to,
1294
- threadName
1295
- }));
1296
- }
1297
- const result = await sendMessageDiscord(to, content ?? "", {
1298
- ...ctx.withOpts(),
1299
- mediaAccess: ctx.options?.mediaAccess,
1277
+ result = await sendVoiceMessageDiscord(to, mediaUrl, sendOptions);
1278
+ } else result = await sendMessageDiscord(to, content ?? "", {
1279
+ ...sendOptions,
1300
1280
  mediaUrl,
1301
- filename: filename ?? void 0,
1302
- mediaLocalRoots: ctx.options?.mediaLocalRoots,
1303
- mediaReadFile: ctx.options?.mediaReadFile,
1304
- reply: resolveActionReplyReference(ctx, replyTo),
1281
+ filename,
1305
1282
  components,
1306
1283
  embeds,
1307
- silent,
1308
1284
  ...suppressEmbeds === void 0 ? {} : { suppressEmbeds }
1309
1285
  });
1310
1286
  return jsonResult(await appendDiscordThreadRenameResult(ctx, {
1311
1287
  payload: {
1312
1288
  ok: true,
1313
- result
1289
+ result,
1290
+ ...componentSpec ? { components: true } : asVoice ? { voiceMessage: true } : {}
1314
1291
  },
1315
- target: result.receipt?.threadId ?? to,
1292
+ target: asVoice ? to : result.receipt?.threadId ?? to,
1316
1293
  threadName
1317
1294
  }));
1318
1295
  }
@@ -1357,25 +1334,32 @@ async function handleDiscordMessageSendAction(ctx) {
1357
1334
  case "threadList": {
1358
1335
  if (!ctx.isActionEnabled("threads")) throw new Error("Discord threads are disabled.");
1359
1336
  const guildId = readStringParam(ctx.params, "guildId", { required: true });
1360
- const channelId = readStringParam(ctx.params, "channelId");
1337
+ const rawChannelId = readStringParam(ctx.params, "channelId");
1338
+ const channelId = rawChannelId ? resolveDiscordChannelId(rawChannelId) : void 0;
1361
1339
  const includeArchived = readBooleanParam(ctx.params, "includeArchived");
1362
1340
  const before = readStringParam(ctx.params, "before");
1363
1341
  const limit = readPositiveIntegerParam(ctx.params, "limit");
1364
- if (channelId && includeArchived === true) await ctx.assertReadTargetAllowed({
1342
+ if (channelId) await ctx.assertReadTargetAllowed({
1365
1343
  guildId,
1366
- channelId
1344
+ channelId,
1345
+ requireGuildMetadata: includeArchived !== true
1367
1346
  });
1368
1347
  else await ctx.assertGuildReadTargetAllowed({
1369
1348
  guildId,
1370
1349
  channelTargetRequiredMessage: "Discord active thread lists require a wildcard channel allowlist so each read target can be authorized."
1371
1350
  });
1372
- const threads = await listThreadsDiscord({
1351
+ const response = await listThreadsDiscord({
1373
1352
  guildId,
1374
1353
  channelId,
1375
1354
  includeArchived,
1376
1355
  before,
1377
1356
  limit
1378
1357
  }, ctx.withOpts());
1358
+ const threads = channelId && includeArchived !== true ? await ctx.filterActiveThreadList({
1359
+ guildId,
1360
+ channelId,
1361
+ value: response
1362
+ }) : response;
1379
1363
  return jsonResult(normalizeDiscordThreadListActionResult({
1380
1364
  value: threads,
1381
1365
  guildId,
@@ -1481,37 +1465,31 @@ async function handleDiscordModerationAction(action, params, isActionEnabled, cf
1481
1465
  accountId,
1482
1466
  cfg
1483
1467
  });
1484
- switch (command.action) {
1485
- case "timeout": {
1486
- const member = await timeoutMemberDiscord({
1487
- guildId: command.guildId,
1488
- userId: command.userId,
1489
- durationMinutes: command.durationMinutes,
1490
- until: command.until,
1491
- reason: command.reason
1492
- }, withOpts());
1493
- return jsonResult({
1494
- ok: true,
1495
- member
1496
- });
1497
- }
1498
- case "kick":
1499
- await kickMemberDiscord({
1500
- guildId: command.guildId,
1501
- userId: command.userId,
1502
- reason: command.reason
1503
- }, withOpts());
1504
- return jsonResult({ ok: true });
1505
- case "ban":
1506
- await banMemberDiscord({
1507
- guildId: command.guildId,
1508
- userId: command.userId,
1509
- reason: command.reason,
1510
- deleteMessageDays: command.deleteMessageDays
1511
- }, withOpts());
1512
- return jsonResult({ ok: true });
1468
+ const target = {
1469
+ guildId: command.guildId,
1470
+ userId: command.userId,
1471
+ reason: command.reason
1472
+ };
1473
+ if (command.action === "timeout") {
1474
+ const member = await timeoutMemberDiscord({
1475
+ ...target,
1476
+ durationMinutes: command.durationMinutes,
1477
+ until: command.until
1478
+ }, withOpts());
1479
+ return jsonResult({
1480
+ ok: true,
1481
+ member
1482
+ });
1513
1483
  }
1514
- throw new Error("Unsupported Discord moderation action");
1484
+ if (command.action === "kick") {
1485
+ await kickMemberDiscord(target, withOpts());
1486
+ return jsonResult({ ok: true });
1487
+ }
1488
+ await banMemberDiscord({
1489
+ ...target,
1490
+ deleteMessageDays: command.deleteMessageDays
1491
+ }, withOpts());
1492
+ return jsonResult({ ok: true });
1515
1493
  }
1516
1494
  //#endregion
1517
1495
  //#region extensions/discord/src/actions/runtime.presence.ts
@@ -1618,11 +1596,6 @@ const guildActions = /* @__PURE__ */ new Set([
1618
1596
  "channelPermissionSet",
1619
1597
  "channelPermissionRemove"
1620
1598
  ]);
1621
- const moderationActions = /* @__PURE__ */ new Set([
1622
- "timeout",
1623
- "kick",
1624
- "ban"
1625
- ]);
1626
1599
  async function handleDiscordAction(params, cfg, options) {
1627
1600
  const action = readStringParam(params, "action", { required: true });
1628
1601
  const accountId = readStringParam(params, "accountId");
@@ -1632,7 +1605,7 @@ async function handleDiscordAction(params, cfg, options) {
1632
1605
  });
1633
1606
  if (messagingActions.has(action)) return await handleDiscordMessagingAction(action, params, isActionEnabled, cfg, options);
1634
1607
  if (guildActions.has(action)) return await handleDiscordGuildAction(action, params, isActionEnabled, cfg, options);
1635
- if (moderationActions.has(action)) return await handleDiscordModerationAction(action, params, isActionEnabled, cfg);
1608
+ if (isDiscordModerationAction(action)) return await handleDiscordModerationAction(action, params, isActionEnabled, cfg);
1636
1609
  if (action === "setPresence") return await handleDiscordPresenceAction(action, params, isActionEnabled, cfg);
1637
1610
  throw new Error(`Unknown action: ${action}`);
1638
1611
  }