@openclaw/discord 2026.9.1-beta.1 → 2026.9.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 (165) hide show
  1. package/dist/account-inspect-BY-ve3yH.js +45 -0
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-CfQ-vSyf.js → accounts-CwJQoLjM.js} +89 -45
  4. package/dist/action-runtime-api.js +1 -1
  5. package/dist/{activities-api-q-9PaaHH.js → activities-api-CTcGq3Hf.js} +30 -17
  6. package/dist/activities-api.js +1 -1
  7. package/dist/{allow-list-BDMimASD.js → allow-list-DBTtR2dz.js} +13 -35
  8. package/dist/{api-DNVbJyEy.js → api-BfmEP6wp.js} +6 -5
  9. package/dist/api.js +18 -18
  10. package/dist/{approval-handler.runtime-B7qhK3fR.js → approval-handler.runtime-DUSe5fyH.js} +19 -12
  11. package/dist/{audit-CBEv_ERu.js → audit-DpPfwoJM.js} +8 -7
  12. package/dist/{channel-Dx1tMTfx.js → channel-BHajPgwR.js} +29 -23
  13. package/dist/{channel-actions.runtime-CLWWu9nC.js → channel-actions.runtime-DS8pXo0S.js} +38 -38
  14. package/dist/channel-config-api.js +1 -1
  15. package/dist/channel-plugin-api.js +1 -1
  16. package/dist/{channel.setup-DOzXS2Pk.js → channel.setup-BWmMe1tT.js} +18 -18
  17. package/dist/command-owners-D78sAoOz.js +10 -0
  18. package/dist/{components-B9V5o361.js → components-BimX47Mq.js} +111 -149
  19. package/dist/{config-schema-BR13IAx6.js → config-schema-B797-Spt.js} +19 -12
  20. package/dist/{conversation-binding-route-DJYrY2TQ.js → conversation-binding-route-DuR5NGIx.js} +1 -1
  21. package/dist/{directory-config-BK6eqekJ.js → directory-config-CD2v2Szs.js} +2 -2
  22. package/dist/directory-contract-api.js +1 -1
  23. package/dist/{directory-live-DSAJSrJk.js → directory-live-DaJzWJ2N.js} +4 -4
  24. package/dist/{doctor-Cm7Y1pJ2.js → doctor-D4HH1inA.js} +9 -6
  25. package/dist/{doctor-contract-DsWvKIXF.js → doctor-contract-Co5vRCZ6.js} +9 -6
  26. package/dist/doctor-contract-api.js +31 -28
  27. package/dist/{handle-action.guild-admin-BdwCRHmm.js → handle-action.guild-admin-4We6wWQU.js} +6 -3
  28. package/dist/index.js +1 -1
  29. package/dist/ingress-identity-XNmW-mZS.js +60 -0
  30. package/dist/{message-handler-BXpWZyni.js → message-handler-DhgBabyU.js} +61 -70
  31. package/dist/{message-handler.preflight-Ba5LAY_X.js → message-handler.preflight-oZ7dQCd0.js} +41 -101
  32. package/dist/{message-handler.process-3HEzmemS.js → message-handler.process-BzCYf1pa.js} +82 -108
  33. package/dist/{message-text-aiwO5R2F.js → message-text-DK4NnBg-.js} +11 -6
  34. package/dist/{outbound-adapter-BE4jSq2d.js → outbound-adapter-CtggmGh9.js} +52 -67
  35. package/dist/{outbound-components-oLpg8Qzb.js → outbound-components-Dn8SJWMS.js} +5 -4
  36. package/dist/{outbound-session-route-Cg15ZFJd.js → outbound-session-route-Q_HEusBQ.js} +57 -15
  37. package/dist/{owner-access-UlYi9t0M.js → owner-access-Cp8r6Ipf.js} +9 -7
  38. package/dist/{pluralkit-Tiyl70dx.js → pluralkit-BY75YcK0.js} +2 -2
  39. package/dist/{probe-n6ZXxK8V.js → probe-3ovFAp3b.js} +3 -3
  40. package/dist/{probe.runtime-CN4bdPfZ.js → probe.runtime-BckHn3cJ.js} +1 -1
  41. package/dist/{provider-session.runtime-B9xe-Qaf.js → provider-session.runtime-BL2lHBH7.js} +3 -3
  42. package/dist/{provider-B11xwilq.js → provider-uKmmrDM4.js} +299 -136
  43. package/dist/provider.runtime-C-IkWF2w.js +2 -0
  44. package/dist/{realtime-session.runtime-CU8IQUS-.js → realtime-session.runtime-CGYm1t_0.js} +798 -448
  45. package/dist/{resolve-allowlist-common-BLoYaxEG.js → resolve-allowlist-common-sKIKy-cF.js} +3 -3
  46. package/dist/{resolve-channels-C2sT_n67.js → resolve-channels-CoiMlWy0.js} +4 -4
  47. package/dist/{resolve-users-CzpjLwjy.js → resolve-users-DJpiokfW.js} +5 -4
  48. package/dist/{retry-Cv4jCU5Z.js → retry-DQt1zDgH.js} +356 -214
  49. package/dist/{retry-after-DdLPmPoa.js → retry-after-BrLjLUJi.js} +2 -1
  50. package/dist/{runtime-CY4PRMF-.js → runtime-BHsdEdr5.js} +2 -2
  51. package/dist/{runtime-BHrTlFkf.js → runtime-Ghtfh5ZA.js} +151 -109
  52. package/dist/runtime-api.js +20 -20
  53. package/dist/{secret-config-contract-B3i6WxV5.js → secret-config-contract-DFu9hfU8.js} +14 -6
  54. package/dist/secret-contract-api.js +1 -1
  55. package/dist/{security-audit-BfJhAXZp.js → security-audit-DKfK-iPY.js} +10 -11
  56. package/dist/security-audit-contract-api.js +1 -1
  57. package/dist/{security-audit.runtime-BVKF9VtY.js → security-audit.runtime-sKZyKgpx.js} +1 -1
  58. package/dist/{send-C49MFF9j.js → send-CZeWKUiA.js} +132 -100
  59. package/dist/{send.components-DKKAw5VX.js → send.components-BG5IDABj.js} +21 -15
  60. package/dist/{send.outbound-zam0TrZx.js → send.outbound-DHuFUL6W.js} +42 -63
  61. package/dist/{send.shared-JjljcV4O.js → send.shared-B0n_fWzu.js} +77 -149
  62. package/dist/{sender-identity-BJtfyise.js → sender-identity-B8Ncfi63.js} +1 -1
  63. package/dist/setup-plugin-api.js +1 -1
  64. package/dist/{shared-_5EcP4jW.js → shared-C3dKun_X.js} +24 -15
  65. package/dist/{subagent-hooks-DQzvOptn.js → subagent-hooks-ZoQXEI1E.js} +2 -2
  66. package/dist/subagent-hooks-api.js +1 -1
  67. package/dist/{system-events-C7yxaHWP.js → system-events-DFF_awl7.js} +2 -2
  68. package/dist/{target-resolver-vxIh6O3-.js → target-resolver-DLtHDwMK.js} +6 -5
  69. package/dist/targets-BObRyaKX.js +3 -0
  70. package/dist/{thread-bindings-DW5F9vat.js → thread-bindings-DKvsNjQR.js} +7 -6
  71. package/dist/{thread-bindings.manager-ByOtwjo_.js → thread-bindings.manager-pbbRT5gb.js} +38 -29
  72. package/dist/{thread-bindings.session-updates-CJb-BpPL.js → thread-bindings.session-updates-t6jeFB1-.js} +3 -2
  73. package/dist/{thread-bindings.state-D8OMdk4O.js → thread-bindings.state-DtgOqsbX.js} +34 -1
  74. package/dist/{threading-agH1T_6s.js → threading-BCx49X-6.js} +8 -6
  75. package/dist/{timeouts-B9cy6RvQ.js → timeouts-D86uWLt_.js} +1 -1
  76. package/dist/{transcripts-source-BR11iHA4.js → transcripts-source-Dc6Nnli5.js} +55 -7
  77. package/dist/transcripts-source-api.js +1 -1
  78. package/dist/{typing-Dc_YMY2e.js → typing-CuopV-Hi.js} +2 -2
  79. package/dist/{voice-runtime-DIeaa8fJ.js → voice-runtime-BQnILUbG.js} +492 -105
  80. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/README.md +1 -1
  81. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/conforms.d.ts +2 -0
  82. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/package.json +3 -3
  83. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/stubArray.d.ts +2 -0
  84. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/stubObject.d.ts +2 -0
  85. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/stubString.d.ts +2 -0
  86. package/node_modules/@discordjs/voice/node_modules/@types/node/README.md +1 -1
  87. package/node_modules/@discordjs/voice/node_modules/@types/node/buffer.buffer.d.ts +5 -5
  88. package/node_modules/@discordjs/voice/node_modules/@types/node/crypto.d.ts +2 -2
  89. package/node_modules/@discordjs/voice/node_modules/@types/node/http.d.ts +16 -0
  90. package/node_modules/@discordjs/voice/node_modules/@types/node/http2.d.ts +10 -2
  91. package/node_modules/@discordjs/voice/node_modules/@types/node/package.json +2 -2
  92. package/node_modules/@discordjs/voice/node_modules/@types/node/process.d.ts +52 -0
  93. package/node_modules/@discordjs/voice/node_modules/@types/node/quic.d.ts +210 -28
  94. package/node_modules/@discordjs/voice/node_modules/@types/node/sqlite.d.ts +6 -2
  95. package/node_modules/@discordjs/voice/node_modules/@types/node/test.d.ts +36 -0
  96. package/node_modules/typebox/build/format/email.mjs +1 -1
  97. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +19 -1
  98. package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
  99. package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
  100. package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
  101. package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
  102. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  103. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  104. package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
  105. package/node_modules/typebox/build/system/memory/create.mjs +3 -4
  106. package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
  107. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  108. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  109. package/node_modules/typebox/build/system/memory/update.mjs +3 -2
  110. package/node_modules/typebox/package.json +1 -1
  111. package/node_modules/undici/docs/docs/api/Client.md +4 -0
  112. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +3 -2
  113. package/node_modules/undici/docs/docs/api/EventSource.md +4 -0
  114. package/node_modules/undici/docs/docs/api/Interceptors.md +7 -3
  115. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +7 -1
  116. package/node_modules/undici/lib/cache/memory-cache-store.js +2 -2
  117. package/node_modules/undici/lib/core/symbols.js +2 -0
  118. package/node_modules/undici/lib/dispatcher/agent.js +7 -2
  119. package/node_modules/undici/lib/dispatcher/balanced-pool.js +7 -4
  120. package/node_modules/undici/lib/dispatcher/client-h1.js +12 -4
  121. package/node_modules/undici/lib/dispatcher/client-h2.js +43 -3
  122. package/node_modules/undici/lib/dispatcher/client.js +3 -2
  123. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +13 -1
  124. package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -1
  125. package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +3 -0
  126. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +10 -3
  127. package/node_modules/undici/lib/dispatcher/proxy-agent.js +18 -1
  128. package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
  129. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +1 -1
  130. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +91 -21
  131. package/node_modules/undici/lib/handler/cache-handler.js +29 -5
  132. package/node_modules/undici/lib/handler/decorator-handler.js +7 -1
  133. package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
  134. package/node_modules/undici/lib/handler/redirect-handler.js +21 -4
  135. package/node_modules/undici/lib/handler/retry-handler.js +148 -30
  136. package/node_modules/undici/lib/interceptor/cache.js +65 -12
  137. package/node_modules/undici/lib/interceptor/decompress.js +115 -13
  138. package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
  139. package/node_modules/undici/lib/interceptor/dns.js +7 -0
  140. package/node_modules/undici/lib/interceptor/dump.js +10 -23
  141. package/node_modules/undici/lib/mock/mock-agent.js +13 -1
  142. package/node_modules/undici/lib/mock/mock-utils.js +11 -10
  143. package/node_modules/undici/lib/util/cache.js +45 -3
  144. package/node_modules/undici/lib/web/cookies/parse.js +150 -147
  145. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
  146. package/node_modules/undici/lib/web/eventsource/eventsource.js +13 -3
  147. package/node_modules/undici/lib/web/fetch/index.js +6 -0
  148. package/node_modules/undici/lib/web/fetch/request.js +2 -3
  149. package/node_modules/undici/lib/web/fetch/util.js +6 -1
  150. package/node_modules/undici/lib/web/webidl/index.js +3 -3
  151. package/node_modules/undici/lib/web/websocket/connection.js +1 -1
  152. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
  153. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
  154. package/node_modules/undici/package.json +3 -3
  155. package/node_modules/undici/types/client.d.ts +10 -0
  156. package/node_modules/undici/types/interceptors.d.ts +2 -0
  157. package/node_modules/undici/types/mock-agent.d.ts +11 -10
  158. package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -0
  159. package/openclaw.plugin.json +15 -8
  160. package/package.json +7 -6
  161. package/skills/discord/SKILL.md +1 -1
  162. package/dist/account-inspect-BDfKyuvL.js +0 -89
  163. package/dist/provider.runtime-DiYaHvOz.js +0 -2
  164. package/dist/sdk-runtime-4geQHtXc.js +0 -338
  165. package/dist/targets-CtTKvntJ.js +0 -3
