@kodelyth/discord 2026.5.39 → 2026.6.1
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/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/package.json +19 -7
- 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,130 @@
|
|
|
1
|
+
import { resolveFetch } from "klaw/plugin-sdk/fetch-runtime";
|
|
2
|
+
import { resolveRetryConfig, retryAsync } from "klaw/plugin-sdk/retry-runtime";
|
|
3
|
+
//#region extensions/discord/src/error-body.ts
|
|
4
|
+
const DISCORD_RESPONSE_BODY_SUMMARY_MAX_CHARS = 240;
|
|
5
|
+
function summarizeDiscordResponseBody(body, opts = {}) {
|
|
6
|
+
const summary = body.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, " ").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " ").replace(/ /gi, " ").replace(/&/gi, "&").replace(/</gi, "<").replace(/>/gi, ">").replace(/\s+/g, " ").trim();
|
|
7
|
+
if (!summary) return opts.emptyText;
|
|
8
|
+
return summary.slice(0, DISCORD_RESPONSE_BODY_SUMMARY_MAX_CHARS);
|
|
9
|
+
}
|
|
10
|
+
function isDiscordHtmlResponseBody(body, contentType) {
|
|
11
|
+
return /\bhtml\b/i.test(contentType ?? "") || /^\s*<!doctype\s+html\b/i.test(body) || /^\s*<html\b/i.test(body);
|
|
12
|
+
}
|
|
13
|
+
function isDiscordRateLimitResponseBody(body) {
|
|
14
|
+
const normalized = body.toLowerCase();
|
|
15
|
+
return normalized.includes("error 1015") || normalized.includes("cloudflare") || normalized.includes("rate limit");
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region extensions/discord/src/api.ts
|
|
19
|
+
const DISCORD_API_BASE = "https://discord.com/api/v10";
|
|
20
|
+
const DISCORD_API_RETRY_DEFAULTS = {
|
|
21
|
+
attempts: 3,
|
|
22
|
+
minDelayMs: 500,
|
|
23
|
+
maxDelayMs: 5 * 6e4,
|
|
24
|
+
jitter: .1
|
|
25
|
+
};
|
|
26
|
+
const DISCORD_API_429_FALLBACK_RETRY_AFTER_SECONDS = 60;
|
|
27
|
+
function parseDiscordApiErrorPayload(text) {
|
|
28
|
+
const trimmed = text.trim();
|
|
29
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return null;
|
|
30
|
+
try {
|
|
31
|
+
const payload = JSON.parse(trimmed);
|
|
32
|
+
if (payload && typeof payload === "object") return payload;
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function parseRetryAfterSeconds(text, response) {
|
|
39
|
+
const payload = parseDiscordApiErrorPayload(text);
|
|
40
|
+
const retryAfter = payload && typeof payload.retry_after === "number" && Number.isFinite(payload.retry_after) ? payload.retry_after : void 0;
|
|
41
|
+
if (retryAfter !== void 0) return retryAfter;
|
|
42
|
+
const header = response.headers.get("Retry-After");
|
|
43
|
+
if (!header) return;
|
|
44
|
+
const parsed = Number(header);
|
|
45
|
+
if (Number.isFinite(parsed) && parsed >= 0) return parsed;
|
|
46
|
+
const retryAt = Date.parse(header);
|
|
47
|
+
if (!Number.isFinite(retryAt)) return;
|
|
48
|
+
return Math.max(0, (retryAt - Date.now()) / 1e3);
|
|
49
|
+
}
|
|
50
|
+
function formatRetryAfterSeconds(value) {
|
|
51
|
+
if (value === void 0 || !Number.isFinite(value) || value < 0) return;
|
|
52
|
+
return `${value < 10 ? value.toFixed(1) : Math.round(value).toString()}s`;
|
|
53
|
+
}
|
|
54
|
+
function formatDiscordApiErrorText(text, response) {
|
|
55
|
+
const trimmed = text.trim();
|
|
56
|
+
if (!trimmed) return;
|
|
57
|
+
const payload = parseDiscordApiErrorPayload(trimmed);
|
|
58
|
+
if (!payload) {
|
|
59
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) return "unknown error";
|
|
60
|
+
const summary = summarizeDiscordResponseBody(trimmed);
|
|
61
|
+
if (isDiscordHtmlResponseBody(trimmed, response.headers.get("content-type"))) {
|
|
62
|
+
if (!summary) return response.status === 429 ? "rate limited by Discord upstream" : void 0;
|
|
63
|
+
return response.status === 429 ? `rate limited by Discord upstream: ${summary}` : summary;
|
|
64
|
+
}
|
|
65
|
+
return summary;
|
|
66
|
+
}
|
|
67
|
+
const message = typeof payload.message === "string" && payload.message.trim() ? payload.message.trim() : "unknown error";
|
|
68
|
+
const retryAfter = formatRetryAfterSeconds(typeof payload.retry_after === "number" ? payload.retry_after : void 0);
|
|
69
|
+
return retryAfter ? `${message} (retry after ${retryAfter})` : message;
|
|
70
|
+
}
|
|
71
|
+
var DiscordApiError = class extends Error {
|
|
72
|
+
constructor(message, status, retryAfter) {
|
|
73
|
+
super(message);
|
|
74
|
+
this.status = status;
|
|
75
|
+
this.retryAfter = retryAfter;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
function getDiscordApiRetryAfterMs(err, retryConfig) {
|
|
79
|
+
if (!(err instanceof DiscordApiError) || typeof err.retryAfter !== "number") return;
|
|
80
|
+
return Math.min(Math.max(0, err.retryAfter * 1e3), retryConfig.maxDelayMs);
|
|
81
|
+
}
|
|
82
|
+
function normalizeDiscordRequestBody(body, headers) {
|
|
83
|
+
if (body === void 0) return;
|
|
84
|
+
if (typeof body === "string" || body instanceof Blob || body instanceof FormData || body instanceof URLSearchParams || body instanceof ArrayBuffer) return body;
|
|
85
|
+
headers.set("Content-Type", headers.get("Content-Type") ?? "application/json");
|
|
86
|
+
return JSON.stringify(body);
|
|
87
|
+
}
|
|
88
|
+
function resolveDiscordRequestSignal(options) {
|
|
89
|
+
if (options.signal || typeof options.timeoutMs !== "number") return options.signal;
|
|
90
|
+
return AbortSignal.timeout(options.timeoutMs);
|
|
91
|
+
}
|
|
92
|
+
async function requestDiscord(path, token, options) {
|
|
93
|
+
const fetchImpl = resolveFetch(options?.fetcher ?? fetch);
|
|
94
|
+
if (!fetchImpl) throw new Error("fetch is not available");
|
|
95
|
+
const retryConfig = resolveRetryConfig(DISCORD_API_RETRY_DEFAULTS, options?.retry);
|
|
96
|
+
return retryAsync(async () => {
|
|
97
|
+
const headers = new Headers(options?.headers);
|
|
98
|
+
headers.set("Authorization", `Bot ${token}`);
|
|
99
|
+
const body = normalizeDiscordRequestBody(options?.body, headers);
|
|
100
|
+
const res = await fetchImpl(`${DISCORD_API_BASE}${path}`, {
|
|
101
|
+
method: options?.method ?? (body === void 0 ? "GET" : "POST"),
|
|
102
|
+
headers,
|
|
103
|
+
body,
|
|
104
|
+
signal: resolveDiscordRequestSignal(options ?? {})
|
|
105
|
+
});
|
|
106
|
+
const text = await res.text().catch(() => "");
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
const detail = formatDiscordApiErrorText(text, res);
|
|
109
|
+
const suffix = detail ? `: ${detail}` : "";
|
|
110
|
+
const retryAfter = res.status === 429 ? parseRetryAfterSeconds(text, res) ?? DISCORD_API_429_FALLBACK_RETRY_AFTER_SECONDS : void 0;
|
|
111
|
+
throw new DiscordApiError(`Discord API ${path} failed (${res.status})${suffix}`, res.status, retryAfter);
|
|
112
|
+
}
|
|
113
|
+
if (!text.trim()) return;
|
|
114
|
+
return JSON.parse(text);
|
|
115
|
+
}, {
|
|
116
|
+
...retryConfig,
|
|
117
|
+
label: options?.label ?? path,
|
|
118
|
+
shouldRetry: (err) => err instanceof DiscordApiError && err.status === 429,
|
|
119
|
+
retryAfterMs: (err) => getDiscordApiRetryAfterMs(err, retryConfig)
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async function fetchDiscord(path, token, fetcher = fetch, options) {
|
|
123
|
+
return await requestDiscord(path, token, {
|
|
124
|
+
...options,
|
|
125
|
+
fetcher,
|
|
126
|
+
method: "GET"
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
export { summarizeDiscordResponseBody as a, isDiscordRateLimitResponseBody as i, fetchDiscord as n, requestDiscord as r, DiscordApiError as t };
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Ht as parseDiscordTarget, Ut as resolveDiscordChannelId, a as normalizeDiscordMessagingTarget, i as looksLikeDiscordTargetId, o as normalizeDiscordOutboundTarget } from "./send.receipt-CDn3GBWC.js";
|
|
2
|
+
import { a as mergeDiscordAccountConfig, f as resolveDiscordMaxLinesPerMessage, i as listEnabledDiscordAccounts, l as resolveDiscordAccountConfig, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount, t as createDiscordActionGate } from "./accounts-B7OBFePq.js";
|
|
3
|
+
import { t as inspectDiscordAccount } from "./account-inspect-Dqw-enky.js";
|
|
4
|
+
import { _ as parseDiscordComponentCustomId, b as parseDiscordModalCustomIdForInteraction, c as buildDiscordComponentMessage, d as readDiscordComponentSpec, f as resolveDiscordComponentAttachmentName, g as buildDiscordModalCustomId, h as buildDiscordComponentCustomId, l as buildDiscordComponentMessageFlags, m as DISCORD_MODAL_CUSTOM_ID_KEY, n as formatDiscordComponentEventText, o as DiscordFormModal, p as DISCORD_COMPONENT_CUSTOM_ID_KEY, r as buildDiscordInteractiveComponents, s as createDiscordFormModal, u as DISCORD_COMPONENT_ATTACHMENT_PREFIX, v as parseDiscordComponentCustomIdForInteraction, y as parseDiscordModalCustomId } from "./components-luonoe13.js";
|
|
5
|
+
import { n as fetchDiscord, r as requestDiscord, t as DiscordApiError } from "./api-CXAcv9nZ.js";
|
|
6
|
+
import { i as parseDiscordSendTarget, n as resolveDiscordTarget } from "./target-resolver-BrtFQtoK.js";
|
|
7
|
+
import "./targets-DWLLZE2l.js";
|
|
8
|
+
import { a as getDiscordExecApprovalApprovers, c as shouldSuppressLocalDiscordExecApprovalPrompt, o as isDiscordExecApprovalApprover, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-DXAm0_Mk.js";
|
|
9
|
+
import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./channel-U_aeoFwW.js";
|
|
10
|
+
import { t as normalizeExplicitDiscordSessionKey } from "./session-key-normalization-CP8dPUid.js";
|
|
11
|
+
import { t as discordSetupPlugin } from "./channel.setup-BUSC0apv.js";
|
|
12
|
+
import { n as handleDiscordSubagentEnded, r as handleDiscordSubagentSpawning, t as handleDiscordSubagentDeliveryTarget } from "./subagent-hooks-8bK-mgiU.js";
|
|
13
|
+
import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-B5BArS2n.js";
|
|
14
|
+
import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-CYbuMmPS.js";
|
|
15
|
+
import { t as fetchPluralKitMessageInfo } from "./pluralkit-D1Q2x0w5.js";
|
|
16
|
+
import { a as resolveDiscordPrivilegedIntentsFromFlags, i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-D--Ca4JF.js";
|
|
17
|
+
import { t as collectDiscordSecurityAuditFindings } from "./security-audit-CnyIQKz6.js";
|
|
18
|
+
import { a as mergeAbortSignals, i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./timeouts-CEwuGaWT.js";
|
|
19
|
+
import { resolveOpenProviderRuntimeGroupPolicy as resolveDiscordRuntimeGroupPolicy } from "klaw/plugin-sdk/runtime-group-policy";
|
|
20
|
+
//#region extensions/discord/api.ts
|
|
21
|
+
const handleDiscordMessageAction = async (...args) => (await import("./channel-actions.runtime-CPtpH-yl.js")).handleDiscordMessageAction(...args);
|
|
22
|
+
//#endregion
|
|
23
|
+
export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_COMPONENT_ATTACHMENT_PREFIX, DISCORD_COMPONENT_CUSTOM_ID_KEY, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_MODAL_CUSTOM_ID_KEY, DiscordApiError, DiscordFormModal, buildDiscordComponentCustomId, buildDiscordComponentMessage, buildDiscordComponentMessageFlags, buildDiscordInteractiveComponents, buildDiscordModalCustomId, collectDiscordSecurityAuditFindings, collectDiscordStatusIssues, createDiscordActionGate, createDiscordFormModal, discordPlugin, discordSetupPlugin, fetchDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchPluralKitMessageInfo, formatDiscordComponentEventText, getDiscordExecApprovalApprovers, handleDiscordMessageAction, handleDiscordSubagentDeliveryTarget, handleDiscordSubagentEnded, handleDiscordSubagentSpawning, inspectDiscordAccount, isDiscordExecApprovalApprover, isDiscordExecApprovalClientEnabled, listDiscordAccountIds, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, listEnabledDiscordAccounts, looksLikeDiscordTargetId, mergeAbortSignals, mergeDiscordAccountConfig, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, normalizeExplicitDiscordSessionKey, parseApplicationIdFromToken, parseDiscordComponentCustomId, parseDiscordComponentCustomIdForInteraction as parseDiscordComponentCustomIdForCarbon, parseDiscordComponentCustomIdForInteraction, parseDiscordModalCustomId, parseDiscordModalCustomIdForInteraction as parseDiscordModalCustomIdForCarbon, parseDiscordModalCustomIdForInteraction, parseDiscordSendTarget, parseDiscordTarget, probeDiscord, readDiscordComponentSpec, requestDiscord, resolveDefaultDiscordAccountId, resolveDiscordAccount, resolveDiscordAccountConfig, resolveDiscordChannelId, resolveDiscordComponentAttachmentName, resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, resolveDiscordMaxLinesPerMessage, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordRuntimeGroupPolicy, resolveDiscordTarget, shouldSuppressLocalDiscordExecApprovalPrompt, tryHandleDiscordMessageActionGuildAdmin };
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { B as Container, J as Separator, K as Row, M as serializePayload, R as Button, Wt as __exportAll, X as TextDisplay, ft as editChannelMessage, nt as createUserDmChannel, st as createChannelMessage, ut as deleteChannelMessage } from "./send.receipt-CDn3GBWC.js";
|
|
2
|
+
import { t as inspectDiscordAccount } from "./account-inspect-Dqw-enky.js";
|
|
3
|
+
import { M as createDiscordClient, b as stripUndefinedFields } from "./send.shared-D4iBnAmn.js";
|
|
4
|
+
import { i as shouldHandleDiscordApprovalRequest, s as isDiscordExecApprovalClientEnabled } from "./conversation-identity-DXAm0_Mk.js";
|
|
5
|
+
import { normalizeOptionalString } from "klaw/plugin-sdk/string-coerce-runtime";
|
|
6
|
+
import { ButtonStyle } from "discord-api-types/v10";
|
|
7
|
+
import { logDebug, logError } from "klaw/plugin-sdk/logging-core";
|
|
8
|
+
import { createChannelApprovalNativeRuntimeAdapter } from "klaw/plugin-sdk/approval-handler-runtime";
|
|
9
|
+
//#region extensions/discord/src/ui-colors.ts
|
|
10
|
+
const DEFAULT_DISCORD_ACCENT_COLOR = "#5865F2";
|
|
11
|
+
function normalizeDiscordAccentColor(raw) {
|
|
12
|
+
const trimmed = (raw ?? "").trim();
|
|
13
|
+
if (!trimmed) return null;
|
|
14
|
+
const normalized = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
|
|
15
|
+
if (!/^#[0-9a-fA-F]{6}$/.test(normalized)) return null;
|
|
16
|
+
return normalized.toUpperCase();
|
|
17
|
+
}
|
|
18
|
+
function resolveDiscordAccentColor(params) {
|
|
19
|
+
return normalizeDiscordAccentColor(inspectDiscordAccount({
|
|
20
|
+
cfg: params.cfg,
|
|
21
|
+
accountId: params.accountId
|
|
22
|
+
}).config.ui?.components?.accentColor) ?? DEFAULT_DISCORD_ACCENT_COLOR;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region extensions/discord/src/ui.ts
|
|
26
|
+
var DiscordUiContainer = class extends Container {
|
|
27
|
+
constructor(params) {
|
|
28
|
+
const accentColor = normalizeDiscordAccentColor(params.accentColor) ?? resolveDiscordAccentColor({
|
|
29
|
+
cfg: params.cfg,
|
|
30
|
+
accountId: params.accountId
|
|
31
|
+
});
|
|
32
|
+
super(params.components, {
|
|
33
|
+
accentColor,
|
|
34
|
+
spoiler: params.spoiler
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region extensions/discord/src/approval-handler.runtime.ts
|
|
40
|
+
var approval_handler_runtime_exports = /* @__PURE__ */ __exportAll({
|
|
41
|
+
buildExecApprovalCustomId: () => buildExecApprovalCustomId,
|
|
42
|
+
discordApprovalNativeRuntime: () => discordApprovalNativeRuntime
|
|
43
|
+
});
|
|
44
|
+
function resolveHandlerContext(params) {
|
|
45
|
+
const context = params.context;
|
|
46
|
+
const accountId = normalizeOptionalString(params.accountId) ?? "";
|
|
47
|
+
if (!context?.token || !accountId) return null;
|
|
48
|
+
return {
|
|
49
|
+
accountId,
|
|
50
|
+
context
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
var ExecApprovalContainer = class extends DiscordUiContainer {
|
|
54
|
+
constructor(params) {
|
|
55
|
+
const components = [new TextDisplay(`## ${params.title}`)];
|
|
56
|
+
if (params.description) components.push(new TextDisplay(params.description));
|
|
57
|
+
components.push(new Separator({
|
|
58
|
+
divider: true,
|
|
59
|
+
spacing: "small"
|
|
60
|
+
}));
|
|
61
|
+
components.push(new TextDisplay(`### Command\n\`\`\`\n${params.commandPreview}\n\`\`\``));
|
|
62
|
+
if (params.commandSecondaryPreview) components.push(new TextDisplay(`### Shell Preview\n\`\`\`\n${params.commandSecondaryPreview}\n\`\`\``));
|
|
63
|
+
if (params.metadataLines?.length) components.push(new TextDisplay(params.metadataLines.join("\n")));
|
|
64
|
+
if (params.actionRow) components.push(params.actionRow);
|
|
65
|
+
if (params.footer) {
|
|
66
|
+
components.push(new Separator({
|
|
67
|
+
divider: false,
|
|
68
|
+
spacing: "small"
|
|
69
|
+
}));
|
|
70
|
+
components.push(new TextDisplay(`-# ${params.footer}`));
|
|
71
|
+
}
|
|
72
|
+
super({
|
|
73
|
+
cfg: params.cfg,
|
|
74
|
+
accountId: params.accountId,
|
|
75
|
+
components,
|
|
76
|
+
accentColor: params.accentColor
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var ExecApprovalActionButton = class extends Button {
|
|
81
|
+
constructor(params) {
|
|
82
|
+
super();
|
|
83
|
+
this.customId = buildExecApprovalCustomId(params.approvalId, params.descriptor.decision);
|
|
84
|
+
this.label = params.descriptor.label;
|
|
85
|
+
this.style = params.descriptor.style === "success" ? ButtonStyle.Success : params.descriptor.style === "primary" ? ButtonStyle.Primary : params.descriptor.style === "danger" ? ButtonStyle.Danger : ButtonStyle.Secondary;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var ExecApprovalActionRow = class extends Row {
|
|
89
|
+
constructor(params) {
|
|
90
|
+
super(params.actions.map((descriptor) => new ExecApprovalActionButton({
|
|
91
|
+
approvalId: params.approvalId,
|
|
92
|
+
descriptor
|
|
93
|
+
})));
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
function createApprovalActionRow(view) {
|
|
97
|
+
return new ExecApprovalActionRow({
|
|
98
|
+
approvalId: view.approvalId,
|
|
99
|
+
actions: view.actions
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function buildApprovalMetadataLines(metadata) {
|
|
103
|
+
return metadata.map((item) => `- ${item.label}: ${item.value}`);
|
|
104
|
+
}
|
|
105
|
+
function buildExecApprovalPayload(container) {
|
|
106
|
+
return { components: [container] };
|
|
107
|
+
}
|
|
108
|
+
function formatCommandPreview(commandText, maxChars) {
|
|
109
|
+
return (commandText.length > maxChars ? `${commandText.slice(0, maxChars)}...` : commandText).replace(/`/g, "`");
|
|
110
|
+
}
|
|
111
|
+
function formatOptionalCommandPreview(commandText, maxChars) {
|
|
112
|
+
if (!commandText) return null;
|
|
113
|
+
return formatCommandPreview(commandText, maxChars);
|
|
114
|
+
}
|
|
115
|
+
function resolveCommandPreviews(commandText, commandPreview, maxChars, secondaryMaxChars) {
|
|
116
|
+
return {
|
|
117
|
+
commandPreview: formatCommandPreview(commandText, maxChars),
|
|
118
|
+
commandSecondaryPreview: formatOptionalCommandPreview(commandPreview, secondaryMaxChars)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function createExecApprovalRequestContainer(params) {
|
|
122
|
+
const { commandPreview, commandSecondaryPreview } = resolveCommandPreviews(params.view.commandText, params.view.commandPreview, 1e3, 500);
|
|
123
|
+
const expiresAtSeconds = Math.max(0, Math.floor(params.view.expiresAtMs / 1e3));
|
|
124
|
+
return new ExecApprovalContainer({
|
|
125
|
+
cfg: params.cfg,
|
|
126
|
+
accountId: params.accountId,
|
|
127
|
+
title: "Exec Approval Required",
|
|
128
|
+
description: "A command needs your approval.",
|
|
129
|
+
commandPreview,
|
|
130
|
+
commandSecondaryPreview,
|
|
131
|
+
metadataLines: buildApprovalMetadataLines(params.view.metadata),
|
|
132
|
+
actionRow: params.actionRow,
|
|
133
|
+
footer: `Expires <t:${expiresAtSeconds}:R> · ID: ${params.view.approvalId}`,
|
|
134
|
+
accentColor: "#FFA500"
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function createPluginApprovalRequestContainer(params) {
|
|
138
|
+
const expiresAtSeconds = Math.max(0, Math.floor(params.view.expiresAtMs / 1e3));
|
|
139
|
+
const severity = params.view.severity;
|
|
140
|
+
const accentColor = severity === "critical" ? "#ED4245" : severity === "info" ? "#5865F2" : "#FAA61A";
|
|
141
|
+
return new ExecApprovalContainer({
|
|
142
|
+
cfg: params.cfg,
|
|
143
|
+
accountId: params.accountId,
|
|
144
|
+
title: "Plugin Approval Required",
|
|
145
|
+
description: "A plugin action needs your approval.",
|
|
146
|
+
commandPreview: formatCommandPreview(params.view.title, 700),
|
|
147
|
+
commandSecondaryPreview: formatOptionalCommandPreview(params.view.description, 1e3),
|
|
148
|
+
metadataLines: buildApprovalMetadataLines(params.view.metadata),
|
|
149
|
+
actionRow: params.actionRow,
|
|
150
|
+
footer: `Expires <t:${expiresAtSeconds}:R> · ID: ${params.view.approvalId}`,
|
|
151
|
+
accentColor
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function createExecResolvedContainer(params) {
|
|
155
|
+
const { commandPreview, commandSecondaryPreview } = resolveCommandPreviews(params.view.commandText, params.view.commandPreview, 500, 300);
|
|
156
|
+
const decisionLabel = params.view.decision === "allow-once" ? "Allowed (once)" : params.view.decision === "allow-always" ? "Allowed (always)" : "Denied";
|
|
157
|
+
const accentColor = params.view.decision === "deny" ? "#ED4245" : params.view.decision === "allow-always" ? "#5865F2" : "#57F287";
|
|
158
|
+
return new ExecApprovalContainer({
|
|
159
|
+
cfg: params.cfg,
|
|
160
|
+
accountId: params.accountId,
|
|
161
|
+
title: `Exec Approval: ${decisionLabel}`,
|
|
162
|
+
description: params.view.resolvedBy ? `Resolved by ${params.view.resolvedBy}` : "Resolved",
|
|
163
|
+
commandPreview,
|
|
164
|
+
commandSecondaryPreview,
|
|
165
|
+
metadataLines: buildApprovalMetadataLines(params.view.metadata),
|
|
166
|
+
footer: `ID: ${params.view.approvalId}`,
|
|
167
|
+
accentColor
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function createPluginResolvedContainer(params) {
|
|
171
|
+
const decisionLabel = params.view.decision === "allow-once" ? "Allowed (once)" : params.view.decision === "allow-always" ? "Allowed (always)" : "Denied";
|
|
172
|
+
const accentColor = params.view.decision === "deny" ? "#ED4245" : params.view.decision === "allow-always" ? "#5865F2" : "#57F287";
|
|
173
|
+
return new ExecApprovalContainer({
|
|
174
|
+
cfg: params.cfg,
|
|
175
|
+
accountId: params.accountId,
|
|
176
|
+
title: `Plugin Approval: ${decisionLabel}`,
|
|
177
|
+
description: params.view.resolvedBy ? `Resolved by ${params.view.resolvedBy}` : "Resolved",
|
|
178
|
+
commandPreview: formatCommandPreview(params.view.title, 700),
|
|
179
|
+
commandSecondaryPreview: formatOptionalCommandPreview(params.view.description, 1e3),
|
|
180
|
+
metadataLines: buildApprovalMetadataLines(params.view.metadata),
|
|
181
|
+
footer: `ID: ${params.view.approvalId}`,
|
|
182
|
+
accentColor
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function createExecExpiredContainer(params) {
|
|
186
|
+
const { commandPreview, commandSecondaryPreview } = resolveCommandPreviews(params.view.commandText, params.view.commandPreview, 500, 300);
|
|
187
|
+
return new ExecApprovalContainer({
|
|
188
|
+
cfg: params.cfg,
|
|
189
|
+
accountId: params.accountId,
|
|
190
|
+
title: "Exec Approval: Expired",
|
|
191
|
+
description: "This approval request has expired.",
|
|
192
|
+
commandPreview,
|
|
193
|
+
commandSecondaryPreview,
|
|
194
|
+
metadataLines: buildApprovalMetadataLines(params.view.metadata),
|
|
195
|
+
footer: `ID: ${params.view.approvalId}`,
|
|
196
|
+
accentColor: "#99AAB5"
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function createPluginExpiredContainer(params) {
|
|
200
|
+
return new ExecApprovalContainer({
|
|
201
|
+
cfg: params.cfg,
|
|
202
|
+
accountId: params.accountId,
|
|
203
|
+
title: "Plugin Approval: Expired",
|
|
204
|
+
description: "This approval request has expired.",
|
|
205
|
+
commandPreview: formatCommandPreview(params.view.title, 700),
|
|
206
|
+
commandSecondaryPreview: formatOptionalCommandPreview(params.view.description, 1e3),
|
|
207
|
+
metadataLines: buildApprovalMetadataLines(params.view.metadata),
|
|
208
|
+
footer: `ID: ${params.view.approvalId}`,
|
|
209
|
+
accentColor: "#99AAB5"
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function buildExecApprovalCustomId(approvalId, action) {
|
|
213
|
+
return [`execapproval:id=${encodeURIComponent(approvalId)}`, `action=${action}`].join(";");
|
|
214
|
+
}
|
|
215
|
+
async function updateMessage(params) {
|
|
216
|
+
try {
|
|
217
|
+
const { rest, request: discordRequest } = createDiscordClient({
|
|
218
|
+
cfg: params.cfg,
|
|
219
|
+
token: params.token,
|
|
220
|
+
accountId: params.accountId
|
|
221
|
+
});
|
|
222
|
+
const payload = buildExecApprovalPayload(params.container);
|
|
223
|
+
await discordRequest(() => editChannelMessage(rest, params.channelId, params.messageId, { body: stripUndefinedFields(serializePayload(payload)) }), "update-approval");
|
|
224
|
+
} catch (err) {
|
|
225
|
+
logError(`discord approvals: failed to update message: ${String(err)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function finalizeMessage(params) {
|
|
229
|
+
if (!params.cleanupAfterResolve) {
|
|
230
|
+
await updateMessage(params);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
const { rest, request: discordRequest } = createDiscordClient({
|
|
235
|
+
cfg: params.cfg,
|
|
236
|
+
token: params.token,
|
|
237
|
+
accountId: params.accountId
|
|
238
|
+
});
|
|
239
|
+
await discordRequest(() => deleteChannelMessage(rest, params.channelId, params.messageId), "delete-approval");
|
|
240
|
+
} catch (err) {
|
|
241
|
+
logError(`discord approvals: failed to delete message: ${String(err)}`);
|
|
242
|
+
await updateMessage(params);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const discordApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
|
|
246
|
+
eventKinds: ["exec", "plugin"],
|
|
247
|
+
resolveApprovalKind: (request) => request.id.startsWith("plugin:") ? "plugin" : "exec",
|
|
248
|
+
availability: {
|
|
249
|
+
isConfigured: (params) => {
|
|
250
|
+
const resolved = resolveHandlerContext(params);
|
|
251
|
+
return resolved ? isDiscordExecApprovalClientEnabled({
|
|
252
|
+
cfg: params.cfg,
|
|
253
|
+
accountId: resolved.accountId,
|
|
254
|
+
configOverride: resolved.context.config
|
|
255
|
+
}) : false;
|
|
256
|
+
},
|
|
257
|
+
shouldHandle: (params) => {
|
|
258
|
+
const resolved = resolveHandlerContext(params);
|
|
259
|
+
return resolved ? shouldHandleDiscordApprovalRequest({
|
|
260
|
+
cfg: params.cfg,
|
|
261
|
+
accountId: resolved.accountId,
|
|
262
|
+
request: params.request,
|
|
263
|
+
configOverride: resolved.context.config
|
|
264
|
+
}) : false;
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
presentation: {
|
|
268
|
+
buildPendingPayload: ({ cfg, accountId, context, view }) => {
|
|
269
|
+
const resolved = resolveHandlerContext({
|
|
270
|
+
cfg,
|
|
271
|
+
accountId,
|
|
272
|
+
context
|
|
273
|
+
});
|
|
274
|
+
if (!resolved) return { body: {} };
|
|
275
|
+
const actionRow = createApprovalActionRow(view);
|
|
276
|
+
return { body: stripUndefinedFields(serializePayload(buildExecApprovalPayload(view.approvalKind === "plugin" ? createPluginApprovalRequestContainer({
|
|
277
|
+
view,
|
|
278
|
+
cfg,
|
|
279
|
+
accountId: resolved.accountId,
|
|
280
|
+
actionRow
|
|
281
|
+
}) : createExecApprovalRequestContainer({
|
|
282
|
+
view,
|
|
283
|
+
cfg,
|
|
284
|
+
accountId: resolved.accountId,
|
|
285
|
+
actionRow
|
|
286
|
+
})))) };
|
|
287
|
+
},
|
|
288
|
+
buildResolvedResult: ({ cfg, accountId, context, view }) => {
|
|
289
|
+
const resolvedContext = resolveHandlerContext({
|
|
290
|
+
cfg,
|
|
291
|
+
accountId,
|
|
292
|
+
context
|
|
293
|
+
});
|
|
294
|
+
if (!resolvedContext) return { kind: "delete" };
|
|
295
|
+
return {
|
|
296
|
+
kind: "update",
|
|
297
|
+
payload: view.approvalKind === "plugin" ? createPluginResolvedContainer({
|
|
298
|
+
view,
|
|
299
|
+
cfg,
|
|
300
|
+
accountId: resolvedContext.accountId
|
|
301
|
+
}) : createExecResolvedContainer({
|
|
302
|
+
view,
|
|
303
|
+
cfg,
|
|
304
|
+
accountId: resolvedContext.accountId
|
|
305
|
+
})
|
|
306
|
+
};
|
|
307
|
+
},
|
|
308
|
+
buildExpiredResult: ({ cfg, accountId, context, view }) => {
|
|
309
|
+
const resolvedContext = resolveHandlerContext({
|
|
310
|
+
cfg,
|
|
311
|
+
accountId,
|
|
312
|
+
context
|
|
313
|
+
});
|
|
314
|
+
if (!resolvedContext) return { kind: "delete" };
|
|
315
|
+
return {
|
|
316
|
+
kind: "update",
|
|
317
|
+
payload: view.approvalKind === "plugin" ? createPluginExpiredContainer({
|
|
318
|
+
view,
|
|
319
|
+
cfg,
|
|
320
|
+
accountId: resolvedContext.accountId
|
|
321
|
+
}) : createExecExpiredContainer({
|
|
322
|
+
view,
|
|
323
|
+
cfg,
|
|
324
|
+
accountId: resolvedContext.accountId
|
|
325
|
+
})
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
transport: {
|
|
330
|
+
prepareTarget: async ({ cfg, accountId, context, plannedTarget }) => {
|
|
331
|
+
const resolved = resolveHandlerContext({
|
|
332
|
+
cfg,
|
|
333
|
+
accountId,
|
|
334
|
+
context
|
|
335
|
+
});
|
|
336
|
+
if (!resolved) return null;
|
|
337
|
+
if (plannedTarget.surface === "origin") {
|
|
338
|
+
const destinationId = typeof plannedTarget.target.threadId === "string" && plannedTarget.target.threadId.trim().length > 0 ? plannedTarget.target.threadId.trim() : plannedTarget.target.to;
|
|
339
|
+
return {
|
|
340
|
+
dedupeKey: destinationId,
|
|
341
|
+
target: { discordChannelId: destinationId }
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const { rest, request: discordRequest } = createDiscordClient({
|
|
345
|
+
cfg,
|
|
346
|
+
token: resolved.context.token,
|
|
347
|
+
accountId: resolved.accountId
|
|
348
|
+
});
|
|
349
|
+
const userId = plannedTarget.target.to;
|
|
350
|
+
const dmChannel = await discordRequest(() => createUserDmChannel(rest, userId), "dm-channel");
|
|
351
|
+
if (!dmChannel?.id) {
|
|
352
|
+
logError(`discord approvals: failed to create DM for user ${userId}`);
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
dedupeKey: dmChannel.id,
|
|
357
|
+
target: {
|
|
358
|
+
discordChannelId: dmChannel.id,
|
|
359
|
+
recipientUserId: userId
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
},
|
|
363
|
+
deliverPending: async ({ cfg, accountId, context, plannedTarget, preparedTarget, pendingPayload }) => {
|
|
364
|
+
const resolved = resolveHandlerContext({
|
|
365
|
+
cfg,
|
|
366
|
+
accountId,
|
|
367
|
+
context
|
|
368
|
+
});
|
|
369
|
+
if (!resolved) return null;
|
|
370
|
+
const { rest, request: discordRequest } = createDiscordClient({
|
|
371
|
+
cfg,
|
|
372
|
+
token: resolved.context.token,
|
|
373
|
+
accountId: resolved.accountId
|
|
374
|
+
});
|
|
375
|
+
const message = await discordRequest(() => createChannelMessage(rest, preparedTarget.discordChannelId, { body: pendingPayload.body }), plannedTarget.surface === "origin" ? "send-approval-channel" : "send-approval");
|
|
376
|
+
if (!message?.id) {
|
|
377
|
+
if (plannedTarget.surface === "origin") logError("discord approvals: failed to send to channel");
|
|
378
|
+
else if (preparedTarget.recipientUserId) logError(`discord approvals: failed to send message to user ${preparedTarget.recipientUserId}`);
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
discordMessageId: message.id,
|
|
383
|
+
discordChannelId: preparedTarget.discordChannelId
|
|
384
|
+
};
|
|
385
|
+
},
|
|
386
|
+
updateEntry: async ({ cfg, accountId, context, entry, payload, phase }) => {
|
|
387
|
+
const resolved = resolveHandlerContext({
|
|
388
|
+
cfg,
|
|
389
|
+
accountId,
|
|
390
|
+
context
|
|
391
|
+
});
|
|
392
|
+
if (!resolved) return;
|
|
393
|
+
const container = payload;
|
|
394
|
+
await finalizeMessage({
|
|
395
|
+
cfg,
|
|
396
|
+
accountId: resolved.accountId,
|
|
397
|
+
token: resolved.context.token,
|
|
398
|
+
cleanupAfterResolve: phase === "resolved" ? resolved.context.config.cleanupAfterResolve : false,
|
|
399
|
+
channelId: entry.discordChannelId,
|
|
400
|
+
messageId: entry.discordMessageId,
|
|
401
|
+
container
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
observe: {
|
|
406
|
+
onDuplicateSkipped: ({ preparedTarget, request }) => {
|
|
407
|
+
logDebug(`discord approvals: skipping duplicate approval ${request.id} for channel ${preparedTarget.dedupeKey}`);
|
|
408
|
+
},
|
|
409
|
+
onDelivered: ({ plannedTarget, preparedTarget, request }) => {
|
|
410
|
+
if (plannedTarget.surface === "origin") {
|
|
411
|
+
logDebug(`discord approvals: sent approval ${request.id} to channel ${preparedTarget.target.discordChannelId}`);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
logDebug(`discord approvals: sent approval ${request.id} to user ${plannedTarget.target.to}`);
|
|
415
|
+
},
|
|
416
|
+
onDeliveryError: ({ error, plannedTarget }) => {
|
|
417
|
+
if (plannedTarget.surface === "origin") {
|
|
418
|
+
logError(`discord approvals: failed to send to channel: ${String(error)}`);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
logError(`discord approvals: failed to notify user ${plannedTarget.target.to}: ${String(error)}`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
//#endregion
|
|
426
|
+
export { approval_handler_runtime_exports as t };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Wt as __exportAll } from "./send.receipt-CDn3GBWC.js";
|
|
2
|
+
import { t as inspectDiscordAccount } from "./account-inspect-Dqw-enky.js";
|
|
3
|
+
import { E as fetchChannelPermissionsDiscord } from "./send.shared-D4iBnAmn.js";
|
|
4
|
+
import "./send-DCtPCHGk.js";
|
|
5
|
+
import { n as collectDiscordAuditChannelIdsForAccount, t as auditDiscordChannelPermissionsWithFetcher } from "./audit-core-BGrq3G7r.js";
|
|
6
|
+
//#region extensions/discord/src/audit.ts
|
|
7
|
+
var audit_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
auditDiscordChannelPermissions: () => auditDiscordChannelPermissions,
|
|
9
|
+
collectDiscordAuditChannelIds: () => collectDiscordAuditChannelIds
|
|
10
|
+
});
|
|
11
|
+
function collectDiscordAuditChannelIds(params) {
|
|
12
|
+
return collectDiscordAuditChannelIdsForAccount(inspectDiscordAccount({
|
|
13
|
+
cfg: params.cfg,
|
|
14
|
+
accountId: params.accountId
|
|
15
|
+
}).config);
|
|
16
|
+
}
|
|
17
|
+
async function auditDiscordChannelPermissions(params) {
|
|
18
|
+
return await auditDiscordChannelPermissionsWithFetcher({
|
|
19
|
+
...params,
|
|
20
|
+
fetchChannelPermissions: fetchChannelPermissionsDiscord
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { audit_exports as n, collectDiscordAuditChannelIds as r, auditDiscordChannelPermissions as t };
|