@openclaw/discord 2026.7.2-beta.7 → 2026.8.1-beta.3

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 (114) hide show
  1. package/dist/{account-inspect-SXiCBCgP.js → account-inspect-D5xmUpnj.js} +49 -43
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/accounts-DNl-oCEw.js +371 -0
  4. package/dist/action-runtime-api.js +1 -1
  5. package/dist/{active-turn-thread-route-MlKWp8RD.js → active-turn-thread-route-fmHl1HNd.js} +9 -11
  6. package/dist/{activities-api-DTKsuDxf.js → activities-api-KCBAmWxD.js} +133 -175
  7. package/dist/activities-api.js +1 -1
  8. package/dist/{allow-list-DzKrtfah.js → allow-list-BDMimASD.js} +2 -3
  9. package/dist/{api-DnrK9gML.js → api-DNVbJyEy.js} +7 -2
  10. package/dist/api.js +18 -18
  11. package/dist/{approval-handler.runtime-HymvFTYn.js → approval-handler.runtime-B12RCYr8.js} +6 -6
  12. package/dist/{approval-message-safety-DEyKVsAw.js → approval-message-safety-XGFPbDoI.js} +89 -3
  13. package/dist/{audit-CjsrabP8.js → audit-Yc7eZDd6.js} +5 -5
  14. package/dist/{channel-actions-uXFTJX3o.js → channel-actions-Dr2QI8Bf.js} +11 -7
  15. package/dist/{channel-actions.runtime-CIYU90sl.js → channel-actions.runtime-CODTvo7c.js} +99 -97
  16. package/dist/{channel-vKa-76xY.js → channel-cXYzGc4L.js} +102 -104
  17. package/dist/channel-config-api.js +1 -1
  18. package/dist/channel-plugin-api.js +1 -1
  19. package/dist/{channel.setup-CmcwZ_qd.js → channel.setup-CSiwnMgs.js} +16 -54
  20. package/dist/{outbound-session-route-H-HoyH5U.js → components-ezGKo_Yh.js} +69 -142
  21. package/dist/{config-schema-WHRQcY19.js → config-schema-DC5kDtQ5.js} +42 -11
  22. package/dist/conversation-binding-route-D6rCQ5S0.js +43 -0
  23. package/dist/{directory-config-D_LojtCe.js → directory-config-XyCfoqLg.js} +2 -2
  24. package/dist/directory-contract-api.js +1 -1
  25. package/dist/{directory-live-Bw5Ephzv.js → directory-live-Df0NbFJB.js} +7 -4
  26. package/dist/{doctor-Bc4S1qyd.js → doctor-DYY31GrO.js} +34 -13
  27. package/dist/{doctor-contract-CCFMIDk9.js → doctor-contract-DsWvKIXF.js} +2 -3
  28. package/dist/doctor-contract-api.js +147 -2
  29. package/dist/{handle-action.guild-admin-D6VRRW-C.js → handle-action.guild-admin-6Tvvinsa.js} +4 -7
  30. package/dist/{inbound-event-delivery-CEPlt2uz.js → inbound-event-delivery-De2qxTrP.js} +4 -25
  31. package/dist/index.js +5 -4
  32. package/dist/{message-handler-CeiSulIw.js → message-handler-B61q5MOF.js} +118 -33
  33. package/dist/{message-handler.preflight-DibgQFf2.js → message-handler.preflight-Bzg_Hawz.js} +75 -61
  34. package/dist/{message-handler.process-Dnc_oz9y.js → message-handler.process--4_712Ec.js} +236 -296
  35. package/dist/{message-utils-BgTwT_q7.js → message-utils-BXLLnFl6.js} +34 -35
  36. package/dist/{model-picker-preference-primitives-D25pnCOu.js → model-picker-preference-primitives-BHT1LkR_.js} +3 -3
  37. package/dist/{outbound-adapter-DtE-i2OJ.js → outbound-adapter-DxHTOqiN.js} +157 -68
  38. package/dist/{outbound-components-C7GVyfPh.js → outbound-components-B2PL0ooH.js} +3 -3
  39. package/dist/owner-access-Bg41VzAf.js +107 -0
  40. package/dist/{pluralkit-CD4B11JB.js → pluralkit-dUl4v1X3.js} +1 -1
  41. package/dist/{preflight-audio-BjnQZ5yS.js → preflight-audio-DrnqFA8U.js} +22 -28
  42. package/dist/{probe-BeWKhjqX.js → probe-BTdtVRwU.js} +37 -13
  43. package/dist/probe.runtime-Dq5-PRKT.js +2 -0
  44. package/dist/{provider-DfQJX3z5.js → provider-DlK_ynqt.js} +1131 -2021
  45. package/dist/{provider-session.runtime-Bo88k0pV.js → provider-session.runtime-CvvphHvs.js} +3 -3
  46. package/dist/provider.runtime-CzKGRiAF.js +2 -0
  47. package/dist/realtime-session.runtime-ysbMG8v7.js +1351 -0
  48. package/dist/{resolve-allowlist-common-DHERApxi.js → resolve-allowlist-common-DIVXbD1P.js} +3 -3
  49. package/dist/{resolve-channels-BjepAj8b.js → resolve-channels-CGeUoIqb.js} +4 -4
  50. package/dist/{resolve-users-Bc28htgt.js → resolve-users-BtKxLUZv.js} +3 -3
  51. package/dist/{chunk-DX4jpFQP.js → retry-DNsVTeTo.js} +308 -131
  52. package/dist/{runtime-BmW_j_hl.js → runtime-CQovMsH3.js} +12 -15
  53. package/dist/{runtime-_aRC6V2s.js → runtime-D71_VFLr.js} +49 -58
  54. package/dist/runtime-api.actions.js +2 -2
  55. package/dist/runtime-api.js +23 -23
  56. package/dist/runtime-api.lookup.js +5 -5
  57. package/dist/runtime-api.monitor-CzeTYF32.js +6 -0
  58. package/dist/runtime-api.monitor.js +6 -5
  59. package/dist/runtime-api.send.js +6 -6
  60. package/dist/runtime-api.threads.js +5 -6
  61. package/dist/sdk-runtime-37OU6_Yh.js +369 -0
  62. package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
  63. package/dist/secret-contract-api.js +1 -1
  64. package/dist/security-audit-contract-api.js +1 -1
  65. package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
  66. package/dist/{send-CdkZ6zeW.js → send-rQIffSYu.js} +180 -91
  67. package/dist/{send.components-5uqwkjgE.js → send.components-ChK1wS7w.js} +32 -46
  68. package/dist/{send.outbound-D-80Ej-t.js → send.outbound-HIkgji_7.js} +57 -34
  69. package/dist/{send.reactions-CtlmGd_o.js → send.reactions-gmJ6yFPo.js} +14 -21
  70. package/dist/{send.receipt-CuwRrpFz.js → send.receipt-Cnhoautb.js} +29 -1
  71. package/dist/{send.shared-jpvAG_u6.js → send.shared-B3fpaLWJ.js} +112 -181
  72. package/dist/{sender-identity-mG_zsdox.js → sender-identity-BJtfyise.js} +1 -1
  73. package/dist/setup-entry.js +0 -5
  74. package/dist/setup-plugin-api.js +1 -1
  75. package/dist/{shared-CXF1tup1.js → shared-CaAaoksy.js} +27 -23
  76. package/dist/subagent-hooks-CNT2ZJTJ.js +49 -0
  77. package/dist/subagent-hooks-api.js +2 -6
  78. package/dist/subagent-progress-FPLqBY1s.js +110 -0
  79. package/dist/{system-events-DdUqf91B.js → system-events-Nuwoq_au.js} +2 -2
  80. package/dist/{target-resolver-C3s_2m0t.js → target-resolver-DIXShHaZ.js} +3 -3
  81. package/dist/targets-B2pf49zc.js +3 -0
  82. package/dist/{thread-bindings-C-M-ly7P.js → thread-bindings-VlymUnbz.js} +29 -28
  83. package/dist/{thread-bindings.manager-DYvSlrva.js → thread-bindings.manager-CngsgErq.js} +258 -29
  84. package/dist/{thread-bindings.session-updates-DAIlp7Px.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
  85. package/dist/{thread-bindings.state-Cgi5uRn-.js → thread-bindings.state-D8OMdk4O.js} +3 -16
  86. package/dist/threading-DU6pgeGm.js +456 -0
  87. package/dist/transcripts-source-DeIMNbRh.js +265 -0
  88. package/dist/transcripts-source-api.js +7 -2
  89. package/dist/{typing--Mzo2kM7.js → typing-oLiS5Z13.js} +1 -1
  90. package/dist/voice-runtime-CjNFaynA.js +2549 -0
  91. package/openclaw.plugin.json +215 -25
  92. package/package.json +15 -11
  93. package/skills/discord/SKILL.md +22 -115
  94. package/dist/accounts-DJTf1LtA.js +0 -219
  95. package/dist/channel-api-CAJ0wMoV.js +0 -21
  96. package/dist/legacy-state-migrations-api.js +0 -138
  97. package/dist/manager.runtime-Bjav3pfC.js +0 -3655
  98. package/dist/preflight-audio.runtime-CoCXMM8r.js +0 -7
  99. package/dist/probe.runtime-DqFGFMbZ.js +0 -2
  100. package/dist/provider.runtime-Cy7XZmyh.js +0 -2
  101. package/dist/runtime-api.monitor-CCRubd3-.js +0 -5
  102. package/dist/session-binding-contract-api.js +0 -2
  103. package/dist/subagent-hooks-Dxy7Fmnq.js +0 -120
  104. package/dist/subagent-progress-DI3sYLLo.js +0 -664
  105. package/dist/targets-Dv_RN7vT.js +0 -3
  106. package/dist/thread-bindings.discord-api-BoDNqamb.js +0 -246
  107. package/dist/transcripts-source-DIKGsTGT.js +0 -123
  108. package/node_modules/p-map/index.d.ts +0 -155
  109. package/node_modules/p-map/index.js +0 -285
  110. package/node_modules/p-map/license +0 -9
  111. package/node_modules/p-map/package.json +0 -57
  112. package/node_modules/p-map/readme.md +0 -190
  113. package/dist/{audit-core-xwjIczO0.js → audit-core-BCX8UeFH.js} +1 -1
  114. package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
@@ -1,4 +1,4 @@
1
- import { a as mergeDiscordAccountConfig, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId } from "./accounts-DJTf1LtA.js";
1
+ import { o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId, u as resolveDiscordAccountConfig } from "./accounts-DNl-oCEw.js";
2
2
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
@@ -17,67 +17,73 @@ function inspectDiscordConfiguredToken(value) {
17
17
  };
18
18
  return null;
19
19
  }