@@ -1,8 +1,9 @@
1
- import { $ as TextInput, Q as RadioGroup, X as Label, Y as CheckboxGroup, Z as Modal, at as MediaGallery, ct as Row, dt as StringSelectMenu, et as Button, ft as TextDisplay, gt as parseCustomId, it as LinkButton, lt as Section, mt as UserSelectMenu, nt as Container, on as __exportAll, ot as MentionableSelectMenu, pt as Thumbnail, rt as File, st as RoleSelectMenu, tt as ChannelSelectMenu, ut as Separator } from "./retry-Cv4jCU5Z.js";
1
+ import { $ as RadioGroup, Q as Modal, X as CheckboxGroup, Z as Label, _t as parseCustomId, at as LinkButton, ct as RoleSelectMenu, dt as Separator, et as TextInput, ft as StringSelectMenu, ht as UserSelectMenu, it as File, lt as Row, mt as Thumbnail, nt as ChannelSelectMenu, ot as MediaGallery, pt as TextDisplay, rt as Container, sn as __exportAll, st as MentionableSelectMenu, tt as Button, ut as Section } from "./retry-DQt1zDgH.js";
2
2
  import { ButtonStyle, MessageFlags, TextInputStyle } from "discord-api-types/v10";
3
3
  import crypto from "node:crypto";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { legacyInteractiveReplyToPresentation, resolveMessagePresentationActionValue, resolveMessagePresentationButtonAction, resolveMessagePresentationOptionAction } from "openclaw/plugin-sdk/interactive-runtime";
