@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.
- package/account-inspect-api.ts +6 -0
- package/action-runtime-api.ts +1 -0
- package/api.ts +130 -0
- package/channel-config-api.ts +1 -0
- package/channel-plugin-api.ts +3 -0
- package/config-api.ts +4 -0
- package/configured-state.ts +6 -0
- package/contract-api.ts +21 -0
- package/directory-contract-api.ts +4 -0
- package/dist/account-inspect-Dqw-enky.js +81 -0
- package/dist/account-inspect-api.js +10 -0
- package/dist/accounts-B7OBFePq.js +224 -0
- package/dist/action-runtime-api.js +2 -0
- package/dist/agent-components.runtime-DVY_1VB4.js +4 -0
- package/dist/allow-list-B0s7evD7.js +354 -0
- package/dist/api-CXAcv9nZ.js +130 -0
- package/dist/api.js +23 -0
- package/dist/approval-handler.runtime-B9xUAF3n.js +426 -0
- package/dist/audit-DoiK49WO.js +24 -0
- package/dist/audit-core-BGrq3G7r.js +105 -0
- package/dist/channel-U_aeoFwW.js +795 -0
- package/dist/channel-actions-BxEBnEuv.js +173 -0
- package/dist/channel-actions.runtime-CPtpH-yl.js +263 -0
- package/dist/channel-api-BfjklLby.js +21 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.setup-BUSC0apv.js +337 -0
- package/dist/components-luonoe13.js +909 -0
- package/dist/config-api-DSYGqaLQ.js +2 -0
- package/dist/config-schema-DIqJBGwC.js +357 -0
- package/dist/configured-state.js +6 -0
- package/dist/contract-api.js +8 -0
- package/dist/conversation-identity-DXAm0_Mk.js +270 -0
- package/dist/directory-config-CYbuMmPS.js +49 -0
- package/dist/directory-contract-api.js +2 -0
- package/dist/directory-live-DX4dLRpJ.js +159 -0
- package/dist/doctor-bbKSvGVD.js +244 -0
- package/dist/doctor-contract-Btjt6NJD.js +383 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/gateway-registry-BKSpa4GB.js +74 -0
- package/dist/handle-action.guild-admin-B5BArS2n.js +286 -0
- package/dist/inbound-context-WAOqhGlT.js +48 -0
- package/dist/inbound-event-delivery-C-1Ji3WP.js +65 -0
- package/dist/index.js +26 -0
- package/dist/manager.runtime-DXHynKE4.js +2356 -0
- package/dist/message-handler-mXzc3tA_.js +381 -0
- package/dist/message-handler.preflight-BPD1a347.js +1113 -0
- package/dist/message-handler.process-GUa3aV8z.js +1438 -0
- package/dist/message-utils-dUbem16p.js +549 -0
- package/dist/outbound-adapter-C18OAc1y.js +536 -0
- package/dist/pluralkit-D1Q2x0w5.js +22 -0
- package/dist/preflight-audio-CZtpWcIm.js +72 -0
- package/dist/preflight-audio.runtime-Brx_0_xW.js +7 -0
- package/dist/preview-streaming-D_slNIiO.js +8 -0
- package/dist/probe-D--Ca4JF.js +139 -0
- package/dist/probe.runtime-DQBchZzv.js +2 -0
- package/dist/provider-B2-31CIT.js +9565 -0
- package/dist/provider-session.runtime-BwzzSsrH.js +6 -0
- package/dist/provider.runtime-CP3oHLls.js +2 -0
- package/dist/resolve-allowlist-common-CqxPLcJO.js +34 -0
- package/dist/resolve-channels-0LX4pUbB.js +265 -0
- package/dist/resolve-users-CztOv0Qs.js +120 -0
- package/dist/runtime-DUaw66V_.js +1073 -0
- package/dist/runtime-api.actions.js +3 -0
- package/dist/runtime-api.js +30 -0
- package/dist/runtime-api.lookup.js +7 -0
- package/dist/runtime-api.monitor-CvVKvEXW.js +5 -0
- package/dist/runtime-api.monitor.js +8 -0
- package/dist/runtime-api.send.js +6 -0
- package/dist/runtime-api.threads.js +6 -0
- package/dist/runtime-fC6f4UF2.js +8 -0
- package/dist/runtime-setter-api.js +2 -0
- package/dist/secret-config-contract-B6WW5V88.js +115 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/security-audit-CnyIQKz6.js +120 -0
- package/dist/security-audit-contract-api.js +2 -0
- package/dist/security-audit.runtime-CQSkjNLu.js +2 -0
- package/dist/security-contract-DLvYOgLM.js +26 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/security-doctor-DepqtNCI.js +18 -0
- package/dist/send-DCtPCHGk.js +881 -0
- package/dist/send.components-Bcgxvm52.js +474 -0
- package/dist/send.outbound-S9t0UuHc.js +330 -0
- package/dist/send.receipt-CDn3GBWC.js +3119 -0
- package/dist/send.shared-D4iBnAmn.js +669 -0
- package/dist/sender-identity-CxCe3_1a.js +43 -0
- package/dist/session-contract-Dwhw3RTY.js +6 -0
- package/dist/session-key-api.js +2 -0
- package/dist/session-key-normalization-CP8dPUid.js +23 -0
- package/dist/setup-entry.js +11 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/shared-AIlvuZXt.js +171 -0
- package/dist/subagent-hooks-8bK-mgiU.js +120 -0
- package/dist/subagent-hooks-api.js +22 -0
- package/dist/system-events-Ba1TklaL.js +34 -0
- package/dist/target-resolver-BrtFQtoK.js +82 -0
- package/dist/targets-DWLLZE2l.js +3 -0
- package/dist/test-api.js +45 -0
- package/dist/thread-binding-api.js +4 -0
- package/dist/thread-bindings-9aKRmZv0.js +255 -0
- package/dist/thread-bindings.discord-api-ssGH5wc2.js +244 -0
- package/dist/thread-bindings.manager-0YBHGemk.js +534 -0
- package/dist/thread-bindings.session-updates-DJZGIwaU.js +54 -0
- package/dist/thread-bindings.state-eTFl-PqJ.js +318 -0
- package/dist/timeouts-CEwuGaWT.js +52 -0
- package/dist/timeouts.js +2 -0
- package/dist/typing-BmJKRpCS.js +14 -0
- package/doctor-contract-api.ts +1 -0
- package/index.test.ts +13 -0
- package/index.ts +24 -0
- package/klaw.plugin.json +2 -3822
- package/package.json +4 -4
- package/runtime-api.actions.ts +15 -0
- package/runtime-api.lookup.ts +22 -0
- package/runtime-api.monitor.ts +50 -0
- package/runtime-api.send.ts +79 -0
- package/runtime-api.threads.ts +31 -0
- package/runtime-api.ts +181 -0
- package/runtime-setter-api.ts +3 -0
- package/secret-contract-api.ts +4 -0
- package/security-audit-contract-api.ts +1 -0
- package/security-contract-api.ts +4 -0
- package/session-key-api.ts +1 -0
- package/setup-entry.ts +9 -0
- package/setup-plugin-api.ts +3 -0
- package/src/account-inspect.test.ts +126 -0
- package/src/account-inspect.ts +128 -0
- package/src/accounts.test.ts +381 -0
- package/src/accounts.ts +205 -0
- package/src/actions/handle-action.guild-admin.ts +421 -0
- package/src/actions/handle-action.test.ts +480 -0
- package/src/actions/handle-action.ts +402 -0
- package/src/actions/runtime.guild.ts +446 -0
- package/src/actions/runtime.messaging.messages.ts +226 -0
- package/src/actions/runtime.messaging.reactions.ts +67 -0
- package/src/actions/runtime.messaging.runtime.ts +73 -0
- package/src/actions/runtime.messaging.send.ts +336 -0
- package/src/actions/runtime.messaging.shared.ts +97 -0
- package/src/actions/runtime.messaging.ts +37 -0
- package/src/actions/runtime.moderation-shared.ts +48 -0
- package/src/actions/runtime.moderation.authz.test.ts +151 -0
- package/src/actions/runtime.moderation.ts +116 -0
- package/src/actions/runtime.presence.test.ts +165 -0
- package/src/actions/runtime.presence.ts +117 -0
- package/src/actions/runtime.shared.ts +86 -0
- package/src/actions/runtime.test.ts +1337 -0
- package/src/actions/runtime.ts +87 -0
- package/src/api-barrel.test.ts +78 -0
- package/src/api.test.ts +152 -0
- package/src/api.ts +215 -0
- package/src/approval-handler.runtime.test.ts +41 -0
- package/src/approval-handler.runtime.ts +633 -0
- package/src/approval-native.test.ts +330 -0
- package/src/approval-native.ts +219 -0
- package/src/approval-runtime.ts +14 -0
- package/src/approval-shared.ts +50 -0
- package/src/audit-core.ts +178 -0
- package/src/audit.test.ts +204 -0
- package/src/audit.ts +32 -0
- package/src/channel-actions.contract.test.ts +45 -0
- package/src/channel-actions.runtime.ts +1 -0
- package/src/channel-actions.test.ts +504 -0
- package/src/channel-actions.ts +254 -0
- package/src/channel-api.ts +29 -0
- package/src/channel.conversation.ts +159 -0
- package/src/channel.loaders.ts +50 -0
- package/src/channel.message-adapter.test.ts +230 -0
- package/src/channel.runtime.ts +1 -0
- package/src/channel.setup.ts +12 -0
- package/src/channel.test.ts +828 -0
- package/src/channel.ts +728 -0
- package/src/chunk.test.ts +170 -0
- package/src/chunk.ts +321 -0
- package/src/client.proxy.test.ts +177 -0
- package/src/client.test.ts +83 -0
- package/src/client.ts +143 -0
- package/src/component-custom-id.ts +72 -0
- package/src/components-registry.ts +356 -0
- package/src/components.builders.ts +409 -0
- package/src/components.modal.ts +124 -0
- package/src/components.parse.ts +407 -0
- package/src/components.test.ts +345 -0
- package/src/components.ts +54 -0
- package/src/components.types.ts +187 -0
- package/src/config-schema.test.ts +439 -0
- package/src/config-schema.ts +6 -0
- package/src/config-ui-hints.ts +354 -0
- package/src/conversation-identity.ts +58 -0
- package/src/delivery-retry.ts +52 -0
- package/src/directory-cache.ts +116 -0
- package/src/directory-config.ts +58 -0
- package/src/directory-contract.test.ts +129 -0
- package/src/directory-live.test.ts +141 -0
- package/src/directory-live.ts +135 -0
- package/src/doctor-contract.ts +477 -0
- package/src/doctor-shared.ts +5 -0
- package/src/doctor.test.ts +393 -0
- package/src/doctor.ts +340 -0
- package/src/draft-chunking.test.ts +64 -0
- package/src/draft-chunking.ts +43 -0
- package/src/draft-stream.test.ts +193 -0
- package/src/draft-stream.ts +162 -0
- package/src/durable-delivery.test.ts +103 -0
- package/src/error-body.ts +38 -0
- package/src/exec-approvals.test.ts +88 -0
- package/src/exec-approvals.ts +110 -0
- package/src/gateway-logging.test.ts +98 -0
- package/src/gateway-logging.ts +67 -0
- package/src/group-policy.ts +113 -0
- package/src/guilds.ts +29 -0
- package/src/inbound-context.contract.test.ts +11 -0
- package/src/inbound-event-delivery.ts +135 -0
- package/src/interactive-dispatch.ts +104 -0
- package/src/internal/api.commands.ts +51 -0
- package/src/internal/api.guild.ts +164 -0
- package/src/internal/api.interactions.ts +53 -0
- package/src/internal/api.messages.ts +113 -0
- package/src/internal/api.reactions.ts +38 -0
- package/src/internal/api.test.ts +260 -0
- package/src/internal/api.ts +61 -0
- package/src/internal/api.users.ts +19 -0
- package/src/internal/api.webhooks.ts +13 -0
- package/src/internal/client.test.ts +472 -0
- package/src/internal/client.ts +310 -0
- package/src/internal/command-deploy.test.ts +197 -0
- package/src/internal/command-deploy.ts +352 -0
- package/src/internal/commands.ts +188 -0
- package/src/internal/components.base.ts +65 -0
- package/src/internal/components.message.ts +279 -0
- package/src/internal/components.modal.ts +95 -0
- package/src/internal/components.ts +31 -0
- package/src/internal/discord.ts +11 -0
- package/src/internal/embeds.ts +35 -0
- package/src/internal/entity-cache.ts +98 -0
- package/src/internal/event-queue.ts +185 -0
- package/src/internal/gateway-close-codes.ts +25 -0
- package/src/internal/gateway-dispatch.ts +96 -0
- package/src/internal/gateway-identify-limiter.ts +26 -0
- package/src/internal/gateway-lifecycle.test.ts +114 -0
- package/src/internal/gateway-lifecycle.ts +75 -0
- package/src/internal/gateway-rate-limit.ts +104 -0
- package/src/internal/gateway.test.ts +676 -0
- package/src/internal/gateway.ts +479 -0
- package/src/internal/interaction-dispatch.test.ts +148 -0
- package/src/internal/interaction-dispatch.ts +162 -0
- package/src/internal/interaction-options.ts +98 -0
- package/src/internal/interaction-response.ts +53 -0
- package/src/internal/interactions.test.ts +329 -0
- package/src/internal/interactions.ts +378 -0
- package/src/internal/listeners.ts +91 -0
- package/src/internal/live-smoke.live.test.ts +26 -0
- package/src/internal/modal-fields.ts +95 -0
- package/src/internal/payload.ts +69 -0
- package/src/internal/rest-body.ts +115 -0
- package/src/internal/rest-errors.ts +88 -0
- package/src/internal/rest-routes.ts +50 -0
- package/src/internal/rest-scheduler.ts +557 -0
- package/src/internal/rest.test.ts +681 -0
- package/src/internal/rest.ts +322 -0
- package/src/internal/schemas.ts +36 -0
- package/src/internal/structures.test.ts +43 -0
- package/src/internal/structures.ts +280 -0
- package/src/internal/test-builders.test-support.ts +167 -0
- package/src/internal/voice.ts +49 -0
- package/src/media-detection.ts +28 -0
- package/src/mentions.test.ts +111 -0
- package/src/mentions.ts +147 -0
- package/src/monitor/ack-reactions.ts +70 -0
- package/src/monitor/acp-bind-here.integration.test.ts +219 -0
- package/src/monitor/agent-components-auth.ts +7 -0
- package/src/monitor/agent-components-context.ts +154 -0
- package/src/monitor/agent-components-data.ts +224 -0
- package/src/monitor/agent-components-dm-auth.ts +177 -0
- package/src/monitor/agent-components-guild-auth.ts +322 -0
- package/src/monitor/agent-components-helpers.runtime.ts +3 -0
- package/src/monitor/agent-components-helpers.ts +34 -0
- package/src/monitor/agent-components-reply.ts +10 -0
- package/src/monitor/agent-components.deps.runtime.ts +2 -0
- package/src/monitor/agent-components.dispatch.ts +359 -0
- package/src/monitor/agent-components.handlers.ts +303 -0
- package/src/monitor/agent-components.modal.ts +160 -0
- package/src/monitor/agent-components.plugin-interactive.ts +187 -0
- package/src/monitor/agent-components.runtime.ts +14 -0
- package/src/monitor/agent-components.system-controls.ts +215 -0
- package/src/monitor/agent-components.ts +70 -0
- package/src/monitor/agent-components.types.ts +58 -0
- package/src/monitor/agent-components.wildcard-controls.ts +171 -0
- package/src/monitor/agent-components.wildcard.test.ts +71 -0
- package/src/monitor/allow-list.test.ts +14 -0
- package/src/monitor/allow-list.ts +631 -0
- package/src/monitor/auto-presence.test.ts +184 -0
- package/src/monitor/auto-presence.ts +356 -0
- package/src/monitor/channel-access.test.ts +113 -0
- package/src/monitor/channel-access.ts +102 -0
- package/src/monitor/commands.test.ts +24 -0
- package/src/monitor/commands.ts +9 -0
- package/src/monitor/dm-command-auth.test.ts +274 -0
- package/src/monitor/dm-command-auth.ts +259 -0
- package/src/monitor/dm-command-decision.test.ts +108 -0
- package/src/monitor/dm-command-decision.ts +49 -0
- package/src/monitor/exec-approvals.test.ts +225 -0
- package/src/monitor/exec-approvals.ts +158 -0
- package/src/monitor/format.ts +45 -0
- package/src/monitor/gateway-handle.ts +33 -0
- package/src/monitor/gateway-metadata.test.ts +29 -0
- package/src/monitor/gateway-metadata.ts +298 -0
- package/src/monitor/gateway-plugin.test.ts +320 -0
- package/src/monitor/gateway-plugin.ts +302 -0
- package/src/monitor/gateway-registry.ts +37 -0
- package/src/monitor/gateway-supervisor.test.ts +157 -0
- package/src/monitor/gateway-supervisor.ts +206 -0
- package/src/monitor/inbound-context.test-helpers.ts +37 -0
- package/src/monitor/inbound-context.test.ts +112 -0
- package/src/monitor/inbound-context.ts +95 -0
- package/src/monitor/inbound-dedupe.ts +79 -0
- package/src/monitor/inbound-job.test.ts +216 -0
- package/src/monitor/inbound-job.ts +118 -0
- package/src/monitor/listeners.queue.ts +91 -0
- package/src/monitor/listeners.reactions.ts +594 -0
- package/src/monitor/listeners.test.ts +209 -0
- package/src/monitor/listeners.ts +150 -0
- package/src/monitor/message-channel-info.ts +96 -0
- package/src/monitor/message-forwarded.ts +114 -0
- package/src/monitor/message-handler.batch-gate.test.ts +22 -0
- package/src/monitor/message-handler.batch-gate.ts +19 -0
- package/src/monitor/message-handler.bot-self-filter.test.ts +68 -0
- package/src/monitor/message-handler.context.ts +492 -0
- package/src/monitor/message-handler.dm-preflight.ts +119 -0
- package/src/monitor/message-handler.draft-preview.ts +426 -0
- package/src/monitor/message-handler.hydration.test.ts +80 -0
- package/src/monitor/message-handler.hydration.ts +198 -0
- package/src/monitor/message-handler.inbound-context.test.ts +61 -0
- package/src/monitor/message-handler.module-test-helpers.ts +31 -0
- package/src/monitor/message-handler.preflight-channel-access.ts +86 -0
- package/src/monitor/message-handler.preflight-channel-context.test.ts +18 -0
- package/src/monitor/message-handler.preflight-channel-context.ts +58 -0
- package/src/monitor/message-handler.preflight-context.ts +54 -0
- package/src/monitor/message-handler.preflight-helpers.ts +164 -0
- package/src/monitor/message-handler.preflight-history.ts +23 -0
- package/src/monitor/message-handler.preflight-logging.ts +36 -0
- package/src/monitor/message-handler.preflight-pluralkit.ts +26 -0
- package/src/monitor/message-handler.preflight-runtime.ts +28 -0
- package/src/monitor/message-handler.preflight-thread.ts +49 -0
- package/src/monitor/message-handler.preflight.acp-bindings.test.ts +371 -0
- package/src/monitor/message-handler.preflight.test-helpers.ts +114 -0
- package/src/monitor/message-handler.preflight.test.ts +2255 -0
- package/src/monitor/message-handler.preflight.ts +822 -0
- package/src/monitor/message-handler.preflight.types.ts +115 -0
- package/src/monitor/message-handler.process.test.ts +2520 -0
- package/src/monitor/message-handler.process.ts +1027 -0
- package/src/monitor/message-handler.queue.test.ts +680 -0
- package/src/monitor/message-handler.routing-preflight.ts +112 -0
- package/src/monitor/message-handler.test-harness.ts +99 -0
- package/src/monitor/message-handler.test-helpers.ts +75 -0
- package/src/monitor/message-handler.ts +309 -0
- package/src/monitor/message-media.ts +536 -0
- package/src/monitor/message-run-queue.ts +101 -0
- package/src/monitor/message-text.ts +171 -0
- package/src/monitor/message-utils.test.ts +1234 -0
- package/src/monitor/message-utils.ts +34 -0
- package/src/monitor/model-picker-preferences.test.ts +67 -0
- package/src/monitor/model-picker-preferences.ts +184 -0
- package/src/monitor/model-picker.state.ts +364 -0
- package/src/monitor/model-picker.test-utils.ts +26 -0
- package/src/monitor/model-picker.test.ts +869 -0
- package/src/monitor/model-picker.ts +38 -0
- package/src/monitor/model-picker.view.ts +722 -0
- package/src/monitor/monitor.agent-components.test.ts +410 -0
- package/src/monitor/monitor.test.ts +919 -0
- package/src/monitor/monitor.threading-utils.test.ts +614 -0
- package/src/monitor/native-command-agent-reply.ts +125 -0
- package/src/monitor/native-command-arg-ui.ts +233 -0
- package/src/monitor/native-command-auth.ts +309 -0
- package/src/monitor/native-command-bypass.ts +13 -0
- package/src/monitor/native-command-context.test.ts +105 -0
- package/src/monitor/native-command-context.ts +109 -0
- package/src/monitor/native-command-dispatch.ts +35 -0
- package/src/monitor/native-command-model-picker-apply.ts +209 -0
- package/src/monitor/native-command-model-picker-interaction.ts +516 -0
- package/src/monitor/native-command-model-picker-ui.ts +357 -0
- package/src/monitor/native-command-reply.test.ts +68 -0
- package/src/monitor/native-command-reply.ts +185 -0
- package/src/monitor/native-command-route.ts +91 -0
- package/src/monitor/native-command-status.ts +76 -0
- package/src/monitor/native-command-ui.ts +26 -0
- package/src/monitor/native-command-ui.types.ts +20 -0
- package/src/monitor/native-command.args.ts +45 -0
- package/src/monitor/native-command.command-arg.test.ts +108 -0
- package/src/monitor/native-command.commands-allowfrom.test.ts +504 -0
- package/src/monitor/native-command.model-picker.test.ts +930 -0
- package/src/monitor/native-command.options.test.ts +379 -0
- package/src/monitor/native-command.options.ts +153 -0
- package/src/monitor/native-command.plugin-dispatch.test.ts +1212 -0
- package/src/monitor/native-command.runtime.ts +51 -0
- package/src/monitor/native-command.status-direct.test.ts +278 -0
- package/src/monitor/native-command.test-helpers.ts +64 -0
- package/src/monitor/native-command.think-autocomplete.test.ts +411 -0
- package/src/monitor/native-command.ts +747 -0
- package/src/monitor/native-command.types.ts +9 -0
- package/src/monitor/native-interaction-channel-context.ts +50 -0
- package/src/monitor/preflight-audio.runtime.ts +9 -0
- package/src/monitor/preflight-audio.test.ts +157 -0
- package/src/monitor/preflight-audio.ts +130 -0
- package/src/monitor/presence-cache.ts +61 -0
- package/src/monitor/presence.test.ts +61 -0
- package/src/monitor/presence.ts +50 -0
- package/src/monitor/provider-session.runtime.ts +12 -0
- package/src/monitor/provider.acp.ts +89 -0
- package/src/monitor/provider.allowlist.test.ts +217 -0
- package/src/monitor/provider.allowlist.ts +398 -0
- package/src/monitor/provider.cleanup.ts +41 -0
- package/src/monitor/provider.commands.ts +129 -0
- package/src/monitor/provider.config-log.ts +45 -0
- package/src/monitor/provider.deploy-errors.ts +362 -0
- package/src/monitor/provider.deploy.ts +221 -0
- package/src/monitor/provider.interactions.ts +160 -0
- package/src/monitor/provider.lifecycle.test.ts +734 -0
- package/src/monitor/provider.lifecycle.ts +562 -0
- package/src/monitor/provider.proxy.test.ts +804 -0
- package/src/monitor/provider.rest-proxy.test.ts +389 -0
- package/src/monitor/provider.runtime.ts +1 -0
- package/src/monitor/provider.skill-dedupe.test.ts +42 -0
- package/src/monitor/provider.startup-log.ts +32 -0
- package/src/monitor/provider.startup.test.ts +440 -0
- package/src/monitor/provider.startup.ts +323 -0
- package/src/monitor/provider.test.ts +1173 -0
- package/src/monitor/provider.ts +688 -0
- package/src/monitor/reply-context.ts +64 -0
- package/src/monitor/reply-delivery.test.ts +474 -0
- package/src/monitor/reply-delivery.ts +212 -0
- package/src/monitor/reply-safety.ts +96 -0
- package/src/monitor/rest-fetch.ts +94 -0
- package/src/monitor/route-resolution.test.ts +209 -0
- package/src/monitor/route-resolution.ts +140 -0
- package/src/monitor/sender-identity.ts +81 -0
- package/src/monitor/startup-status.test.ts +30 -0
- package/src/monitor/startup-status.ts +10 -0
- package/src/monitor/status.ts +22 -0
- package/src/monitor/system-events.ts +55 -0
- package/src/monitor/thread-bindings.config.ts +35 -0
- package/src/monitor/thread-bindings.discord-api.test.ts +250 -0
- package/src/monitor/thread-bindings.discord-api.ts +310 -0
- package/src/monitor/thread-bindings.lifecycle.test.ts +1994 -0
- package/src/monitor/thread-bindings.lifecycle.ts +354 -0
- package/src/monitor/thread-bindings.manager.ts +551 -0
- package/src/monitor/thread-bindings.messages.ts +6 -0
- package/src/monitor/thread-bindings.persona.test.ts +34 -0
- package/src/monitor/thread-bindings.persona.ts +25 -0
- package/src/monitor/thread-bindings.session-adapter.ts +229 -0
- package/src/monitor/thread-bindings.session-shared.ts +59 -0
- package/src/monitor/thread-bindings.session-updates.ts +35 -0
- package/src/monitor/thread-bindings.shared-state.test.ts +39 -0
- package/src/monitor/thread-bindings.state.ts +540 -0
- package/src/monitor/thread-bindings.ts +48 -0
- package/src/monitor/thread-bindings.types.ts +83 -0
- package/src/monitor/thread-channel-context.ts +112 -0
- package/src/monitor/thread-session-close.test.ts +180 -0
- package/src/monitor/thread-session-close.ts +63 -0
- package/src/monitor/thread-title.generate.test.ts +209 -0
- package/src/monitor/thread-title.test.ts +31 -0
- package/src/monitor/thread-title.ts +181 -0
- package/src/monitor/threading.auto-thread.test.ts +330 -0
- package/src/monitor/threading.auto-thread.ts +287 -0
- package/src/monitor/threading.cache.ts +45 -0
- package/src/monitor/threading.parent-info.test.ts +156 -0
- package/src/monitor/threading.starter.test.ts +279 -0
- package/src/monitor/threading.starter.ts +288 -0
- package/src/monitor/threading.ts +20 -0
- package/src/monitor/threading.types.ts +102 -0
- package/src/monitor/timeouts.ts +84 -0
- package/src/monitor/typing.test.ts +42 -0
- package/src/monitor/typing.ts +17 -0
- package/src/monitor.gateway.test.ts +187 -0
- package/src/monitor.gateway.ts +75 -0
- package/src/monitor.test.ts +1416 -0
- package/src/monitor.ts +28 -0
- package/src/network-config.test.ts +92 -0
- package/src/network-config.ts +79 -0
- package/src/normalize.test.ts +56 -0
- package/src/normalize.ts +86 -0
- package/src/outbound-adapter.interactive-order.test.ts +82 -0
- package/src/outbound-adapter.test-harness.ts +207 -0
- package/src/outbound-adapter.test.ts +804 -0
- package/src/outbound-adapter.ts +326 -0
- package/src/outbound-approval.ts +29 -0
- package/src/outbound-components.ts +86 -0
- package/src/outbound-payload.contract.test.ts +49 -0
- package/src/outbound-payload.ts +208 -0
- package/src/outbound-send-context.ts +89 -0
- package/src/outbound-session-route.test.ts +42 -0
- package/src/outbound-session-route.ts +72 -0
- package/src/pluralkit.test.ts +67 -0
- package/src/pluralkit.ts +58 -0
- package/src/preview-streaming.ts +18 -0
- package/src/probe.intents.test.ts +94 -0
- package/src/probe.parse-token.test.ts +43 -0
- package/src/probe.runtime.ts +1 -0
- package/src/probe.ts +237 -0
- package/src/proxy-fetch.ts +92 -0
- package/src/proxy-request-client.test.ts +100 -0
- package/src/proxy-request-client.ts +21 -0
- package/src/recipient-resolution.ts +39 -0
- package/src/resolve-allowlist-common.test.ts +40 -0
- package/src/resolve-allowlist-common.ts +39 -0
- package/src/resolve-channels.test.ts +341 -0
- package/src/resolve-channels.ts +369 -0
- package/src/resolve-users.test.ts +243 -0
- package/src/resolve-users.ts +184 -0
- package/src/retry.test.ts +83 -0
- package/src/retry.ts +98 -0
- package/src/runtime-api.ts +61 -0
- package/src/runtime-config.ts +16 -0
- package/src/runtime.ts +23 -0
- package/src/secret-config-contract.ts +140 -0
- package/src/security-audit.runtime.ts +1 -0
- package/src/security-audit.test.ts +245 -0
- package/src/security-audit.ts +208 -0
- package/src/security-contract.ts +47 -0
- package/src/security-doctor.test.ts +25 -0
- package/src/security-doctor.ts +20 -0
- package/src/security.ts +60 -0
- package/src/send-target-parsing.ts +14 -0
- package/src/send.channels.ts +139 -0
- package/src/send.components.test.ts +330 -0
- package/src/send.components.ts +391 -0
- package/src/send.creates-thread.test.ts +681 -0
- package/src/send.emojis-stickers.ts +57 -0
- package/src/send.guild.ts +170 -0
- package/src/send.message-request.ts +112 -0
- package/src/send.messages.test.ts +59 -0
- package/src/send.messages.ts +229 -0
- package/src/send.outbound.ts +459 -0
- package/src/send.permissions.authz.test.ts +190 -0
- package/src/send.permissions.ts +283 -0
- package/src/send.reactions.ts +155 -0
- package/src/send.receipt.ts +69 -0
- package/src/send.sends-basic-channel-messages.test.ts +1068 -0
- package/src/send.shared.ts +469 -0
- package/src/send.test-harness.ts +56 -0
- package/src/send.ts +82 -0
- package/src/send.types.ts +191 -0
- package/src/send.typing.test.ts +41 -0
- package/src/send.typing.ts +9 -0
- package/src/send.voice.ts +136 -0
- package/src/send.webhook-activity.test.ts +152 -0
- package/src/send.webhook.proxy.test.ts +210 -0
- package/src/send.webhook.ts +137 -0
- package/src/session-contract.ts +3 -0
- package/src/session-key-normalization.test.ts +44 -0
- package/src/session-key-normalization.ts +47 -0
- package/src/setup-account-state.test.ts +113 -0
- package/src/setup-account-state.ts +141 -0
- package/src/setup-adapter.ts +14 -0
- package/src/setup-core.ts +215 -0
- package/src/setup-runtime-helpers.ts +10 -0
- package/src/setup-surface.test.ts +137 -0
- package/src/setup-surface.ts +132 -0
- package/src/shared-interactive.test.ts +153 -0
- package/src/shared-interactive.ts +161 -0
- package/src/shared.test.ts +186 -0
- package/src/shared.ts +197 -0
- package/src/status-issues.test.ts +97 -0
- package/src/status-issues.ts +198 -0
- package/src/subagent-hooks.test.ts +465 -0
- package/src/subagent-hooks.ts +232 -0
- package/src/target-parsing.ts +70 -0
- package/src/target-resolver.ts +129 -0
- package/src/targets.test.ts +393 -0
- package/src/targets.ts +12 -0
- package/src/test-http-helpers.ts +10 -0
- package/src/test-support/component-runtime.ts +194 -0
- package/src/test-support/config.ts +7 -0
- package/src/test-support/configured-binding-runtime.ts +29 -0
- package/src/test-support/partial-channel.ts +26 -0
- package/src/test-support/provider.test-support.ts +547 -0
- package/src/token.test.ts +174 -0
- package/src/token.ts +107 -0
- package/src/ui-colors.ts +27 -0
- package/src/ui.ts +20 -0
- package/src/voice/access.test.ts +288 -0
- package/src/voice/access.ts +126 -0
- package/src/voice/audio.test.ts +47 -0
- package/src/voice/audio.ts +249 -0
- package/src/voice/capture-state.test.ts +48 -0
- package/src/voice/capture-state.ts +120 -0
- package/src/voice/command.test.ts +170 -0
- package/src/voice/command.ts +284 -0
- package/src/voice/config.ts +8 -0
- package/src/voice/ingress.ts +164 -0
- package/src/voice/manager.e2e.test.ts +3286 -0
- package/src/voice/manager.ready-listener.test.ts +54 -0
- package/src/voice/manager.runtime.ts +14 -0
- package/src/voice/manager.ts +1155 -0
- package/src/voice/prompt.test.ts +30 -0
- package/src/voice/prompt.ts +22 -0
- package/src/voice/realtime.ts +1370 -0
- package/src/voice/receive-recovery.test.ts +81 -0
- package/src/voice/receive-recovery.ts +159 -0
- package/src/voice/sanitize.test.ts +34 -0
- package/src/voice/sanitize.ts +29 -0
- package/src/voice/sdk-runtime.ts +14 -0
- package/src/voice/segment.ts +160 -0
- package/src/voice/session.ts +81 -0
- package/src/voice/speaker-context.ts +127 -0
- package/src/voice/tts.ts +151 -0
- package/src/voice-message.test.ts +376 -0
- package/src/voice-message.ts +474 -0
- package/subagent-hooks-api.ts +27 -0
- package/test-api.ts +4 -0
- package/thread-binding-api.ts +1 -0
- package/timeouts.ts +6 -0
- package/tsconfig.json +16 -0
- package/account-inspect-api.js +0 -7
- package/action-runtime-api.js +0 -7
- package/api.js +0 -7
- package/channel-config-api.js +0 -7
- package/channel-plugin-api.js +0 -7
- package/configured-state.js +0 -7
- package/contract-api.js +0 -7
- package/directory-contract-api.js +0 -7
- package/doctor-contract-api.js +0 -7
- package/index.js +0 -7
- package/runtime-api.actions.js +0 -7
- package/runtime-api.js +0 -7
- package/runtime-api.lookup.js +0 -7
- package/runtime-api.monitor.js +0 -7
- package/runtime-api.send.js +0 -7
- package/runtime-api.threads.js +0 -7
- package/runtime-setter-api.js +0 -7
- package/secret-contract-api.js +0 -7
- package/security-audit-contract-api.js +0 -7
- package/security-contract-api.js +0 -7
- package/session-key-api.js +0 -7
- package/setup-entry.js +0 -7
- package/setup-plugin-api.js +0 -7
- package/subagent-hooks-api.js +0 -7
- package/test-api.js +0 -7
- package/thread-binding-api.js +0 -7
- package/timeouts.js +0 -7
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import type { ChannelConfigUiHint } from "klaw/plugin-sdk/channel-core";
|
|
2
|
+
|
|
3
|
+
export const discordChannelConfigUiHints = {
|
|
4
|
+
"": {
|
|
5
|
+
label: "Discord",
|
|
6
|
+
help: "Discord channel provider configuration for bot auth, retry policy, streaming, thread bindings, and optional voice capabilities. Keep privileged intents and advanced features disabled unless needed.",
|
|
7
|
+
},
|
|
8
|
+
dmPolicy: {
|
|
9
|
+
label: "Discord DM Policy",
|
|
10
|
+
help: 'Direct message access control ("pairing" recommended). "open" requires channels.discord.allowFrom=["*"].',
|
|
11
|
+
},
|
|
12
|
+
"dm.policy": {
|
|
13
|
+
label: "Discord DM Policy",
|
|
14
|
+
help: 'Direct message access control ("pairing" recommended). "open" requires channels.discord.allowFrom=["*"] (legacy: channels.discord.dm.allowFrom).',
|
|
15
|
+
},
|
|
16
|
+
configWrites: {
|
|
17
|
+
label: "Discord Config Writes",
|
|
18
|
+
help: "Allow Discord to write config in response to channel events/commands (default: true).",
|
|
19
|
+
},
|
|
20
|
+
proxy: {
|
|
21
|
+
label: "Discord Proxy URL",
|
|
22
|
+
help: "Proxy URL for Discord gateway + API requests (app-id lookup and allowlist resolution). Set per account via channels.discord.accounts.<id>.proxy.",
|
|
23
|
+
},
|
|
24
|
+
"commands.native": {
|
|
25
|
+
label: "Discord Native Commands",
|
|
26
|
+
help: 'Override native commands for Discord (bool or "auto").',
|
|
27
|
+
},
|
|
28
|
+
"commands.nativeSkills": {
|
|
29
|
+
label: "Discord Native Skill Commands",
|
|
30
|
+
help: 'Override native skill commands for Discord (bool or "auto").',
|
|
31
|
+
},
|
|
32
|
+
streaming: {
|
|
33
|
+
label: "Discord Streaming Mode",
|
|
34
|
+
help: 'Unified Discord stream preview mode: "off" | "partial" | "block" | "progress". "progress" keeps a single editable progress draft until final delivery. Legacy boolean/streamMode keys are auto-mapped.',
|
|
35
|
+
},
|
|
36
|
+
"streaming.mode": {
|
|
37
|
+
label: "Discord Streaming Mode",
|
|
38
|
+
help: 'Canonical Discord preview mode: "off" | "partial" | "block" | "progress".',
|
|
39
|
+
},
|
|
40
|
+
"streaming.chunkMode": {
|
|
41
|
+
label: "Discord Chunk Mode",
|
|
42
|
+
help: 'Chunking mode for outbound Discord text delivery: "length" (default) or "newline".',
|
|
43
|
+
},
|
|
44
|
+
"streaming.block.enabled": {
|
|
45
|
+
label: "Discord Block Streaming Enabled",
|
|
46
|
+
help: 'Enable chunked block-style Discord preview delivery when channels.discord.streaming.mode="block".',
|
|
47
|
+
},
|
|
48
|
+
"streaming.block.coalesce": {
|
|
49
|
+
label: "Discord Block Streaming Coalesce",
|
|
50
|
+
help: "Merge streamed Discord block replies before final delivery.",
|
|
51
|
+
},
|
|
52
|
+
"streaming.preview.chunk.minChars": {
|
|
53
|
+
label: "Discord Draft Chunk Min Chars",
|
|
54
|
+
help: 'Minimum chars before emitting a Discord stream preview update when channels.discord.streaming.mode="block" (default: 200).',
|
|
55
|
+
},
|
|
56
|
+
"streaming.preview.chunk.maxChars": {
|
|
57
|
+
label: "Discord Draft Chunk Max Chars",
|
|
58
|
+
help: 'Target max size for a Discord stream preview chunk when channels.discord.streaming.mode="block" (default: 800; clamped to channels.discord.textChunkLimit).',
|
|
59
|
+
},
|
|
60
|
+
"streaming.preview.chunk.breakPreference": {
|
|
61
|
+
label: "Discord Draft Chunk Break Preference",
|
|
62
|
+
help: "Preferred breakpoints for Discord draft chunks (paragraph | newline | sentence). Default: paragraph.",
|
|
63
|
+
},
|
|
64
|
+
"streaming.preview.toolProgress": {
|
|
65
|
+
label: "Discord Draft Tool Progress",
|
|
66
|
+
help: "Show tool/progress activity in the live draft preview message (default: true). Set false to hide interim tool updates while the draft preview stays active.",
|
|
67
|
+
},
|
|
68
|
+
"streaming.preview.commandText": {
|
|
69
|
+
label: "Discord Draft Command Text",
|
|
70
|
+
help: 'Command/exec detail in preview tool-progress lines: "raw" preserves released behavior; "status" shows only the tool label.',
|
|
71
|
+
},
|
|
72
|
+
"streaming.progress.label": {
|
|
73
|
+
label: "Discord Progress Label",
|
|
74
|
+
help: 'Initial progress draft title. Use "auto" for built-in single-word labels, a custom string, or false to hide the title.',
|
|
75
|
+
},
|
|
76
|
+
"streaming.progress.labels": {
|
|
77
|
+
label: "Discord Progress Label Pool",
|
|
78
|
+
help: 'Candidate labels for streaming.progress.label="auto". Leave unset to use Klaw built-in progress labels.',
|
|
79
|
+
},
|
|
80
|
+
"streaming.progress.maxLines": {
|
|
81
|
+
label: "Discord Progress Max Lines",
|
|
82
|
+
help: "Maximum number of compact progress lines to keep below the draft label (default: 8).",
|
|
83
|
+
},
|
|
84
|
+
"streaming.progress.maxLineChars": {
|
|
85
|
+
label: "Discord Progress Max Line Chars",
|
|
86
|
+
help: "Maximum characters per compact progress line before truncation (default: 120). Prose cuts at word boundaries; commands and paths keep useful suffixes.",
|
|
87
|
+
},
|
|
88
|
+
"streaming.progress.toolProgress": {
|
|
89
|
+
label: "Discord Progress Tool Lines",
|
|
90
|
+
help: "Show compact tool/progress lines in progress draft mode (default: true). Set false to keep only the label until final delivery.",
|
|
91
|
+
},
|
|
92
|
+
"streaming.progress.commandText": {
|
|
93
|
+
label: "Discord Progress Command Text",
|
|
94
|
+
help: 'Command/exec detail in progress draft lines: "raw" preserves released behavior; "status" shows only the tool label.',
|
|
95
|
+
},
|
|
96
|
+
"retry.attempts": {
|
|
97
|
+
label: "Discord Retry Attempts",
|
|
98
|
+
help: "Max retry attempts for outbound Discord API calls (default: 3).",
|
|
99
|
+
},
|
|
100
|
+
"retry.minDelayMs": {
|
|
101
|
+
label: "Discord Retry Min Delay (ms)",
|
|
102
|
+
help: "Minimum retry delay in ms for Discord outbound calls.",
|
|
103
|
+
},
|
|
104
|
+
"retry.maxDelayMs": {
|
|
105
|
+
label: "Discord Retry Max Delay (ms)",
|
|
106
|
+
help: "Maximum retry delay cap in ms for Discord outbound calls.",
|
|
107
|
+
},
|
|
108
|
+
"retry.jitter": {
|
|
109
|
+
label: "Discord Retry Jitter",
|
|
110
|
+
help: "Jitter factor (0-1) applied to Discord retry delays.",
|
|
111
|
+
},
|
|
112
|
+
maxLinesPerMessage: {
|
|
113
|
+
label: "Discord Max Lines Per Message",
|
|
114
|
+
help: "Soft max line count per Discord message (default: 17).",
|
|
115
|
+
},
|
|
116
|
+
suppressEmbeds: {
|
|
117
|
+
label: "Discord Suppress Link Embeds",
|
|
118
|
+
help: "Suppress Discord-generated link embeds on outbound messages by default. Explicit embeds still send normally. Default: true.",
|
|
119
|
+
},
|
|
120
|
+
"thread.inheritParent": {
|
|
121
|
+
label: "Discord Thread Parent Inheritance",
|
|
122
|
+
help: "If true, Discord thread sessions inherit the parent channel transcript (default: false).",
|
|
123
|
+
},
|
|
124
|
+
"eventQueue.listenerTimeout": {
|
|
125
|
+
label: "Discord EventQueue Listener Timeout (ms)",
|
|
126
|
+
help: "Canonical Discord listener timeout control in ms for gateway normalization/enqueue handlers. Default is 120000 in Klaw; set per account via channels.discord.accounts.<id>.eventQueue.listenerTimeout.",
|
|
127
|
+
},
|
|
128
|
+
"eventQueue.maxQueueSize": {
|
|
129
|
+
label: "Discord EventQueue Max Queue Size",
|
|
130
|
+
help: "Optional Discord EventQueue capacity override (max queued events before backpressure). Set per account via channels.discord.accounts.<id>.eventQueue.maxQueueSize.",
|
|
131
|
+
},
|
|
132
|
+
"eventQueue.maxConcurrency": {
|
|
133
|
+
label: "Discord EventQueue Max Concurrency",
|
|
134
|
+
help: "Optional Discord EventQueue concurrency override (max concurrent handler executions). Set per account via channels.discord.accounts.<id>.eventQueue.maxConcurrency.",
|
|
135
|
+
},
|
|
136
|
+
"threadBindings.enabled": {
|
|
137
|
+
label: "Discord Thread Binding Enabled",
|
|
138
|
+
help: "Enable Discord thread binding features (/focus, bound-thread routing/delivery, and thread-bound subagent sessions). Overrides session.threadBindings.enabled when set.",
|
|
139
|
+
},
|
|
140
|
+
"threadBindings.idleHours": {
|
|
141
|
+
label: "Discord Thread Binding Idle Timeout (hours)",
|
|
142
|
+
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.",
|
|
143
|
+
},
|
|
144
|
+
"threadBindings.maxAgeHours": {
|
|
145
|
+
label: "Discord Thread Binding Max Age (hours)",
|
|
146
|
+
help: "Optional hard max age in hours for Discord thread-bound sessions. Set 0 to disable hard cap (default: 0). Overrides session.threadBindings.maxAgeHours when set.",
|
|
147
|
+
},
|
|
148
|
+
"threadBindings.spawnSessions": {
|
|
149
|
+
label: "Discord Thread-Bound Session Spawn",
|
|
150
|
+
help: "Allow sessions_spawn(thread=true) and ACP thread spawns to auto-create and bind Discord threads (default: true). Set false to disable for this account/channel.",
|
|
151
|
+
},
|
|
152
|
+
"threadBindings.defaultSpawnContext": {
|
|
153
|
+
label: "Discord Thread Spawn Context",
|
|
154
|
+
help: 'Default native subagent context for thread-bound spawns. "fork" starts from the requester transcript; "isolated" starts clean. Default: "fork".',
|
|
155
|
+
},
|
|
156
|
+
"ui.components.accentColor": {
|
|
157
|
+
label: "Discord Component Accent Color",
|
|
158
|
+
help: "Accent color for Discord component containers (hex). Set per account via channels.discord.accounts.<id>.ui.components.accentColor.",
|
|
159
|
+
},
|
|
160
|
+
"intents.presence": {
|
|
161
|
+
label: "Discord Presence Intent",
|
|
162
|
+
help: "Enable the Guild Presences privileged intent. Must also be enabled in the Discord Developer Portal. Allows tracking user activities (e.g. Spotify). Default: false.",
|
|
163
|
+
},
|
|
164
|
+
"intents.guildMembers": {
|
|
165
|
+
label: "Discord Guild Members Intent",
|
|
166
|
+
help: "Enable the Guild Members privileged intent. Must also be enabled in the Discord Developer Portal. Default: false.",
|
|
167
|
+
},
|
|
168
|
+
"intents.voiceStates": {
|
|
169
|
+
label: "Discord Voice States Intent",
|
|
170
|
+
help: "Enable the Guild Voice States intent. Defaults to the effective Discord voice setting; set true only for Discord voice channel conversations.",
|
|
171
|
+
},
|
|
172
|
+
gatewayInfoTimeoutMs: {
|
|
173
|
+
label: "Discord Gateway Metadata Timeout (ms)",
|
|
174
|
+
help: "Timeout for Discord /gateway/bot metadata lookup before falling back to the default gateway URL. Default is 30000; KLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS can override when config is unset.",
|
|
175
|
+
},
|
|
176
|
+
gatewayReadyTimeoutMs: {
|
|
177
|
+
label: "Discord Gateway READY Timeout (ms)",
|
|
178
|
+
help: "Startup wait for the Discord gateway READY event before restarting the socket. Default is 15000; KLAW_DISCORD_READY_TIMEOUT_MS can override when config is unset.",
|
|
179
|
+
},
|
|
180
|
+
gatewayRuntimeReadyTimeoutMs: {
|
|
181
|
+
label: "Discord Gateway Runtime READY Timeout (ms)",
|
|
182
|
+
help: "Runtime reconnect wait for the Discord gateway READY event before force-stopping the lifecycle. Default is 30000; KLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS can override when config is unset.",
|
|
183
|
+
},
|
|
184
|
+
"voice.enabled": {
|
|
185
|
+
label: "Discord Voice Enabled",
|
|
186
|
+
help: "Enable Discord voice channel conversations. Text-only Discord configs leave voice off by default; set true to enable /vc commands and the Guild Voice States intent.",
|
|
187
|
+
},
|
|
188
|
+
"voice.model": {
|
|
189
|
+
label: "Discord Voice Model",
|
|
190
|
+
help: "Optional LLM model override for Discord voice channel responses and realtime agent consults (for example openai-codex/gpt-5.5). Leave unset to inherit the routed agent model.",
|
|
191
|
+
},
|
|
192
|
+
"voice.mode": {
|
|
193
|
+
label: "Discord Voice Mode",
|
|
194
|
+
help: "Conversation mode: agent-proxy (default) uses realtime voice as the microphone/speaker for the routed Klaw agent, stt-tts uses batch speech-to-text plus TTS, and bidi lets the realtime provider converse directly with the Klaw consult tool.",
|
|
195
|
+
},
|
|
196
|
+
"voice.agentSession": {
|
|
197
|
+
label: "Discord Voice Agent Session",
|
|
198
|
+
help: 'Controls which Klaw conversation receives voice turns. Leave unset for the voice channel session, or set mode="target" with a Discord target such as channel:123 to make voice an extension of an existing text channel session.',
|
|
199
|
+
},
|
|
200
|
+
"voice.agentSession.target": {
|
|
201
|
+
label: "Discord Voice Agent Session Target",
|
|
202
|
+
help: 'Discord target used when voice.agentSession.mode="target", for example channel:123.',
|
|
203
|
+
},
|
|
204
|
+
"voice.realtime.provider": {
|
|
205
|
+
label: "Discord Realtime Provider",
|
|
206
|
+
help: "Realtime voice provider for agent-proxy or bidi Discord voice modes, such as openai.",
|
|
207
|
+
},
|
|
208
|
+
"voice.realtime.model": {
|
|
209
|
+
label: "Discord Realtime Model",
|
|
210
|
+
help: "Provider realtime session model, such as gpt-realtime-2. This is separate from voice.model, which remains the Klaw agent brain model.",
|
|
211
|
+
},
|
|
212
|
+
"voice.realtime.voice": {
|
|
213
|
+
label: "Discord Realtime Voice",
|
|
214
|
+
help: "Provider realtime output voice, such as cedar.",
|
|
215
|
+
},
|
|
216
|
+
"voice.realtime.toolPolicy": {
|
|
217
|
+
label: "Discord Realtime Tool Policy",
|
|
218
|
+
help: "Tool policy for the Klaw agent consult tool in realtime voice modes: safe-read-only, owner, or none. Default is owner for agent-proxy and safe-read-only for bidi.",
|
|
219
|
+
},
|
|
220
|
+
"voice.realtime.consultPolicy": {
|
|
221
|
+
label: "Discord Realtime Consult Policy",
|
|
222
|
+
help: "Use always to strongly prefer the Klaw agent brain for substantive realtime turns. agent-proxy defaults to always.",
|
|
223
|
+
},
|
|
224
|
+
"voice.realtime.bargeIn": {
|
|
225
|
+
label: "Discord Realtime Barge-In",
|
|
226
|
+
help: "Allow Discord speaker-start events to interrupt active realtime playback. Set true to keep manual interruption when provider input-audio interruption is disabled for echo control.",
|
|
227
|
+
},
|
|
228
|
+
"voice.realtime.minBargeInAudioEndMs": {
|
|
229
|
+
label: "Discord Realtime Minimum Barge-In Audio (ms)",
|
|
230
|
+
help: "Minimum assistant playback duration before a Discord barge-in truncates realtime audio. Default: 250; set 0 for immediate interruption in low-echo rooms.",
|
|
231
|
+
},
|
|
232
|
+
"voice.realtime.providers": {
|
|
233
|
+
label: "Discord Realtime Provider Settings",
|
|
234
|
+
help: "Provider-specific realtime voice settings keyed by provider id.",
|
|
235
|
+
advanced: true,
|
|
236
|
+
},
|
|
237
|
+
"voice.autoJoin": {
|
|
238
|
+
label: "Discord Voice Auto-Join",
|
|
239
|
+
help: "Voice channels to auto-join on startup (list of guildId/channelId entries).",
|
|
240
|
+
},
|
|
241
|
+
"voice.allowedChannels": {
|
|
242
|
+
label: "Discord Voice Allowed Channels",
|
|
243
|
+
help: "Optional voice channel residency allowlist. When set, /vc join, auto-join, and bot voice-state moves are restricted to these guildId/channelId entries. Leave unset to allow any voice channel.",
|
|
244
|
+
},
|
|
245
|
+
"voice.daveEncryption": {
|
|
246
|
+
label: "Discord Voice DAVE Encryption",
|
|
247
|
+
help: "Toggle DAVE end-to-end encryption for Discord voice joins (default: true in @discordjs/voice; Discord may require this).",
|
|
248
|
+
},
|
|
249
|
+
"voice.decryptionFailureTolerance": {
|
|
250
|
+
label: "Discord Voice Decrypt Failure Tolerance",
|
|
251
|
+
help: "Consecutive decrypt failures before DAVE attempts session recovery (passed to @discordjs/voice; default: 24).",
|
|
252
|
+
},
|
|
253
|
+
"voice.connectTimeoutMs": {
|
|
254
|
+
label: "Discord Voice Connect Timeout (ms)",
|
|
255
|
+
help: "Initial @discordjs/voice Ready wait before a join is treated as failed. Default: 30000.",
|
|
256
|
+
},
|
|
257
|
+
"voice.reconnectGraceMs": {
|
|
258
|
+
label: "Discord Voice Reconnect Grace (ms)",
|
|
259
|
+
help: "Grace period for a disconnected Discord voice session to enter Signalling or Connecting before Klaw destroys it. Default: 15000.",
|
|
260
|
+
},
|
|
261
|
+
"voice.captureSilenceGraceMs": {
|
|
262
|
+
label: "Discord Voice Capture Silence Grace (ms)",
|
|
263
|
+
help: "Silence window after Discord reports a speaker ended before Klaw finalizes the audio segment for transcription. Default: 2500.",
|
|
264
|
+
},
|
|
265
|
+
"voice.tts": {
|
|
266
|
+
label: "Discord Voice Text-to-Speech",
|
|
267
|
+
help: "Optional TTS overrides for Discord voice playback (merged with messages.tts).",
|
|
268
|
+
},
|
|
269
|
+
"pluralkit.enabled": {
|
|
270
|
+
label: "Discord PluralKit Enabled",
|
|
271
|
+
help: "Resolve PluralKit proxied messages and treat system members as distinct senders.",
|
|
272
|
+
},
|
|
273
|
+
"pluralkit.token": {
|
|
274
|
+
label: "Discord PluralKit Token",
|
|
275
|
+
help: "Optional PluralKit token for resolving private systems or members.",
|
|
276
|
+
},
|
|
277
|
+
activity: {
|
|
278
|
+
label: "Discord Presence Activity",
|
|
279
|
+
help: "Discord presence activity text (defaults to custom status).",
|
|
280
|
+
},
|
|
281
|
+
status: {
|
|
282
|
+
label: "Discord Presence Status",
|
|
283
|
+
help: "Discord presence status (online, dnd, idle, invisible).",
|
|
284
|
+
},
|
|
285
|
+
"autoPresence.enabled": {
|
|
286
|
+
label: "Discord Auto Presence Enabled",
|
|
287
|
+
help: "Enable automatic Discord bot presence updates based on runtime/model availability signals. When enabled: healthy=>online, degraded/unknown=>idle, exhausted/unavailable=>dnd.",
|
|
288
|
+
},
|
|
289
|
+
"autoPresence.intervalMs": {
|
|
290
|
+
label: "Discord Auto Presence Check Interval (ms)",
|
|
291
|
+
help: "How often to evaluate Discord auto-presence state in milliseconds (default: 30000).",
|
|
292
|
+
},
|
|
293
|
+
"autoPresence.minUpdateIntervalMs": {
|
|
294
|
+
label: "Discord Auto Presence Min Update Interval (ms)",
|
|
295
|
+
help: "Minimum time between actual Discord presence update calls in milliseconds (default: 15000). Prevents status spam on noisy state changes.",
|
|
296
|
+
},
|
|
297
|
+
"autoPresence.healthyText": {
|
|
298
|
+
label: "Discord Auto Presence Healthy Text",
|
|
299
|
+
help: "Optional custom status text while runtime is healthy (online). If omitted, falls back to static channels.discord.activity when set.",
|
|
300
|
+
},
|
|
301
|
+
"autoPresence.degradedText": {
|
|
302
|
+
label: "Discord Auto Presence Degraded Text",
|
|
303
|
+
help: "Optional custom status text while runtime/model availability is degraded or unknown (idle).",
|
|
304
|
+
},
|
|
305
|
+
"autoPresence.exhaustedText": {
|
|
306
|
+
label: "Discord Auto Presence Exhausted Text",
|
|
307
|
+
help: "Optional custom status text while runtime detects exhausted/unavailable model quota (dnd). Supports {reason} template placeholder.",
|
|
308
|
+
},
|
|
309
|
+
activityType: {
|
|
310
|
+
label: "Discord Presence Activity Type",
|
|
311
|
+
help: "Discord presence activity type (0=Playing,1=Streaming,2=Listening,3=Watching,4=Custom,5=Competing).",
|
|
312
|
+
},
|
|
313
|
+
activityUrl: {
|
|
314
|
+
label: "Discord Presence Activity URL",
|
|
315
|
+
help: "Discord presence streaming URL (required for activityType=1).",
|
|
316
|
+
},
|
|
317
|
+
allowBots: {
|
|
318
|
+
label: "Discord Allow Bot Messages",
|
|
319
|
+
help: 'Allow bot-authored messages to trigger Discord replies (default: false). Set "mentions" to only accept bot messages that mention the bot.',
|
|
320
|
+
},
|
|
321
|
+
botLoopProtection: {
|
|
322
|
+
label: "Discord Bot Loop Protection",
|
|
323
|
+
help: "Sliding-window guard for bot-to-bot Discord loops. Default is enabled whenever allowBots lets bot-authored messages reach dispatch.",
|
|
324
|
+
},
|
|
325
|
+
"botLoopProtection.enabled": {
|
|
326
|
+
label: "Discord Bot Loop Protection Enabled",
|
|
327
|
+
help: 'Enable the bot-pair loop guard. Defaults to true when allowBots is true or "mentions", and false when bot messages are ignored.',
|
|
328
|
+
},
|
|
329
|
+
"botLoopProtection.maxEventsPerWindow": {
|
|
330
|
+
label: "Discord Bot Pair Events Per Window",
|
|
331
|
+
help: "Maximum messages a single Discord bot pair may exchange in the configured window before suppression starts. Default: 20.",
|
|
332
|
+
},
|
|
333
|
+
"botLoopProtection.windowSeconds": {
|
|
334
|
+
label: "Discord Bot Loop Window Seconds",
|
|
335
|
+
help: "Sliding window length in seconds for Discord bot-pair loop budgets. Default: 60.",
|
|
336
|
+
},
|
|
337
|
+
"botLoopProtection.cooldownSeconds": {
|
|
338
|
+
label: "Discord Bot Loop Cooldown Seconds",
|
|
339
|
+
help: "Seconds to suppress a Discord bot pair after it exceeds the loop budget. Default: 60.",
|
|
340
|
+
},
|
|
341
|
+
mentionAliases: {
|
|
342
|
+
label: "Discord Mention Aliases",
|
|
343
|
+
help: "Map outbound @handle text to stable Discord user IDs before sending. Set per account via channels.discord.accounts.<id>.mentionAliases.",
|
|
344
|
+
},
|
|
345
|
+
token: {
|
|
346
|
+
label: "Discord Bot Token",
|
|
347
|
+
help: "Discord bot token used for gateway and REST API authentication for this provider account. Keep this secret out of committed config and rotate immediately after any leak.",
|
|
348
|
+
sensitive: true,
|
|
349
|
+
},
|
|
350
|
+
applicationId: {
|
|
351
|
+
label: "Discord Application ID",
|
|
352
|
+
help: "Optional Discord application/client ID. Set this when hosted environments cannot reach Discord's application lookup endpoint during startup.",
|
|
353
|
+
},
|
|
354
|
+
} satisfies Record<string, ChannelConfigUiHint>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeOptionalLowercaseString,
|
|
3
|
+
normalizeOptionalString,
|
|
4
|
+
} from "klaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
+
import { parseDiscordTarget } from "./target-parsing.js";
|
|
6
|
+
|
|
7
|
+
function normalizeDiscordTarget(
|
|
8
|
+
raw: string | null | undefined,
|
|
9
|
+
defaultKind: "user" | "channel",
|
|
10
|
+
): string | undefined {
|
|
11
|
+
const trimmed = normalizeOptionalString(raw);
|
|
12
|
+
if (!trimmed) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
return parseDiscordTarget(trimmed, { defaultKind })?.normalized;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function buildDiscordConversationIdentity(
|
|
19
|
+
kind: "user" | "channel",
|
|
20
|
+
rawId: string | null | undefined,
|
|
21
|
+
): string | undefined {
|
|
22
|
+
const trimmed = normalizeOptionalString(rawId);
|
|
23
|
+
return trimmed ? `${kind}:${trimmed}` : undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function resolveDiscordConversationIdentity(params: {
|
|
27
|
+
isDirectMessage: boolean;
|
|
28
|
+
userId?: string | null;
|
|
29
|
+
channelId?: string | null;
|
|
30
|
+
}): string | undefined {
|
|
31
|
+
return params.isDirectMessage
|
|
32
|
+
? buildDiscordConversationIdentity("user", params.userId)
|
|
33
|
+
: buildDiscordConversationIdentity("channel", params.channelId);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resolveDiscordCurrentConversationIdentity(params: {
|
|
37
|
+
chatType?: string | null;
|
|
38
|
+
from?: string | null;
|
|
39
|
+
originatingTo?: string | null;
|
|
40
|
+
commandTo?: string | null;
|
|
41
|
+
fallbackTo?: string | null;
|
|
42
|
+
}): string | undefined {
|
|
43
|
+
if (normalizeOptionalLowercaseString(params.chatType) === "direct") {
|
|
44
|
+
const senderTarget = normalizeDiscordTarget(params.from, "user");
|
|
45
|
+
if (senderTarget?.startsWith("user:")) {
|
|
46
|
+
return senderTarget;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const candidate of [params.originatingTo, params.commandTo, params.fallbackTo]) {
|
|
51
|
+
const target = normalizeDiscordTarget(candidate, "channel");
|
|
52
|
+
if (target) {
|
|
53
|
+
return target;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { KlawConfig } from "klaw/plugin-sdk/config-contracts";
|
|
2
|
+
import { resolveRetryConfig, retryAsync, type RetryConfig } from "klaw/plugin-sdk/retry-runtime";
|
|
3
|
+
import { resolveDiscordAccount } from "./accounts.js";
|
|
4
|
+
import { DiscordError } from "./internal/discord.js";
|
|
5
|
+
|
|
6
|
+
const DISCORD_DELIVERY_RETRY_DEFAULTS = {
|
|
7
|
+
attempts: 3,
|
|
8
|
+
minDelayMs: 1000,
|
|
9
|
+
maxDelayMs: 30_000,
|
|
10
|
+
jitter: 0,
|
|
11
|
+
} satisfies Required<RetryConfig>;
|
|
12
|
+
|
|
13
|
+
export function isRetryableDiscordDeliveryError(err: unknown): boolean {
|
|
14
|
+
if (err instanceof DiscordError) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const status = (err as { status?: number }).status ?? (err as { statusCode?: number }).statusCode;
|
|
18
|
+
return status === 429 || (status !== undefined && status >= 500);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getDiscordDeliveryRetryAfterMs(err: unknown): number | undefined {
|
|
22
|
+
if (!err || typeof err !== "object") {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
if (
|
|
26
|
+
"retryAfter" in err &&
|
|
27
|
+
typeof err.retryAfter === "number" &&
|
|
28
|
+
Number.isFinite(err.retryAfter)
|
|
29
|
+
) {
|
|
30
|
+
return err.retryAfter * 1000;
|
|
31
|
+
}
|
|
32
|
+
const retryAfterRaw = (err as { headers?: Record<string, string> }).headers?.["retry-after"];
|
|
33
|
+
if (!retryAfterRaw) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const retryAfterMs = Number(retryAfterRaw) * 1000;
|
|
37
|
+
return Number.isFinite(retryAfterMs) ? retryAfterMs : undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function withDiscordDeliveryRetry<T>(params: {
|
|
41
|
+
cfg: KlawConfig;
|
|
42
|
+
accountId?: string | null;
|
|
43
|
+
fn: () => Promise<T>;
|
|
44
|
+
}): Promise<T> {
|
|
45
|
+
const account = resolveDiscordAccount({ cfg: params.cfg, accountId: params.accountId });
|
|
46
|
+
const retryConfig = resolveRetryConfig(DISCORD_DELIVERY_RETRY_DEFAULTS, account.config.retry);
|
|
47
|
+
return await retryAsync(params.fn, {
|
|
48
|
+
...retryConfig,
|
|
49
|
+
shouldRetry: (err) => isRetryableDiscordDeliveryError(err),
|
|
50
|
+
retryAfterMs: getDiscordDeliveryRetryAfterMs,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "klaw/plugin-sdk/routing";
|
|
2
|
+
import {
|
|
3
|
+
normalizeLowercaseStringOrEmpty,
|
|
4
|
+
normalizeOptionalString,
|
|
5
|
+
normalizeOptionalStringifiedId,
|
|
6
|
+
} from "klaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
|
|
8
|
+
const DISCORD_DIRECTORY_CACHE_MAX_ENTRIES = 4000;
|
|
9
|
+
const DISCORD_DISCRIMINATOR_SUFFIX = /#\d{4}$/;
|
|
10
|
+
|
|
11
|
+
const DIRECTORY_HANDLE_CACHE = new Map<string, Map<string, string>>();
|
|
12
|
+
|
|
13
|
+
function normalizeAccountCacheKey(accountId?: string | null): string {
|
|
14
|
+
const normalized = normalizeAccountId(accountId ?? DEFAULT_ACCOUNT_ID);
|
|
15
|
+
return normalized || DEFAULT_ACCOUNT_ID;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function normalizeSnowflake(value: string | number | bigint): string | null {
|
|
19
|
+
const text = normalizeOptionalStringifiedId(value) ?? "";
|
|
20
|
+
if (!/^\d+$/.test(text)) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return text;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function normalizeHandleKey(raw: string): string | null {
|
|
27
|
+
let handle = normalizeOptionalString(raw) ?? "";
|
|
28
|
+
if (!handle) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
if (handle.startsWith("@")) {
|
|
32
|
+
handle = normalizeOptionalString(handle.slice(1)) ?? "";
|
|
33
|
+
}
|
|
34
|
+
if (!handle || /\s/.test(handle)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return normalizeLowercaseStringOrEmpty(handle);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function ensureAccountCache(accountId?: string | null): Map<string, string> {
|
|
41
|
+
const cacheKey = normalizeAccountCacheKey(accountId);
|
|
42
|
+
const existing = DIRECTORY_HANDLE_CACHE.get(cacheKey);
|
|
43
|
+
if (existing) {
|
|
44
|
+
return existing;
|
|
45
|
+
}
|
|
46
|
+
const created = new Map<string, string>();
|
|
47
|
+
DIRECTORY_HANDLE_CACHE.set(cacheKey, created);
|
|
48
|
+
return created;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function setCacheEntry(cache: Map<string, string>, key: string, userId: string): void {
|
|
52
|
+
if (cache.has(key)) {
|
|
53
|
+
cache.delete(key);
|
|
54
|
+
}
|
|
55
|
+
cache.set(key, userId);
|
|
56
|
+
if (cache.size <= DISCORD_DIRECTORY_CACHE_MAX_ENTRIES) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const oldest = cache.keys().next();
|
|
60
|
+
if (!oldest.done) {
|
|
61
|
+
cache.delete(oldest.value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function rememberDiscordDirectoryUser(params: {
|
|
66
|
+
accountId?: string | null;
|
|
67
|
+
userId: string | number | bigint;
|
|
68
|
+
handles: Array<string | null | undefined>;
|
|
69
|
+
}): void {
|
|
70
|
+
const userId = normalizeSnowflake(params.userId);
|
|
71
|
+
if (!userId) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const cache = ensureAccountCache(params.accountId);
|
|
75
|
+
for (const candidate of params.handles) {
|
|
76
|
+
if (typeof candidate !== "string") {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const handle = normalizeHandleKey(candidate);
|
|
80
|
+
if (!handle) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
setCacheEntry(cache, handle, userId);
|
|
84
|
+
const withoutDiscriminator = handle.replace(DISCORD_DISCRIMINATOR_SUFFIX, "");
|
|
85
|
+
if (withoutDiscriminator && withoutDiscriminator !== handle) {
|
|
86
|
+
setCacheEntry(cache, withoutDiscriminator, userId);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function resolveDiscordDirectoryUserId(params: {
|
|
92
|
+
accountId?: string | null;
|
|
93
|
+
handle: string;
|
|
94
|
+
}): string | undefined {
|
|
95
|
+
const cache = DIRECTORY_HANDLE_CACHE.get(normalizeAccountCacheKey(params.accountId));
|
|
96
|
+
if (!cache) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const handle = normalizeHandleKey(params.handle);
|
|
100
|
+
if (!handle) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
const direct = cache.get(handle);
|
|
104
|
+
if (direct) {
|
|
105
|
+
return direct;
|
|
106
|
+
}
|
|
107
|
+
const withoutDiscriminator = handle.replace(DISCORD_DISCRIMINATOR_SUFFIX, "");
|
|
108
|
+
if (!withoutDiscriminator || withoutDiscriminator === handle) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
return cache.get(withoutDiscriminator);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function resetDiscordDirectoryCacheForTest(): void {
|
|
115
|
+
DIRECTORY_HANDLE_CACHE.clear();
|
|
116
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { normalizeAccountId } from "klaw/plugin-sdk/account-id";
|
|
2
|
+
import {
|
|
3
|
+
createResolvedDirectoryEntriesLister,
|
|
4
|
+
type DirectoryConfigParams,
|
|
5
|
+
} from "klaw/plugin-sdk/directory-config-runtime";
|
|
6
|
+
import {
|
|
7
|
+
mergeDiscordAccountConfig,
|
|
8
|
+
resolveDefaultDiscordAccountId,
|
|
9
|
+
resolveDiscordAccountAllowFrom,
|
|
10
|
+
} from "./accounts.js";
|
|
11
|
+
|
|
12
|
+
function resolveDiscordDirectoryConfigAccount(
|
|
13
|
+
cfg: DirectoryConfigParams["cfg"],
|
|
14
|
+
accountId?: string | null,
|
|
15
|
+
) {
|
|
16
|
+
const resolvedAccountId = normalizeAccountId(accountId ?? resolveDefaultDiscordAccountId(cfg));
|
|
17
|
+
const config = mergeDiscordAccountConfig(cfg, resolvedAccountId);
|
|
18
|
+
return {
|
|
19
|
+
accountId: resolvedAccountId,
|
|
20
|
+
config,
|
|
21
|
+
allowFrom: resolveDiscordAccountAllowFrom({ cfg, accountId: resolvedAccountId }) ?? [],
|
|
22
|
+
dm: config.dm,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const listDiscordDirectoryPeersFromConfig = createResolvedDirectoryEntriesLister<
|
|
27
|
+
ReturnType<typeof resolveDiscordDirectoryConfigAccount>
|
|
28
|
+
>({
|
|
29
|
+
kind: "user",
|
|
30
|
+
resolveAccount: (cfg, accountId) => resolveDiscordDirectoryConfigAccount(cfg, accountId),
|
|
31
|
+
resolveSources: (account) => {
|
|
32
|
+
const guildUsers = Object.values(account.config.guilds ?? {}).flatMap((guild) =>
|
|
33
|
+
(guild.users ?? []).concat(
|
|
34
|
+
Object.values(guild.channels ?? {}).flatMap((channel) => channel.users ?? []),
|
|
35
|
+
),
|
|
36
|
+
);
|
|
37
|
+
return [account.allowFrom, Object.keys(account.config.dms ?? {}), guildUsers];
|
|
38
|
+
},
|
|
39
|
+
normalizeId: (raw) => {
|
|
40
|
+
const mention = raw.match(/^<@!?(\d+)>$/);
|
|
41
|
+
const cleaned = (mention?.[1] ?? raw).replace(/^(discord|user):/i, "").trim();
|
|
42
|
+
return /^\d+$/.test(cleaned) ? `user:${cleaned}` : null;
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const listDiscordDirectoryGroupsFromConfig = createResolvedDirectoryEntriesLister<
|
|
47
|
+
ReturnType<typeof resolveDiscordDirectoryConfigAccount>
|
|
48
|
+
>({
|
|
49
|
+
kind: "group",
|
|
50
|
+
resolveAccount: (cfg, accountId) => resolveDiscordDirectoryConfigAccount(cfg, accountId),
|
|
51
|
+
resolveSources: (account) =>
|
|
52
|
+
Object.values(account.config.guilds ?? {}).map((guild) => Object.keys(guild.channels ?? {})),
|
|
53
|
+
normalizeId: (raw) => {
|
|
54
|
+
const mention = raw.match(/^<#(\d+)>$/);
|
|
55
|
+
const cleaned = (mention?.[1] ?? raw).replace(/^(discord|channel|group):/i, "").trim();
|
|
56
|
+
return /^\d+$/.test(cleaned) ? `channel:${cleaned}` : null;
|
|
57
|
+
},
|
|
58
|
+
});
|