20
- //#endregion
21
- //#region extensions/discord/src/account-inspect.ts
22
- function inspectDiscordAccount(params) {
23
- const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
24
- const merged = mergeDiscordAccountConfig(params.cfg, accountId);
25
- const enabled = params.cfg.channels?.discord?.enabled !== false && merged.enabled !== false;
26
- const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId);
27
- const hasAccountToken = Boolean(accountConfig && Object.hasOwn(accountConfig, "token"));
28
- const accountToken = inspectDiscordConfiguredToken(accountConfig?.token);
20
+ function inspectDiscordAccountTokenState(params) {
21
+ const accountToken = inspectDiscordConfiguredToken(params.accountToken);
29
22
  if (accountToken) return {
30
- accountId,
31
- enabled,
32
- name: normalizeOptionalString(merged.name),
33
- token: accountToken.token,
34
- tokenSource: accountToken.tokenSource,
35
- tokenStatus: accountToken.tokenStatus,
23
+ ...params.base,
24
+ ...accountToken,
36
25
  configured: true,
37
- config: merged
26
+ config: params.config
38
27
  };
39
- if (hasAccountToken) return {
40
- accountId,
41
- enabled,
42
- name: normalizeOptionalString(merged.name),
28
+ if (params.hasAccountToken) return {
29
+ ...params.base,
43
30
  token: "",
44
31
  tokenSource: "none",
45
32
  tokenStatus: "missing",
46
33
  configured: false,
47
- config: merged
34
+ config: params.config
48
35
  };
49
- const channelToken = inspectDiscordConfiguredToken(params.cfg.channels?.discord?.token);
36
+ const channelToken = inspectDiscordConfiguredToken(params.channelToken);
50
37
  if (channelToken) return {
51
- accountId,
52
- enabled,
53
- name: normalizeOptionalString(merged.name),
54
- token: channelToken.token,
55
- tokenSource: channelToken.tokenSource,
56
- tokenStatus: channelToken.tokenStatus,
38
+ ...params.base,
39
+ ...channelToken,
57
40
  configured: true,
58
- config: merged
41
+ config: params.config
59
42
  };
60
- const envToken = accountId === DEFAULT_ACCOUNT_ID ? normalizeSecretInputString(params.envToken ?? process.env.DISCORD_BOT_TOKEN) : void 0;
61
- if (envToken) return {
62
- accountId,
63
- enabled,
64
- name: normalizeOptionalString(merged.name),
65
- token: envToken.replace(/^Bot\s+/i, ""),
66
- tokenSource: "env",
43
+ const fallback = params.resolveFallbackToken();
44
+ if (fallback.token) return {
45
+ ...params.base,
46
+ token: fallback.token,
47
+ tokenSource: fallback.source,
67
48
  tokenStatus: "available",
68
49
  configured: true,
69
- config: merged
50
+ config: params.config
70
51
  };
71
52
  return {
72
- accountId,
73
- enabled,
74
- name: normalizeOptionalString(merged.name),
53
+ ...params.base,
75
54
  token: "",
76
55
  tokenSource: "none",
77
56
  tokenStatus: "missing",
78
57
  configured: false,
79
- config: merged
58
+ config: params.config
80
59
  };
81
60
  }
82
61
  //#endregion
83
- export { inspectDiscordConfiguredToken as n, inspectDiscordAccount as t };
62
+ //#region extensions/discord/src/account-inspect.ts
63
+ function inspectDiscordAccount(params) {
64
+ const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
65
+ const merged = mergeDiscordAccountConfig(params.cfg, accountId);
66
+ const enabled = params.cfg.channels?.discord?.enabled !== false && merged.enabled !== false;
67
+ const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId);
68
+ const hasAccountToken = Boolean(accountConfig && Object.hasOwn(accountConfig, "token"));
69
+ return inspectDiscordAccountTokenState({
70
+ base: {
71
+ accountId,
72
+ enabled,
73
+ name: normalizeOptionalString(merged.name)
74
+ },
75
+ config: merged,
76
+ accountToken: accountConfig?.token,
77
+ hasAccountToken,
78
+ channelToken: params.cfg.channels?.discord?.token,
79
+ resolveFallbackToken: () => {
80
+ const envToken = accountId === DEFAULT_ACCOUNT_ID ? normalizeSecretInputString(params.envToken ?? process.env.DISCORD_BOT_TOKEN) : void 0;
81
+ return {
82
+ token: envToken?.replace(/^Bot\s+/i, "") ?? "",
83
+ source: envToken ? "env" : "none"
84
+ };
85
+ }
86
+ });
87
+ }
88
+ //#endregion
89
+ export { inspectDiscordAccountTokenState as n, inspectDiscordAccount as t };
@@ -1,4 +1,4 @@
1
- import { t as inspectDiscordAccount } from "./account-inspect-SXiCBCgP.js";
1
+ import { t as inspectDiscordAccount } from "./account-inspect-D5xmUpnj.js";
2
2
  //#region extensions/discord/account-inspect-api.ts
3
3
  function inspectDiscordReadOnlyAccount(cfg, accountId) {
4
4
  return inspectDiscordAccount({
@@ -0,0 +1,371 @@
1
+ import "./config-schema-DC5kDtQ5.js";
2
+ import { createAccountActionGate, createAccountListHelpers } from "openclaw/plugin-sdk/account-helpers";
3
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
4
+ import { mapAllowFromEntries, normalizeChannelDmPolicy } from "openclaw/plugin-sdk/channel-config-helpers";
5
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, buildOutboundBaseSessionKey, normalizeAccountId as normalizeAccountId$1, resolveAccountEntry } from "openclaw/plugin-sdk/routing";
6
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
+ import { PAIRING_APPROVED_MESSAGE as PAIRING_APPROVED_MESSAGE$1, buildTokenChannelStatusSummary as buildTokenChannelStatusSummary$1, projectCredentialSnapshotFields as projectCredentialSnapshotFields$1, resolveConfiguredFromCredentialStatuses, resolveConfiguredFromCredentialStatuses as resolveConfiguredFromCredentialStatuses$1 } from "openclaw/plugin-sdk/channel-status";
8
+ import "openclaw/plugin-sdk/channel-config-schema";
9
+ import { normalizeResolvedSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
10
+ import { buildThreadAwareOutboundSessionRoute } from "openclaw/plugin-sdk/channel-core";
11
+ import { assertMediaNotDataUrl, jsonResult, parseAvailableTags, readNonNegativeIntegerParam, readPositiveIntegerParam, readReactionParams, readStringArrayParam, readStringParam, withNormalizedTimestamp } from "openclaw/plugin-sdk/channel-actions";
12
+ import { readBooleanParam as readBooleanParam$1 } from "openclaw/plugin-sdk/boolean-param";
13
+ import "openclaw/plugin-sdk/channel-plugin-common";
14
+ import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
15
+ import { buildMessagingTarget, parseMentionPrefixOrAtUserTarget, requireTargetKind } from "openclaw/plugin-sdk/channel-targets";
16
+ import { getRuntimeConfigSnapshot, getRuntimeConfigSourceSnapshot, selectApplicableRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
17
+ //#region extensions/discord/src/channel-api.ts
18
+ const DISCORD_CHANNEL_META = {
19
+ id: "discord",
20
+ label: "Discord",
21
+ selectionLabel: "Discord (Bot API)",
22
+ detailLabel: "Discord Bot",
23
+ docsPath: "/channels/discord",
24
+ docsLabel: "discord",
25
+ blurb: "very well supported right now.",
26
+ systemImage: "bubble.left.and.bubble.right",
27
+ markdownCapable: true,
28
+ preferSessionLookupForAnnounceTarget: true
29
+ };
30
+ function getChatChannelMeta(id) {
31
+ if (id !== DISCORD_CHANNEL_META.id) throw new Error(`Unsupported Discord channel meta lookup: ${id}`);
32
+ return DISCORD_CHANNEL_META;
33
+ }
34
+ //#endregion
35
+ //#region extensions/discord/src/target-parsing.ts
36
+ function parseDiscordTarget(raw, options = {}) {
37
+ const trimmed = raw.trim();
38
+ if (!trimmed) return;
39
+ const providerPrefixedTarget = parseDiscordProviderPrefixedTarget(trimmed);
40
+ if (providerPrefixedTarget) return providerPrefixedTarget;
41
+ const userTarget = parseMentionPrefixOrAtUserTarget({
42
+ raw: trimmed,
43
+ mentionPattern: /^<@!?(\d+)>$/,
44
+ prefixes: [
45
+ {
46
+ prefix: "user:",
47
+ kind: "user"
48
+ },
49
+ {
50
+ prefix: "channel:",
51
+ kind: "channel"
52
+ },
53
+ {
54
+ prefix: "discord:",
55
+ kind: "user"
56
+ }
57
+ ],
58
+ atUserPattern: /^\d+$/,
59
+ atUserErrorMessage: "Discord DMs require a user id (use user:<id> or a <@id> mention)"
60
+ });
61
+ if (userTarget) return userTarget;
62
+ if (/^\d+$/.test(trimmed)) {
63
+ if (options.defaultKind) return buildMessagingTarget(options.defaultKind, trimmed, trimmed);
64
+ throw new Error(options.ambiguousMessage ?? `Ambiguous Discord recipient "${trimmed}". For DMs use "user:${trimmed}" or "<@${trimmed}>"; for channels use "channel:${trimmed}".`);
65
+ }
66
+ return buildMessagingTarget("channel", trimmed, trimmed);
67
+ }
68
+ function parseDiscordProviderPrefixedTarget(raw) {
69
+ const match = /^discord:(channel|user):(.+)$/i.exec(raw);
70
+ if (!match) return;
71
+ const kind = match[1]?.toLowerCase();
72
+ const id = match[2]?.trim();
73
+ if (!kind || !id) return;
74
+ return buildMessagingTarget(kind, id, `${kind}:${id}`);
75
+ }
76
+ function resolveDiscordChannelId(raw) {
77
+ return requireTargetKind({
78
+ platform: "Discord",
79
+ target: parseDiscordTarget(raw, { defaultKind: "channel" }),
80
+ kind: "channel"
81
+ });
82
+ }
83
+ //#endregion
84
+ //#region extensions/discord/src/outbound-session-route.ts
85
+ function resolveDiscordOutboundSessionRoute(params) {
86
+ const parsed = parseDiscordTarget(params.target, { defaultKind: resolveDiscordOutboundTargetKindHint(params) });
87
+ if (!parsed) return null;
88
+ const explicitThreadId = params.threadId == null ? void 0 : String(params.threadId).trim();
89
+ const peerId = explicitThreadId || parsed.id;
90
+ const isDm = parsed.kind === "user" && !explicitThreadId;
91
+ const recipientSessionExact = /^\d+$/.test(peerId);
92
+ const peer = {
93
+ kind: isDm ? "direct" : "channel",
94
+ id: peerId
95
+ };
96
+ const baseSessionKey = buildOutboundBaseSessionKey({
97
+ cfg: params.cfg,
98
+ agentId: params.agentId,
99
+ channel: "discord",
100
+ accountId: params.accountId,
101
+ peer
102
+ });
103
+ return buildThreadAwareOutboundSessionRoute({
104
+ route: {
105
+ sessionKey: baseSessionKey,
106
+ baseSessionKey,
107
+ recipientSessionExact,
108
+ peer,
109
+ chatType: isDm ? "direct" : "channel",
110
+ from: isDm ? `discord:${peerId}` : `discord:channel:${peerId}`,
111
+ to: isDm ? `user:${peerId}` : `channel:${peerId}`
112
+ },
113
+ threadId: params.threadId,
114
+ precedence: ["threadId"],
115
+ useSuffix: false
116
+ });
117
+ }
118
+ function resolveDiscordOutboundTargetKindHint(params) {
119
+ const resolvedKind = params.resolvedTarget?.kind;
120
+ if (resolvedKind === "user") return "user";
121
+ if (resolvedKind === "group" || resolvedKind === "channel") return "channel";
122
+ const target = params.target.trim();
123
+ if (/^channel:/i.test(target)) return "channel";
124
+ if (/^(user:|discord:|@|<@!?)/i.test(target)) return "user";
125
+ return "channel";
126
+ }
127
+ //#endregion
128
+ //#region extensions/discord/src/runtime-config.ts
129
+ function selectDiscordRuntimeConfig(inputConfig) {
130
+ return selectApplicableRuntimeConfig({
131
+ inputConfig,
132
+ runtimeConfig: getRuntimeConfigSnapshot(),
133
+ runtimeSourceConfig: getRuntimeConfigSourceSnapshot()
134
+ }) ?? inputConfig;
135
+ }
136
+ function withSourceActivities(runtimeAccount, sourceAccount) {
137
+ const { activities: _runtimeActivities, ...runtimeRest } = runtimeAccount ?? {};
138
+ return {
139
+ ...runtimeRest,
140
+ ...sourceAccount?.activities ? { activities: sourceAccount.activities } : {}
141
+ };
142
+ }
143
+ /** Restores plugin-owned sensitive Activity config onto the resolved runtime shape. */
144
+ function selectDiscordActivitiesRuntimeConfig(inputConfig) {
145
+ const runtimeConfig = selectDiscordRuntimeConfig(inputConfig);
146
+ const sourceDiscord = getRuntimeConfigSourceSnapshot()?.channels?.discord;
147
+ if (!sourceDiscord) return runtimeConfig;
148
+ const runtimeDiscord = runtimeConfig.channels?.discord;
149
+ const accountIds = /* @__PURE__ */ new Set([...Object.keys(runtimeDiscord?.accounts ?? {}), ...Object.keys(sourceDiscord.accounts ?? {})]);
150
+ const accounts = Object.fromEntries([...accountIds].map((accountId) => [accountId, withSourceActivities(runtimeDiscord?.accounts?.[accountId], sourceDiscord.accounts?.[accountId])]));
151
+ return {
152
+ ...runtimeConfig,
153
+ channels: {
154
+ ...runtimeConfig.channels,
155
+ discord: {
156
+ ...withSourceActivities(runtimeDiscord, sourceDiscord),
157
+ ...accountIds.size > 0 ? { accounts } : {}
158
+ }
159
+ }
160
+ };
161
+ }
162
+ //#endregion
163
+ //#region extensions/discord/src/token.ts
164
+ function stripDiscordBotPrefix(token) {
165
+ return token.replace(/^Bot\s+/i, "");
166
+ }
167
+ function normalizeDiscordToken(raw, path) {
168
+ const trimmed = normalizeResolvedSecretInputString({
169
+ value: raw,
170
+ path
171
+ });
172
+ if (!trimmed) return;
173
+ return stripDiscordBotPrefix(trimmed);
174
+ }
175
+ function resolveDiscordTokenValue(params) {
176
+ const resolved = resolveSecretInputString({
177
+ value: params.value,
178
+ path: params.path,
179
+ defaults: params.cfg.secrets?.defaults,
180
+ mode: "inspect"
181
+ });
182
+ if (resolved.status === "available") return {
183
+ status: "available",
184
+ value: stripDiscordBotPrefix(resolved.value)
185
+ };
186
+ if (resolved.status === "configured_unavailable") return { status: "configured_unavailable" };
187
+ return { status: "missing" };
188
+ }
189
+ function resolveDiscordToken(cfg, opts = {}) {
190
+ const selectedCfg = selectDiscordRuntimeConfig(cfg);
191
+ const accountId = normalizeAccountId$1(opts.accountId);
192
+ const discordCfg = selectedCfg?.channels?.discord;
193
+ const accountCfg = resolveAccountEntry(discordCfg?.accounts, accountId);
194
+ const hasAccountToken = Boolean(accountCfg && Object.hasOwn(accountCfg, "token"));
195
+ const accountToken = resolveDiscordTokenValue({
196
+ cfg: selectedCfg,
197
+ value: accountCfg?.token,
198
+ path: `channels.discord.accounts.${accountId}.token`
199
+ });
200
+ if (accountToken.status === "available" && accountToken.value) return {
201
+ token: accountToken.value,
202
+ source: "config",
203
+ tokenStatus: "available"
204
+ };
205
+ if (accountToken.status === "configured_unavailable") return {
206
+ token: "",
207
+ source: "config",
208
+ tokenStatus: "configured_unavailable"
209
+ };
210
+ if (hasAccountToken) return {
211
+ token: "",
212
+ source: "none",
213
+ tokenStatus: "missing"
214
+ };
215
+ const configToken = resolveDiscordTokenValue({
216
+ cfg: selectedCfg,
217
+ value: discordCfg?.token,
218
+ path: "channels.discord.token"
219
+ });
220
+ if (configToken.status === "available" && configToken.value) return {
221
+ token: configToken.value,
222
+ source: "config",
223
+ tokenStatus: "available"
224
+ };
225
+ if (configToken.status === "configured_unavailable") return {
226
+ token: "",
227
+ source: "config",
228
+ tokenStatus: "configured_unavailable"
229
+ };
230
+ const envToken = accountId === DEFAULT_ACCOUNT_ID$1 ? normalizeDiscordToken(opts.envToken ?? process.env.DISCORD_BOT_TOKEN, "DISCORD_BOT_TOKEN") : void 0;
231
+ if (envToken) return {
232
+ token: envToken,
233
+ source: "env",
234
+ tokenStatus: "available"
235
+ };
236
+ return {
237
+ token: "",
238
+ source: "none",
239
+ tokenStatus: "missing"
240
+ };
241
+ }
242
+ //#endregion
243
+ //#region extensions/discord/src/accounts.ts
244
+ const { listAccountIds, resolveDefaultAccountId, resolveAccountConfig: resolveMergedDiscordAccountConfig } = createAccountListHelpers("discord", {
245
+ implicitDefaultAccount: {
246
+ channelKeys: ["token"],
247
+ envVars: ["DISCORD_BOT_TOKEN"]
248
+ },
249
+ nestedObjectKeys: [
250
+ "activities",
251
+ "agentComponents",
252
+ "botLoopProtection"
253
+ ]
254
+ });
255
+ const listDiscordAccountIds = listAccountIds;
256
+ const resolveDefaultDiscordAccountId = resolveDefaultAccountId;
257
+ function resolveDiscordAccountConfig(cfg, accountId) {
258
+ return resolveAccountEntry(cfg.channels?.discord?.accounts, accountId);
259
+ }
260
+ function mergeDiscordAccountConfig(cfg, accountId) {
261
+ return resolveMergedDiscordAccountConfig(cfg, accountId);
262
+ }
263
+ function resolveDiscordAccountAllowFrom(params) {
264
+ const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
265
+ const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId);
266
+ const rootConfig = params.cfg.channels?.discord;
267
+ const allowFrom = accountConfig?.allowFrom ?? rootConfig?.allowFrom;
268
+ return allowFrom ? mapAllowFromEntries(allowFrom) : void 0;
269
+ }
270
+ function resolveDiscordAccountDmPolicy(params) {
271
+ const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
272
+ const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId);
273
+ const rootConfig = params.cfg.channels?.discord;
274
+ return normalizeChannelDmPolicy(accountConfig?.dmPolicy ?? rootConfig?.dmPolicy ?? "pairing");
275
+ }
276
+ function createDiscordActionGate(params) {
277
+ const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
278
+ return createAccountActionGate({
279
+ baseActions: params.cfg.channels?.discord?.actions,
280
+ accountActions: resolveDiscordAccountConfig(params.cfg, accountId)?.actions
281
+ });
282
+ }
283
+ function resolveDiscordAccount(params) {
284
+ const cfg = selectDiscordRuntimeConfig(params.cfg);
285
+ const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(cfg));
286
+ const baseEnabled = cfg.channels?.discord?.enabled !== false;
287
+ const merged = mergeDiscordAccountConfig(cfg, accountId);
288
+ const accountEnabled = merged.enabled !== false;
289
+ const enabled = baseEnabled && accountEnabled;
290
+ const tokenResolution = resolveDiscordToken(cfg, { accountId });
291
+ return {
292
+ accountId,
293
+ enabled,
294
+ name: normalizeOptionalString(merged.name),
295
+ token: tokenResolution.token,
296
+ tokenSource: tokenResolution.source,
297
+ tokenStatus: tokenResolution.tokenStatus,
298
+ config: merged
299
+ };
300
+ }
301
+ function resolveDiscordMaxLinesPerMessage(params) {
302
+ if (typeof params.discordConfig?.maxLinesPerMessage === "number") return params.discordConfig.maxLinesPerMessage;
303
+ return resolveDiscordAccount({
304
+ cfg: params.cfg,
305
+ accountId: params.accountId
306
+ }).config.maxLinesPerMessage;
307
+ }
308
+ function resolveDiscordAccountTokenOwner(params) {
309
+ const token = params.token.trim();
310
+ if (!token) return;
311
+ let owner;
312
+ const accountIds = listDiscordAccountIds(params.cfg);
313
+ for (const [index, accountId] of accountIds.entries()) {
314
+ const account = resolveDiscordAccount({
315
+ cfg: params.cfg,
316
+ accountId
317
+ });
318
+ const accountToken = account.token.trim();
319
+ if (!account.enabled || accountToken !== token) continue;
320
+ const priority = account.tokenSource === "config" ? 2 : account.tokenSource === "env" ? 1 : 0;
321
+ if (!owner || priority > owner.priority) {
322
+ owner = {
323
+ accountId: account.accountId,
324
+ priority,
325
+ index
326
+ };
327
+ continue;
328
+ }
329
+ if (priority === owner.priority && index < owner.index) owner = {
330
+ accountId: account.accountId,
331
+ priority,
332
+ index
333
+ };
334
+ }
335
+ return owner?.accountId;
336
+ }
337
+ function resolveDiscordDuplicateTokenOwner(params) {
338
+ const owner = resolveDiscordAccountTokenOwner({
339
+ cfg: params.cfg,
340
+ token: params.account.token
341
+ });
342
+ return owner && owner !== params.account.accountId ? owner : void 0;
343
+ }
344
+ function isDiscordAccountEnabledForRuntime(account, cfg) {
345
+ return account.enabled && !resolveDiscordDuplicateTokenOwner({
346
+ cfg,
347
+ account
348
+ });
349
+ }
350
+ function resolveDiscordAccountDisabledReason(account, cfg) {
351
+ if (!account.enabled) return "disabled";
352
+ const owner = resolveDiscordDuplicateTokenOwner({
353
+ cfg,
354
+ account
355
+ });
356
+ return owner ? `duplicate bot token; using account "${owner}"` : "disabled";
357
+ }
358
+ function listEnabledDiscordAccounts(cfg) {
359
+ return listDiscordAccountIds(cfg).map((accountId) => resolveDiscordAccount({
360
+ cfg,
361
+ accountId
362
+ })).filter((account) => isDiscordAccountEnabledForRuntime(account, cfg));
363
+ }
364
+ function listDiscordStartupAccountIds(cfg) {
365
+ const startupAccountIds = listEnabledDiscordAccounts(cfg).filter((candidate) => resolveConfiguredFromCredentialStatuses(candidate) ?? Boolean(normalizeOptionalString(candidate.token))).map((candidate) => candidate.accountId);
366
+ const defaultAccountId = resolveDefaultDiscordAccountId(cfg);
367
+ if (!startupAccountIds.includes(defaultAccountId)) return startupAccountIds;
368
+ return [defaultAccountId, ...startupAccountIds.filter((candidateId) => candidateId !== defaultAccountId)];
369
+ }
370
+ //#endregion
371
+ export { resolveDiscordChannelId as A, readPositiveIntegerParam as C, withNormalizedTimestamp as D, readStringParam as E, projectCredentialSnapshotFields$1 as F, resolveConfiguredFromCredentialStatuses$1 as I, PAIRING_APPROVED_MESSAGE$1 as M, buildTokenChannelStatusSummary$1 as N, resolveDiscordOutboundSessionRoute as O, getChatChannelMeta as P, readNonNegativeIntegerParam as S, readStringArrayParam as T, assertMediaNotDataUrl as _, listEnabledDiscordAccounts as a, parseAvailableTags as b, resolveDiscordAccount as c, resolveDiscordAccountDisabledReason as d, resolveDiscordAccountDmPolicy as f, selectDiscordActivitiesRuntimeConfig as g, resolveDiscordToken as h, listDiscordStartupAccountIds as i, DEFAULT_ACCOUNT_ID$2 as j, parseDiscordTarget as k, resolveDiscordAccountAllowFrom as l, normalizeDiscordToken as m, isDiscordAccountEnabledForRuntime as n, mergeDiscordAccountConfig as o, resolveDiscordMaxLinesPerMessage as p, listDiscordAccountIds as r, resolveDefaultDiscordAccountId as s, createDiscordActionGate as t, resolveDiscordAccountConfig as u, jsonResult as v, readReactionParams as w, readBooleanParam$1 as x, loadOutboundMediaFromUrl as y };
@@ -1,2 +1,2 @@
1
- import { t as handleDiscordAction } from "./runtime-_aRC6V2s.js";
1
+ import { t as handleDiscordAction } from "./runtime-D71_VFLr.js";
2
2
  export { handleDiscordAction };
@@ -1,10 +1,8 @@
1
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
1
2
  //#region extensions/discord/src/active-turn-thread-route.ts
2
3
  const activeRoutes = /* @__PURE__ */ new Map();
3
- function normalizeId(value) {
4
- return value?.trim() || void 0;
5
- }
6
4
  function beginDiscordActiveTurnThreadRoute(sessionKey, route) {
7
- const key = normalizeId(sessionKey);
5
+ const key = normalizeOptionalString(sessionKey);
8
6
  if (!key) return () => {};
9
7
  const routes = activeRoutes.get(key) ?? /* @__PURE__ */ new Set();
10
8
  routes.add(route);
@@ -15,10 +13,10 @@ function beginDiscordActiveTurnThreadRoute(sessionKey, route) {
15
13
  };
16
14
  }
17
15
  async function notifyDiscordActiveTurnThreadCreated(params) {
18
- const key = normalizeId(params.sessionKey ?? void 0);
19
- const threadId = normalizeId(params.threadId);
20
- const sourceChannelId = normalizeId(params.sourceChannelId);
21
- const sourceMessageId = normalizeId(params.sourceMessageId);
16
+ const key = normalizeOptionalString(params.sessionKey ?? void 0);
17
+ const threadId = normalizeOptionalString(params.threadId);
18
+ const sourceChannelId = normalizeOptionalString(params.sourceChannelId);
19
+ const sourceMessageId = normalizeOptionalString(params.sourceMessageId);
22
20
  const route = key ? Array.from(activeRoutes.get(key) ?? []).find((candidate) => sourceChannelId === candidate.sourceChannelId && sourceMessageId === candidate.sourceMessageId && (!candidate.accountId || !params.accountId || candidate.accountId === params.accountId)) : void 0;
23
21
  if (!route || !threadId) return false;
24
22
  route.adoptedThreadId = threadId;
@@ -31,14 +29,14 @@ async function notifyDiscordActiveTurnThreadCreated(params) {
31
29
  }
32
30
  function notifyDiscordActiveTurnThreadReplyDelivered(params) {
33
31
  const route = findDiscordActiveTurnThreadReplyRoute(params);
34
- const threadId = normalizeId(params.threadId ?? void 0);
32
+ const threadId = normalizeOptionalString(params.threadId ?? void 0);
35
33
  if (!route || !threadId) return false;
36
34
  route.onThreadReplyDelivered?.(threadId);
37
35
  return true;
38
36
  }
39
37
  function findDiscordActiveTurnThreadReplyRoute(params) {
40
- const key = normalizeId(params.sessionKey ?? void 0);
41
- const threadId = normalizeId(params.threadId);
38
+ const key = normalizeOptionalString(params.sessionKey ?? void 0);
39
+ const threadId = normalizeOptionalString(params.threadId);
42
40
  if (!key || !threadId) return;
43
41
  return Array.from(activeRoutes.get(key) ?? []).find((route) => Boolean(route.adoptedThreadId) && route.adoptedThreadId === threadId && (!route.accountId || !params.accountId || route.accountId === params.accountId));
44
42
  }