6
+ import { resolveAskUserQuestionOptionIndex } from "openclaw/plugin-sdk/reply-payload";
6
7
  import { buildApprovalResolutionRef } from "openclaw/plugin-sdk/approval-reference-runtime";
7
8
  //#region extensions/discord/src/custom-id-codec.ts
8
9
  /**
@@ -391,6 +392,14 @@ function parseComponentBlock(raw, label) {
391
392
  default: throw new Error(`${label}.type must be a supported component block`);
392
393
  }
393
394
  }
395
+ function coerceDiscordComponentParam(raw) {
396
+ if (typeof raw !== "string") return raw;
397
+ try {
398
+ return JSON.parse(raw);
399
+ } catch {
400
+ return raw;
401
+ }
402
+ }
394
403
  function readDiscordComponentSpec(raw) {
395
404
  if (raw === void 0 || raw === null) return null;
396
405
  const obj = requireObject(raw, "components");
@@ -429,6 +438,46 @@ function readDiscordComponentSpec(raw) {
429
438
  function createShortId(prefix) {
430
439
  return `${prefix}${crypto.randomBytes(6).toString("base64url")}`;
431
440
  }
441
+ const selectMenuConstructors = {
442
+ string: class extends StringSelectMenu {
443
+ constructor(..._args) {
444
+ super(..._args);
445
+ this.customId = "";
446
+ this.options = [];
447
+ }
448
+ },
449
+ user: class extends UserSelectMenu {
450
+ constructor(..._args2) {
451
+ super(..._args2);
452
+ this.customId = "";
453
+ }
454
+ },
455
+ role: class extends RoleSelectMenu {
456
+ constructor(..._args3) {
457
+ super(..._args3);
458
+ this.customId = "";
459
+ }
460
+ },
461
+ mentionable: class extends MentionableSelectMenu {
462
+ constructor(..._args4) {
463
+ super(..._args4);
464
+ this.customId = "";
465
+ }
466
+ },
467
+ channel: class extends ChannelSelectMenu {
468
+ constructor(..._args5) {
469
+ super(..._args5);
470
+ this.customId = "";
471
+ }
472
+ }
473
+ };
474
+ function createDiscordSelectMenu(type, customId, options) {
475
+ const SelectMenu = selectMenuConstructors[type];
476
+ const select = new SelectMenu();
477
+ select.customId = customId;
478
+ if (select instanceof StringSelectMenu) select.options = options ?? [];
479
+ return select;
480
+ }
432
481
  function buildTextDisplays(text, texts) {
433
482
  if (texts && texts.length > 0) return texts.map((entry) => new TextDisplay(entry));
434
483
  if (text) return [new TextDisplay(text)];
@@ -440,8 +489,8 @@ function createButtonComponent(params) {
440
489
  if (!params.spec.url) throw new Error("Link buttons require a url");
441
490
  const linkUrl = params.spec.url;
442
491
  class DynamicLinkButton extends LinkButton {
443
- constructor(..._args) {
444
- super(..._args);
492
+ constructor(..._args6) {
493
+ super(..._args6);
445
494
  this.label = params.spec.label;
446
495
  this.url = linkUrl;
447
496
  this.disabled = params.spec.disabled ?? false;
@@ -456,8 +505,8 @@ function createButtonComponent(params) {
456
505
  modalId: params.modalId
457
506
  });
458
507
  class DynamicButton extends Button {
459
- constructor(..._args2) {
460
- super(..._args2);
508
+ constructor(..._args7) {
509
+ super(..._args7);
461
510
  this.label = params.spec.label;
462
511
  this.customId = customId;
463
512
  this.style = style;
@@ -484,99 +533,34 @@ function createSelectComponent(params) {
484
533
  const type = normalizeLowercaseStringOrEmpty(params.spec.type ?? "string");
485
534
  const componentId = params.componentId ?? createShortId("sel_");
486
535
  const customId = buildDiscordComponentCustomId({ componentId });
487
- const createEntry = (selectType, label, options) => ({
488
- id: componentId,
489
- kind: "select",
490
- label,
491
- ...params.spec.callbackData !== void 0 ? { callbackData: params.spec.callbackData } : {},
492
- ...params.spec.callbackDataKind !== void 0 ? { callbackDataKind: params.spec.callbackDataKind } : {},
493
- selectType,
494
- ...options ? { options } : {},
495
- ...params.spec.allowedUsers !== void 0 ? { allowedUsers: params.spec.allowedUsers } : {}
496
- });
497
- if (type === "string") {
498
- const options = params.spec.options ?? [];
499
- if (options.length === 0) throw new Error("String select menus require options");
500
- class DynamicStringSelect extends StringSelectMenu {
501
- constructor(..._args3) {
502
- super(..._args3);
503
- this.customId = customId;
504
- this.options = options;
505
- this.minValues = params.spec.minValues;
506
- this.maxValues = params.spec.maxValues;
507
- this.placeholder = params.spec.placeholder;
508
- this.disabled = false;
509
- }
510
- }
511
- return {
512
- component: new DynamicStringSelect(),
513
- entry: createEntry("string", params.spec.placeholder ?? "select", options.map((option) => ({
536
+ const options = params.spec.options ?? [];
537
+ if (type === "string" && options.length === 0) throw new Error("String select menus require options");
538
+ const select = createDiscordSelectMenu(type, customId, options);
539
+ select.minValues = params.spec.minValues;
540
+ select.maxValues = params.spec.maxValues;
541
+ select.placeholder = params.spec.placeholder;
542
+ select.disabled = false;
543
+ return {
544
+ component: select,
545
+ entry: {
546
+ id: componentId,
547
+ kind: "select",
548
+ label: params.spec.placeholder ?? {
549
+ string: "select",
550
+ user: "user select",
551
+ role: "role select",
552
+ mentionable: "mentionable select",
553
+ channel: "channel select"
554
+ }[type],
555
+ ...params.spec.callbackData !== void 0 ? { callbackData: params.spec.callbackData } : {},
556
+ ...params.spec.callbackDataKind !== void 0 ? { callbackDataKind: params.spec.callbackDataKind } : {},
557
+ selectType: type,
558
+ ...type === "string" ? { options: options.map((option) => ({
514
559
  value: option.value,
515
560
  label: option.label
516
- })))
517
- };
518
- }
519
- if (type === "user") {
520
- class DynamicUserSelect extends UserSelectMenu {
521
- constructor(..._args4) {
522
- super(..._args4);
523
- this.customId = customId;
524
- this.minValues = params.spec.minValues;
525
- this.maxValues = params.spec.maxValues;
526
- this.placeholder = params.spec.placeholder;
527
- this.disabled = false;
528
- }
529
- }
530
- return {
531
- component: new DynamicUserSelect(),
532
- entry: createEntry("user", params.spec.placeholder ?? "user select")
533
- };
534
- }
535
- if (type === "role") {
536
- class DynamicRoleSelect extends RoleSelectMenu {
537
- constructor(..._args5) {
538
- super(..._args5);
539
- this.customId = customId;
540
- this.minValues = params.spec.minValues;
541
- this.maxValues = params.spec.maxValues;
542
- this.placeholder = params.spec.placeholder;
543
- this.disabled = false;
544
- }
545
- }
546
- return {
547
- component: new DynamicRoleSelect(),
548
- entry: createEntry("role", params.spec.placeholder ?? "role select")
549
- };
550
- }
551
- if (type === "mentionable") {
552
- class DynamicMentionableSelect extends MentionableSelectMenu {
553
- constructor(..._args6) {
554
- super(..._args6);
555
- this.customId = customId;
556
- this.minValues = params.spec.minValues;
557
- this.maxValues = params.spec.maxValues;
558
- this.placeholder = params.spec.placeholder;
559
- this.disabled = false;
560
- }
561
- }
562
- return {
563
- component: new DynamicMentionableSelect(),
564
- entry: createEntry("mentionable", params.spec.placeholder ?? "mentionable select")
565
- };
566
- }
567
- class DynamicChannelSelect extends ChannelSelectMenu {
568
- constructor(..._args7) {
569
- super(..._args7);
570
- this.customId = customId;
571
- this.minValues = params.spec.minValues;
572
- this.maxValues = params.spec.maxValues;
573
- this.placeholder = params.spec.placeholder;
574
- this.disabled = false;
561
+ })) } : {},
562
+ ...params.spec.allowedUsers !== void 0 ? { allowedUsers: params.spec.allowedUsers } : {}
575
563
  }
576
- }
577
- return {
578
- component: new DynamicChannelSelect(),
579
- entry: createEntry("channel", params.spec.placeholder ?? "channel select")
580
564
  };
581
565
  }
582
566
  function isSelectComponent(component) {
@@ -728,52 +712,19 @@ function createModalFieldComponent(field) {
728
712
  }
729
713
  return new DynamicTextInput();
730
714
  }
731
- if (field.type === "select") {
732
- const options = field.options ?? [];
733
- class DynamicModalSelect extends StringSelectMenu {
734
- constructor(..._args2) {
735
- super(..._args2);
736
- this.customId = field.id;
737
- this.options = options;
738
- this.required = field.required;
739
- this.minValues = field.minValues;
740
- this.maxValues = field.maxValues;
741
- this.placeholder = field.placeholder;
742
- }
743
- }
744
- return new DynamicModalSelect();
745
- }
746
- if (field.type === "role-select") {
747
- class DynamicModalRoleSelect extends RoleSelectMenu {
748
- constructor(..._args3) {
749
- super(..._args3);
750
- this.customId = field.id;
751
- this.required = field.required;
752
- this.minValues = field.minValues;
753
- this.maxValues = field.maxValues;
754
- this.placeholder = field.placeholder;
755
- }
756
- }
757
- return new DynamicModalRoleSelect();
758
- }
759
- if (field.type === "user-select") {
760
- class DynamicModalUserSelect extends UserSelectMenu {
761
- constructor(..._args4) {
762
- super(..._args4);
763
- this.customId = field.id;
764
- this.required = field.required;
765
- this.minValues = field.minValues;
766
- this.maxValues = field.maxValues;
767
- this.placeholder = field.placeholder;
768
- }
769
- }
770
- return new DynamicModalUserSelect();
715
+ if (field.type === "select" || field.type === "role-select" || field.type === "user-select") {
716
+ const select = createDiscordSelectMenu(field.type === "select" ? "string" : field.type === "role-select" ? "role" : "user", field.id, field.options);
717
+ select.required = field.required;
718
+ select.minValues = field.minValues;
719
+ select.maxValues = field.maxValues;
720
+ select.placeholder = field.placeholder;
721
+ return select;
771
722
  }
772
723
  if (field.type === "checkbox") {
773
724
  const options = field.options ?? [];
774
725
  class DynamicCheckboxGroup extends CheckboxGroup {
775
- constructor(..._args5) {
776
- super(..._args5);
726
+ constructor(..._args2) {
727
+ super(..._args2);
777
728
  this.customId = field.id;
778
729
  this.options = options;
779
730
  this.required = field.required;
@@ -785,8 +736,8 @@ function createModalFieldComponent(field) {
785
736
  }
786
737
  const options = field.options ?? [];
787
738
  class DynamicRadioGroup extends RadioGroup {
788
- constructor(..._args6) {
789
- super(..._args6);
739
+ constructor(..._args3) {
740
+ super(..._args3);
790
741
  this.customId = field.id;
791
742
  this.options = options;
792
743
  this.required = field.required;
@@ -803,8 +754,8 @@ var DiscordFormModal = class extends ModalBase {
803
754
  this.components = params.fields.map((field) => {
804
755
  const component = createModalFieldComponent(field);
805
756
  class DynamicLabel extends Label {
806
- constructor(..._args7) {
807
- super(..._args7);
757
+ constructor(..._args4) {
758
+ super(..._args4);
808
759
  this.label = field.label;
809
760
  this.description = field.description;
810
761
  this.component = component;
@@ -919,7 +870,7 @@ function resolveDiscordSelectCallbackDataKind(options) {
919
870
  if (renderableOptions.some((option) => option.action)) return "mixed";
920
871
  }
921
872
  const DISCORD_INTERACTIVE_BUTTON_ROW_SIZE = 5;
922
- function buildDiscordButtonComponent(button, optionIndex) {
873
+ function buildDiscordButtonComponent(button, options) {
923
874
  const action = resolveMessagePresentationButtonAction(button);
924
875
  if (!action) return;
925
876
  if (action.type === "approval") {
@@ -933,6 +884,13 @@ function buildDiscordButtonComponent(button, optionIndex) {
933
884
  };
934
885
  }
935
886
  if (action.type === "question") {
887
+ if ("intent" in action) return;
888
+ const optionIndex = resolveAskUserQuestionOptionIndex({
889
+ questionOptionIndices: options.questionOptionIndices,
890
+ questionId: action.questionId,
891
+ optionValue: action.optionValue
892
+ });
893
+ if (optionIndex === void 0) return;
936
894
  const internalCustomId = buildDiscordQuestionCustomId({
937
895
  questionId: action.questionId,
938
896
  optionIndex
@@ -965,8 +923,11 @@ function buildDiscordButtonComponent(button, optionIndex) {
965
923
  if (button.reusable === true) component.reusable = true;
966
924
  return component;
967
925
  }
968
- function appendDiscordButtonBlocks(blocks, buttons) {
969
- const components = buttons.map((button, optionIndex) => buildDiscordButtonComponent(button, optionIndex)).filter((button) => Boolean(button));
926
+ function appendDiscordButtonBlocks(blocks, buttons, options) {
927
+ const components = buttons.flatMap((button) => {
928
+ const component = buildDiscordButtonComponent(button, options);
929
+ return component ? [component] : [];
930
+ });
970
931
  for (let index = 0; index < components.length; index += DISCORD_INTERACTIVE_BUTTON_ROW_SIZE) blocks.push({
971
932
  type: "actions",
972
933
  buttons: components.slice(index, index + DISCORD_INTERACTIVE_BUTTON_ROW_SIZE)
@@ -993,10 +954,10 @@ function appendDiscordSelectBlock(blocks, block) {
993
954
  /**
994
955
  * @deprecated Use buildDiscordPresentationComponents with MessagePresentation.
995
956
  */
