@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,43 @@
|
|
|
1
|
+
import { b as formatDiscordUserTag } from "./allow-list-B0s7evD7.js";
|
|
2
|
+
import { normalizeOptionalString } from "klaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
//#region extensions/discord/src/monitor/sender-identity.ts
|
|
4
|
+
function resolveDiscordWebhookId(message) {
|
|
5
|
+
const candidate = message.webhookId ?? message.webhook_id;
|
|
6
|
+
return typeof candidate === "string" && candidate.trim() ? candidate.trim() : null;
|
|
7
|
+
}
|
|
8
|
+
function resolveDiscordSenderIdentity(params) {
|
|
9
|
+
const pkInfo = params.pluralkitInfo ?? null;
|
|
10
|
+
const pkMember = pkInfo?.member ?? void 0;
|
|
11
|
+
const pkSystem = pkInfo?.system ?? void 0;
|
|
12
|
+
const memberId = pkMember?.id?.trim();
|
|
13
|
+
const memberName = (pkMember?.display_name ?? pkMember?.name ?? "")?.trim();
|
|
14
|
+
if (memberId && memberName) {
|
|
15
|
+
const systemName = pkSystem?.name?.trim();
|
|
16
|
+
const label = systemName ? `${memberName} (PK:${systemName})` : `${memberName} (PK)`;
|
|
17
|
+
return {
|
|
18
|
+
id: memberId,
|
|
19
|
+
name: memberName,
|
|
20
|
+
tag: normalizeOptionalString(pkMember?.name),
|
|
21
|
+
label,
|
|
22
|
+
isPluralKit: true,
|
|
23
|
+
pluralkit: {
|
|
24
|
+
memberId,
|
|
25
|
+
memberName,
|
|
26
|
+
systemId: normalizeOptionalString(pkSystem?.id),
|
|
27
|
+
systemName
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const senderTag = formatDiscordUserTag(params.author);
|
|
32
|
+
const senderDisplay = params.member?.nickname ?? params.member?.nick ?? params.author.globalName ?? params.author.username;
|
|
33
|
+
const senderLabel = senderDisplay && senderTag && senderDisplay !== senderTag ? `${senderDisplay} (${senderTag})` : senderDisplay ?? senderTag ?? params.author.id;
|
|
34
|
+
return {
|
|
35
|
+
id: params.author.id,
|
|
36
|
+
name: params.author.username ?? void 0,
|
|
37
|
+
tag: senderTag,
|
|
38
|
+
label: senderLabel,
|
|
39
|
+
isPluralKit: false
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { resolveDiscordWebhookId as n, resolveDiscordSenderIdentity as t };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { normalizeLowercaseStringOrEmpty } from "klaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
//#region extensions/discord/src/session-key-normalization.ts
|
|
3
|
+
function normalizeDiscordChatType(raw) {
|
|
4
|
+
const normalized = normalizeLowercaseStringOrEmpty(raw);
|
|
5
|
+
if (!normalized) return;
|
|
6
|
+
if (normalized === "dm") return "direct";
|
|
7
|
+
if (normalized === "group" || normalized === "channel" || normalized === "direct") return normalized;
|
|
8
|
+
}
|
|
9
|
+
function normalizeExplicitDiscordSessionKey(sessionKey, ctx) {
|
|
10
|
+
let normalized = normalizeLowercaseStringOrEmpty(sessionKey);
|
|
11
|
+
if (normalizeDiscordChatType(ctx.ChatType) !== "direct") return normalized;
|
|
12
|
+
normalized = normalized.replace(/^(discord:)dm:/, "$1direct:");
|
|
13
|
+
normalized = normalized.replace(/^(agent:[^:]+:discord:)dm:/, "$1direct:");
|
|
14
|
+
const match = normalized.match(/^((?:agent:[^:]+:)?)discord:channel:([^:]+)$/);
|
|
15
|
+
if (!match) return normalized;
|
|
16
|
+
const from = normalizeLowercaseStringOrEmpty(ctx.From);
|
|
17
|
+
const senderId = normalizeLowercaseStringOrEmpty(ctx.SenderId);
|
|
18
|
+
const fromDiscordId = from.startsWith("discord:") && !from.includes(":channel:") && !from.includes(":group:") ? from.slice(8) : "";
|
|
19
|
+
const directId = senderId || fromDiscordId;
|
|
20
|
+
return directId && directId === match[2] ? `${match[1]}discord:direct:${match[2]}` : normalized;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { normalizeExplicitDiscordSessionKey as t };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineBundledChannelSetupEntry } from "klaw/plugin-sdk/channel-entry-contract";
|
|
2
|
+
//#region extensions/discord/setup-entry.ts
|
|
3
|
+
var setup_entry_default = defineBundledChannelSetupEntry({
|
|
4
|
+
importMetaUrl: import.meta.url,
|
|
5
|
+
plugin: {
|
|
6
|
+
specifier: "./setup-plugin-api.js",
|
|
7
|
+
exportName: "discordSetupPlugin"
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { setup_entry_default as default };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, d as resolveDiscordAccountDmPolicy, n as isDiscordAccountEnabledForRuntime, o as resolveDefaultDiscordAccountId, r as listDiscordAccountIds, s as resolveDiscordAccount, u as resolveDiscordAccountDisabledReason } from "./accounts-B7OBFePq.js";
|
|
2
|
+
import { t as inspectDiscordAccount } from "./account-inspect-Dqw-enky.js";
|
|
3
|
+
import { i as getChatChannelMeta, o as resolveConfiguredFromCredentialStatuses } from "./channel-api-BfjklLby.js";
|
|
4
|
+
import { t as DiscordChannelConfigSchema } from "./config-schema-DIqJBGwC.js";
|
|
5
|
+
import { n as normalizeCompatibilityConfig } from "./doctor-contract-Btjt6NJD.js";
|
|
6
|
+
import { n as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B6WW5V88.js";
|
|
7
|
+
import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DLvYOgLM.js";
|
|
8
|
+
import { t as deriveLegacySessionChatType } from "./session-contract-Dwhw3RTY.js";
|
|
9
|
+
import { normalizeAccountId } from "klaw/plugin-sdk/account-id";
|
|
10
|
+
import { describeAccountSnapshot } from "klaw/plugin-sdk/account-helpers";
|
|
11
|
+
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "klaw/plugin-sdk/channel-config-helpers";
|
|
12
|
+
import { createOpenProviderConfiguredRouteWarningCollector } from "klaw/plugin-sdk/channel-policy";
|
|
13
|
+
import { createEnvPatchedAccountSetupAdapter } from "klaw/plugin-sdk/setup-runtime";
|
|
14
|
+
import { formatAllowFromLowercase } from "klaw/plugin-sdk/allow-from";
|
|
15
|
+
//#region extensions/discord/src/security.ts
|
|
16
|
+
const resolveDiscordDmPolicy = createScopedDmSecurityResolver({
|
|
17
|
+
channelKey: "discord",
|
|
18
|
+
resolvePolicy: (account) => account.config.dmPolicy,
|
|
19
|
+
resolveAllowFrom: (account) => account.config.allowFrom,
|
|
20
|
+
resolveAccess: ({ cfg, account }) => ({
|
|
21
|
+
dmPolicy: resolveDiscordAccountDmPolicy({
|
|
22
|
+
cfg,
|
|
23
|
+
accountId: account.accountId
|
|
24
|
+
}),
|
|
25
|
+
allowFrom: resolveDiscordAccountAllowFrom({
|
|
26
|
+
cfg,
|
|
27
|
+
accountId: account.accountId
|
|
28
|
+
})
|
|
29
|
+
}),
|
|
30
|
+
policyPathSuffix: "dmPolicy",
|
|
31
|
+
normalizeEntry: (raw) => raw.trim().replace(/^(discord|user):/i, "").replace(/^<@!?(\d+)>$/, "$1")
|
|
32
|
+
});
|
|
33
|
+
const collectDiscordSecurityWarnings = createOpenProviderConfiguredRouteWarningCollector({
|
|
34
|
+
providerConfigPresent: (cfg) => cfg.channels?.discord !== void 0,
|
|
35
|
+
resolveGroupPolicy: (account) => account.config.groupPolicy,
|
|
36
|
+
resolveRouteAllowlistConfigured: (account) => Object.keys(account.config.guilds ?? {}).length > 0,
|
|
37
|
+
configureRouteAllowlist: {
|
|
38
|
+
surface: "Discord guilds",
|
|
39
|
+
openScope: "any channel not explicitly denied",
|
|
40
|
+
groupPolicyPath: "channels.discord.groupPolicy",
|
|
41
|
+
routeAllowlistPath: "channels.discord.guilds.<id>.channels"
|
|
42
|
+
},
|
|
43
|
+
missingRouteAllowlist: {
|
|
44
|
+
surface: "Discord guilds",
|
|
45
|
+
openBehavior: "with no guild/channel allowlist; any channel can trigger (mention-gated)",
|
|
46
|
+
remediation: "Set channels.discord.groupPolicy=\"allowlist\" and configure channels.discord.guilds.<id>.channels"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
let discordSecurityAuditModulePromise;
|
|
50
|
+
async function loadDiscordSecurityAuditModule() {
|
|
51
|
+
discordSecurityAuditModulePromise ??= import("./security-audit.runtime-CQSkjNLu.js");
|
|
52
|
+
return await discordSecurityAuditModulePromise;
|
|
53
|
+
}
|
|
54
|
+
const discordSecurityAdapter = {
|
|
55
|
+
resolveDmPolicy: resolveDiscordDmPolicy,
|
|
56
|
+
collectWarnings: collectDiscordSecurityWarnings,
|
|
57
|
+
collectAuditFindings: async (params) => (await loadDiscordSecurityAuditModule()).collectDiscordSecurityAuditFindings(params)
|
|
58
|
+
};
|
|
59
|
+
const discordSetupAdapter = createEnvPatchedAccountSetupAdapter({
|
|
60
|
+
channelKey: "discord",
|
|
61
|
+
defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
|
|
62
|
+
missingCredentialError: "Discord requires token (or --use-env).",
|
|
63
|
+
hasCredentials: (input) => Boolean(input.token),
|
|
64
|
+
buildPatch: (input) => input.token ? { token: input.token } : {}
|
|
65
|
+
});
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region extensions/discord/src/doctor-shared.ts
|
|
68
|
+
const DISCORD_LEGACY_CONFIG_RULES = [];
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region extensions/discord/src/shared.ts
|
|
71
|
+
const DISCORD_CHANNEL = "discord";
|
|
72
|
+
let discordDoctorModulePromise;
|
|
73
|
+
async function loadDiscordDoctorModule() {
|
|
74
|
+
discordDoctorModulePromise ??= import("./doctor-bbKSvGVD.js");
|
|
75
|
+
return await discordDoctorModulePromise;
|
|
76
|
+
}
|
|
77
|
+
const discordDoctor = {
|
|
78
|
+
dmAllowFromMode: "topOnly",
|
|
79
|
+
groupModel: "route",
|
|
80
|
+
groupAllowFromFallbackToAllowFrom: false,
|
|
81
|
+
warnOnEmptyGroupSenderAllowlist: false,
|
|
82
|
+
legacyConfigRules: DISCORD_LEGACY_CONFIG_RULES,
|
|
83
|
+
normalizeCompatibilityConfig,
|
|
84
|
+
collectPreviewWarnings: async (params) => (await loadDiscordDoctorModule()).discordDoctor.collectPreviewWarnings?.(params) ?? [],
|
|
85
|
+
collectMutableAllowlistWarnings: async (params) => (await loadDiscordDoctorModule()).discordDoctor.collectMutableAllowlistWarnings?.(params) ?? [],
|
|
86
|
+
repairConfig: async (params) => (await loadDiscordDoctorModule()).discordDoctor.repairConfig?.(params) ?? {
|
|
87
|
+
config: params.cfg,
|
|
88
|
+
changes: []
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
function resolveDiscordConfigAccessorAccount(params) {
|
|
92
|
+
const accountId = normalizeAccountId(params.accountId ?? resolveDefaultDiscordAccountId(params.cfg));
|
|
93
|
+
const config = mergeDiscordAccountConfig(params.cfg, accountId);
|
|
94
|
+
return {
|
|
95
|
+
allowFrom: resolveDiscordAccountAllowFrom({
|
|
96
|
+
cfg: params.cfg,
|
|
97
|
+
accountId
|
|
98
|
+
}),
|
|
99
|
+
defaultTo: config.defaultTo
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const discordConfigAdapter = createScopedChannelConfigAdapter({
|
|
103
|
+
sectionKey: DISCORD_CHANNEL,
|
|
104
|
+
listAccountIds: listDiscordAccountIds,
|
|
105
|
+
resolveAccount: adaptScopedAccountAccessor(resolveDiscordAccount),
|
|
106
|
+
resolveAccessorAccount: resolveDiscordConfigAccessorAccount,
|
|
107
|
+
inspectAccount: adaptScopedAccountAccessor(inspectDiscordAccount),
|
|
108
|
+
defaultAccountId: resolveDefaultDiscordAccountId,
|
|
109
|
+
clearBaseFields: ["token", "name"],
|
|
110
|
+
resolveAllowFrom: (account) => account.allowFrom,
|
|
111
|
+
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
|
|
112
|
+
resolveDefaultTo: (account) => account.defaultTo
|
|
113
|
+
});
|
|
114
|
+
function createDiscordPluginBase(params) {
|
|
115
|
+
return {
|
|
116
|
+
id: DISCORD_CHANNEL,
|
|
117
|
+
...params.setupWizard ? { setupWizard: params.setupWizard } : {},
|
|
118
|
+
meta: { ...getChatChannelMeta(DISCORD_CHANNEL) },
|
|
119
|
+
capabilities: {
|
|
120
|
+
chatTypes: [
|
|
121
|
+
"direct",
|
|
122
|
+
"channel",
|
|
123
|
+
"thread"
|
|
124
|
+
],
|
|
125
|
+
polls: true,
|
|
126
|
+
reactions: true,
|
|
127
|
+
threads: true,
|
|
128
|
+
media: true,
|
|
129
|
+
tts: { voice: { synthesisTarget: "voice-note" } },
|
|
130
|
+
nativeCommands: true
|
|
131
|
+
},
|
|
132
|
+
commands: {
|
|
133
|
+
nativeCommandsAutoEnabled: true,
|
|
134
|
+
nativeSkillsAutoEnabled: true,
|
|
135
|
+
resolveNativeCommandName: ({ commandKey, defaultName }) => commandKey === "tts" ? "voice" : defaultName
|
|
136
|
+
},
|
|
137
|
+
doctor: discordDoctor,
|
|
138
|
+
streaming: { blockStreamingCoalesceDefaults: {
|
|
139
|
+
minChars: 1500,
|
|
140
|
+
idleMs: 1e3
|
|
141
|
+
} },
|
|
142
|
+
reload: { configPrefixes: ["channels.discord"] },
|
|
143
|
+
configSchema: DiscordChannelConfigSchema,
|
|
144
|
+
config: {
|
|
145
|
+
...discordConfigAdapter,
|
|
146
|
+
hasConfiguredState: ({ env }) => typeof env?.DISCORD_BOT_TOKEN === "string" && env.DISCORD_BOT_TOKEN.trim().length > 0,
|
|
147
|
+
isEnabled: (account, cfg) => isDiscordAccountEnabledForRuntime(account, cfg),
|
|
148
|
+
disabledReason: (account, cfg) => resolveDiscordAccountDisabledReason(account, cfg),
|
|
149
|
+
isConfigured: (account) => resolveConfiguredFromCredentialStatuses(account) ?? Boolean(account.token?.trim()),
|
|
150
|
+
describeAccount: (account) => describeAccountSnapshot({
|
|
151
|
+
account,
|
|
152
|
+
configured: resolveConfiguredFromCredentialStatuses(account) ?? Boolean(account.token?.trim()),
|
|
153
|
+
extra: {
|
|
154
|
+
tokenSource: account.tokenSource,
|
|
155
|
+
tokenStatus: account.tokenStatus
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
},
|
|
159
|
+
messaging: { deriveLegacySessionChatType },
|
|
160
|
+
security: discordSecurityAdapter,
|
|
161
|
+
secrets: {
|
|
162
|
+
secretTargetRegistryEntries,
|
|
163
|
+
unsupportedSecretRefSurfacePatterns,
|
|
164
|
+
collectUnsupportedSecretRefConfigCandidates,
|
|
165
|
+
collectRuntimeConfigAssignments
|
|
166
|
+
},
|
|
167
|
+
setup: params.setup
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { discordSecurityAdapter as a, discordSetupAdapter as i, discordConfigAdapter as n, DISCORD_LEGACY_CONFIG_RULES as r, createDiscordPluginBase as t };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Wt as __exportAll } from "./send.receipt-CDn3GBWC.js";
|
|
2
|
+
import { s as resolveDiscordAccount } from "./accounts-B7OBFePq.js";
|
|
3
|
+
import { n as autoBindSpawnedDiscordSubagent, o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-9aKRmZv0.js";
|
|
4
|
+
import { normalizeOptionalLowercaseString, normalizeOptionalStringifiedId } from "klaw/plugin-sdk/string-coerce-runtime";
|
|
5
|
+
import { formatThreadBindingDisabledError, formatThreadBindingSpawnDisabledError, resolveThreadBindingSpawnPolicy } from "klaw/plugin-sdk/conversation-runtime";
|
|
6
|
+
//#region extensions/discord/src/subagent-hooks.ts
|
|
7
|
+
var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
handleDiscordSubagentDeliveryTarget: () => handleDiscordSubagentDeliveryTarget,
|
|
9
|
+
handleDiscordSubagentEnded: () => handleDiscordSubagentEnded,
|
|
10
|
+
handleDiscordSubagentSpawning: () => handleDiscordSubagentSpawning
|
|
11
|
+
});
|
|
12
|
+
function summarizeError(err) {
|
|
13
|
+
if (err instanceof Error) return err.message;
|
|
14
|
+
if (typeof err === "string") return err;
|
|
15
|
+
return "error";
|
|
16
|
+
}
|
|
17
|
+
function normalizeThreadBindingTargetKind(raw) {
|
|
18
|
+
const normalized = normalizeOptionalLowercaseString(raw);
|
|
19
|
+
if (normalized === "subagent" || normalized === "acp") return normalized;
|
|
20
|
+
}
|
|
21
|
+
async function handleDiscordSubagentSpawning(api, event) {
|
|
22
|
+
if (!event.threadRequested) return;
|
|
23
|
+
if (normalizeOptionalLowercaseString(event.requester?.channel) !== "discord") return;
|
|
24
|
+
const account = resolveDiscordAccount({
|
|
25
|
+
cfg: api.config,
|
|
26
|
+
accountId: event.requester?.accountId
|
|
27
|
+
});
|
|
28
|
+
const threadBindingPolicy = resolveThreadBindingSpawnPolicy({
|
|
29
|
+
cfg: api.config,
|
|
30
|
+
channel: "discord",
|
|
31
|
+
accountId: account.accountId,
|
|
32
|
+
kind: "subagent"
|
|
33
|
+
});
|
|
34
|
+
if (!threadBindingPolicy.enabled) return {
|
|
35
|
+
status: "error",
|
|
36
|
+
error: formatThreadBindingDisabledError({
|
|
37
|
+
channel: threadBindingPolicy.channel,
|
|
38
|
+
accountId: threadBindingPolicy.accountId,
|
|
39
|
+
kind: "subagent"
|
|
40
|
+
})
|
|
41
|
+
};
|
|
42
|
+
if (!threadBindingPolicy.spawnEnabled) return {
|
|
43
|
+
status: "error",
|
|
44
|
+
error: formatThreadBindingSpawnDisabledError({
|
|
45
|
+
channel: threadBindingPolicy.channel,
|
|
46
|
+
accountId: threadBindingPolicy.accountId,
|
|
47
|
+
kind: "subagent"
|
|
48
|
+
})
|
|
49
|
+
};
|
|
50
|
+
try {
|
|
51
|
+
const agentId = event.agentId?.trim() || "subagent";
|
|
52
|
+
const binding = await autoBindSpawnedDiscordSubagent({
|
|
53
|
+
cfg: api.config,
|
|
54
|
+
accountId: account.accountId,
|
|
55
|
+
channel: event.requester?.channel,
|
|
56
|
+
to: event.requester?.to,
|
|
57
|
+
threadId: event.requester?.threadId,
|
|
58
|
+
childSessionKey: event.childSessionKey,
|
|
59
|
+
agentId,
|
|
60
|
+
label: event.label,
|
|
61
|
+
boundBy: "system"
|
|
62
|
+
});
|
|
63
|
+
if (!binding) return {
|
|
64
|
+
status: "error",
|
|
65
|
+
error: "Unable to create or bind a Discord thread for this subagent session. Session mode is unavailable for this target."
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
status: "ok",
|
|
69
|
+
threadBindingReady: true,
|
|
70
|
+
deliveryOrigin: {
|
|
71
|
+
channel: "discord",
|
|
72
|
+
accountId: account.accountId,
|
|
73
|
+
to: `channel:${binding.threadId}`,
|
|
74
|
+
threadId: binding.threadId
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
} catch (err) {
|
|
78
|
+
return {
|
|
79
|
+
status: "error",
|
|
80
|
+
error: `Discord thread bind failed: ${summarizeError(err)}`
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function handleDiscordSubagentEnded(event) {
|
|
85
|
+
unbindThreadBindingsBySessionKey({
|
|
86
|
+
targetSessionKey: event.targetSessionKey,
|
|
87
|
+
accountId: event.accountId,
|
|
88
|
+
targetKind: normalizeThreadBindingTargetKind(event.targetKind),
|
|
89
|
+
reason: event.reason,
|
|
90
|
+
sendFarewell: event.sendFarewell
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function handleDiscordSubagentDeliveryTarget(event) {
|
|
94
|
+
if (!event.expectsCompletionMessage) return;
|
|
95
|
+
if (normalizeOptionalLowercaseString(event.requesterOrigin?.channel) !== "discord") return;
|
|
96
|
+
const requesterAccountId = event.requesterOrigin?.accountId?.trim();
|
|
97
|
+
const requesterThreadId = event.requesterOrigin?.threadId != null && event.requesterOrigin.threadId !== "" ? normalizeOptionalStringifiedId(event.requesterOrigin.threadId) ?? "" : "";
|
|
98
|
+
const bindings = listThreadBindingsBySessionKey({
|
|
99
|
+
targetSessionKey: event.childSessionKey,
|
|
100
|
+
...requesterAccountId ? { accountId: requesterAccountId } : {},
|
|
101
|
+
targetKind: "subagent"
|
|
102
|
+
});
|
|
103
|
+
if (bindings.length === 0) return;
|
|
104
|
+
let binding;
|
|
105
|
+
if (requesterThreadId) binding = bindings.find((entry) => {
|
|
106
|
+
if (entry.threadId !== requesterThreadId) return false;
|
|
107
|
+
if (requesterAccountId && entry.accountId !== requesterAccountId) return false;
|
|
108
|
+
return true;
|
|
109
|
+
});
|
|
110
|
+
if (!binding && bindings.length === 1) binding = bindings[0];
|
|
111
|
+
if (!binding) return;
|
|
112
|
+
return { origin: {
|
|
113
|
+
channel: "discord",
|
|
114
|
+
accountId: binding.accountId,
|
|
115
|
+
to: `channel:${binding.threadId}`,
|
|
116
|
+
threadId: binding.threadId
|
|
117
|
+
} };
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { subagent_hooks_exports as i, handleDiscordSubagentEnded as n, handleDiscordSubagentSpawning as r, handleDiscordSubagentDeliveryTarget as t };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region extensions/discord/subagent-hooks-api.ts
|
|
2
|
+
let discordSubagentHooksPromise = null;
|
|
3
|
+
function loadDiscordSubagentHooksModule() {
|
|
4
|
+
discordSubagentHooksPromise ??= import("./subagent-hooks-8bK-mgiU.js").then((n) => n.i);
|
|
5
|
+
return discordSubagentHooksPromise;
|
|
6
|
+
}
|
|
7
|
+
function registerDiscordSubagentHooks(api) {
|
|
8
|
+
api.on("subagent_spawning", async (event) => {
|
|
9
|
+
const { handleDiscordSubagentSpawning } = await loadDiscordSubagentHooksModule();
|
|
10
|
+
return await handleDiscordSubagentSpawning(api, event);
|
|
11
|
+
});
|
|
12
|
+
api.on("subagent_ended", async (event) => {
|
|
13
|
+
const { handleDiscordSubagentEnded } = await loadDiscordSubagentHooksModule();
|
|
14
|
+
handleDiscordSubagentEnded(event);
|
|
15
|
+
});
|
|
16
|
+
api.on("subagent_delivery_target", async (event) => {
|
|
17
|
+
const { handleDiscordSubagentDeliveryTarget } = await loadDiscordSubagentHooksModule();
|
|
18
|
+
return handleDiscordSubagentDeliveryTarget(event);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { registerDiscordSubagentHooks };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { c as discord_exports } from "./send.receipt-CDn3GBWC.js";
|
|
2
|
+
import { b as formatDiscordUserTag } from "./allow-list-B0s7evD7.js";
|
|
3
|
+
//#region extensions/discord/src/monitor/system-events.ts
|
|
4
|
+
function resolveDiscordSystemEvent(message, location) {
|
|
5
|
+
switch (message.type) {
|
|
6
|
+
case discord_exports.MessageType.ChannelPinnedMessage: return buildDiscordSystemEvent(message, location, "pinned a message");
|
|
7
|
+
case discord_exports.MessageType.RecipientAdd: return buildDiscordSystemEvent(message, location, "added a recipient");
|
|
8
|
+
case discord_exports.MessageType.RecipientRemove: return buildDiscordSystemEvent(message, location, "removed a recipient");
|
|
9
|
+
case discord_exports.MessageType.UserJoin: return buildDiscordSystemEvent(message, location, "user joined");
|
|
10
|
+
case discord_exports.MessageType.GuildBoost: return buildDiscordSystemEvent(message, location, "boosted the server");
|
|
11
|
+
case discord_exports.MessageType.GuildBoostTier1: return buildDiscordSystemEvent(message, location, "boosted the server (Tier 1 reached)");
|
|
12
|
+
case discord_exports.MessageType.GuildBoostTier2: return buildDiscordSystemEvent(message, location, "boosted the server (Tier 2 reached)");
|
|
13
|
+
case discord_exports.MessageType.GuildBoostTier3: return buildDiscordSystemEvent(message, location, "boosted the server (Tier 3 reached)");
|
|
14
|
+
case discord_exports.MessageType.ThreadCreated: return buildDiscordSystemEvent(message, location, "created a thread");
|
|
15
|
+
case discord_exports.MessageType.AutoModerationAction: return buildDiscordSystemEvent(message, location, "auto moderation action");
|
|
16
|
+
case discord_exports.MessageType.GuildIncidentAlertModeEnabled: return buildDiscordSystemEvent(message, location, "raid protection enabled");
|
|
17
|
+
case discord_exports.MessageType.GuildIncidentAlertModeDisabled: return buildDiscordSystemEvent(message, location, "raid protection disabled");
|
|
18
|
+
case discord_exports.MessageType.GuildIncidentReportRaid: return buildDiscordSystemEvent(message, location, "raid reported");
|
|
19
|
+
case discord_exports.MessageType.GuildIncidentReportFalseAlarm: return buildDiscordSystemEvent(message, location, "raid report marked false alarm");
|
|
20
|
+
case discord_exports.MessageType.StageStart: return buildDiscordSystemEvent(message, location, "stage started");
|
|
21
|
+
case discord_exports.MessageType.StageEnd: return buildDiscordSystemEvent(message, location, "stage ended");
|
|
22
|
+
case discord_exports.MessageType.StageSpeaker: return buildDiscordSystemEvent(message, location, "stage speaker updated");
|
|
23
|
+
case discord_exports.MessageType.StageTopic: return buildDiscordSystemEvent(message, location, "stage topic updated");
|
|
24
|
+
case discord_exports.MessageType.PollResult: return buildDiscordSystemEvent(message, location, "poll results posted");
|
|
25
|
+
case discord_exports.MessageType.PurchaseNotification: return buildDiscordSystemEvent(message, location, "purchase notification");
|
|
26
|
+
default: return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function buildDiscordSystemEvent(message, location, action) {
|
|
30
|
+
const authorLabel = message.author ? formatDiscordUserTag(message.author) : "";
|
|
31
|
+
return `Discord system: ${authorLabel ? `${authorLabel} ` : ""}${action} in ${location}`;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { resolveDiscordSystemEvent };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Ht as parseDiscordTarget, Wt as __exportAll, r as allowFromContainsDiscordUserId } from "./send.receipt-CDn3GBWC.js";
|
|
2
|
+
import { c as resolveDiscordAccountAllowFrom, s as resolveDiscordAccount } from "./accounts-B7OBFePq.js";
|
|
3
|
+
import { i as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-DX4dLRpJ.js";
|
|
4
|
+
import { buildMessagingTarget } from "klaw/plugin-sdk/messaging-targets";
|
|
5
|
+
//#region extensions/discord/src/send-target-parsing.ts
|
|
6
|
+
const parseDiscordSendTarget = (raw, options = {}) => parseDiscordTarget(raw, options);
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region extensions/discord/src/target-resolver.ts
|
|
9
|
+
var target_resolver_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
parseAndResolveDiscordTarget: () => parseAndResolveDiscordTarget,
|
|
11
|
+
resolveDiscordTarget: () => resolveDiscordTarget
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a Discord username to user ID using the directory lookup.
|
|
15
|
+
* This enables sending DMs by username instead of requiring explicit user IDs.
|
|
16
|
+
*/
|
|
17
|
+
async function resolveDiscordTarget(raw, options, parseOptions = {}) {
|
|
18
|
+
const trimmed = raw.trim();
|
|
19
|
+
if (!trimmed) return;
|
|
20
|
+
const likelyUsername = isLikelyUsername(trimmed);
|
|
21
|
+
const shouldLookup = isExplicitUserLookup(trimmed, parseOptions) || likelyUsername;
|
|
22
|
+
if (/^\d+$/.test(trimmed) && parseOptions.defaultKind !== "user" && isConfiguredAllowedDiscordDmUser(trimmed, options)) return buildMessagingTarget("user", trimmed, trimmed);
|
|
23
|
+
const directParse = safeParseDiscordTarget(trimmed, parseOptions);
|
|
24
|
+
if (directParse && directParse.kind !== "channel" && !likelyUsername) return directParse;
|
|
25
|
+
if (!shouldLookup) return directParse ?? parseDiscordSendTarget(trimmed, parseOptions);
|
|
26
|
+
try {
|
|
27
|
+
const match = (await listDiscordDirectoryPeersLive({
|
|
28
|
+
...options,
|
|
29
|
+
query: trimmed,
|
|
30
|
+
limit: 1
|
|
31
|
+
}))[0];
|
|
32
|
+
if (match && match.kind === "user") {
|
|
33
|
+
const userId = match.id.replace(/^user:/, "");
|
|
34
|
+
const resolvedAccountId = resolveDiscordAccount({
|
|
35
|
+
cfg: options.cfg,
|
|
36
|
+
accountId: options.accountId
|
|
37
|
+
}).accountId;
|
|
38
|
+
rememberDiscordDirectoryUser({
|
|
39
|
+
accountId: resolvedAccountId,
|
|
40
|
+
userId,
|
|
41
|
+
handles: [
|
|
42
|
+
trimmed,
|
|
43
|
+
match.name,
|
|
44
|
+
match.handle
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
return buildMessagingTarget("user", userId, trimmed);
|
|
48
|
+
}
|
|
49
|
+
} catch {}
|
|
50
|
+
return parseDiscordSendTarget(trimmed, parseOptions);
|
|
51
|
+
}
|
|
52
|
+
async function parseAndResolveDiscordTarget(raw, options, parseOptions = {}) {
|
|
53
|
+
const resolved = await resolveDiscordTarget(raw, options, parseOptions) ?? parseDiscordSendTarget(raw, parseOptions);
|
|
54
|
+
if (!resolved) throw new Error("Recipient is required for Discord sends");
|
|
55
|
+
return resolved;
|
|
56
|
+
}
|
|
57
|
+
function safeParseDiscordTarget(input, options) {
|
|
58
|
+
try {
|
|
59
|
+
return parseDiscordSendTarget(input, options);
|
|
60
|
+
} catch {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function isConfiguredAllowedDiscordDmUser(input, options) {
|
|
65
|
+
return allowFromContainsDiscordUserId(resolveDiscordAccountAllowFrom({
|
|
66
|
+
cfg: options.cfg,
|
|
67
|
+
accountId: options.accountId
|
|
68
|
+
}) ?? [], input);
|
|
69
|
+
}
|
|
70
|
+
function isExplicitUserLookup(input, options) {
|
|
71
|
+
if (/^<@!?(\d+)>$/.test(input)) return true;
|
|
72
|
+
if (/^(user:|discord:)/.test(input)) return true;
|
|
73
|
+
if (input.startsWith("@")) return true;
|
|
74
|
+
if (/^\d+$/.test(input)) return options.defaultKind === "user";
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
function isLikelyUsername(input) {
|
|
78
|
+
if (/^(user:|channel:|discord:|@|<@!?)|[\d]+$/.test(input)) return false;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { parseDiscordSendTarget as i, resolveDiscordTarget as n, target_resolver_exports as r, parseAndResolveDiscordTarget as t };
|
package/dist/test-api.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { t as discordPlugin } from "./channel-U_aeoFwW.js";
|
|
2
|
+
import { n as discordOutbound } from "./outbound-adapter-C18OAc1y.js";
|
|
3
|
+
import { i as testing } from "./thread-bindings.manager-0YBHGemk.js";
|
|
4
|
+
import { n as buildDiscordInboundAccessContext } from "./inbound-context-WAOqhGlT.js";
|
|
5
|
+
import { finalizeInboundContext } from "klaw/plugin-sdk/reply-dispatch-runtime";
|
|
6
|
+
//#region extensions/discord/src/monitor/inbound-context.test-helpers.ts
|
|
7
|
+
function buildFinalizedDiscordDirectInboundContext() {
|
|
8
|
+
const { groupSystemPrompt, ownerAllowFrom, untrustedContext } = buildDiscordInboundAccessContext({
|
|
9
|
+
channelConfig: null,
|
|
10
|
+
guildInfo: null,
|
|
11
|
+
sender: {
|
|
12
|
+
id: "U1",
|
|
13
|
+
name: "Alice",
|
|
14
|
+
tag: "alice"
|
|
15
|
+
},
|
|
16
|
+
isGuild: false
|
|
17
|
+
});
|
|
18
|
+
return finalizeInboundContext({
|
|
19
|
+
Body: "hi",
|
|
20
|
+
BodyForAgent: "hi",
|
|
21
|
+
RawBody: "hi",
|
|
22
|
+
CommandBody: "hi",
|
|
23
|
+
From: "discord:U1",
|
|
24
|
+
To: "user:U1",
|
|
25
|
+
SessionKey: "agent:main:discord:direct:u1",
|
|
26
|
+
AccountId: "default",
|
|
27
|
+
ChatType: "direct",
|
|
28
|
+
ConversationLabel: "Alice",
|
|
29
|
+
SenderName: "Alice",
|
|
30
|
+
SenderId: "U1",
|
|
31
|
+
SenderUsername: "alice",
|
|
32
|
+
GroupSystemPrompt: groupSystemPrompt,
|
|
33
|
+
OwnerAllowFrom: ownerAllowFrom,
|
|
34
|
+
UntrustedStructuredContext: untrustedContext,
|
|
35
|
+
Provider: "discord",
|
|
36
|
+
Surface: "discord",
|
|
37
|
+
WasMentioned: false,
|
|
38
|
+
MessageSid: "m1",
|
|
39
|
+
CommandAuthorized: true,
|
|
40
|
+
OriginatingChannel: "discord",
|
|
41
|
+
OriginatingTo: "user:U1"
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { buildFinalizedDiscordDirectInboundContext, discordOutbound, discordPlugin, testing as discordThreadBindingTesting };
|