@poolzin/pool-bot 2026.2.25 → 2026.2.26
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/dist/acp/event-mapper.js +87 -22
- package/dist/acp/meta.js +12 -6
- package/dist/agents/agent-paths.js +8 -9
- package/dist/agents/agent-scope.js +7 -5
- package/dist/agents/auth-profiles/oauth.js +148 -64
- package/dist/agents/auth-profiles/session-override.js +13 -7
- package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
- package/dist/agents/bash-tools.exec-runtime.js +2 -25
- package/dist/agents/bedrock-discovery.js +3 -1
- package/dist/agents/byteplus-models.js +97 -0
- package/dist/agents/chutes-oauth.js +1 -0
- package/dist/agents/cli-runner/helpers.js +4 -0
- package/dist/agents/compaction.js +41 -14
- package/dist/agents/doubao-models.js +121 -0
- package/dist/agents/failover-error.js +2 -0
- package/dist/agents/huggingface-models.js +5 -3
- package/dist/agents/live-model-filter.js +5 -0
- package/dist/agents/minimax-vlm.js +10 -8
- package/dist/agents/model-auth.js +6 -0
- package/dist/agents/model-catalog.js +3 -1
- package/dist/agents/model-selection.js +7 -1
- package/dist/agents/models-config.providers.js +93 -11
- package/dist/agents/ollama-stream.js +117 -4
- package/dist/agents/opencode-zen-models.js +22 -11
- package/dist/agents/pi-embedded-helpers/errors.js +55 -33
- package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
- package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +29 -7
- package/dist/agents/pi-embedded-runner/extensions.js +28 -26
- package/dist/agents/pi-embedded-runner/google.js +20 -8
- package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
- package/dist/agents/pi-embedded-runner/run.js +71 -12
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
- package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
- package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
- package/dist/agents/pi-embedded-runner/thinking.js +42 -0
- package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
- package/dist/agents/pi-embedded-runner/utils.js +7 -10
- package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
- package/dist/agents/pi-embedded-subscribe.js +9 -4
- package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
- package/dist/agents/pi-embedded-utils.js +3 -0
- package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
- package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
- package/dist/agents/pi-settings.js +40 -0
- package/dist/agents/pi-tools.policy.js +2 -1
- package/dist/agents/provider/config-loader.js +1 -1
- package/dist/agents/sandbox/browser.js +170 -33
- package/dist/agents/sandbox/config-hash.js +14 -27
- package/dist/agents/sandbox/config.js +21 -2
- package/dist/agents/sandbox/constants.js +2 -0
- package/dist/agents/sandbox/docker.js +16 -2
- package/dist/agents/sandbox/novnc-auth.js +62 -0
- package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
- package/dist/agents/sandbox/shared.js +10 -6
- package/dist/agents/sandbox-paths.js +24 -11
- package/dist/agents/schema/clean-for-gemini.js +132 -85
- package/dist/agents/session-slug.js +10 -5
- package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
- package/dist/agents/session-tool-result-guard.js +3 -1
- package/dist/agents/session-transcript-repair.js +40 -6
- package/dist/agents/skills/bundled-dir.js +19 -5
- package/dist/agents/skills/env-overrides.js +124 -43
- package/dist/agents/skills/frontmatter.js +6 -6
- package/dist/agents/skills/plugin-skills.js +14 -7
- package/dist/agents/skills/workspace.js +1 -0
- package/dist/agents/subagent-announce.js +251 -49
- package/dist/agents/subagent-lifecycle-events.js +19 -0
- package/dist/agents/subagent-registry-cleanup.js +31 -0
- package/dist/agents/subagent-registry-completion.js +68 -0
- package/dist/agents/subagent-registry-queries.js +117 -0
- package/dist/agents/subagent-registry-state.js +46 -0
- package/dist/agents/subagent-registry.js +252 -221
- package/dist/agents/subagent-registry.store.js +1 -0
- package/dist/agents/subagent-registry.types.js +1 -0
- package/dist/agents/subagent-spawn.js +195 -7
- package/dist/agents/system-prompt.js +22 -6
- package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
- package/dist/agents/test-helpers/fast-core-tools.js +1 -17
- package/dist/agents/timeout.js +18 -6
- package/dist/agents/tool-call-id.js +1 -1
- package/dist/agents/tool-display-common.js +162 -29
- package/dist/agents/tool-images.js +82 -9
- package/dist/agents/tool-policy.js +51 -26
- package/dist/agents/tools/browser-tool.js +2 -2
- package/dist/agents/tools/canvas-tool.js +27 -1
- package/dist/agents/tools/common.js +45 -0
- package/dist/agents/tools/discord-actions-guild.js +4 -1
- package/dist/agents/tools/gateway-tool.js +3 -1
- package/dist/agents/tools/nodes-utils.js +1 -10
- package/dist/agents/tools/sessions-send-helpers.js +12 -6
- package/dist/agents/tools/sessions-spawn-tool.js +8 -2
- package/dist/agents/tools/subagents-tool.js +2 -1
- package/dist/agents/tools/whatsapp-actions.js +10 -2
- package/dist/agents/tools/whatsapp-target-auth.js +18 -0
- package/dist/agents/transcript-policy.js +22 -8
- package/dist/agents/venice-models.js +11 -3
- package/dist/auto-reply/commands-registry.data.js +51 -0
- package/dist/auto-reply/commands-registry.js +4 -3
- package/dist/auto-reply/group-activation.js +10 -5
- package/dist/auto-reply/inbound-debounce.js +10 -5
- package/dist/auto-reply/reply/abort.js +1 -1
- package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
- package/dist/auto-reply/reply/bash-command.js +41 -39
- package/dist/auto-reply/reply/command-gates.js +25 -0
- package/dist/auto-reply/reply/commands-allowlist.js +111 -72
- package/dist/auto-reply/reply/commands-bash.js +6 -5
- package/dist/auto-reply/reply/commands-config.js +30 -28
- package/dist/auto-reply/reply/commands-core.js +2 -1
- package/dist/auto-reply/reply/commands-info.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +65 -14
- package/dist/auto-reply/reply/commands-session.js +237 -82
- package/dist/auto-reply/reply/commands-setunset.js +45 -0
- package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
- package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
- package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
- package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
- package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
- package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
- package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
- package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
- package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
- package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
- package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
- package/dist/auto-reply/reply/commands-subagents.js +51 -587
- package/dist/auto-reply/reply/commands-tts.js +10 -5
- package/dist/auto-reply/reply/config-value.js +10 -5
- package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
- package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
- package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
- package/dist/auto-reply/reply/followup-runner.js +1 -0
- package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
- package/dist/auto-reply/reply/get-reply-directives.js +17 -28
- package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
- package/dist/auto-reply/reply/get-reply.js +71 -12
- package/dist/auto-reply/reply/model-selection.js +80 -39
- package/dist/auto-reply/reply/queue/enqueue.js +10 -5
- package/dist/auto-reply/reply/queue/state.js +13 -12
- package/dist/auto-reply/reply/reply-payloads.js +67 -36
- package/dist/auto-reply/reply/reply-reference.js +9 -8
- package/dist/auto-reply/reply/route-reply.js +15 -8
- package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
- package/dist/auto-reply/reply/session.js +22 -6
- package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
- package/dist/auto-reply/reply/subagents-utils.js +56 -30
- package/dist/auto-reply/reply/typing.js +46 -21
- package/dist/auto-reply/send-policy.js +14 -7
- package/dist/auto-reply/status.js +140 -16
- package/dist/auto-reply/templating.js +10 -5
- package/dist/auto-reply/thinking.js +7 -16
- package/dist/auto-reply/tokens.js +21 -5
- package/dist/browser/bridge-server.js +36 -20
- package/dist/browser/cdp.helpers.js +7 -14
- package/dist/browser/cdp.js +35 -15
- package/dist/browser/chrome.profile-decoration.js +7 -4
- package/dist/browser/config.js +4 -0
- package/dist/browser/extension-relay-auth.js +55 -0
- package/dist/browser/extension-relay.js +74 -29
- package/dist/browser/navigation-guard.js +9 -1
- package/dist/browser/paths.js +77 -0
- package/dist/browser/profiles.js +13 -8
- package/dist/browser/pw-ai-module.js +10 -5
- package/dist/browser/pw-session.js +76 -39
- package/dist/browser/pw-tools-core.interactions.js +14 -7
- package/dist/browser/pw-tools-core.state.js +12 -6
- package/dist/browser/routes/agent.act.js +2 -2
- package/dist/browser/server-context.js +7 -0
- package/dist/build-info.json +3 -3
- package/dist/channels/allow-from.js +2 -1
- package/dist/channels/allowlists/resolve-utils.js +43 -19
- package/dist/channels/channel-config.js +14 -7
- package/dist/channels/draft-stream-loop.js +7 -0
- package/dist/channels/model-overrides.js +82 -0
- package/dist/channels/plugins/normalize/imessage.js +14 -7
- package/dist/channels/plugins/normalize/slack.js +10 -5
- package/dist/channels/plugins/normalize/telegram.js +14 -7
- package/dist/channels/plugins/outbound/discord.js +80 -8
- package/dist/channels/plugins/outbound/signal.js +11 -11
- package/dist/channels/plugins/setup-helpers.js +10 -5
- package/dist/channels/sender-label.js +14 -7
- package/dist/channels/session.js +4 -2
- package/dist/channels/status-reactions.js +297 -0
- package/dist/cli/banner.js +1 -1
- package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
- package/dist/cli/cli-name.js +11 -11
- package/dist/cli/cli-utils.js +13 -3
- package/dist/cli/command-format.js +1 -1
- package/dist/cli/config-cli.js +1 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
- package/dist/cli/daemon-cli/lifecycle.js +64 -2
- package/dist/cli/daemon-cli/restart-health.js +126 -0
- package/dist/cli/daemon-cli/status.gather.js +9 -13
- package/dist/cli/daemon-cli/status.print.js +2 -10
- package/dist/cli/deps.js +27 -22
- package/dist/cli/gateway-cli/run-loop.js +23 -5
- package/dist/cli/node-cli/register.js +14 -5
- package/dist/cli/nodes-media-utils.js +7 -2
- package/dist/cli/outbound-send-deps.js +2 -9
- package/dist/cli/outbound-send-mapping.js +11 -0
- package/dist/cli/pairing-cli.js +40 -14
- package/dist/cli/plugins-cli.js +34 -41
- package/dist/cli/ports.js +11 -10
- package/dist/cli/program/command-registry.js +2 -11
- package/dist/cli/program/command-tree.js +16 -0
- package/dist/cli/program/preaction.js +13 -9
- package/dist/cli/program/register.configure.js +3 -18
- package/dist/cli/program/register.maintenance.js +2 -2
- package/dist/cli/program/register.onboard.js +2 -0
- package/dist/cli/program/register.status-health-sessions.js +16 -17
- package/dist/cli/program/register.subclis.js +93 -52
- package/dist/cli/route.js +11 -7
- package/dist/cli/system-cli.js +36 -46
- package/dist/cli/update-cli/shared.js +22 -9
- package/dist/cli/update-cli/update-command.js +89 -14
- package/dist/cli/update-cli/wizard.js +6 -12
- package/dist/commands/agent/run-context.js +18 -5
- package/dist/commands/agent/session-store.js +17 -4
- package/dist/commands/agent.js +22 -2
- package/dist/commands/agents.bindings.js +14 -7
- package/dist/commands/agents.commands.add.js +13 -9
- package/dist/commands/agents.commands.identity.js +12 -6
- package/dist/commands/agents.commands.list.js +11 -6
- package/dist/commands/agents.config.js +8 -10
- package/dist/commands/agents.providers.js +12 -6
- package/dist/commands/auth-choice-options.js +103 -75
- package/dist/commands/auth-choice.apply.byteplus.js +55 -0
- package/dist/commands/auth-choice.apply.js +4 -0
- package/dist/commands/auth-choice.apply.minimax.js +61 -13
- package/dist/commands/auth-choice.apply.openai.js +3 -1
- package/dist/commands/auth-choice.apply.volcengine.js +55 -0
- package/dist/commands/auth-choice.preferred-provider.js +2 -0
- package/dist/commands/channels/remove.js +13 -6
- package/dist/commands/channels/shared.js +4 -14
- package/dist/commands/configure.commands.js +14 -0
- package/dist/commands/configure.gateway.js +2 -4
- package/dist/commands/configure.js +1 -1
- package/dist/commands/configure.shared.js +11 -0
- package/dist/commands/daemon-install-helpers.js +2 -2
- package/dist/commands/dashboard.js +12 -10
- package/dist/commands/docs.js +14 -8
- package/dist/commands/doctor-config-flow.js +11 -9
- package/dist/commands/doctor-legacy-config.js +281 -0
- package/dist/commands/doctor-state-integrity.js +99 -23
- package/dist/commands/doctor-update.js +12 -9
- package/dist/commands/models/list.list-command.js +7 -5
- package/dist/commands/models/set-image.js +2 -21
- package/dist/commands/node-daemon-install-helpers.js +10 -8
- package/dist/commands/onboard-auth.config-minimax.js +54 -80
- package/dist/commands/onboard-auth.config-opencode.js +2 -18
- package/dist/commands/onboard-auth.credentials.js +90 -13
- package/dist/commands/onboard-auth.js +1 -1
- package/dist/commands/onboard-auth.models.js +6 -5
- package/dist/commands/onboard-hooks.js +1 -1
- package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
- package/dist/commands/onboard-provider-auth-flags.js +14 -0
- package/dist/commands/onboard-remote.js +14 -7
- package/dist/commands/onboard.js +11 -13
- package/dist/commands/sandbox-display.js +6 -5
- package/dist/commands/status-all/diagnosis.js +14 -10
- package/dist/commands/status-all/format.js +1 -0
- package/dist/commands/status.gateway-probe.js +1 -16
- package/dist/commands/systemd-linger.js +12 -6
- package/dist/config/agent-limits.js +2 -0
- package/dist/config/commands.js +30 -16
- package/dist/config/config-paths.js +9 -11
- package/dist/config/defaults.js +22 -2
- package/dist/config/discord-preview-streaming.js +104 -0
- package/dist/config/env-vars.js +37 -8
- package/dist/config/includes.js +4 -0
- package/dist/config/io.js +97 -12
- package/dist/config/legacy.migrations.part-1.js +189 -78
- package/dist/config/legacy.shared.js +3 -1
- package/dist/config/merge-patch.js +4 -0
- package/dist/config/prototype-keys.js +4 -0
- package/dist/config/schema.help.js +44 -7
- package/dist/config/schema.labels.js +38 -6
- package/dist/config/sessions/delivery-info.js +10 -3
- package/dist/config/sessions/main-session.js +10 -5
- package/dist/config/sessions/session-file.js +33 -0
- package/dist/config/sessions/session-key.js +10 -5
- package/dist/config/sessions/store.js +1 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/zod-schema.agent-runtime.js +11 -0
- package/dist/config/zod-schema.js +148 -13
- package/dist/config/zod-schema.providers-core.js +78 -4
- package/dist/config/zod-schema.providers.js +6 -1
- package/dist/config/zod-schema.session.js +41 -2
- package/dist/cron/run-log.js +3 -0
- package/dist/cron/schedule.js +21 -10
- package/dist/cron/service/ops.js +35 -21
- package/dist/cron/service/timer.js +116 -16
- package/dist/cron/stagger.js +3 -1
- package/dist/discord/api.js +12 -6
- package/dist/discord/draft-chunking.js +22 -0
- package/dist/discord/draft-stream.js +124 -0
- package/dist/discord/monitor/agent-components.js +1 -1
- package/dist/discord/monitor/commands.js +5 -0
- package/dist/discord/monitor/gateway-plugin.js +2 -1
- package/dist/discord/monitor/listeners.js +37 -27
- package/dist/discord/monitor/message-handler.js +4 -1
- package/dist/discord/monitor/message-handler.preflight.js +65 -8
- package/dist/discord/monitor/message-handler.process.js +246 -217
- package/dist/discord/monitor/message-utils.js +143 -6
- package/dist/discord/monitor/model-picker-preferences.js +143 -0
- package/dist/discord/monitor/model-picker.js +651 -0
- package/dist/discord/monitor/native-command.js +573 -16
- package/dist/discord/monitor/provider.allowlist.js +223 -0
- package/dist/discord/monitor/provider.js +275 -347
- package/dist/discord/monitor/provider.lifecycle.js +100 -0
- package/dist/discord/monitor/reply-delivery.js +123 -16
- package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
- package/dist/discord/monitor/thread-bindings.js +4 -0
- package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
- package/dist/discord/monitor/thread-bindings.manager.js +423 -0
- package/dist/discord/monitor/thread-bindings.messages.js +55 -0
- package/dist/discord/monitor/thread-bindings.state.js +358 -0
- package/dist/discord/monitor/thread-bindings.types.js +6 -0
- package/dist/discord/resolve-users.js +33 -21
- package/dist/discord/send.channels.js +15 -0
- package/dist/discord/send.js +3 -2
- package/dist/discord/send.outbound.js +82 -26
- package/dist/discord/send.permissions.js +83 -30
- package/dist/discord/send.reactions.js +8 -4
- package/dist/discord/token.js +10 -5
- package/dist/discord/voice/command.js +263 -0
- package/dist/discord/voice/manager.js +531 -0
- package/dist/gateway/auth.js +34 -10
- package/dist/gateway/call.js +4 -16
- package/dist/gateway/client.js +28 -4
- package/dist/gateway/config-reload.js +3 -4
- package/dist/gateway/control-ui.js +219 -96
- package/dist/gateway/hooks-mapping.js +88 -38
- package/dist/gateway/http-auth-helpers.js +3 -2
- package/dist/gateway/http-endpoint-helpers.js +1 -0
- package/dist/gateway/net.js +54 -12
- package/dist/gateway/node-invoke-system-run-approval.js +14 -35
- package/dist/gateway/node-registry.js +10 -5
- package/dist/gateway/openai-http.js +1 -0
- package/dist/gateway/openresponses-http.js +1 -0
- package/dist/gateway/origin-check.js +1 -18
- package/dist/gateway/protocol/index.js +4 -3
- package/dist/gateway/protocol/schema/cron.js +1 -0
- package/dist/gateway/protocol/schema/devices.js +1 -0
- package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
- package/dist/gateway/protocol/schema/sessions.js +6 -0
- package/dist/gateway/role-policy.js +17 -0
- package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
- package/dist/gateway/server/ws-connection/message-handler.js +175 -148
- package/dist/gateway/server-chat.js +83 -25
- package/dist/gateway/server-constants.js +10 -9
- package/dist/gateway/server-cron.js +1 -0
- package/dist/gateway/server-http.js +16 -7
- package/dist/gateway/server-maintenance.js +20 -5
- package/dist/gateway/server-methods/chat.js +10 -6
- package/dist/gateway/server-methods/config.js +12 -14
- package/dist/gateway/server-methods/devices.js +17 -3
- package/dist/gateway/server-methods/models.js +11 -1
- package/dist/gateway/server-methods/sessions.js +64 -8
- package/dist/gateway/server-methods/usage.js +162 -75
- package/dist/gateway/server-node-events.js +29 -0
- package/dist/gateway/server-runtime-config.js +34 -13
- package/dist/gateway/server-startup-memory.js +17 -11
- package/dist/gateway/session-utils.fs.js +32 -34
- package/dist/gateway/sessions-resolve.js +17 -5
- package/dist/gateway/test-helpers.openai-mock.js +14 -7
- package/dist/gateway/tools-invoke-http.js +21 -10
- package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
- package/dist/hooks/bundled/command-logger/handler.js +7 -2
- package/dist/hooks/bundled/session-memory/handler.js +6 -5
- package/dist/hooks/frontmatter.js +6 -6
- package/dist/hooks/gmail-watcher.js +11 -6
- package/dist/hooks/internal-hooks.js +11 -1
- package/dist/hooks/llm-slug-generator.js +4 -1
- package/dist/hooks/workspace.js +47 -17
- package/dist/imessage/accounts.js +9 -20
- package/dist/imessage/monitor/inbound-processing.js +2 -1
- package/dist/infra/archive.js +174 -73
- package/dist/infra/control-ui-assets.js +14 -6
- package/dist/infra/device-pairing.js +108 -29
- package/dist/infra/env.js +10 -5
- package/dist/infra/exec-approvals-allowlist.js +122 -0
- package/dist/infra/exec-approvals-analysis.js +34 -3
- package/dist/infra/exec-approvals.js +5 -17
- package/dist/infra/exec-safe-bin-policy.js +53 -45
- package/dist/infra/fs-safe.js +71 -39
- package/dist/infra/gateway-lock.js +6 -2
- package/dist/infra/heartbeat-wake.js +6 -12
- package/dist/infra/host-env-security-policy.json +19 -0
- package/dist/infra/host-env-security.js +66 -0
- package/dist/infra/net/ssrf.js +131 -38
- package/dist/infra/outbound/bound-delivery-router.js +88 -0
- package/dist/infra/outbound/channel-selection.js +12 -6
- package/dist/infra/outbound/envelope.js +1 -1
- package/dist/infra/outbound/format.js +12 -6
- package/dist/infra/outbound/payloads.js +14 -7
- package/dist/infra/outbound/session-binding-service.js +123 -0
- package/dist/infra/path-guards.js +25 -0
- package/dist/infra/provider-usage.fetch.codex.js +7 -15
- package/dist/infra/provider-usage.fetch.gemini.js +14 -11
- package/dist/infra/provider-usage.fetch.shared.js +30 -1
- package/dist/infra/provider-usage.fetch.zai.js +10 -9
- package/dist/infra/retry-policy.js +4 -2
- package/dist/infra/retry.js +9 -5
- package/dist/infra/session-cost-usage.js +107 -59
- package/dist/infra/session-maintenance-warning.js +3 -1
- package/dist/infra/shell-env.js +98 -34
- package/dist/infra/ssh-config.js +12 -6
- package/dist/infra/system-run-command.js +49 -4
- package/dist/infra/update-channels.js +10 -5
- package/dist/line/accounts.js +5 -7
- package/dist/line/bot-access.js +8 -20
- package/dist/line/bot-handlers.js +3 -1
- package/dist/link-understanding/detect.js +15 -7
- package/dist/media/constants.js +15 -6
- package/dist/media/image-ops.js +7 -0
- package/dist/media/local-roots.js +3 -2
- package/dist/media-understanding/apply.js +4 -1
- package/dist/media-understanding/concurrency.js +8 -20
- package/dist/memory/backend-config.js +45 -6
- package/dist/memory/embeddings.js +10 -4
- package/dist/memory/fs-utils.js +23 -0
- package/dist/memory/manager-search.js +12 -6
- package/dist/memory/manager-sync-ops.js +12 -2
- package/dist/memory/qmd-manager.js +466 -53
- package/dist/memory/query-expansion.js +167 -3
- package/dist/memory/status-format.js +10 -5
- package/dist/memory/sync-memory-files.js +1 -1
- package/dist/node-host/invoke-system-run.js +281 -0
- package/dist/node-host/invoke.js +55 -337
- package/dist/pairing/pairing-store.js +22 -0
- package/dist/plugin-sdk/allow-from.js +1 -1
- package/dist/plugin-sdk/command-auth.js +3 -1
- package/dist/plugin-sdk/index.js +6 -3
- package/dist/plugin-sdk/webhook-targets.js +32 -0
- package/dist/plugins/bundled-dir.js +9 -6
- package/dist/plugins/hooks.js +50 -0
- package/dist/plugins/install.js +28 -16
- package/dist/plugins/runtime.js +3 -17
- package/dist/plugins/update.js +78 -12
- package/dist/process/spawn-utils.js +14 -7
- package/dist/providers/github-copilot-token.js +11 -6
- package/dist/providers/qwen-portal-oauth.js +14 -6
- package/dist/routing/account-id.js +30 -0
- package/dist/routing/resolve-route.js +3 -7
- package/dist/routing/session-key.js +2 -16
- package/dist/security/audit-channel.js +93 -2
- package/dist/security/audit-extra.async.js +159 -5
- package/dist/security/audit-extra.js +1 -1
- package/dist/security/audit-extra.sync.js +85 -6
- package/dist/security/audit.js +40 -4
- package/dist/security/dm-policy-shared.js +44 -0
- package/dist/security/external-content.js +26 -6
- package/dist/shared/entry-status.js +6 -0
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-match.js +11 -4
- package/dist/shared/operator-scope-compat.js +8 -3
- package/dist/signal/accounts.js +7 -20
- package/dist/signal/monitor/event-handler.js +3 -1
- package/dist/slack/accounts.js +6 -19
- package/dist/slack/actions.js +11 -3
- package/dist/slack/monitor/auth.js +1 -1
- package/dist/slack/monitor/message-handler/dispatch.js +50 -29
- package/dist/slack/monitor/replies.js +15 -7
- package/dist/slack/monitor/slash.js +22 -13
- package/dist/slack/resolve-channels.js +10 -5
- package/dist/slack/send.js +102 -12
- package/dist/slack/stream-mode.js +10 -0
- package/dist/slack/streaming.js +4 -2
- package/dist/telegram/accounts.js +19 -14
- package/dist/telegram/bot/helpers.js +3 -5
- package/dist/telegram/bot-access.js +35 -36
- package/dist/telegram/bot-handlers.js +120 -148
- package/dist/telegram/bot-message-context.js +68 -9
- package/dist/telegram/bot-message-dispatch.js +155 -90
- package/dist/telegram/bot-native-commands.js +16 -0
- package/dist/telegram/draft-stream.js +14 -1
- package/dist/telegram/inline-buttons.js +5 -15
- package/dist/telegram/monitor.js +11 -7
- package/dist/telegram/network-config.js +19 -7
- package/dist/telegram/send.js +3 -2
- package/dist/telegram/sent-message-cache.js +5 -6
- package/dist/telegram/status-reaction-variants.js +208 -0
- package/dist/telegram/sticker-cache.js +11 -9
- package/dist/terminal/theme.js +12 -12
- package/dist/tts/tts.js +80 -567
- package/dist/tui/components/chat-log.js +41 -8
- package/dist/tui/theme/theme.js +10 -12
- package/dist/tui/tui-local-shell.js +16 -6
- package/dist/tui/tui.js +58 -6
- package/dist/utils/account-id.js +2 -4
- package/dist/utils/boolean.js +10 -5
- package/dist/utils/directive-tags.js +11 -0
- package/dist/utils/queue-helpers.js +67 -12
- package/dist/web/auto-reply/deliver-reply.js +8 -4
- package/dist/web/auto-reply/mentions.js +10 -5
- package/dist/web/auto-reply/monitor/group-members.js +14 -7
- package/dist/web/auto-reply/monitor/process-message.js +45 -24
- package/dist/web/inbound/access-control.js +5 -2
- package/dist/web/login-qr.js +12 -6
- package/dist/web/media.js +123 -16
- package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
- package/extensions/bluebubbles/src/monitor.ts +208 -1950
- package/package.json +1 -1
|
@@ -1,46 +1,30 @@
|
|
|
1
|
-
import { RequestClient } from "@buape/carbon";
|
|
2
1
|
import { ChannelType, PermissionFlagsBits, Routes } from "discord-api-types/v10";
|
|
3
|
-
import {
|
|
4
|
-
import { resolveDiscordAccount } from "./accounts.js";
|
|
5
|
-
import { normalizeDiscordToken } from "./token.js";
|
|
2
|
+
import { resolveDiscordRest } from "./client.js";
|
|
6
3
|
const PERMISSION_ENTRIES = Object.entries(PermissionFlagsBits).filter(([, value]) => typeof value === "bigint");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (explicit)
|
|
10
|
-
return explicit;
|
|
11
|
-
const fallback = normalizeDiscordToken(params.fallbackToken);
|
|
12
|
-
if (!fallback) {
|
|
13
|
-
throw new Error(`Discord bot token missing for account "${params.accountId}" (set discord.accounts.${params.accountId}.token or DISCORD_BOT_TOKEN for default).`);
|
|
14
|
-
}
|
|
15
|
-
return fallback;
|
|
16
|
-
}
|
|
17
|
-
function resolveRest(token, rest) {
|
|
18
|
-
return rest ?? new RequestClient(token);
|
|
19
|
-
}
|
|
20
|
-
function resolveDiscordRest(opts) {
|
|
21
|
-
const cfg = loadConfig();
|
|
22
|
-
const account = resolveDiscordAccount({ cfg, accountId: opts.accountId });
|
|
23
|
-
const token = resolveToken({
|
|
24
|
-
explicit: opts.token,
|
|
25
|
-
accountId: account.accountId,
|
|
26
|
-
fallbackToken: account.token,
|
|
27
|
-
});
|
|
28
|
-
return resolveRest(token, opts.rest);
|
|
29
|
-
}
|
|
4
|
+
const ALL_PERMISSIONS = PERMISSION_ENTRIES.reduce((acc, [, value]) => acc | value, 0n);
|
|
5
|
+
const ADMINISTRATOR_BIT = PermissionFlagsBits.Administrator;
|
|
30
6
|
function addPermissionBits(base, add) {
|
|
31
|
-
if (!add)
|
|
7
|
+
if (!add) {
|
|
32
8
|
return base;
|
|
9
|
+
}
|
|
33
10
|
return base | BigInt(add);
|
|
34
11
|
}
|
|
35
12
|
function removePermissionBits(base, deny) {
|
|
36
|
-
if (!deny)
|
|
13
|
+
if (!deny) {
|
|
37
14
|
return base;
|
|
15
|
+
}
|
|
38
16
|
return base & ~BigInt(deny);
|
|
39
17
|
}
|
|
40
18
|
function bitfieldToPermissions(bitfield) {
|
|
41
19
|
return PERMISSION_ENTRIES.filter(([, value]) => (bitfield & value) === value)
|
|
42
20
|
.map(([name]) => name)
|
|
43
|
-
.
|
|
21
|
+
.toSorted();
|
|
22
|
+
}
|
|
23
|
+
function hasAdministrator(bitfield) {
|
|
24
|
+
return (bitfield & ADMINISTRATOR_BIT) === ADMINISTRATOR_BIT;
|
|
25
|
+
}
|
|
26
|
+
function hasPermissionBit(bitfield, permission) {
|
|
27
|
+
return (bitfield & permission) === permission;
|
|
44
28
|
}
|
|
45
29
|
export function isThreadChannelType(channelType) {
|
|
46
30
|
return (channelType === ChannelType.GuildNewsThread ||
|
|
@@ -54,6 +38,65 @@ async function fetchBotUserId(rest) {
|
|
|
54
38
|
}
|
|
55
39
|
return me.id;
|
|
56
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Fetch guild-level permissions for a user. This does not include channel-specific overwrites.
|
|
43
|
+
*/
|
|
44
|
+
export async function fetchMemberGuildPermissionsDiscord(guildId, userId, opts = {}) {
|
|
45
|
+
const rest = resolveDiscordRest(opts);
|
|
46
|
+
try {
|
|
47
|
+
const [guild, member] = await Promise.all([
|
|
48
|
+
rest.get(Routes.guild(guildId)),
|
|
49
|
+
rest.get(Routes.guildMember(guildId, userId)),
|
|
50
|
+
]);
|
|
51
|
+
const rolesById = new Map((guild.roles ?? []).map((role) => [role.id, role]));
|
|
52
|
+
const everyoneRole = rolesById.get(guildId);
|
|
53
|
+
let permissions = 0n;
|
|
54
|
+
if (everyoneRole?.permissions) {
|
|
55
|
+
permissions = addPermissionBits(permissions, everyoneRole.permissions);
|
|
56
|
+
}
|
|
57
|
+
for (const roleId of member.roles ?? []) {
|
|
58
|
+
const role = rolesById.get(roleId);
|
|
59
|
+
if (role?.permissions) {
|
|
60
|
+
permissions = addPermissionBits(permissions, role.permissions);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return permissions;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Not a guild member, guild not found, or API failure.
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns true when the user has ADMINISTRATOR or any required permission bit.
|
|
72
|
+
*/
|
|
73
|
+
export async function hasAnyGuildPermissionDiscord(guildId, userId, requiredPermissions, opts = {}) {
|
|
74
|
+
const permissions = await fetchMemberGuildPermissionsDiscord(guildId, userId, opts);
|
|
75
|
+
if (permissions === null) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
if (hasAdministrator(permissions)) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return requiredPermissions.some((permission) => hasPermissionBit(permissions, permission));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Returns true when the user has ADMINISTRATOR or all required permission bits.
|
|
85
|
+
*/
|
|
86
|
+
export async function hasAllGuildPermissionsDiscord(guildId, userId, requiredPermissions, opts = {}) {
|
|
87
|
+
const permissions = await fetchMemberGuildPermissionsDiscord(guildId, userId, opts);
|
|
88
|
+
if (permissions === null) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (hasAdministrator(permissions)) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return requiredPermissions.every((permission) => hasPermissionBit(permissions, permission));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* @deprecated Prefer hasAnyGuildPermissionDiscord or hasAllGuildPermissionsDiscord for clarity.
|
|
98
|
+
*/
|
|
99
|
+
export const hasGuildPermissionDiscord = hasAnyGuildPermissionDiscord;
|
|
57
100
|
export async function fetchChannelPermissionsDiscord(channelId, opts = {}) {
|
|
58
101
|
const rest = resolveDiscordRest(opts);
|
|
59
102
|
const channel = (await rest.get(Routes.channel(channelId)));
|
|
@@ -85,6 +128,16 @@ export async function fetchChannelPermissionsDiscord(channelId, opts = {}) {
|
|
|
85
128
|
base = addPermissionBits(base, role.permissions);
|
|
86
129
|
}
|
|
87
130
|
}
|
|
131
|
+
if (hasAdministrator(base)) {
|
|
132
|
+
return {
|
|
133
|
+
channelId,
|
|
134
|
+
guildId,
|
|
135
|
+
permissions: bitfieldToPermissions(ALL_PERMISSIONS),
|
|
136
|
+
raw: ALL_PERMISSIONS.toString(),
|
|
137
|
+
isDm: false,
|
|
138
|
+
channelType,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
88
141
|
let permissions = base;
|
|
89
142
|
const overwrites = "permission_overwrites" in channel ? (channel.permission_overwrites ?? []) : [];
|
|
90
143
|
for (const overwrite of overwrites) {
|
|
@@ -20,11 +20,13 @@ export async function removeOwnReactionsDiscord(channelId, messageId, opts = {})
|
|
|
20
20
|
const identifiers = new Set();
|
|
21
21
|
for (const reaction of message.reactions ?? []) {
|
|
22
22
|
const identifier = buildReactionIdentifier(reaction.emoji);
|
|
23
|
-
if (identifier)
|
|
23
|
+
if (identifier) {
|
|
24
24
|
identifiers.add(identifier);
|
|
25
|
+
}
|
|
25
26
|
}
|
|
26
|
-
if (identifiers.size === 0)
|
|
27
|
+
if (identifiers.size === 0) {
|
|
27
28
|
return { ok: true, removed: [] };
|
|
29
|
+
}
|
|
28
30
|
const removed = [];
|
|
29
31
|
await Promise.allSettled(Array.from(identifiers, (identifier) => {
|
|
30
32
|
removed.push(identifier);
|
|
@@ -36,16 +38,18 @@ export async function fetchReactionsDiscord(channelId, messageId, opts = {}) {
|
|
|
36
38
|
const rest = resolveDiscordRest(opts);
|
|
37
39
|
const message = (await rest.get(Routes.channelMessage(channelId, messageId)));
|
|
38
40
|
const reactions = message.reactions ?? [];
|
|
39
|
-
if (reactions.length === 0)
|
|
41
|
+
if (reactions.length === 0) {
|
|
40
42
|
return [];
|
|
43
|
+
}
|
|
41
44
|
const limit = typeof opts.limit === "number" && Number.isFinite(opts.limit)
|
|
42
45
|
? Math.min(Math.max(Math.floor(opts.limit), 1), 100)
|
|
43
46
|
: 100;
|
|
44
47
|
const summaries = [];
|
|
45
48
|
for (const reaction of reactions) {
|
|
46
49
|
const identifier = buildReactionIdentifier(reaction.emoji);
|
|
47
|
-
if (!identifier)
|
|
50
|
+
if (!identifier) {
|
|
48
51
|
continue;
|
|
52
|
+
}
|
|
49
53
|
const encoded = encodeURIComponent(identifier);
|
|
50
54
|
const users = (await rest.get(Routes.channelMessageReaction(channelId, messageId, encoded), {
|
|
51
55
|
limit,
|
package/dist/discord/token.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js";
|
|
2
2
|
export function normalizeDiscordToken(raw) {
|
|
3
|
-
if (!raw)
|
|
3
|
+
if (!raw) {
|
|
4
4
|
return undefined;
|
|
5
|
+
}
|
|
5
6
|
const trimmed = raw.trim();
|
|
6
|
-
if (!trimmed)
|
|
7
|
+
if (!trimmed) {
|
|
7
8
|
return undefined;
|
|
9
|
+
}
|
|
8
10
|
return trimmed.replace(/^Bot\s+/i, "");
|
|
9
11
|
}
|
|
10
12
|
export function resolveDiscordToken(cfg, opts = {}) {
|
|
@@ -14,16 +16,19 @@ export function resolveDiscordToken(cfg, opts = {}) {
|
|
|
14
16
|
? discordCfg?.accounts?.[accountId]
|
|
15
17
|
: discordCfg?.accounts?.[DEFAULT_ACCOUNT_ID];
|
|
16
18
|
const accountToken = normalizeDiscordToken(accountCfg?.token ?? undefined);
|
|
17
|
-
if (accountToken)
|
|
19
|
+
if (accountToken) {
|
|
18
20
|
return { token: accountToken, source: "config" };
|
|
21
|
+
}
|
|
19
22
|
const allowEnv = accountId === DEFAULT_ACCOUNT_ID;
|
|
20
23
|
const configToken = allowEnv ? normalizeDiscordToken(discordCfg?.token ?? undefined) : undefined;
|
|
21
|
-
if (configToken)
|
|
24
|
+
if (configToken) {
|
|
22
25
|
return { token: configToken, source: "config" };
|
|
26
|
+
}
|
|
23
27
|
const envToken = allowEnv
|
|
24
28
|
? normalizeDiscordToken(opts.envToken ?? process.env.DISCORD_BOT_TOKEN)
|
|
25
29
|
: undefined;
|
|
26
|
-
if (envToken)
|
|
30
|
+
if (envToken) {
|
|
27
31
|
return { token: envToken, source: "env" };
|
|
32
|
+
}
|
|
28
33
|
return { token: "", source: "none" };
|
|
29
34
|
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { ChannelType as CarbonChannelType, Command, CommandWithSubcommands, } from "@buape/carbon";
|
|
2
|
+
import { ApplicationCommandOptionType, ChannelType as DiscordChannelType, } from "discord-api-types/v10";
|
|
3
|
+
import { resolveCommandAuthorizedFromAuthorizers } from "../../channels/command-gating.js";
|
|
4
|
+
import { allowListMatches, isDiscordGroupAllowedByPolicy, normalizeDiscordAllowList, normalizeDiscordSlug, resolveDiscordChannelConfigWithFallback, resolveDiscordGuildEntry, resolveDiscordMemberAccessState, } from "../monitor/allow-list.js";
|
|
5
|
+
import { resolveDiscordChannelInfo } from "../monitor/message-utils.js";
|
|
6
|
+
import { resolveDiscordSenderIdentity } from "../monitor/sender-identity.js";
|
|
7
|
+
import { resolveDiscordThreadParentInfo } from "../monitor/threading.js";
|
|
8
|
+
const VOICE_CHANNEL_TYPES = [
|
|
9
|
+
DiscordChannelType.GuildVoice,
|
|
10
|
+
DiscordChannelType.GuildStageVoice,
|
|
11
|
+
];
|
|
12
|
+
async function authorizeVoiceCommand(interaction, params, options) {
|
|
13
|
+
const channelOverride = options?.channelOverride;
|
|
14
|
+
const channel = channelOverride ? undefined : interaction.channel;
|
|
15
|
+
if (!interaction.guild) {
|
|
16
|
+
return { ok: false, message: "Voice commands are only available in guilds." };
|
|
17
|
+
}
|
|
18
|
+
const user = interaction.user;
|
|
19
|
+
if (!user) {
|
|
20
|
+
return { ok: false, message: "Unable to resolve command user." };
|
|
21
|
+
}
|
|
22
|
+
const channelId = channelOverride?.id ?? channel?.id ?? "";
|
|
23
|
+
const rawChannelName = channelOverride?.name ?? (channel && "name" in channel ? channel.name : undefined);
|
|
24
|
+
const rawParentId = channelOverride?.parentId ??
|
|
25
|
+
("parentId" in (channel ?? {})
|
|
26
|
+
? (channel.parentId ?? undefined)
|
|
27
|
+
: undefined);
|
|
28
|
+
const channelInfo = channelId
|
|
29
|
+
? await resolveDiscordChannelInfo(interaction.client, channelId)
|
|
30
|
+
: null;
|
|
31
|
+
const channelName = rawChannelName ?? channelInfo?.name;
|
|
32
|
+
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
|
33
|
+
const isThreadChannel = channelInfo?.type === CarbonChannelType.PublicThread ||
|
|
34
|
+
channelInfo?.type === CarbonChannelType.PrivateThread ||
|
|
35
|
+
channelInfo?.type === CarbonChannelType.AnnouncementThread;
|
|
36
|
+
let parentId;
|
|
37
|
+
let parentName;
|
|
38
|
+
let parentSlug;
|
|
39
|
+
if (isThreadChannel && channelId) {
|
|
40
|
+
const parentInfo = await resolveDiscordThreadParentInfo({
|
|
41
|
+
client: interaction.client,
|
|
42
|
+
threadChannel: {
|
|
43
|
+
id: channelId,
|
|
44
|
+
name: channelName,
|
|
45
|
+
parentId: rawParentId ?? channelInfo?.parentId,
|
|
46
|
+
parent: undefined,
|
|
47
|
+
},
|
|
48
|
+
channelInfo,
|
|
49
|
+
});
|
|
50
|
+
parentId = parentInfo.id;
|
|
51
|
+
parentName = parentInfo.name;
|
|
52
|
+
parentSlug = parentName ? normalizeDiscordSlug(parentName) : undefined;
|
|
53
|
+
}
|
|
54
|
+
const guildInfo = resolveDiscordGuildEntry({
|
|
55
|
+
guild: interaction.guild ?? undefined,
|
|
56
|
+
guildEntries: params.discordConfig.guilds,
|
|
57
|
+
});
|
|
58
|
+
const channelConfig = channelId
|
|
59
|
+
? resolveDiscordChannelConfigWithFallback({
|
|
60
|
+
guildInfo,
|
|
61
|
+
channelId,
|
|
62
|
+
channelName,
|
|
63
|
+
channelSlug,
|
|
64
|
+
parentId,
|
|
65
|
+
parentName,
|
|
66
|
+
parentSlug,
|
|
67
|
+
scope: isThreadChannel ? "thread" : "channel",
|
|
68
|
+
})
|
|
69
|
+
: null;
|
|
70
|
+
if (channelConfig?.enabled === false) {
|
|
71
|
+
return { ok: false, message: "This channel is disabled." };
|
|
72
|
+
}
|
|
73
|
+
const channelAllowlistConfigured = Boolean(guildInfo?.channels) && Object.keys(guildInfo?.channels ?? {}).length > 0;
|
|
74
|
+
const channelAllowed = channelConfig?.allowed !== false;
|
|
75
|
+
if (!isDiscordGroupAllowedByPolicy({
|
|
76
|
+
groupPolicy: params.groupPolicy,
|
|
77
|
+
guildAllowlisted: Boolean(guildInfo),
|
|
78
|
+
channelAllowlistConfigured,
|
|
79
|
+
channelAllowed,
|
|
80
|
+
}) ||
|
|
81
|
+
channelConfig?.allowed === false) {
|
|
82
|
+
const channelId = channelOverride?.id ?? channel?.id;
|
|
83
|
+
const channelLabel = channelId ? `<#${channelId}>` : "This channel";
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
message: `${channelLabel} is not allowlisted for voice commands.`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const memberRoleIds = Array.isArray(interaction.rawData.member?.roles)
|
|
90
|
+
? interaction.rawData.member.roles.map((roleId) => String(roleId))
|
|
91
|
+
: [];
|
|
92
|
+
const sender = resolveDiscordSenderIdentity({ author: user, member: interaction.rawData.member });
|
|
93
|
+
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
94
|
+
channelConfig,
|
|
95
|
+
guildInfo,
|
|
96
|
+
memberRoleIds,
|
|
97
|
+
sender,
|
|
98
|
+
});
|
|
99
|
+
const ownerAllowList = normalizeDiscordAllowList(params.discordConfig.allowFrom ?? params.discordConfig.dm?.allowFrom ?? [], ["discord:", "user:", "pk:"]);
|
|
100
|
+
const ownerOk = ownerAllowList
|
|
101
|
+
? allowListMatches(ownerAllowList, {
|
|
102
|
+
id: sender.id,
|
|
103
|
+
name: sender.name,
|
|
104
|
+
tag: sender.tag,
|
|
105
|
+
})
|
|
106
|
+
: false;
|
|
107
|
+
const authorizers = params.useAccessGroups
|
|
108
|
+
? [
|
|
109
|
+
{ configured: ownerAllowList != null, allowed: ownerOk },
|
|
110
|
+
{ configured: hasAccessRestrictions, allowed: memberAllowed },
|
|
111
|
+
]
|
|
112
|
+
: [{ configured: hasAccessRestrictions, allowed: memberAllowed }];
|
|
113
|
+
const commandAuthorized = resolveCommandAuthorizedFromAuthorizers({
|
|
114
|
+
useAccessGroups: params.useAccessGroups,
|
|
115
|
+
authorizers,
|
|
116
|
+
modeWhenAccessGroupsOff: "configured",
|
|
117
|
+
});
|
|
118
|
+
if (!commandAuthorized) {
|
|
119
|
+
return { ok: false, message: "You are not authorized to use this command." };
|
|
120
|
+
}
|
|
121
|
+
return { ok: true, guildId: interaction.guild.id };
|
|
122
|
+
}
|
|
123
|
+
export function createDiscordVoiceCommand(params) {
|
|
124
|
+
const resolveSessionChannelId = (manager, guildId) => manager.status().find((entry) => entry.guildId === guildId)?.channelId;
|
|
125
|
+
class JoinCommand extends Command {
|
|
126
|
+
name = "join";
|
|
127
|
+
description = "Join a voice channel";
|
|
128
|
+
defer = true;
|
|
129
|
+
ephemeral = params.ephemeralDefault;
|
|
130
|
+
options = [
|
|
131
|
+
{
|
|
132
|
+
name: "channel",
|
|
133
|
+
description: "Voice channel to join",
|
|
134
|
+
type: ApplicationCommandOptionType.Channel,
|
|
135
|
+
required: true,
|
|
136
|
+
channel_types: VOICE_CHANNEL_TYPES,
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
async run(interaction) {
|
|
140
|
+
const channel = await interaction.options.getChannel("channel", true);
|
|
141
|
+
if (!channel || !("id" in channel)) {
|
|
142
|
+
await interaction.reply({ content: "Voice channel not found.", ephemeral: true });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const access = await authorizeVoiceCommand(interaction, params, {
|
|
146
|
+
channelOverride: {
|
|
147
|
+
id: channel.id,
|
|
148
|
+
name: "name" in channel ? channel.name : undefined,
|
|
149
|
+
parentId: "parentId" in channel
|
|
150
|
+
? (channel.parentId ?? undefined)
|
|
151
|
+
: undefined,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
if (!access.ok) {
|
|
155
|
+
await interaction.reply({ content: access.message ?? "Not authorized.", ephemeral: true });
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (!isVoiceChannelType(channel.type)) {
|
|
159
|
+
await interaction.reply({ content: "That is not a voice channel.", ephemeral: true });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const guildId = access.guildId ?? ("guildId" in channel ? channel.guildId : undefined);
|
|
163
|
+
if (!guildId) {
|
|
164
|
+
await interaction.reply({
|
|
165
|
+
content: "Unable to resolve guild for this voice channel.",
|
|
166
|
+
ephemeral: true,
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const manager = params.getManager();
|
|
171
|
+
if (!manager) {
|
|
172
|
+
await interaction.reply({
|
|
173
|
+
content: "Voice manager is not available yet.",
|
|
174
|
+
ephemeral: true,
|
|
175
|
+
});
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const result = await manager.join({ guildId, channelId: channel.id });
|
|
179
|
+
await interaction.reply({ content: result.message, ephemeral: true });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
class LeaveCommand extends Command {
|
|
183
|
+
name = "leave";
|
|
184
|
+
description = "Leave the current voice channel";
|
|
185
|
+
defer = true;
|
|
186
|
+
ephemeral = params.ephemeralDefault;
|
|
187
|
+
async run(interaction) {
|
|
188
|
+
const guildId = interaction.guild?.id;
|
|
189
|
+
if (!guildId) {
|
|
190
|
+
await interaction.reply({
|
|
191
|
+
content: "Unable to resolve guild for this command.",
|
|
192
|
+
ephemeral: true,
|
|
193
|
+
});
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const manager = params.getManager();
|
|
197
|
+
if (!manager) {
|
|
198
|
+
await interaction.reply({
|
|
199
|
+
content: "Voice manager is not available yet.",
|
|
200
|
+
ephemeral: true,
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const sessionChannelId = resolveSessionChannelId(manager, guildId);
|
|
205
|
+
const access = await authorizeVoiceCommand(interaction, params, {
|
|
206
|
+
channelOverride: sessionChannelId ? { id: sessionChannelId } : undefined,
|
|
207
|
+
});
|
|
208
|
+
if (!access.ok) {
|
|
209
|
+
await interaction.reply({ content: access.message ?? "Not authorized.", ephemeral: true });
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const result = await manager.leave({ guildId });
|
|
213
|
+
await interaction.reply({ content: result.message, ephemeral: true });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
class StatusCommand extends Command {
|
|
217
|
+
name = "status";
|
|
218
|
+
description = "Show active voice sessions";
|
|
219
|
+
defer = true;
|
|
220
|
+
ephemeral = params.ephemeralDefault;
|
|
221
|
+
async run(interaction) {
|
|
222
|
+
const guildId = interaction.guild?.id;
|
|
223
|
+
if (!guildId) {
|
|
224
|
+
await interaction.reply({
|
|
225
|
+
content: "Unable to resolve guild for this command.",
|
|
226
|
+
ephemeral: true,
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const manager = params.getManager();
|
|
231
|
+
if (!manager) {
|
|
232
|
+
await interaction.reply({
|
|
233
|
+
content: "Voice manager is not available yet.",
|
|
234
|
+
ephemeral: true,
|
|
235
|
+
});
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const sessions = manager.status().filter((entry) => entry.guildId === guildId);
|
|
239
|
+
const sessionChannelId = sessions[0]?.channelId;
|
|
240
|
+
const access = await authorizeVoiceCommand(interaction, params, {
|
|
241
|
+
channelOverride: sessionChannelId ? { id: sessionChannelId } : undefined,
|
|
242
|
+
});
|
|
243
|
+
if (!access.ok) {
|
|
244
|
+
await interaction.reply({ content: access.message ?? "Not authorized.", ephemeral: true });
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (sessions.length === 0) {
|
|
248
|
+
await interaction.reply({ content: "No active voice sessions.", ephemeral: true });
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const lines = sessions.map((entry) => `\u2022 <#${entry.channelId}> (guild ${entry.guildId})`);
|
|
252
|
+
await interaction.reply({ content: lines.join("\n"), ephemeral: true });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return new (class extends CommandWithSubcommands {
|
|
256
|
+
name = "vc";
|
|
257
|
+
description = "Voice channel controls";
|
|
258
|
+
subcommands = [new JoinCommand(), new LeaveCommand(), new StatusCommand()];
|
|
259
|
+
})();
|
|
260
|
+
}
|
|
261
|
+
function isVoiceChannelType(type) {
|
|
262
|
+
return type === CarbonChannelType.GuildVoice || type === CarbonChannelType.GuildStageVoice;
|
|
263
|
+
}
|