996
- function buildDiscordInteractiveComponents(interactive) {
997
- return buildDiscordPresentationComponents(interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
957
+ function buildDiscordInteractiveComponents(interactive, options = {}) {
958
+ return buildDiscordPresentationComponents(interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0, options);
998
959
  }
999
- function buildDiscordPresentationComponents(presentation) {
960
+ function buildDiscordPresentationComponents(presentation, options = {}) {
1000
961
  if (!presentation) return;
1001
962
  const blocks = [];
1002
963
  if (presentation.title) blocks.push({
@@ -1017,7 +978,7 @@ function buildDiscordPresentationComponents(presentation) {
1017
978
  continue;
1018
979
  }
1019
980
  if (block.type === "buttons") {
1020
- appendDiscordButtonBlocks(blocks, block.buttons);
981
+ appendDiscordButtonBlocks(blocks, block.buttons, options);
1021
982
  continue;
1022
983
  }
1023
984
  if (block.type === "select") appendDiscordSelectBlock(blocks, block);
@@ -1037,6 +998,7 @@ var components_exports = /* @__PURE__ */ __exportAll({
1037
998
  buildDiscordComponentMessageFlags: () => buildDiscordComponentMessageFlags,
1038
999
  buildDiscordInteractiveComponents: () => buildDiscordInteractiveComponents,
1039
1000
  buildDiscordModalCustomId: () => buildDiscordModalCustomId,
1001
+ coerceDiscordComponentParam: () => coerceDiscordComponentParam,
1040
1002
  createDiscordFormModal: () => createDiscordFormModal,
1041
1003
  formatDiscordComponentEventText: () => formatDiscordComponentEventText,
1042
1004
  parseDiscordComponentCustomId: () => parseDiscordComponentCustomId,
@@ -1053,4 +1015,4 @@ function formatDiscordComponentEventText(params) {
1053
1015
  return `Selected ${values.join(", ")} from "${params.label}".`;
1054
1016
  }
1055
1017
  //#endregion
1056
- export { parseDiscordComponentCustomId as C, decodeCustomIdComponent as D, parseDiscordModalCustomIdForInteraction as E, encodeCustomIdComponent as O, parseDiscordActivityCustomIdForInteraction as S, parseDiscordModalCustomId as T, DISCORD_MODAL_CUSTOM_ID_KEY as _, shared_interactive_exports as a, buildDiscordModalCustomId as b, parseExecApprovalData as c, buildDiscordComponentMessage as d, buildDiscordComponentMessageFlags as f, DISCORD_COMPONENT_CUSTOM_ID_KEY as g, resolveDiscordComponentAttachmentName as h, buildDiscordPresentationComponents as i, DiscordFormModal as l, readDiscordComponentSpec as m, formatDiscordComponentEventText as n, parseDiscordQuestionData as o, DISCORD_COMPONENT_ATTACHMENT_PREFIX as p, buildDiscordInteractiveComponents as r, buildExecApprovalCustomId as s, components_exports as t, createDiscordFormModal as u, buildDiscordActivityCustomId as v, parseDiscordComponentCustomIdForInteraction as w, parseDiscordActivityCustomId as x, buildDiscordComponentCustomId as y };
1018
+ export { parseDiscordActivityCustomIdForInteraction as C, parseDiscordModalCustomIdForInteraction as D, parseDiscordModalCustomId as E, decodeCustomIdComponent as O, parseDiscordActivityCustomId as S, parseDiscordComponentCustomIdForInteraction as T, DISCORD_COMPONENT_CUSTOM_ID_KEY as _, shared_interactive_exports as a, buildDiscordComponentCustomId as b, parseExecApprovalData as c, buildDiscordComponentMessage as d, buildDiscordComponentMessageFlags as f, resolveDiscordComponentAttachmentName as g, readDiscordComponentSpec as h, buildDiscordPresentationComponents as i, encodeCustomIdComponent as k, DiscordFormModal as l, coerceDiscordComponentParam as m, formatDiscordComponentEventText as n, parseDiscordQuestionData as o, DISCORD_COMPONENT_ATTACHMENT_PREFIX as p, buildDiscordInteractiveComponents as r, buildExecApprovalCustomId as s, components_exports as t, createDiscordFormModal as u, DISCORD_MODAL_CUSTOM_ID_KEY as v, parseDiscordComponentCustomId as w, buildDiscordModalCustomId as x, buildDiscordActivityCustomId as y };
@@ -2,7 +2,7 @@ import { normalizeLegacyDmAliases } from "openclaw/plugin-sdk/channel-config-hel
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { buildSecretInputSchema, registerSensitiveConfigSchema } from "openclaw/plugin-sdk/secret-input";
4
4
  import { createChannelConfigUiHints } from "openclaw/plugin-sdk/channel-core";
5
- import { ChannelBotLoopProtectionSchema, ChannelDangerouslyAllowNameMatchingSchema, ChannelPreviewStreamingConfigSchema, ChannelStreamingProgressSchema, ProviderCommandsSchema, TtsConfigSchema, buildChannelAllowBotsSchema, buildChannelConfigSchema, buildChannelExecApprovalsSchema, buildChannelReactionShape, buildCommonChannelAccountShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
5
+ import { ChannelBotLoopProtectionSchema, ChannelDangerouslyAllowNameMatchingSchema, ChannelPreviewStreamingConfigSchema, ChannelStreamingProgressSchema, ProviderCommandsSchema, TtsConfigSchema, buildChannelAccountSchemaParts, buildChannelAllowBotsSchema, buildChannelConfigSchema, buildChannelExecApprovalsSchema, buildChannelReactionShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
6
6
  import { asObjectRecord } from "openclaw/plugin-sdk/runtime-doctor-migrations";
7
7
  import { z } from "zod";
8
8
  //#region extensions/discord/src/config-ui-hints.ts
@@ -35,6 +35,10 @@ const discordChannelConfigUiHints = {
35
35
  },
36
36
  progress: { includeCommentary: true }
37
37
  }),
38
+ joinIntro: {
39
+ label: "Discord Guild Join Introduction",
40
+ help: "Post one brief, room-specific introduction when the bot joins an allowed Discord guild (default: true). Account settings override the channel-wide setting."
41
+ },
38
42
  proxy: {
39
43
  label: "Discord Proxy URL",
40
44
  help: "Proxy URL for Discord gateway + API requests (app-id lookup and allowlist resolution). Set per account via channels.discord.accounts.<id>.proxy."
@@ -53,11 +57,11 @@ const discordChannelConfigUiHints = {
53
57
  },
54
58
  "threadBindings.enabled": {
55
59
  label: "Discord Thread Binding Enabled",
56
- help: "Enable Discord thread binding features (/focus, bound-thread routing/delivery, and thread-bound subagent sessions). Overrides session.threadBindings.enabled when set."
60
+ help: "Enable Discord thread-bound session spawning, routing, and delivery. Overrides session.threadBindings.enabled when set."
57
61
  },
58
62
  "threadBindings.idleHours": {
59
63
  label: "Discord Thread Binding Idle Timeout (hours)",
60
- help: "Inactivity window in hours for Discord thread-bound sessions (/focus and spawned thread sessions). Set 0 to disable idle auto-unfocus (default: 24). Overrides session.threadBindings.idleHours when set."
64
+ help: "Inactivity window in hours for Discord thread-bound sessions. Set 0 to disable idle expiry (default: 24). Overrides session.threadBindings.idleHours when set."
61
65
  },
62
66
  "threadBindings.maxAgeHours": {
63
67
  label: "Discord Thread Binding Max Age (hours)",
@@ -461,13 +465,14 @@ const DiscordVoiceSchema = z.object({
461
465
  captureSilenceGraceMs: z.number().int().positive().max(3e4).optional(),
462
466
  tts: TtsConfigSchema.optional()
463
467
  }).strict().optional();
468
+ const { accountShape, rootPolicyShape } = buildChannelAccountSchemaParts({
469
+ omit: ["groupAllowFrom"],
470
+ allowFrom: DiscordIdListSchema.optional(),
471
+ streaming: DiscordPreviewStreamingConfigSchema.optional()
472
+ });
464
473
  const DiscordAccountSchemaBase = z.object({
465
- ...buildCommonChannelAccountShape({
466
- omit: ["groupAllowFrom"],
467
- groupPolicyDefault: true,
468
- allowFrom: DiscordIdListSchema.optional(),
469
- streaming: DiscordPreviewStreamingConfigSchema.optional()
470
- }),
474
+ ...accountShape,
475
+ joinIntro: z.boolean().optional(),
471
476
  commands: ProviderCommandsSchema,
472
477
  token: registerSensitiveConfigSchema(SecretInputSchema.optional()),
473
478
  applicationId: DiscordIdSchema.optional(),
@@ -509,7 +514,7 @@ const DiscordAccountSchemaBase = z.object({
509
514
  execApprovals: buildChannelExecApprovalsSchema(DiscordIdSchema, { cleanupAfterResolve: z.boolean().optional() }),
510
515
  agentComponents: z.object({
511
516
  enabled: z.boolean().optional(),
512
- ttlMs: z.number().int().positive().max(1440 * 60 * 1e3).optional()
517
+ ttlMs: z.number().int().positive().max(864e5).optional()
513
518
  }).strict().optional(),
514
519
  slashCommand: z.object({ ephemeral: z.boolean().optional() }).strict().optional(),
515
520
  threadBindings: z.object({
@@ -608,7 +613,8 @@ function normalizeShippedDiscordDmAliases(value) {
608
613
  } : rest;
609
614
  }
610
615
  const DiscordAccountSchema = z.preprocess(normalizeShippedDiscordDmAliases, DiscordAccountSchemaBase);
611
- const DiscordConfigSchemaBase = DiscordAccountSchemaBase.extend({
616
+ const DiscordConfigSchemaBase = DiscordAccountSchemaBase.safeExtend({
617
+ ...rootPolicyShape,
612
618
  accounts: z.record(z.string(), DiscordAccountSchema.optional()).optional(),
613
619
  defaultAccount: z.string().optional()
614
620
  }).superRefine((value, ctx) => {
@@ -657,6 +663,7 @@ const DiscordConfigSchemaBase = DiscordAccountSchemaBase.extend({
657
663
  });
658
664
  }
659
665
  });
660
- const DiscordChannelConfigSchema = buildChannelConfigSchema(z.preprocess(normalizeShippedDiscordDmAliases, DiscordConfigSchemaBase), { uiHints: discordChannelConfigUiHints });
666
+ const DiscordConfigSchema = z.preprocess(normalizeShippedDiscordDmAliases, DiscordConfigSchemaBase);
667
+ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema, { uiHints: discordChannelConfigUiHints });
661
668
  //#endregion
662
669
  export { DiscordChannelConfigSchema as t };
@@ -1,4 +1,4 @@
1
- import { l as shouldIgnoreStaleDiscordRouteBinding } from "./outbound-session-route-Cg15ZFJd.js";
1
+ import { l as shouldIgnoreStaleDiscordRouteBinding } from "./outbound-session-route-Q_HEusBQ.js";
2
2
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
3
3
  import { resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
4
4
  //#region extensions/discord/src/monitor/conversation-binding-route.ts
@@ -1,5 +1,5 @@
1
- import { on as __exportAll } from "./retry-Cv4jCU5Z.js";
2
- import { l as resolveDiscordAccountAllowFrom, o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId } from "./accounts-CfQ-vSyf.js";
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
2
+ import { l as resolveDiscordAccountAllowFrom, o as mergeDiscordAccountConfig, s as resolveDefaultDiscordAccountId } from "./accounts-CwJQoLjM.js";
3
3
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
4
4
  import { createResolvedDirectoryEntriesLister } from "openclaw/plugin-sdk/directory-config-runtime";
5
5
  //#region extensions/discord/src/directory-config.ts
@@ -1,4 +1,4 @@
1
- import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-BK6eqekJ.js";
1
+ import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CD2v2Szs.js";
2
2
  //#region extensions/discord/directory-contract-api.ts
3
3
  const discordDirectoryContractPlugin = {
4
4
  id: "discord",
@@ -1,7 +1,7 @@
1
- import { on as __exportAll } from "./retry-Cv4jCU5Z.js";
2
- import { c as resolveDiscordAccount, m as normalizeDiscordToken } from "./accounts-CfQ-vSyf.js";
3
- import { r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api-DNVbJyEy.js";
4
- import { a as normalizeDiscordSlug } from "./allow-list-BDMimASD.js";
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
2
+ import { c as resolveDiscordAccount, m as normalizeDiscordToken } from "./accounts-CwJQoLjM.js";
3
+ import { r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api-BfmEP6wp.js";
4
+ import { a as normalizeDiscordSlug } from "./allow-list-DBTtR2dz.js";
5
5
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/routing";
6
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  //#region extensions/discord/src/directory-cache-state.ts
@@ -1,8 +1,8 @@
1
- import { s as resolveDefaultDiscordAccountId } from "./accounts-CfQ-vSyf.js";
2
- import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-BR11iHA4.js";
3
- import { t as inspectDiscordAccount } from "./account-inspect-BDfKyuvL.js";
4
- import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-_5EcP4jW.js";
5
- import { n as normalizeCompatibilityConfig } from "./doctor-contract-DsWvKIXF.js";
1
+ import { s as resolveDefaultDiscordAccountId } from "./accounts-CwJQoLjM.js";
2
+ import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-Dc6Nnli5.js";
3
+ import { t as inspectDiscordAccount } from "./account-inspect-BY-ve3yH.js";
4
+ import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-C3dKun_X.js";
5
+ import { n as normalizeCompatibilityConfig } from "./doctor-contract-Co5vRCZ6.js";
6
6
  import { t as isDiscordMutableAllowEntry } from "./security-doctor-nGgPm65L.js";
7
7
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
8
8
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -175,7 +175,10 @@ function collectDiscordTranscriptsAutoStartWarnings(cfg) {
175
175
  if (providerId !== discordVoiceTranscriptsSourceProvider.id && !discordVoiceTranscriptsSourceProvider.aliases?.includes(providerId ?? "") || normalizeOptionalString(entry.accountId)) return [];
176
176
  const resolution = ownership.resolveAccountId({
177
177
  cfg,
178
- source: entry
178
+ source: {
179
+ providerId: entry.providerId,
180
+ accountId: entry.accountId
181
+ }
179
182
  });
180
183
  if (resolution.ok) return [];
181
184
  const path = `transcripts.autoStart[${index}]`;
@@ -65,7 +65,8 @@ function hasLegacyDiscordGuildChannelAgentId(value) {
65
65
  });
66
66
  }
67
67
  function hasUnsupportedRealtimeWakeNamesInVoice(value) {
68
- const wakeNames = asObjectRecord(asObjectRecord(value)?.realtime)?.wakeNames;
68
+ const voice = asObjectRecord(value);
69
+ const wakeNames = asObjectRecord(voice?.realtime)?.wakeNames;
69
70
  return Array.isArray(wakeNames) ? wakeNames.length === 0 || wakeNames.some((wakeName) => typeof wakeName === "string" && !isSupportedRealtimeVoiceActivationName(wakeName)) : false;
70
71
  }
71
72
  function hasUnsupportedDiscordRealtimeWakeNames(value) {
@@ -274,7 +275,8 @@ const legacyConfigRules = [
274
275
  ],
275
276
  message: "channels.discord.accounts.<id>.voice.tts.<provider> keys (openai/elevenlabs/microsoft/edge) are legacy; use channels.discord.accounts.<id>.voice.tts.providers.<provider>. Run \"openclaw doctor --fix\".",
276
277
  match: (value) => hasLegacyAccountStreamingAliases(value, (accountValue) => {
277
- return hasLegacyTtsProviderKeys(asObjectRecord(asObjectRecord(accountValue)?.voice)?.tts);
278
+ const account = asObjectRecord(accountValue);
279
+ return hasLegacyTtsProviderKeys(asObjectRecord(account?.voice)?.tts);
278
280
  })
279
281
  },
280
282
  {
@@ -324,11 +326,12 @@ const legacyConfigRules = [
324
326
  function normalizeCompatibilityConfig({ cfg }) {
325
327
  const changes = [];
326
328
  const bindingsToAdd = [];
329
+ const aliases = streamingAliasMigration.normalizeChannelConfig({
330
+ cfg,
331
+ changes
332
+ });
327
333
  const tuningKnobs = stripRetiredChannelKeys({
328
- cfg: streamingAliasMigration.normalizeChannelConfig({
329
- cfg,
330
- changes
331
- }).config,
334
+ cfg: aliases.config,
332
335
  channelId: "discord",
333
336
  keys: RETIRED_TUNING_KEYS,
334
337
  scope: "root-and-accounts"
@@ -1,6 +1,5 @@
1
1
  import { n as DISCORD_COMMAND_DEPLOY_HASH_NAMESPACE, t as DISCORD_COMMAND_DEPLOY_HASH_MAX_ENTRIES } from "./command-deploy-store-DFkBTViB.js";
2
- import { a as THREAD_BINDINGS_MAX_ENTRIES, d as normalizePersistedBinding, k as toBindingRecordKey, o as THREAD_BINDINGS_NAMESPACE } from "./thread-bindings.state-D8OMdk4O.js";
3
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DsWvKIXF.js";
2
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-Co5vRCZ6.js";
4
3
  import { i as sanitizeRecentModels, r as preferenceTimestampMs, t as buildPreferenceModelKey } from "./model-picker-preference-primitives-BHT1LkR_.js";
5
4
  import { MAX_DATE_TIMESTAMP_MS, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
6
5
  import path from "node:path";
@@ -37,7 +36,8 @@ function normalizeLegacyPreferenceKey(key) {
37
36
  }
38
37
  function legacyUpdatedAtForIndex(updatedAt, index, total) {
39
38
  const baseMs = preferenceTimestampMs(updatedAt);
40
- return timestampMsToIsoString(Math.min(baseMs + Math.max(0, total), MAX_DATE_TIMESTAMP_MS) - Math.max(0, index)) ?? timestampMsToIsoString(baseMs) ?? timestampMsToIsoString(Math.max(0, total - index)) ?? "1970-01-01T00:00:00.000Z";
39
+ const shiftedMs = Math.min(baseMs + Math.max(0, total), MAX_DATE_TIMESTAMP_MS) - Math.max(0, index);
40
+ return timestampMsToIsoString(shiftedMs) ?? timestampMsToIsoString(baseMs) ?? timestampMsToIsoString(Math.max(0, total - index)) ?? "1970-01-01T00:00:00.000Z";
41
41
  }
42
42
  function readFiniteNumberField(entry, key) {
43
43
  const value = entry[key];
@@ -61,7 +61,7 @@ function upgradeLegacyThreadBindingShape(rawEntry) {
61
61
  }
62
62
  return entry;
63
63
  }
64
- const detectDiscordLegacyStateMigrations = ({ stateDir }) => {
64
+ const detectDiscordLegacyStateMigrations = async ({ stateDir }) => {
65
65
  const plans = [];
66
66
  const commandDeployCacheSourcePath = path.join(stateDir, "discord", "command-deploy-cache.json");
67
67
  if (fileExists(commandDeployCacheSourcePath)) plans.push({
@@ -109,31 +109,34 @@ const detectDiscordLegacyStateMigrations = ({ stateDir }) => {
109
109
  }
110
110
  });
111
111
  const threadBindingsSourcePath = path.join(stateDir, "discord", "thread-bindings.json");
112
- if (fileExists(threadBindingsSourcePath)) plans.push({
113
- kind: "plugin-state-import",
114
- label: "Discord thread bindings",
115
- sourcePath: threadBindingsSourcePath,
116
- targetPath: `plugin state:${THREAD_BINDINGS_NAMESPACE}`,
117
- pluginId: "discord",
118
- namespace: THREAD_BINDINGS_NAMESPACE,
119
- maxEntries: THREAD_BINDINGS_MAX_ENTRIES,
120
- scopeKey: "",
121
- cleanupSource: "rename",
122
- cleanupWhenEmpty: true,
123
- readEntries: () => {
124
- const store = readLegacyThreadBindingsStore(threadBindingsSourcePath);
125
- if (store?.version !== 1 || !store.bindings || typeof store.bindings !== "object") throw new Error("legacy Discord thread bindings store must have version 1 bindings");
126
- const out = [];
127
- for (const [rawKey, rawEntry] of Object.entries(store.bindings)) {
128
- const normalized = normalizePersistedBinding(rawKey, upgradeLegacyThreadBindingShape(rawEntry));
129
- if (normalized) out.push({
130
- key: toBindingRecordKey(normalized),
131
- value: normalized
132
- });
112
+ if (fileExists(threadBindingsSourcePath)) {
113
+ const { normalizePersistedBinding, THREAD_BINDINGS_MAX_ENTRIES, THREAD_BINDINGS_NAMESPACE, toBindingRecordKey } = await import("./thread-bindings.state-DtgOqsbX.js").then((n) => n.E);
114
+ plans.push({
115
+ kind: "plugin-state-import",
116
+ label: "Discord thread bindings",
117
+ sourcePath: threadBindingsSourcePath,
118
+ targetPath: `plugin state:${THREAD_BINDINGS_NAMESPACE}`,
119
+ pluginId: "discord",
120
+ namespace: THREAD_BINDINGS_NAMESPACE,
121
+ maxEntries: THREAD_BINDINGS_MAX_ENTRIES,
122
+ scopeKey: "",
123
+ cleanupSource: "rename",
124
+ cleanupWhenEmpty: true,
125
+ readEntries: () => {
126
+ const store = readLegacyThreadBindingsStore(threadBindingsSourcePath);
127
+ if (store?.version !== 1 || !store.bindings || typeof store.bindings !== "object") throw new Error("legacy Discord thread bindings store must have version 1 bindings");
128
+ const out = [];
129
+ for (const [rawKey, rawEntry] of Object.entries(store.bindings)) {
130
+ const normalized = normalizePersistedBinding(rawKey, upgradeLegacyThreadBindingShape(rawEntry));
131
+ if (normalized) out.push({
132
+ key: toBindingRecordKey(normalized),
133
+ value: normalized
134
+ });
135
+ }
136
+ return out;
133
137
  }
134
- return out;
135
- }
136
- });
138
+ });
139
+ }
137
140
  return plans;
138
141
  };
139
142
  //#endregion