@kodelyth/discord 2026.5.39 → 2026.5.42

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 (639) hide show
  1. package/account-inspect-api.ts +6 -0
  2. package/action-runtime-api.ts +1 -0
  3. package/api.ts +130 -0
  4. package/channel-config-api.ts +1 -0
  5. package/channel-plugin-api.ts +3 -0
  6. package/config-api.ts +4 -0
  7. package/configured-state.ts +6 -0
  8. package/contract-api.ts +21 -0
  9. package/directory-contract-api.ts +4 -0
  10. package/dist/account-inspect-Dqw-enky.js +81 -0
  11. package/dist/account-inspect-api.js +10 -0
  12. package/dist/accounts-B7OBFePq.js +224 -0
  13. package/dist/action-runtime-api.js +2 -0
  14. package/dist/agent-components.runtime-DVY_1VB4.js +4 -0
  15. package/dist/allow-list-B0s7evD7.js +354 -0
  16. package/dist/api-CXAcv9nZ.js +130 -0
  17. package/dist/api.js +23 -0
  18. package/dist/approval-handler.runtime-B9xUAF3n.js +426 -0
  19. package/dist/audit-DoiK49WO.js +24 -0
  20. package/dist/audit-core-BGrq3G7r.js +105 -0
  21. package/dist/channel-U_aeoFwW.js +795 -0
  22. package/dist/channel-actions-BxEBnEuv.js +173 -0
  23. package/dist/channel-actions.runtime-CPtpH-yl.js +263 -0
  24. package/dist/channel-api-BfjklLby.js +21 -0
  25. package/dist/channel-config-api.js +2 -0
  26. package/dist/channel-plugin-api.js +2 -0
  27. package/dist/channel.setup-BUSC0apv.js +337 -0
  28. package/dist/components-luonoe13.js +909 -0
  29. package/dist/config-api-DSYGqaLQ.js +2 -0
  30. package/dist/config-schema-DIqJBGwC.js +357 -0
  31. package/dist/configured-state.js +6 -0
  32. package/dist/contract-api.js +8 -0
  33. package/dist/conversation-identity-DXAm0_Mk.js +270 -0
  34. package/dist/directory-config-CYbuMmPS.js +49 -0
  35. package/dist/directory-contract-api.js +2 -0
  36. package/dist/directory-live-DX4dLRpJ.js +159 -0
  37. package/dist/doctor-bbKSvGVD.js +244 -0
  38. package/dist/doctor-contract-Btjt6NJD.js +383 -0
  39. package/dist/doctor-contract-api.js +2 -0
  40. package/dist/gateway-registry-BKSpa4GB.js +74 -0
  41. package/dist/handle-action.guild-admin-B5BArS2n.js +286 -0
  42. package/dist/inbound-context-WAOqhGlT.js +48 -0
  43. package/dist/inbound-event-delivery-C-1Ji3WP.js +65 -0
  44. package/dist/index.js +26 -0
  45. package/dist/manager.runtime-DXHynKE4.js +2356 -0
  46. package/dist/message-handler-mXzc3tA_.js +381 -0
  47. package/dist/message-handler.preflight-BPD1a347.js +1113 -0
  48. package/dist/message-handler.process-GUa3aV8z.js +1438 -0
  49. package/dist/message-utils-dUbem16p.js +549 -0
  50. package/dist/outbound-adapter-C18OAc1y.js +536 -0
  51. package/dist/pluralkit-D1Q2x0w5.js +22 -0
  52. package/dist/preflight-audio-CZtpWcIm.js +72 -0
  53. package/dist/preflight-audio.runtime-Brx_0_xW.js +7 -0
  54. package/dist/preview-streaming-D_slNIiO.js +8 -0
  55. package/dist/probe-D--Ca4JF.js +139 -0
  56. package/dist/probe.runtime-DQBchZzv.js +2 -0
  57. package/dist/provider-B2-31CIT.js +9565 -0
  58. package/dist/provider-session.runtime-BwzzSsrH.js +6 -0
  59. package/dist/provider.runtime-CP3oHLls.js +2 -0
  60. package/dist/resolve-allowlist-common-CqxPLcJO.js +34 -0
  61. package/dist/resolve-channels-0LX4pUbB.js +265 -0
  62. package/dist/resolve-users-CztOv0Qs.js +120 -0
  63. package/dist/runtime-DUaw66V_.js +1073 -0
  64. package/dist/runtime-api.actions.js +3 -0
  65. package/dist/runtime-api.js +30 -0
  66. package/dist/runtime-api.lookup.js +7 -0
  67. package/dist/runtime-api.monitor-CvVKvEXW.js +5 -0
  68. package/dist/runtime-api.monitor.js +8 -0
  69. package/dist/runtime-api.send.js +6 -0
  70. package/dist/runtime-api.threads.js +6 -0
  71. package/dist/runtime-fC6f4UF2.js +8 -0
  72. package/dist/runtime-setter-api.js +2 -0
  73. package/dist/secret-config-contract-B6WW5V88.js +115 -0
  74. package/dist/secret-contract-api.js +2 -0
  75. package/dist/security-audit-CnyIQKz6.js +120 -0
  76. package/dist/security-audit-contract-api.js +2 -0
  77. package/dist/security-audit.runtime-CQSkjNLu.js +2 -0
  78. package/dist/security-contract-DLvYOgLM.js +26 -0
  79. package/dist/security-contract-api.js +2 -0
  80. package/dist/security-doctor-DepqtNCI.js +18 -0
  81. package/dist/send-DCtPCHGk.js +881 -0
  82. package/dist/send.components-Bcgxvm52.js +474 -0
  83. package/dist/send.outbound-S9t0UuHc.js +330 -0
  84. package/dist/send.receipt-CDn3GBWC.js +3119 -0
  85. package/dist/send.shared-D4iBnAmn.js +669 -0
  86. package/dist/sender-identity-CxCe3_1a.js +43 -0
  87. package/dist/session-contract-Dwhw3RTY.js +6 -0
  88. package/dist/session-key-api.js +2 -0
  89. package/dist/session-key-normalization-CP8dPUid.js +23 -0
  90. package/dist/setup-entry.js +11 -0
  91. package/dist/setup-plugin-api.js +2 -0
  92. package/dist/shared-AIlvuZXt.js +171 -0
  93. package/dist/subagent-hooks-8bK-mgiU.js +120 -0
  94. package/dist/subagent-hooks-api.js +22 -0
  95. package/dist/system-events-Ba1TklaL.js +34 -0
  96. package/dist/target-resolver-BrtFQtoK.js +82 -0
  97. package/dist/targets-DWLLZE2l.js +3 -0
  98. package/dist/test-api.js +45 -0
  99. package/dist/thread-binding-api.js +4 -0
  100. package/dist/thread-bindings-9aKRmZv0.js +255 -0
  101. package/dist/thread-bindings.discord-api-ssGH5wc2.js +244 -0
  102. package/dist/thread-bindings.manager-0YBHGemk.js +534 -0
  103. package/dist/thread-bindings.session-updates-DJZGIwaU.js +54 -0
  104. package/dist/thread-bindings.state-eTFl-PqJ.js +318 -0
  105. package/dist/timeouts-CEwuGaWT.js +52 -0
  106. package/dist/timeouts.js +2 -0
  107. package/dist/typing-BmJKRpCS.js +14 -0
  108. package/doctor-contract-api.ts +1 -0
  109. package/index.test.ts +13 -0
  110. package/index.ts +24 -0
  111. package/klaw.plugin.json +2 -3822
  112. package/package.json +4 -4
  113. package/runtime-api.actions.ts +15 -0
  114. package/runtime-api.lookup.ts +22 -0
  115. package/runtime-api.monitor.ts +50 -0
  116. package/runtime-api.send.ts +79 -0
  117. package/runtime-api.threads.ts +31 -0
  118. package/runtime-api.ts +181 -0
  119. package/runtime-setter-api.ts +3 -0
  120. package/secret-contract-api.ts +4 -0
  121. package/security-audit-contract-api.ts +1 -0
  122. package/security-contract-api.ts +4 -0
  123. package/session-key-api.ts +1 -0
  124. package/setup-entry.ts +9 -0
  125. package/setup-plugin-api.ts +3 -0
  126. package/src/account-inspect.test.ts +126 -0
  127. package/src/account-inspect.ts +128 -0
  128. package/src/accounts.test.ts +381 -0
  129. package/src/accounts.ts +205 -0
  130. package/src/actions/handle-action.guild-admin.ts +421 -0
  131. package/src/actions/handle-action.test.ts +480 -0
  132. package/src/actions/handle-action.ts +402 -0
  133. package/src/actions/runtime.guild.ts +446 -0
  134. package/src/actions/runtime.messaging.messages.ts +226 -0
  135. package/src/actions/runtime.messaging.reactions.ts +67 -0
  136. package/src/actions/runtime.messaging.runtime.ts +73 -0
  137. package/src/actions/runtime.messaging.send.ts +336 -0
  138. package/src/actions/runtime.messaging.shared.ts +97 -0
  139. package/src/actions/runtime.messaging.ts +37 -0
  140. package/src/actions/runtime.moderation-shared.ts +48 -0
  141. package/src/actions/runtime.moderation.authz.test.ts +151 -0
  142. package/src/actions/runtime.moderation.ts +116 -0
  143. package/src/actions/runtime.presence.test.ts +165 -0
  144. package/src/actions/runtime.presence.ts +117 -0
  145. package/src/actions/runtime.shared.ts +86 -0
  146. package/src/actions/runtime.test.ts +1337 -0
  147. package/src/actions/runtime.ts +87 -0
  148. package/src/api-barrel.test.ts +78 -0
  149. package/src/api.test.ts +152 -0
  150. package/src/api.ts +215 -0
  151. package/src/approval-handler.runtime.test.ts +41 -0
  152. package/src/approval-handler.runtime.ts +633 -0
  153. package/src/approval-native.test.ts +330 -0
  154. package/src/approval-native.ts +219 -0
  155. package/src/approval-runtime.ts +14 -0
  156. package/src/approval-shared.ts +50 -0
  157. package/src/audit-core.ts +178 -0
  158. package/src/audit.test.ts +204 -0
  159. package/src/audit.ts +32 -0
  160. package/src/channel-actions.contract.test.ts +45 -0
  161. package/src/channel-actions.runtime.ts +1 -0
  162. package/src/channel-actions.test.ts +504 -0
  163. package/src/channel-actions.ts +254 -0
  164. package/src/channel-api.ts +29 -0
  165. package/src/channel.conversation.ts +159 -0
  166. package/src/channel.loaders.ts +50 -0
  167. package/src/channel.message-adapter.test.ts +230 -0
  168. package/src/channel.runtime.ts +1 -0
  169. package/src/channel.setup.ts +12 -0
  170. package/src/channel.test.ts +828 -0
  171. package/src/channel.ts +728 -0
  172. package/src/chunk.test.ts +170 -0
  173. package/src/chunk.ts +321 -0
  174. package/src/client.proxy.test.ts +177 -0
  175. package/src/client.test.ts +83 -0
  176. package/src/client.ts +143 -0
  177. package/src/component-custom-id.ts +72 -0
  178. package/src/components-registry.ts +356 -0
  179. package/src/components.builders.ts +409 -0
  180. package/src/components.modal.ts +124 -0
  181. package/src/components.parse.ts +407 -0
  182. package/src/components.test.ts +345 -0
  183. package/src/components.ts +54 -0
  184. package/src/components.types.ts +187 -0
  185. package/src/config-schema.test.ts +439 -0
  186. package/src/config-schema.ts +6 -0
  187. package/src/config-ui-hints.ts +354 -0
  188. package/src/conversation-identity.ts +58 -0
  189. package/src/delivery-retry.ts +52 -0
  190. package/src/directory-cache.ts +116 -0
  191. package/src/directory-config.ts +58 -0
  192. package/src/directory-contract.test.ts +129 -0
  193. package/src/directory-live.test.ts +141 -0
  194. package/src/directory-live.ts +135 -0
  195. package/src/doctor-contract.ts +477 -0
  196. package/src/doctor-shared.ts +5 -0
  197. package/src/doctor.test.ts +393 -0
  198. package/src/doctor.ts +340 -0
  199. package/src/draft-chunking.test.ts +64 -0
  200. package/src/draft-chunking.ts +43 -0
  201. package/src/draft-stream.test.ts +193 -0
  202. package/src/draft-stream.ts +162 -0
  203. package/src/durable-delivery.test.ts +103 -0
  204. package/src/error-body.ts +38 -0
  205. package/src/exec-approvals.test.ts +88 -0
  206. package/src/exec-approvals.ts +110 -0
  207. package/src/gateway-logging.test.ts +98 -0
  208. package/src/gateway-logging.ts +67 -0
  209. package/src/group-policy.ts +113 -0
  210. package/src/guilds.ts +29 -0
  211. package/src/inbound-context.contract.test.ts +11 -0
  212. package/src/inbound-event-delivery.ts +135 -0
  213. package/src/interactive-dispatch.ts +104 -0
  214. package/src/internal/api.commands.ts +51 -0
  215. package/src/internal/api.guild.ts +164 -0
  216. package/src/internal/api.interactions.ts +53 -0
  217. package/src/internal/api.messages.ts +113 -0
  218. package/src/internal/api.reactions.ts +38 -0
  219. package/src/internal/api.test.ts +260 -0
  220. package/src/internal/api.ts +61 -0
  221. package/src/internal/api.users.ts +19 -0
  222. package/src/internal/api.webhooks.ts +13 -0
  223. package/src/internal/client.test.ts +472 -0
  224. package/src/internal/client.ts +310 -0
  225. package/src/internal/command-deploy.test.ts +197 -0
  226. package/src/internal/command-deploy.ts +352 -0
  227. package/src/internal/commands.ts +188 -0
  228. package/src/internal/components.base.ts +65 -0
  229. package/src/internal/components.message.ts +279 -0
  230. package/src/internal/components.modal.ts +95 -0
  231. package/src/internal/components.ts +31 -0
  232. package/src/internal/discord.ts +11 -0
  233. package/src/internal/embeds.ts +35 -0
  234. package/src/internal/entity-cache.ts +98 -0
  235. package/src/internal/event-queue.ts +185 -0
  236. package/src/internal/gateway-close-codes.ts +25 -0
  237. package/src/internal/gateway-dispatch.ts +96 -0
  238. package/src/internal/gateway-identify-limiter.ts +26 -0
  239. package/src/internal/gateway-lifecycle.test.ts +114 -0
  240. package/src/internal/gateway-lifecycle.ts +75 -0
  241. package/src/internal/gateway-rate-limit.ts +104 -0
  242. package/src/internal/gateway.test.ts +676 -0
  243. package/src/internal/gateway.ts +479 -0
  244. package/src/internal/interaction-dispatch.test.ts +148 -0
  245. package/src/internal/interaction-dispatch.ts +162 -0
  246. package/src/internal/interaction-options.ts +98 -0
  247. package/src/internal/interaction-response.ts +53 -0
  248. package/src/internal/interactions.test.ts +329 -0
  249. package/src/internal/interactions.ts +378 -0
  250. package/src/internal/listeners.ts +91 -0
  251. package/src/internal/live-smoke.live.test.ts +26 -0
  252. package/src/internal/modal-fields.ts +95 -0
  253. package/src/internal/payload.ts +69 -0
  254. package/src/internal/rest-body.ts +115 -0
  255. package/src/internal/rest-errors.ts +88 -0
  256. package/src/internal/rest-routes.ts +50 -0
  257. package/src/internal/rest-scheduler.ts +557 -0
  258. package/src/internal/rest.test.ts +681 -0
  259. package/src/internal/rest.ts +322 -0
  260. package/src/internal/schemas.ts +36 -0
  261. package/src/internal/structures.test.ts +43 -0
  262. package/src/internal/structures.ts +280 -0
  263. package/src/internal/test-builders.test-support.ts +167 -0
  264. package/src/internal/voice.ts +49 -0
  265. package/src/media-detection.ts +28 -0
  266. package/src/mentions.test.ts +111 -0
  267. package/src/mentions.ts +147 -0
  268. package/src/monitor/ack-reactions.ts +70 -0
  269. package/src/monitor/acp-bind-here.integration.test.ts +219 -0
  270. package/src/monitor/agent-components-auth.ts +7 -0
  271. package/src/monitor/agent-components-context.ts +154 -0
  272. package/src/monitor/agent-components-data.ts +224 -0
  273. package/src/monitor/agent-components-dm-auth.ts +177 -0
  274. package/src/monitor/agent-components-guild-auth.ts +322 -0
  275. package/src/monitor/agent-components-helpers.runtime.ts +3 -0
  276. package/src/monitor/agent-components-helpers.ts +34 -0
  277. package/src/monitor/agent-components-reply.ts +10 -0
  278. package/src/monitor/agent-components.deps.runtime.ts +2 -0
  279. package/src/monitor/agent-components.dispatch.ts +359 -0
  280. package/src/monitor/agent-components.handlers.ts +303 -0
  281. package/src/monitor/agent-components.modal.ts +160 -0
  282. package/src/monitor/agent-components.plugin-interactive.ts +187 -0
  283. package/src/monitor/agent-components.runtime.ts +14 -0
  284. package/src/monitor/agent-components.system-controls.ts +215 -0
  285. package/src/monitor/agent-components.ts +70 -0
  286. package/src/monitor/agent-components.types.ts +58 -0
  287. package/src/monitor/agent-components.wildcard-controls.ts +171 -0
  288. package/src/monitor/agent-components.wildcard.test.ts +71 -0
  289. package/src/monitor/allow-list.test.ts +14 -0
  290. package/src/monitor/allow-list.ts +631 -0
  291. package/src/monitor/auto-presence.test.ts +184 -0
  292. package/src/monitor/auto-presence.ts +356 -0
  293. package/src/monitor/channel-access.test.ts +113 -0
  294. package/src/monitor/channel-access.ts +102 -0
  295. package/src/monitor/commands.test.ts +24 -0
  296. package/src/monitor/commands.ts +9 -0
  297. package/src/monitor/dm-command-auth.test.ts +274 -0
  298. package/src/monitor/dm-command-auth.ts +259 -0
  299. package/src/monitor/dm-command-decision.test.ts +108 -0
  300. package/src/monitor/dm-command-decision.ts +49 -0
  301. package/src/monitor/exec-approvals.test.ts +225 -0
  302. package/src/monitor/exec-approvals.ts +158 -0
  303. package/src/monitor/format.ts +45 -0
  304. package/src/monitor/gateway-handle.ts +33 -0
  305. package/src/monitor/gateway-metadata.test.ts +29 -0
  306. package/src/monitor/gateway-metadata.ts +298 -0
  307. package/src/monitor/gateway-plugin.test.ts +320 -0
  308. package/src/monitor/gateway-plugin.ts +302 -0
  309. package/src/monitor/gateway-registry.ts +37 -0
  310. package/src/monitor/gateway-supervisor.test.ts +157 -0
  311. package/src/monitor/gateway-supervisor.ts +206 -0
  312. package/src/monitor/inbound-context.test-helpers.ts +37 -0
  313. package/src/monitor/inbound-context.test.ts +112 -0
  314. package/src/monitor/inbound-context.ts +95 -0
  315. package/src/monitor/inbound-dedupe.ts +79 -0
  316. package/src/monitor/inbound-job.test.ts +216 -0
  317. package/src/monitor/inbound-job.ts +118 -0
  318. package/src/monitor/listeners.queue.ts +91 -0
  319. package/src/monitor/listeners.reactions.ts +594 -0
  320. package/src/monitor/listeners.test.ts +209 -0
  321. package/src/monitor/listeners.ts +150 -0
  322. package/src/monitor/message-channel-info.ts +96 -0
  323. package/src/monitor/message-forwarded.ts +114 -0
  324. package/src/monitor/message-handler.batch-gate.test.ts +22 -0
  325. package/src/monitor/message-handler.batch-gate.ts +19 -0
  326. package/src/monitor/message-handler.bot-self-filter.test.ts +68 -0
  327. package/src/monitor/message-handler.context.ts +492 -0
  328. package/src/monitor/message-handler.dm-preflight.ts +119 -0
  329. package/src/monitor/message-handler.draft-preview.ts +426 -0
  330. package/src/monitor/message-handler.hydration.test.ts +80 -0
  331. package/src/monitor/message-handler.hydration.ts +198 -0
  332. package/src/monitor/message-handler.inbound-context.test.ts +61 -0
  333. package/src/monitor/message-handler.module-test-helpers.ts +31 -0
  334. package/src/monitor/message-handler.preflight-channel-access.ts +86 -0
  335. package/src/monitor/message-handler.preflight-channel-context.test.ts +18 -0
  336. package/src/monitor/message-handler.preflight-channel-context.ts +58 -0
  337. package/src/monitor/message-handler.preflight-context.ts +54 -0
  338. package/src/monitor/message-handler.preflight-helpers.ts +164 -0
  339. package/src/monitor/message-handler.preflight-history.ts +23 -0
  340. package/src/monitor/message-handler.preflight-logging.ts +36 -0
  341. package/src/monitor/message-handler.preflight-pluralkit.ts +26 -0
  342. package/src/monitor/message-handler.preflight-runtime.ts +28 -0
  343. package/src/monitor/message-handler.preflight-thread.ts +49 -0
  344. package/src/monitor/message-handler.preflight.acp-bindings.test.ts +371 -0
  345. package/src/monitor/message-handler.preflight.test-helpers.ts +114 -0
  346. package/src/monitor/message-handler.preflight.test.ts +2255 -0
  347. package/src/monitor/message-handler.preflight.ts +822 -0
  348. package/src/monitor/message-handler.preflight.types.ts +115 -0
  349. package/src/monitor/message-handler.process.test.ts +2520 -0
  350. package/src/monitor/message-handler.process.ts +1027 -0
  351. package/src/monitor/message-handler.queue.test.ts +680 -0
  352. package/src/monitor/message-handler.routing-preflight.ts +112 -0
  353. package/src/monitor/message-handler.test-harness.ts +99 -0
  354. package/src/monitor/message-handler.test-helpers.ts +75 -0
  355. package/src/monitor/message-handler.ts +309 -0
  356. package/src/monitor/message-media.ts +536 -0
  357. package/src/monitor/message-run-queue.ts +101 -0
  358. package/src/monitor/message-text.ts +171 -0
  359. package/src/monitor/message-utils.test.ts +1234 -0
  360. package/src/monitor/message-utils.ts +34 -0
  361. package/src/monitor/model-picker-preferences.test.ts +67 -0
  362. package/src/monitor/model-picker-preferences.ts +184 -0
  363. package/src/monitor/model-picker.state.ts +364 -0
  364. package/src/monitor/model-picker.test-utils.ts +26 -0
  365. package/src/monitor/model-picker.test.ts +869 -0
  366. package/src/monitor/model-picker.ts +38 -0
  367. package/src/monitor/model-picker.view.ts +722 -0
  368. package/src/monitor/monitor.agent-components.test.ts +410 -0
  369. package/src/monitor/monitor.test.ts +919 -0
  370. package/src/monitor/monitor.threading-utils.test.ts +614 -0
  371. package/src/monitor/native-command-agent-reply.ts +125 -0
  372. package/src/monitor/native-command-arg-ui.ts +233 -0
  373. package/src/monitor/native-command-auth.ts +309 -0
  374. package/src/monitor/native-command-bypass.ts +13 -0
  375. package/src/monitor/native-command-context.test.ts +105 -0
  376. package/src/monitor/native-command-context.ts +109 -0
  377. package/src/monitor/native-command-dispatch.ts +35 -0
  378. package/src/monitor/native-command-model-picker-apply.ts +209 -0
  379. package/src/monitor/native-command-model-picker-interaction.ts +516 -0
  380. package/src/monitor/native-command-model-picker-ui.ts +357 -0
  381. package/src/monitor/native-command-reply.test.ts +68 -0
  382. package/src/monitor/native-command-reply.ts +185 -0
  383. package/src/monitor/native-command-route.ts +91 -0
  384. package/src/monitor/native-command-status.ts +76 -0
  385. package/src/monitor/native-command-ui.ts +26 -0
  386. package/src/monitor/native-command-ui.types.ts +20 -0
  387. package/src/monitor/native-command.args.ts +45 -0
  388. package/src/monitor/native-command.command-arg.test.ts +108 -0
  389. package/src/monitor/native-command.commands-allowfrom.test.ts +504 -0
  390. package/src/monitor/native-command.model-picker.test.ts +930 -0
  391. package/src/monitor/native-command.options.test.ts +379 -0
  392. package/src/monitor/native-command.options.ts +153 -0
  393. package/src/monitor/native-command.plugin-dispatch.test.ts +1212 -0
  394. package/src/monitor/native-command.runtime.ts +51 -0
  395. package/src/monitor/native-command.status-direct.test.ts +278 -0
  396. package/src/monitor/native-command.test-helpers.ts +64 -0
  397. package/src/monitor/native-command.think-autocomplete.test.ts +411 -0
  398. package/src/monitor/native-command.ts +747 -0
  399. package/src/monitor/native-command.types.ts +9 -0
  400. package/src/monitor/native-interaction-channel-context.ts +50 -0
  401. package/src/monitor/preflight-audio.runtime.ts +9 -0
  402. package/src/monitor/preflight-audio.test.ts +157 -0
  403. package/src/monitor/preflight-audio.ts +130 -0
  404. package/src/monitor/presence-cache.ts +61 -0
  405. package/src/monitor/presence.test.ts +61 -0
  406. package/src/monitor/presence.ts +50 -0
  407. package/src/monitor/provider-session.runtime.ts +12 -0
  408. package/src/monitor/provider.acp.ts +89 -0
  409. package/src/monitor/provider.allowlist.test.ts +217 -0
  410. package/src/monitor/provider.allowlist.ts +398 -0
  411. package/src/monitor/provider.cleanup.ts +41 -0
  412. package/src/monitor/provider.commands.ts +129 -0
  413. package/src/monitor/provider.config-log.ts +45 -0
  414. package/src/monitor/provider.deploy-errors.ts +362 -0
  415. package/src/monitor/provider.deploy.ts +221 -0
  416. package/src/monitor/provider.interactions.ts +160 -0
  417. package/src/monitor/provider.lifecycle.test.ts +734 -0
  418. package/src/monitor/provider.lifecycle.ts +562 -0
  419. package/src/monitor/provider.proxy.test.ts +804 -0
  420. package/src/monitor/provider.rest-proxy.test.ts +389 -0
  421. package/src/monitor/provider.runtime.ts +1 -0
  422. package/src/monitor/provider.skill-dedupe.test.ts +42 -0
  423. package/src/monitor/provider.startup-log.ts +32 -0
  424. package/src/monitor/provider.startup.test.ts +440 -0
  425. package/src/monitor/provider.startup.ts +323 -0
  426. package/src/monitor/provider.test.ts +1173 -0
  427. package/src/monitor/provider.ts +688 -0
  428. package/src/monitor/reply-context.ts +64 -0
  429. package/src/monitor/reply-delivery.test.ts +474 -0
  430. package/src/monitor/reply-delivery.ts +212 -0
  431. package/src/monitor/reply-safety.ts +96 -0
  432. package/src/monitor/rest-fetch.ts +94 -0
  433. package/src/monitor/route-resolution.test.ts +209 -0
  434. package/src/monitor/route-resolution.ts +140 -0
  435. package/src/monitor/sender-identity.ts +81 -0
  436. package/src/monitor/startup-status.test.ts +30 -0
  437. package/src/monitor/startup-status.ts +10 -0
  438. package/src/monitor/status.ts +22 -0
  439. package/src/monitor/system-events.ts +55 -0
  440. package/src/monitor/thread-bindings.config.ts +35 -0
  441. package/src/monitor/thread-bindings.discord-api.test.ts +250 -0
  442. package/src/monitor/thread-bindings.discord-api.ts +310 -0
  443. package/src/monitor/thread-bindings.lifecycle.test.ts +1994 -0
  444. package/src/monitor/thread-bindings.lifecycle.ts +354 -0
  445. package/src/monitor/thread-bindings.manager.ts +551 -0
  446. package/src/monitor/thread-bindings.messages.ts +6 -0
  447. package/src/monitor/thread-bindings.persona.test.ts +34 -0
  448. package/src/monitor/thread-bindings.persona.ts +25 -0
  449. package/src/monitor/thread-bindings.session-adapter.ts +229 -0
  450. package/src/monitor/thread-bindings.session-shared.ts +59 -0
  451. package/src/monitor/thread-bindings.session-updates.ts +35 -0
  452. package/src/monitor/thread-bindings.shared-state.test.ts +39 -0
  453. package/src/monitor/thread-bindings.state.ts +540 -0
  454. package/src/monitor/thread-bindings.ts +48 -0
  455. package/src/monitor/thread-bindings.types.ts +83 -0
  456. package/src/monitor/thread-channel-context.ts +112 -0
  457. package/src/monitor/thread-session-close.test.ts +180 -0
  458. package/src/monitor/thread-session-close.ts +63 -0
  459. package/src/monitor/thread-title.generate.test.ts +209 -0
  460. package/src/monitor/thread-title.test.ts +31 -0
  461. package/src/monitor/thread-title.ts +181 -0
  462. package/src/monitor/threading.auto-thread.test.ts +330 -0
  463. package/src/monitor/threading.auto-thread.ts +287 -0
  464. package/src/monitor/threading.cache.ts +45 -0
  465. package/src/monitor/threading.parent-info.test.ts +156 -0
  466. package/src/monitor/threading.starter.test.ts +279 -0
  467. package/src/monitor/threading.starter.ts +288 -0
  468. package/src/monitor/threading.ts +20 -0
  469. package/src/monitor/threading.types.ts +102 -0
  470. package/src/monitor/timeouts.ts +84 -0
  471. package/src/monitor/typing.test.ts +42 -0
  472. package/src/monitor/typing.ts +17 -0
  473. package/src/monitor.gateway.test.ts +187 -0
  474. package/src/monitor.gateway.ts +75 -0
  475. package/src/monitor.test.ts +1416 -0
  476. package/src/monitor.ts +28 -0
  477. package/src/network-config.test.ts +92 -0
  478. package/src/network-config.ts +79 -0
  479. package/src/normalize.test.ts +56 -0
  480. package/src/normalize.ts +86 -0
  481. package/src/outbound-adapter.interactive-order.test.ts +82 -0
  482. package/src/outbound-adapter.test-harness.ts +207 -0
  483. package/src/outbound-adapter.test.ts +804 -0
  484. package/src/outbound-adapter.ts +326 -0
  485. package/src/outbound-approval.ts +29 -0
  486. package/src/outbound-components.ts +86 -0
  487. package/src/outbound-payload.contract.test.ts +49 -0
  488. package/src/outbound-payload.ts +208 -0
  489. package/src/outbound-send-context.ts +89 -0
  490. package/src/outbound-session-route.test.ts +42 -0
  491. package/src/outbound-session-route.ts +72 -0
  492. package/src/pluralkit.test.ts +67 -0
  493. package/src/pluralkit.ts +58 -0
  494. package/src/preview-streaming.ts +18 -0
  495. package/src/probe.intents.test.ts +94 -0
  496. package/src/probe.parse-token.test.ts +43 -0
  497. package/src/probe.runtime.ts +1 -0
  498. package/src/probe.ts +237 -0
  499. package/src/proxy-fetch.ts +92 -0
  500. package/src/proxy-request-client.test.ts +100 -0
  501. package/src/proxy-request-client.ts +21 -0
  502. package/src/recipient-resolution.ts +39 -0
  503. package/src/resolve-allowlist-common.test.ts +40 -0
  504. package/src/resolve-allowlist-common.ts +39 -0
  505. package/src/resolve-channels.test.ts +341 -0
  506. package/src/resolve-channels.ts +369 -0
  507. package/src/resolve-users.test.ts +243 -0
  508. package/src/resolve-users.ts +184 -0
  509. package/src/retry.test.ts +83 -0
  510. package/src/retry.ts +98 -0
  511. package/src/runtime-api.ts +61 -0
  512. package/src/runtime-config.ts +16 -0
  513. package/src/runtime.ts +23 -0
  514. package/src/secret-config-contract.ts +140 -0
  515. package/src/security-audit.runtime.ts +1 -0
  516. package/src/security-audit.test.ts +245 -0
  517. package/src/security-audit.ts +208 -0
  518. package/src/security-contract.ts +47 -0
  519. package/src/security-doctor.test.ts +25 -0
  520. package/src/security-doctor.ts +20 -0
  521. package/src/security.ts +60 -0
  522. package/src/send-target-parsing.ts +14 -0
  523. package/src/send.channels.ts +139 -0
  524. package/src/send.components.test.ts +330 -0
  525. package/src/send.components.ts +391 -0
  526. package/src/send.creates-thread.test.ts +681 -0
  527. package/src/send.emojis-stickers.ts +57 -0
  528. package/src/send.guild.ts +170 -0
  529. package/src/send.message-request.ts +112 -0
  530. package/src/send.messages.test.ts +59 -0
  531. package/src/send.messages.ts +229 -0
  532. package/src/send.outbound.ts +459 -0
  533. package/src/send.permissions.authz.test.ts +190 -0
  534. package/src/send.permissions.ts +283 -0
  535. package/src/send.reactions.ts +155 -0
  536. package/src/send.receipt.ts +69 -0
  537. package/src/send.sends-basic-channel-messages.test.ts +1068 -0
  538. package/src/send.shared.ts +469 -0
  539. package/src/send.test-harness.ts +56 -0
  540. package/src/send.ts +82 -0
  541. package/src/send.types.ts +191 -0
  542. package/src/send.typing.test.ts +41 -0
  543. package/src/send.typing.ts +9 -0
  544. package/src/send.voice.ts +136 -0
  545. package/src/send.webhook-activity.test.ts +152 -0
  546. package/src/send.webhook.proxy.test.ts +210 -0
  547. package/src/send.webhook.ts +137 -0
  548. package/src/session-contract.ts +3 -0
  549. package/src/session-key-normalization.test.ts +44 -0
  550. package/src/session-key-normalization.ts +47 -0
  551. package/src/setup-account-state.test.ts +113 -0
  552. package/src/setup-account-state.ts +141 -0
  553. package/src/setup-adapter.ts +14 -0
  554. package/src/setup-core.ts +215 -0
  555. package/src/setup-runtime-helpers.ts +10 -0
  556. package/src/setup-surface.test.ts +137 -0
  557. package/src/setup-surface.ts +132 -0
  558. package/src/shared-interactive.test.ts +153 -0
  559. package/src/shared-interactive.ts +161 -0
  560. package/src/shared.test.ts +186 -0
  561. package/src/shared.ts +197 -0
  562. package/src/status-issues.test.ts +97 -0
  563. package/src/status-issues.ts +198 -0
  564. package/src/subagent-hooks.test.ts +465 -0
  565. package/src/subagent-hooks.ts +232 -0
  566. package/src/target-parsing.ts +70 -0
  567. package/src/target-resolver.ts +129 -0
  568. package/src/targets.test.ts +393 -0
  569. package/src/targets.ts +12 -0
  570. package/src/test-http-helpers.ts +10 -0
  571. package/src/test-support/component-runtime.ts +194 -0
  572. package/src/test-support/config.ts +7 -0
  573. package/src/test-support/configured-binding-runtime.ts +29 -0
  574. package/src/test-support/partial-channel.ts +26 -0
  575. package/src/test-support/provider.test-support.ts +547 -0
  576. package/src/token.test.ts +174 -0
  577. package/src/token.ts +107 -0
  578. package/src/ui-colors.ts +27 -0
  579. package/src/ui.ts +20 -0
  580. package/src/voice/access.test.ts +288 -0
  581. package/src/voice/access.ts +126 -0
  582. package/src/voice/audio.test.ts +47 -0
  583. package/src/voice/audio.ts +249 -0
  584. package/src/voice/capture-state.test.ts +48 -0
  585. package/src/voice/capture-state.ts +120 -0
  586. package/src/voice/command.test.ts +170 -0
  587. package/src/voice/command.ts +284 -0
  588. package/src/voice/config.ts +8 -0
  589. package/src/voice/ingress.ts +164 -0
  590. package/src/voice/manager.e2e.test.ts +3286 -0
  591. package/src/voice/manager.ready-listener.test.ts +54 -0
  592. package/src/voice/manager.runtime.ts +14 -0
  593. package/src/voice/manager.ts +1155 -0
  594. package/src/voice/prompt.test.ts +30 -0
  595. package/src/voice/prompt.ts +22 -0
  596. package/src/voice/realtime.ts +1370 -0
  597. package/src/voice/receive-recovery.test.ts +81 -0
  598. package/src/voice/receive-recovery.ts +159 -0
  599. package/src/voice/sanitize.test.ts +34 -0
  600. package/src/voice/sanitize.ts +29 -0
  601. package/src/voice/sdk-runtime.ts +14 -0
  602. package/src/voice/segment.ts +160 -0
  603. package/src/voice/session.ts +81 -0
  604. package/src/voice/speaker-context.ts +127 -0
  605. package/src/voice/tts.ts +151 -0
  606. package/src/voice-message.test.ts +376 -0
  607. package/src/voice-message.ts +474 -0
  608. package/subagent-hooks-api.ts +27 -0
  609. package/test-api.ts +4 -0
  610. package/thread-binding-api.ts +1 -0
  611. package/timeouts.ts +6 -0
  612. package/tsconfig.json +16 -0
  613. package/account-inspect-api.js +0 -7
  614. package/action-runtime-api.js +0 -7
  615. package/api.js +0 -7
  616. package/channel-config-api.js +0 -7
  617. package/channel-plugin-api.js +0 -7
  618. package/configured-state.js +0 -7
  619. package/contract-api.js +0 -7
  620. package/directory-contract-api.js +0 -7
  621. package/doctor-contract-api.js +0 -7
  622. package/index.js +0 -7
  623. package/runtime-api.actions.js +0 -7
  624. package/runtime-api.js +0 -7
  625. package/runtime-api.lookup.js +0 -7
  626. package/runtime-api.monitor.js +0 -7
  627. package/runtime-api.send.js +0 -7
  628. package/runtime-api.threads.js +0 -7
  629. package/runtime-setter-api.js +0 -7
  630. package/secret-contract-api.js +0 -7
  631. package/security-audit-contract-api.js +0 -7
  632. package/security-contract-api.js +0 -7
  633. package/session-key-api.js +0 -7
  634. package/setup-entry.js +0 -7
  635. package/setup-plugin-api.js +0 -7
  636. package/subagent-hooks-api.js +0 -7
  637. package/test-api.js +0 -7
  638. package/thread-binding-api.js +0 -7
  639. package/timeouts.js +0 -7
@@ -0,0 +1,409 @@
1
+ import crypto from "node:crypto";
2
+ import { ButtonStyle, MessageFlags } from "discord-api-types/v10";
3
+ import { normalizeLowercaseStringOrEmpty } from "klaw/plugin-sdk/string-coerce-runtime";
4
+ import { buildDiscordComponentCustomId as buildDiscordComponentCustomIdImpl } from "./component-custom-id.js";
5
+ import { mapButtonStyle, normalizeModalFieldName } from "./components.parse.js";
6
+ import type {
7
+ DiscordComponentBuildResult,
8
+ DiscordComponentButtonSpec,
9
+ DiscordComponentEntry,
10
+ DiscordComponentMessageSpec,
11
+ DiscordComponentSelectSpec,
12
+ DiscordComponentSelectType,
13
+ DiscordModalEntry,
14
+ } from "./components.types.js";
15
+ import {
16
+ Button,
17
+ ChannelSelectMenu,
18
+ Container,
19
+ File,
20
+ LinkButton,
21
+ MediaGallery,
22
+ MentionableSelectMenu,
23
+ RoleSelectMenu,
24
+ Row,
25
+ Section,
26
+ Separator,
27
+ StringSelectMenu,
28
+ TextDisplay,
29
+ Thumbnail,
30
+ UserSelectMenu,
31
+ type TopLevelComponents,
32
+ } from "./internal/discord.js";
33
+
34
+ function createShortId(prefix: string) {
35
+ return `${prefix}${crypto.randomBytes(6).toString("base64url")}`;
36
+ }
37
+
38
+ function buildTextDisplays(text?: string, texts?: string[]): TextDisplay[] {
39
+ if (texts && texts.length > 0) {
40
+ return texts.map((entry) => new TextDisplay(entry));
41
+ }
42
+ if (text) {
43
+ return [new TextDisplay(text)];
44
+ }
45
+ return [];
46
+ }
47
+
48
+ function createButtonComponent(params: {
49
+ spec: DiscordComponentButtonSpec;
50
+ componentId?: string;
51
+ modalId?: string;
52
+ }): { component: Button | LinkButton; entry?: DiscordComponentEntry } {
53
+ const style = mapButtonStyle(params.spec.style);
54
+ const isLink = style === ButtonStyle.Link || Boolean(params.spec.url);
55
+ if (isLink) {
56
+ if (!params.spec.url) {
57
+ throw new Error("Link buttons require a url");
58
+ }
59
+ const linkUrl = params.spec.url;
60
+ class DynamicLinkButton extends LinkButton {
61
+ label = params.spec.label;
62
+ url = linkUrl;
63
+ }
64
+ return { component: new DynamicLinkButton() };
65
+ }
66
+ const componentId = params.componentId ?? createShortId("btn_");
67
+ const internalCustomId =
68
+ typeof params.spec.internalCustomId === "string" && params.spec.internalCustomId.trim()
69
+ ? params.spec.internalCustomId.trim()
70
+ : undefined;
71
+ const customId =
72
+ internalCustomId ??
73
+ buildDiscordComponentCustomIdImpl({
74
+ componentId,
75
+ modalId: params.modalId,
76
+ });
77
+ class DynamicButton extends Button {
78
+ label = params.spec.label;
79
+ customId = customId;
80
+ override style = style;
81
+ override emoji = params.spec.emoji;
82
+ override disabled = params.spec.disabled ?? false;
83
+ }
84
+ if (internalCustomId) {
85
+ return {
86
+ component: new DynamicButton(),
87
+ };
88
+ }
89
+ return {
90
+ component: new DynamicButton(),
91
+ entry: {
92
+ id: componentId,
93
+ kind: params.modalId ? "modal-trigger" : "button",
94
+ label: params.spec.label,
95
+ callbackData: params.spec.callbackData,
96
+ modalId: params.modalId,
97
+ allowedUsers: params.spec.allowedUsers,
98
+ },
99
+ };
100
+ }
101
+
102
+ function createSelectComponent(params: {
103
+ spec: DiscordComponentSelectSpec;
104
+ componentId?: string;
105
+ }): {
106
+ component:
107
+ | StringSelectMenu
108
+ | UserSelectMenu
109
+ | RoleSelectMenu
110
+ | MentionableSelectMenu
111
+ | ChannelSelectMenu;
112
+ entry: DiscordComponentEntry;
113
+ } {
114
+ const type = normalizeLowercaseStringOrEmpty(
115
+ params.spec.type ?? "string",
116
+ ) as DiscordComponentSelectType;
117
+ const componentId = params.componentId ?? createShortId("sel_");
118
+ const customId = buildDiscordComponentCustomIdImpl({ componentId });
119
+ const createEntry = (
120
+ selectType: DiscordComponentSelectType,
121
+ label: string,
122
+ options?: DiscordComponentEntry["options"],
123
+ ): DiscordComponentEntry => ({
124
+ id: componentId,
125
+ kind: "select",
126
+ label,
127
+ callbackData: params.spec.callbackData,
128
+ selectType,
129
+ ...(options ? { options } : {}),
130
+ allowedUsers: params.spec.allowedUsers,
131
+ });
132
+
133
+ if (type === "string") {
134
+ const options = params.spec.options ?? [];
135
+ if (options.length === 0) {
136
+ throw new Error("String select menus require options");
137
+ }
138
+ class DynamicStringSelect extends StringSelectMenu {
139
+ customId = customId;
140
+ override options = options;
141
+ override minValues = params.spec.minValues;
142
+ override maxValues = params.spec.maxValues;
143
+ override placeholder = params.spec.placeholder;
144
+ override disabled = false;
145
+ }
146
+ return {
147
+ component: new DynamicStringSelect(),
148
+ entry: createEntry(
149
+ "string",
150
+ params.spec.placeholder ?? "select",
151
+ options.map((option) => ({ value: option.value, label: option.label })),
152
+ ),
153
+ };
154
+ }
155
+ if (type === "user") {
156
+ class DynamicUserSelect extends UserSelectMenu {
157
+ customId = customId;
158
+ override minValues = params.spec.minValues;
159
+ override maxValues = params.spec.maxValues;
160
+ override placeholder = params.spec.placeholder;
161
+ override disabled = false;
162
+ }
163
+ return {
164
+ component: new DynamicUserSelect(),
165
+ entry: createEntry("user", params.spec.placeholder ?? "user select"),
166
+ };
167
+ }
168
+ if (type === "role") {
169
+ class DynamicRoleSelect extends RoleSelectMenu {
170
+ customId = customId;
171
+ override minValues = params.spec.minValues;
172
+ override maxValues = params.spec.maxValues;
173
+ override placeholder = params.spec.placeholder;
174
+ override disabled = false;
175
+ }
176
+ return {
177
+ component: new DynamicRoleSelect(),
178
+ entry: createEntry("role", params.spec.placeholder ?? "role select"),
179
+ };
180
+ }
181
+ if (type === "mentionable") {
182
+ class DynamicMentionableSelect extends MentionableSelectMenu {
183
+ customId = customId;
184
+ override minValues = params.spec.minValues;
185
+ override maxValues = params.spec.maxValues;
186
+ override placeholder = params.spec.placeholder;
187
+ override disabled = false;
188
+ }
189
+ return {
190
+ component: new DynamicMentionableSelect(),
191
+ entry: createEntry("mentionable", params.spec.placeholder ?? "mentionable select"),
192
+ };
193
+ }
194
+ class DynamicChannelSelect extends ChannelSelectMenu {
195
+ customId = customId;
196
+ override minValues = params.spec.minValues;
197
+ override maxValues = params.spec.maxValues;
198
+ override placeholder = params.spec.placeholder;
199
+ override disabled = false;
200
+ }
201
+ return {
202
+ component: new DynamicChannelSelect(),
203
+ entry: createEntry("channel", params.spec.placeholder ?? "channel select"),
204
+ };
205
+ }
206
+
207
+ function isSelectComponent(
208
+ component: unknown,
209
+ ): component is
210
+ | StringSelectMenu
211
+ | UserSelectMenu
212
+ | RoleSelectMenu
213
+ | MentionableSelectMenu
214
+ | ChannelSelectMenu {
215
+ return (
216
+ component instanceof StringSelectMenu ||
217
+ component instanceof UserSelectMenu ||
218
+ component instanceof RoleSelectMenu ||
219
+ component instanceof MentionableSelectMenu ||
220
+ component instanceof ChannelSelectMenu
221
+ );
222
+ }
223
+
224
+ export function buildDiscordComponentMessage(params: {
225
+ spec: DiscordComponentMessageSpec;
226
+ fallbackText?: string;
227
+ sessionKey?: string;
228
+ agentId?: string;
229
+ accountId?: string;
230
+ }): DiscordComponentBuildResult {
231
+ const entries: DiscordComponentEntry[] = [];
232
+ const consumptionGroupId = createShortId("grp_");
233
+ const modals: DiscordModalEntry[] = [];
234
+ const components: TopLevelComponents[] = [];
235
+ const containerChildren: Array<
236
+ | Row<
237
+ | Button
238
+ | LinkButton
239
+ | StringSelectMenu
240
+ | UserSelectMenu
241
+ | RoleSelectMenu
242
+ | MentionableSelectMenu
243
+ | ChannelSelectMenu
244
+ >
245
+ | TextDisplay
246
+ | Section
247
+ | MediaGallery
248
+ | Separator
249
+ | File
250
+ > = [];
251
+
252
+ const addEntry = (entry: DiscordComponentEntry) => {
253
+ entries.push({
254
+ ...entry,
255
+ sessionKey: params.sessionKey,
256
+ agentId: params.agentId,
257
+ accountId: params.accountId,
258
+ reusable: entry.reusable ?? params.spec.reusable,
259
+ consumptionGroupId,
260
+ });
261
+ };
262
+
263
+ const text = params.spec.text ?? params.fallbackText;
264
+ if (text) {
265
+ containerChildren.push(new TextDisplay(text));
266
+ }
267
+
268
+ for (const block of params.spec.blocks ?? []) {
269
+ if (block.type === "text") {
270
+ containerChildren.push(new TextDisplay(block.text));
271
+ continue;
272
+ }
273
+ if (block.type === "section") {
274
+ const displays = buildTextDisplays(block.text, block.texts);
275
+ if (displays.length > 3) {
276
+ throw new Error("Section blocks support up to 3 text displays");
277
+ }
278
+ let accessory: Thumbnail | Button | LinkButton | undefined;
279
+ if (block.accessory?.type === "thumbnail") {
280
+ accessory = new Thumbnail(block.accessory.url);
281
+ } else if (block.accessory?.type === "button") {
282
+ const { component, entry } = createButtonComponent({ spec: block.accessory.button });
283
+ accessory = component;
284
+ if (entry) {
285
+ addEntry(entry);
286
+ }
287
+ }
288
+ containerChildren.push(new Section(displays, accessory));
289
+ continue;
290
+ }
291
+ if (block.type === "separator") {
292
+ containerChildren.push(new Separator({ spacing: block.spacing, divider: block.divider }));
293
+ continue;
294
+ }
295
+ if (block.type === "media-gallery") {
296
+ containerChildren.push(new MediaGallery(block.items));
297
+ continue;
298
+ }
299
+ if (block.type === "file") {
300
+ containerChildren.push(new File(block.file, block.spoiler));
301
+ continue;
302
+ }
303
+ if (block.type === "actions") {
304
+ const rowComponents: Array<
305
+ | Button
306
+ | LinkButton
307
+ | StringSelectMenu
308
+ | UserSelectMenu
309
+ | RoleSelectMenu
310
+ | MentionableSelectMenu
311
+ | ChannelSelectMenu
312
+ > = [];
313
+ if (block.buttons) {
314
+ if (block.buttons.length > 5) {
315
+ throw new Error("Action rows support up to 5 buttons");
316
+ }
317
+ for (const button of block.buttons) {
318
+ const { component, entry } = createButtonComponent({ spec: button });
319
+ rowComponents.push(component);
320
+ if (entry) {
321
+ addEntry(entry);
322
+ }
323
+ }
324
+ } else if (block.select) {
325
+ const { component, entry } = createSelectComponent({ spec: block.select });
326
+ rowComponents.push(component);
327
+ addEntry(entry);
328
+ }
329
+ containerChildren.push(new Row(rowComponents));
330
+ }
331
+ }
332
+
333
+ if (params.spec.modal) {
334
+ const modalId = createShortId("mdl_");
335
+ const fields = params.spec.modal.fields.map((field, index) => ({
336
+ id: createShortId("fld_"),
337
+ name: normalizeModalFieldName(field.name, index),
338
+ label: field.label,
339
+ type: field.type,
340
+ description: field.description,
341
+ placeholder: field.placeholder,
342
+ required: field.required,
343
+ options: field.options,
344
+ minValues: field.minValues,
345
+ maxValues: field.maxValues,
346
+ minLength: field.minLength,
347
+ maxLength: field.maxLength,
348
+ style: field.style,
349
+ }));
350
+ modals.push({
351
+ id: modalId,
352
+ title: params.spec.modal.title,
353
+ callbackData: params.spec.modal.callbackData,
354
+ fields,
355
+ sessionKey: params.sessionKey,
356
+ agentId: params.agentId,
357
+ accountId: params.accountId,
358
+ reusable: params.spec.reusable,
359
+ allowedUsers: params.spec.modal.allowedUsers,
360
+ });
361
+
362
+ const triggerSpec: DiscordComponentButtonSpec = {
363
+ label: params.spec.modal.triggerLabel ?? "Open form",
364
+ style: params.spec.modal.triggerStyle ?? "primary",
365
+ allowedUsers: params.spec.modal.allowedUsers,
366
+ };
367
+
368
+ const { component, entry } = createButtonComponent({
369
+ spec: triggerSpec,
370
+ modalId,
371
+ });
372
+
373
+ if (entry) {
374
+ addEntry(entry);
375
+ }
376
+
377
+ const lastChild = containerChildren.at(-1);
378
+ if (lastChild instanceof Row) {
379
+ const row = lastChild;
380
+ const hasSelect = row.components.some((entry) => isSelectComponent(entry));
381
+ if (row.components.length < 5 && !hasSelect) {
382
+ row.addComponent(component as Button);
383
+ } else {
384
+ containerChildren.push(new Row([component as Button]));
385
+ }
386
+ } else {
387
+ containerChildren.push(new Row([component as Button]));
388
+ }
389
+ }
390
+
391
+ if (containerChildren.length === 0) {
392
+ throw new Error("components must include at least one block, text, or modal trigger");
393
+ }
394
+
395
+ const container = new Container(containerChildren, params.spec.container);
396
+ components.push(container);
397
+ const consumptionGroupEntryIds = entries.map((entry) => entry.id);
398
+ for (const entry of entries) {
399
+ entry.consumptionGroupEntryIds = consumptionGroupEntryIds;
400
+ }
401
+ return { components, entries, modals };
402
+ }
403
+
404
+ export function buildDiscordComponentMessageFlags(
405
+ components: TopLevelComponents[],
406
+ ): number | undefined {
407
+ const hasV2 = components.some((component) => component.isV2);
408
+ return hasV2 ? MessageFlags.IsComponentsV2 : undefined;
409
+ }
@@ -0,0 +1,124 @@
1
+ import {
2
+ buildDiscordModalCustomId as buildDiscordModalCustomIdImpl,
3
+ parseDiscordModalCustomIdForInteraction as parseDiscordModalCustomIdForInteractionImpl,
4
+ } from "./component-custom-id.js";
5
+ import { mapTextInputStyle } from "./components.parse.js";
6
+ import type { DiscordModalEntry, DiscordModalFieldDefinition } from "./components.types.js";
7
+ import {
8
+ CheckboxGroup,
9
+ Label,
10
+ Modal,
11
+ RadioGroup,
12
+ RoleSelectMenu,
13
+ StringSelectMenu,
14
+ TextDisplay,
15
+ TextInput,
16
+ UserSelectMenu,
17
+ } from "./internal/discord.js";
18
+
19
+ // Some test-only module graphs partially mock `./internal/discord.js` and can drop `Modal`.
20
+ // Keep dynamic form definitions loadable instead of crashing unrelated suites.
21
+ const ModalBase: typeof Modal = Modal ?? (function ModalFallback() {} as unknown as typeof Modal);
22
+
23
+ function createModalFieldComponent(
24
+ field: DiscordModalFieldDefinition,
25
+ ): TextInput | StringSelectMenu | UserSelectMenu | RoleSelectMenu | CheckboxGroup | RadioGroup {
26
+ if (field.type === "text") {
27
+ class DynamicTextInput extends TextInput {
28
+ customId = field.id;
29
+ override style = mapTextInputStyle(field.style);
30
+ override placeholder = field.placeholder;
31
+ override required = field.required;
32
+ override minLength = field.minLength;
33
+ override maxLength = field.maxLength;
34
+ }
35
+ return new DynamicTextInput();
36
+ }
37
+ if (field.type === "select") {
38
+ const options = field.options ?? [];
39
+ class DynamicModalSelect extends StringSelectMenu {
40
+ customId = field.id;
41
+ override options = options;
42
+ override required = field.required;
43
+ override minValues = field.minValues;
44
+ override maxValues = field.maxValues;
45
+ override placeholder = field.placeholder;
46
+ }
47
+ return new DynamicModalSelect();
48
+ }
49
+ if (field.type === "role-select") {
50
+ class DynamicModalRoleSelect extends RoleSelectMenu {
51
+ customId = field.id;
52
+ override required = field.required;
53
+ override minValues = field.minValues;
54
+ override maxValues = field.maxValues;
55
+ override placeholder = field.placeholder;
56
+ }
57
+ return new DynamicModalRoleSelect();
58
+ }
59
+ if (field.type === "user-select") {
60
+ class DynamicModalUserSelect extends UserSelectMenu {
61
+ customId = field.id;
62
+ override required = field.required;
63
+ override minValues = field.minValues;
64
+ override maxValues = field.maxValues;
65
+ override placeholder = field.placeholder;
66
+ }
67
+ return new DynamicModalUserSelect();
68
+ }
69
+ if (field.type === "checkbox") {
70
+ const options = field.options ?? [];
71
+ class DynamicCheckboxGroup extends CheckboxGroup {
72
+ customId = field.id;
73
+ override options = options;
74
+ override required = field.required;
75
+ override minValues = field.minValues;
76
+ override maxValues = field.maxValues;
77
+ }
78
+ return new DynamicCheckboxGroup();
79
+ }
80
+ const options = field.options ?? [];
81
+ class DynamicRadioGroup extends RadioGroup {
82
+ customId = field.id;
83
+ override options = options;
84
+ override required = field.required;
85
+ override minValues = field.minValues;
86
+ override maxValues = field.maxValues;
87
+ }
88
+ return new DynamicRadioGroup();
89
+ }
90
+
91
+ export class DiscordFormModal extends ModalBase {
92
+ override title: string;
93
+ override customId: string;
94
+ override components: Array<Label | TextDisplay>;
95
+ override customIdParser = parseDiscordModalCustomIdForInteractionImpl;
96
+
97
+ constructor(params: { modalId: string; title: string; fields: DiscordModalFieldDefinition[] }) {
98
+ super();
99
+ this.title = params.title;
100
+ this.customId = buildDiscordModalCustomIdImpl(params.modalId);
101
+ this.components = params.fields.map((field) => {
102
+ const component = createModalFieldComponent(field);
103
+ class DynamicLabel extends Label {
104
+ override label = field.label;
105
+ override description = field.description;
106
+ override component = component;
107
+ override customId = field.id;
108
+ }
109
+ return new DynamicLabel(component);
110
+ });
111
+ }
112
+
113
+ async run(): Promise<void> {
114
+ throw new Error("Modal handler is not registered for dynamic forms");
115
+ }
116
+ }
117
+
118
+ export function createDiscordFormModal(entry: DiscordModalEntry): Modal {
119
+ return new DiscordFormModal({
120
+ modalId: entry.id,
121
+ title: entry.title,
122
+ fields: entry.fields,
123
+ });
124
+ }