@openclaw/discord 2026.7.1 → 2026.7.2-beta.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/action-runtime-api.js +1 -1
- package/dist/{allow-list-C-MqM-B_.js → allow-list-B7qOH5xu.js} +22 -1
- package/dist/{api-DPRqYi4Z.js → api--f62GFaS.js} +38 -23
- package/dist/api.js +15 -15
- package/dist/approval-custom-id-NYPYj9Po.js +58 -0
- package/dist/{approval-handler.runtime-Bw2pZNk1.js → approval-handler.runtime-DeyIiw5I.js} +28 -23
- package/dist/approval-message-safety-C-8BL6Kv.js +47 -0
- package/dist/{audit-MLpDpN3Z.js → audit-Df2w046a.js} +3 -3
- package/dist/{channel-actions-D_fjVUZ_.js → channel-actions-ChpBSRcu.js} +6 -4
- package/dist/{channel-actions.runtime-CVHlFqQg.js → channel-actions.runtime-D8V8tyCq.js} +41 -12
- package/dist/channel-config-api.js +1 -1
- package/dist/{channel-DGWPH5u3.js → channel-nYmJ7FKQ.js} +275 -62
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-tZcpIn4e.js → channel.setup-DyihrqHH.js} +3 -3
- package/dist/{components-BIBizbtZ.js → components-BVrfRS-F.js} +78 -52
- package/dist/config-api-B18fR8M5.js +3 -0
- package/dist/{config-schema-BgIhO3ko.js → config-schema-_bUKcWRm.js} +42 -82
- package/dist/conversation-identity-BpkAzklg.js +94 -0
- package/dist/{directory-config-ByaUKL1f.js → directory-config-BUe-qq_C.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-BX79ImQA.js → directory-live-DZByMdPO.js} +6 -6
- package/dist/{doctor-Bgoxm5AN.js → doctor-bMaWXFKu.js} +5 -4
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{doctor-contract-CU7lnZTF.js → doctor-contract-wId6pV41.js} +41 -37
- package/dist/{handle-action.guild-admin-CgJSNVui.js → handle-action.guild-admin-C_PQcBEV.js} +12 -12
- package/dist/index.js +1 -1
- package/dist/legacy-state-migrations-api.js +24 -2
- package/dist/{manager.runtime-DaB-CTrt.js → manager.runtime-3RVMVkyx.js} +546 -154
- package/dist/{message-handler-DcgvugZt.js → message-handler-CIxWq5Yh.js} +8 -9
- package/dist/{message-handler.preflight-DvLXiYVH.js → message-handler.preflight-BI86IbHz.js} +46 -22
- package/dist/{message-handler.process-Cjf30P_B.js → message-handler.process-bPS_9_tb.js} +241 -107
- package/dist/{message-utils-B_3yA5bN.js → message-utils-D4j07taS.js} +2 -3
- package/dist/{outbound-adapter-82RWi_SR.js → outbound-adapter-Czny0Fae.js} +16 -68
- package/dist/outbound-components-oJKLj62G.js +99 -0
- package/dist/pluralkit-UXq1OyUI.js +40 -0
- package/dist/{probe-D1ImJEo2.js → probe-DxjMBeVG.js} +1 -1
- package/dist/{probe.runtime-B1dsEeBD.js → probe.runtime-Bc8Oo6e8.js} +1 -1
- package/dist/{provider-BkfbC9FQ.js → provider-DWvDNb4J.js} +702 -236
- package/dist/{provider-session.runtime-BDjyFw6Y.js → provider-session.runtime-D5pCGibh.js} +3 -3
- package/dist/provider.runtime-C2iIfbTs.js +2 -0
- package/dist/{resolve-allowlist-common-CWbE8XlH.js → resolve-allowlist-common-B9S8LLBd.js} +5 -5
- package/dist/{resolve-channels-CcpvWoRa.js → resolve-channels-BrkWOKdG.js} +7 -7
- package/dist/{resolve-users-DJamun9s.js → resolve-users-OjrXXvJP.js} +5 -5
- package/dist/{runtime-C6rRmQ6l.js → runtime-C618lis9.js} +223 -33
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +23 -23
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-DSbfGnzS.js +6 -0
- package/dist/runtime-api.monitor.js +7 -7
- package/dist/runtime-api.send.js +5 -5
- package/dist/runtime-api.threads.js +5 -5
- package/dist/{send-iJ0B4bAX.js → send-BFpa_DHn.js} +21 -12
- package/dist/{send.components-D0I39utR.js → send.components-BaXQJKWT.js} +15 -10
- package/dist/{send.outbound-Bj61Q3a0.js → send.outbound-BlA6VzSE.js} +22 -12
- package/dist/{send.receipt-BpBQED_5.js → send.receipt-aegk69an.js} +59 -75
- package/dist/{send.shared-wAwMhHDN.js → send.shared-Xz7IMVpu.js} +44 -20
- package/dist/{sender-identity-CEsfDF0L.js → sender-identity-C62lBe18.js} +1 -1
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-BQVKfnev.js → shared-BLYBt5SA.js} +3 -3
- package/dist/{subagent-hooks-B-bJxxGg.js → subagent-hooks-DKJ4p-Oy.js} +2 -2
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{system-events-DVnqSyTt.js → system-events-DKwfE-2z.js} +2 -2
- package/dist/{target-resolver-CwHaSLt3.js → target-resolver-BQyEHyeS.js} +2 -2
- package/dist/targets-DvItNIvP.js +3 -0
- package/dist/thread-binding-api-BDZJD4na.js +4 -0
- package/dist/thread-binding-api.js +1 -3
- package/dist/{thread-bindings-DsTxqu3E.js → thread-bindings-BbzjUuNB.js} +26 -43
- package/dist/{thread-bindings.discord-api-BjIf9lGs.js → thread-bindings.discord-api-DJD3qwIN.js} +8 -10
- package/dist/{thread-bindings.manager-Bwmtqc3E.js → thread-bindings.manager-BIBm6bQd.js} +4 -4
- package/dist/{thread-bindings.session-updates-Chs3HgGa.js → thread-bindings.session-updates-eRcJlzIU.js} +1 -1
- package/dist/{thread-bindings.state-iSWjCYjB.js → thread-bindings.state-9VAxhVf6.js} +3 -14
- package/dist/{timeouts-C5TBc_9x.js → timeouts-ZRc9Lw4y.js} +3 -15
- package/dist/timeouts.js +1 -1
- package/dist/{transcripts-source-BvvM5Ns9.js → transcripts-source-CLZ5X8fh.js} +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/dist/{typing-BVcJgILg.js → typing-BnYT7Szq.js} +2 -2
- package/node_modules/p-map/index.d.ts +155 -0
- package/node_modules/p-map/index.js +284 -0
- package/node_modules/p-map/license +9 -0
- package/node_modules/p-map/package.json +57 -0
- package/node_modules/p-map/readme.md +190 -0
- package/npm-shrinkwrap.json +16 -3
- package/openclaw.plugin.json +70 -2
- package/package.json +6 -4
- package/dist/config-api-JiPdJeb0.js +0 -2
- package/dist/conversation-identity-DWC5d8Sy.js +0 -272
- package/dist/pluralkit-DcD-3EcL.js +0 -24
- package/dist/preview-streaming-DXT8oJdo.js +0 -8
- package/dist/provider.runtime-WrJXikSv.js +0 -2
- package/dist/runtime-api.monitor-C2_WVtJf.js +0 -6
- package/dist/targets-69w7c3vU.js +0 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { n as buildChannelConfigSchema, t as DiscordConfigSchema } from "./config-api-
|
|
1
|
+
import { n as buildChannelConfigSchema, t as DiscordConfigSchema } from "./config-api-B18fR8M5.js";
|
|
2
|
+
import { createChannelConfigUiHints } from "openclaw/plugin-sdk/channel-core";
|
|
2
3
|
//#endregion
|
|
3
4
|
//#region extensions/discord/src/config-schema.ts
|
|
4
5
|
const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema, { uiHints: {
|
|
@@ -6,46 +7,28 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema,
|
|
|
6
7
|
label: "Discord",
|
|
7
8
|
help: "Discord channel provider configuration for bot auth, retry policy, streaming, thread bindings, and optional voice capabilities. Keep privileged intents and advanced features disabled unless needed."
|
|
8
9
|
},
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
help: "Scopes configured groupChat mentionPatterns to selected Discord channel IDs. Native Discord @mentions still trigger even when regex patterns are denied."
|
|
24
|
-
},
|
|
25
|
-
"mentionPatterns.mode": {
|
|
26
|
-
label: "Discord Mention Pattern Mode",
|
|
27
|
-
help: "\"allow\" enables configured regex mention patterns unless denyIn matches; \"deny\" disables them unless allowIn matches."
|
|
28
|
-
},
|
|
29
|
-
"mentionPatterns.allowIn": {
|
|
30
|
-
label: "Discord Mention Pattern Allowlist",
|
|
31
|
-
help: "Discord channel IDs where configured regex mention patterns are enabled when mode is deny."
|
|
32
|
-
},
|
|
33
|
-
"mentionPatterns.denyIn": {
|
|
34
|
-
label: "Discord Mention Pattern Denylist",
|
|
35
|
-
help: "Discord channel IDs where configured regex mention patterns are disabled. Native @mentions still trigger."
|
|
36
|
-
},
|
|
10
|
+
...createChannelConfigUiHints({
|
|
11
|
+
channelLabel: "Discord",
|
|
12
|
+
dmPolicy: {
|
|
13
|
+
channelKey: "discord",
|
|
14
|
+
includeLegacyNestedPolicy: true,
|
|
15
|
+
legacyNestedPolicyOrder: "after"
|
|
16
|
+
},
|
|
17
|
+
configWrites: true,
|
|
18
|
+
mentionPatterns: {
|
|
19
|
+
targetDescription: "Discord channel IDs",
|
|
20
|
+
policyNote: "Native Discord @mentions still trigger even when regex patterns are denied.",
|
|
21
|
+
denyNote: "Native @mentions still trigger."
|
|
22
|
+
}
|
|
23
|
+
}),
|
|
37
24
|
proxy: {
|
|
38
25
|
label: "Discord Proxy URL",
|
|
39
26
|
help: "Proxy URL for Discord gateway + API requests (app-id lookup and allowlist resolution). Set per account via channels.discord.accounts.<id>.proxy."
|
|
40
27
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
"commands.nativeSkills": {
|
|
46
|
-
label: "Discord Native Skill Commands",
|
|
47
|
-
help: "Override native skill commands for Discord (bool or \"auto\")."
|
|
48
|
-
},
|
|
28
|
+
...createChannelConfigUiHints({
|
|
29
|
+
channelLabel: "Discord",
|
|
30
|
+
nativeCommands: true
|
|
31
|
+
}),
|
|
49
32
|
streaming: {
|
|
50
33
|
label: "Discord Streaming Mode",
|
|
51
34
|
help: "Unified Discord stream preview mode: \"off\" | \"partial\" | \"block\" | \"progress\". \"progress\" keeps a single editable progress draft until final delivery. Legacy boolean/streamMode keys are auto-mapped."
|
|
@@ -86,50 +69,11 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema,
|
|
|
86
69
|
label: "Discord Draft Command Text",
|
|
87
70
|
help: "Command/exec detail in preview tool-progress lines: \"raw\" preserves released behavior; \"status\" shows only the tool label."
|
|
88
71
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
label: "Discord Progress Label Pool",
|
|
95
|
-
help: "Candidate labels for streaming.progress.label=\"auto\". Leave unset to use OpenClaw built-in progress labels."
|
|
96
|
-
},
|
|
97
|
-
"streaming.progress.maxLines": {
|
|
98
|
-
label: "Discord Progress Max Lines",
|
|
99
|
-
help: "Maximum number of compact progress lines to keep below the draft label (default: 8)."
|
|
100
|
-
},
|
|
101
|
-
"streaming.progress.maxLineChars": {
|
|
102
|
-
label: "Discord Progress Max Line Chars",
|
|
103
|
-
help: "Maximum characters per compact progress line before truncation (default: 120). Prose cuts at word boundaries; commands and paths keep useful suffixes."
|
|
104
|
-
},
|
|
105
|
-
"streaming.progress.toolProgress": {
|
|
106
|
-
label: "Discord Progress Tool Lines",
|
|
107
|
-
help: "Show compact tool/progress lines in progress draft mode (default: true). Set false to keep only the label until final delivery."
|
|
108
|
-
},
|
|
109
|
-
"streaming.progress.commentary": {
|
|
110
|
-
label: "Discord Progress Commentary",
|
|
111
|
-
help: "Show assistant commentary/preamble text in the temporary progress draft. Final answer delivery is unchanged."
|
|
112
|
-
},
|
|
113
|
-
"streaming.progress.commandText": {
|
|
114
|
-
label: "Discord Progress Command Text",
|
|
115
|
-
help: "Command/exec detail in progress draft lines: \"raw\" preserves released behavior; \"status\" shows only the tool label."
|
|
116
|
-
},
|
|
117
|
-
"retry.attempts": {
|
|
118
|
-
label: "Discord Retry Attempts",
|
|
119
|
-
help: "Max retry attempts for outbound Discord API calls (default: 3)."
|
|
120
|
-
},
|
|
121
|
-
"retry.minDelayMs": {
|
|
122
|
-
label: "Discord Retry Min Delay (ms)",
|
|
123
|
-
help: "Minimum retry delay in ms for Discord outbound calls."
|
|
124
|
-
},
|
|
125
|
-
"retry.maxDelayMs": {
|
|
126
|
-
label: "Discord Retry Max Delay (ms)",
|
|
127
|
-
help: "Maximum retry delay cap in ms for Discord outbound calls."
|
|
128
|
-
},
|
|
129
|
-
"retry.jitter": {
|
|
130
|
-
label: "Discord Retry Jitter",
|
|
131
|
-
help: "Jitter factor (0-1) applied to Discord retry delays."
|
|
132
|
-
},
|
|
72
|
+
...createChannelConfigUiHints({
|
|
73
|
+
channelLabel: "Discord",
|
|
74
|
+
progress: { includeCommentary: true },
|
|
75
|
+
retry: true
|
|
76
|
+
}),
|
|
133
77
|
maxLinesPerMessage: {
|
|
134
78
|
label: "Discord Max Lines Per Message",
|
|
135
79
|
help: "Soft max line count per Discord message (default: 17)."
|
|
@@ -212,7 +156,7 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema,
|
|
|
212
156
|
},
|
|
213
157
|
"voice.model": {
|
|
214
158
|
label: "Discord Voice Model",
|
|
215
|
-
help: "Optional LLM model override for Discord voice channel responses and realtime agent consults (for example openai/gpt-5.
|
|
159
|
+
help: "Optional LLM model override for Discord voice channel responses and realtime agent consults (for example openai/gpt-5.6-sol). Leave unset to inherit the routed agent model."
|
|
216
160
|
},
|
|
217
161
|
"voice.mode": {
|
|
218
162
|
label: "Discord Voice Mode",
|
|
@@ -359,6 +303,22 @@ const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema,
|
|
|
359
303
|
label: "Discord Auto Presence Exhausted Text",
|
|
360
304
|
help: "Optional custom status text while runtime detects exhausted/unavailable model quota (dnd). Supports {reason} template placeholder."
|
|
361
305
|
},
|
|
306
|
+
"guilds.*.presenceEvents": {
|
|
307
|
+
label: "Discord Online Presence Events",
|
|
308
|
+
help: "Route selected human offline-to-online transitions into the configured guild channel as agent system events. Requires the Guild Presences privileged intent and an enabled agent heartbeat."
|
|
309
|
+
},
|
|
310
|
+
"guilds.*.presenceEvents.enabled": {
|
|
311
|
+
label: "Discord Online Presence Events Enabled",
|
|
312
|
+
help: "Enable online-presence agent wakes for this guild. Defaults to true when presenceEvents is configured."
|
|
313
|
+
},
|
|
314
|
+
"guilds.*.presenceEvents.channelId": {
|
|
315
|
+
label: "Discord Online Presence Target Channel",
|
|
316
|
+
help: "Numeric Discord channel ID whose routed agent session receives online-presence events and greeting delivery."
|
|
317
|
+
},
|
|
318
|
+
"guilds.*.presenceEvents.users": {
|
|
319
|
+
label: "Discord Online Presence User IDs",
|
|
320
|
+
help: "Optional immutable Discord user ID allowlist. Omit to include all human members in the guild."
|
|
321
|
+
},
|
|
362
322
|
activityType: {
|
|
363
323
|
label: "Discord Presence Activity Type",
|
|
364
324
|
help: "Discord presence activity type (0=Playing,1=Streaming,2=Listening,3=Watching,4=Custom,5=Competing)."
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Jt as parseDiscordTarget } from "./send.receipt-aegk69an.js";
|
|
2
|
+
import { s as resolveDiscordAccount } from "./accounts-P19jm1lf.js";
|
|
3
|
+
import { normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
+
import { createChannelApproverDmTargetResolver, createChannelNativeOriginTargetResolver } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
5
|
+
import { getExecApprovalReplyMetadata, isChannelExecApprovalClientEnabledFromConfig, matchesApprovalRequestFilters } from "openclaw/plugin-sdk/approval-client-runtime";
|
|
6
|
+
import { resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
7
|
+
import { createApproverRestrictedNativeApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
|
|
8
|
+
//#region extensions/discord/src/exec-approvals.ts
|
|
9
|
+
function normalizeDiscordApproverId(value) {
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
if (!trimmed) return;
|
|
12
|
+
if (/^\d+$/.test(trimmed)) return trimmed;
|
|
13
|
+
try {
|
|
14
|
+
const target = parseDiscordTarget(trimmed);
|
|
15
|
+
return target?.kind === "user" ? target.id : void 0;
|
|
16
|
+
} catch {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function resolveDiscordOwnerApprovers(cfg) {
|
|
21
|
+
const ownerAllowFrom = cfg.commands?.ownerAllowFrom;
|
|
22
|
+
if (!Array.isArray(ownerAllowFrom) || ownerAllowFrom.length === 0) return [];
|
|
23
|
+
return resolveApprovalApprovers({
|
|
24
|
+
explicit: ownerAllowFrom,
|
|
25
|
+
normalizeApprover: (value) => normalizeDiscordApproverId(String(value))
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function getDiscordExecApprovalApprovers(params) {
|
|
29
|
+
return resolveApprovalApprovers({
|
|
30
|
+
explicit: params.configOverride?.approvers ?? resolveDiscordAccount(params).config.execApprovals?.approvers ?? resolveDiscordOwnerApprovers(params.cfg),
|
|
31
|
+
normalizeApprover: (value) => normalizeDiscordApproverId(String(value))
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function isDiscordExecApprovalClientEnabled(params) {
|
|
35
|
+
return isChannelExecApprovalClientEnabledFromConfig({
|
|
36
|
+
enabled: (params.configOverride ?? resolveDiscordAccount(params).config.execApprovals)?.enabled,
|
|
37
|
+
approverCount: getDiscordExecApprovalApprovers({
|
|
38
|
+
cfg: params.cfg,
|
|
39
|
+
accountId: params.accountId,
|
|
40
|
+
configOverride: params.configOverride
|
|
41
|
+
}).length
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function isDiscordExecApprovalApprover(params) {
|
|
45
|
+
const senderId = params.senderId?.trim();
|
|
46
|
+
if (!senderId) return false;
|
|
47
|
+
return getDiscordExecApprovalApprovers({
|
|
48
|
+
cfg: params.cfg,
|
|
49
|
+
accountId: params.accountId,
|
|
50
|
+
configOverride: params.configOverride
|
|
51
|
+
}).includes(senderId);
|
|
52
|
+
}
|
|
53
|
+
function shouldSuppressLocalDiscordExecApprovalPrompt(params) {
|
|
54
|
+
const metadata = getExecApprovalReplyMetadata(params.payload);
|
|
55
|
+
const config = resolveDiscordAccount(params).config.execApprovals;
|
|
56
|
+
return params.hint?.kind === "approval-pending" && params.hint.nativeRouteActive === true && isDiscordExecApprovalClientEnabled(params) && metadata !== null && matchesApprovalRequestFilters({
|
|
57
|
+
request: {
|
|
58
|
+
agentId: metadata.agentId,
|
|
59
|
+
sessionKey: metadata.sessionKey
|
|
60
|
+
},
|
|
61
|
+
agentFilter: config?.agentFilter,
|
|
62
|
+
sessionFilter: config?.sessionFilter
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region extensions/discord/src/conversation-identity.ts
|
|
67
|
+
function normalizeDiscordTarget(raw, defaultKind) {
|
|
68
|
+
const trimmed = normalizeOptionalString(raw);
|
|
69
|
+
if (!trimmed) return;
|
|
70
|
+
return parseDiscordTarget(trimmed, { defaultKind })?.normalized;
|
|
71
|
+
}
|
|
72
|
+
function buildDiscordConversationIdentity(kind, rawId) {
|
|
73
|
+
const trimmed = normalizeOptionalString(rawId);
|
|
74
|
+
return trimmed ? `${kind}:${trimmed}` : void 0;
|
|
75
|
+
}
|
|
76
|
+
function resolveDiscordConversationIdentity(params) {
|
|
77
|
+
return params.isDirectMessage ? buildDiscordConversationIdentity("user", params.userId) : buildDiscordConversationIdentity("channel", params.channelId);
|
|
78
|
+
}
|
|
79
|
+
function resolveDiscordCurrentConversationIdentity(params) {
|
|
80
|
+
if (normalizeOptionalLowercaseString(params.chatType) === "direct") {
|
|
81
|
+
const senderTarget = normalizeDiscordTarget(params.from, "user");
|
|
82
|
+
if (senderTarget?.startsWith("user:")) return senderTarget;
|
|
83
|
+
}
|
|
84
|
+
for (const candidate of [
|
|
85
|
+
params.originatingTo,
|
|
86
|
+
params.commandTo,
|
|
87
|
+
params.fallbackTo
|
|
88
|
+
]) {
|
|
89
|
+
const target = normalizeDiscordTarget(candidate, "channel");
|
|
90
|
+
if (target) return target;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
export { isDiscordExecApprovalClientEnabled as a, createChannelApproverDmTargetResolver as c, matchesApprovalRequestFilters as d, isDiscordExecApprovalApprover as i, createChannelNativeOriginTargetResolver as l, resolveDiscordCurrentConversationIdentity as n, shouldSuppressLocalDiscordExecApprovalPrompt as o, getDiscordExecApprovalApprovers as r, createApproverRestrictedNativeApprovalCapability as s, resolveDiscordConversationIdentity as t, isChannelExecApprovalClientEnabledFromConfig as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Xt as __exportAll } from "./send.receipt-aegk69an.js";
|
|
2
2
|
import { a as mergeDiscordAccountConfig, c as resolveDiscordAccountAllowFrom, o as resolveDefaultDiscordAccountId } from "./accounts-P19jm1lf.js";
|
|
3
3
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
4
4
|
import { createResolvedDirectoryEntriesLister } from "openclaw/plugin-sdk/directory-config-runtime";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-
|
|
1
|
+
import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./directory-config-BUe-qq_C.js";
|
|
2
2
|
//#region extensions/discord/directory-contract-api.ts
|
|
3
3
|
const discordDirectoryContractPlugin = {
|
|
4
4
|
id: "discord",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Xt as __exportAll } from "./send.receipt-aegk69an.js";
|
|
2
2
|
import { p as normalizeDiscordToken, s as resolveDiscordAccount } from "./accounts-P19jm1lf.js";
|
|
3
|
-
import {
|
|
4
|
-
import { a as normalizeDiscordSlug } from "./allow-list-
|
|
3
|
+
import { r as fetchDiscord, t as DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS } from "./api--f62GFaS.js";
|
|
4
|
+
import { a as normalizeDiscordSlug } from "./allow-list-B7qOH5xu.js";
|
|
5
5
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
|
7
7
|
//#region extensions/discord/src/directory-cache.ts
|
|
@@ -88,7 +88,7 @@ function resolveDiscordDirectoryAccess(params) {
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
async function listDiscordGuilds(token) {
|
|
91
|
-
return (await fetchDiscord("/users/@me/guilds", token)).filter((guild) => guild.id && guild.name);
|
|
91
|
+
return (await fetchDiscord("/users/@me/guilds", token, fetch, { timeoutMs: DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS })).filter((guild) => guild.id && guild.name);
|
|
92
92
|
}
|
|
93
93
|
async function listDiscordDirectoryGroupsLive(params) {
|
|
94
94
|
const access = resolveDiscordDirectoryAccess(params);
|
|
@@ -97,7 +97,7 @@ async function listDiscordDirectoryGroupsLive(params) {
|
|
|
97
97
|
const guilds = await listDiscordGuilds(token);
|
|
98
98
|
const rows = [];
|
|
99
99
|
for (const guild of guilds) {
|
|
100
|
-
const channels = await fetchDiscord(`/guilds/${guild.id}/channels`, token);
|
|
100
|
+
const channels = await fetchDiscord(`/guilds/${guild.id}/channels`, token, fetch, { timeoutMs: DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS });
|
|
101
101
|
for (const channel of channels) {
|
|
102
102
|
const name = channel.name?.trim();
|
|
103
103
|
if (!name) continue;
|
|
@@ -127,7 +127,7 @@ async function listDiscordDirectoryPeersLive(params) {
|
|
|
127
127
|
query,
|
|
128
128
|
limit: String(Math.min(limit, 100))
|
|
129
129
|
});
|
|
130
|
-
const members = await fetchDiscord(`/guilds/${guild.id}/members/search?${paramsObj.toString()}`, token);
|
|
130
|
+
const members = await fetchDiscord(`/guilds/${guild.id}/members/search?${paramsObj.toString()}`, token, fetch, { timeoutMs: DISCORD_DIRECTORY_LOOKUP_TIMEOUT_MS });
|
|
131
131
|
for (const member of members) {
|
|
132
132
|
const user = member.user;
|
|
133
133
|
if (!user?.id) continue;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { t as inspectDiscordAccount } from "./account-inspect-DDZtT5C8.js";
|
|
2
2
|
import { o as resolveDefaultDiscordAccountId } from "./accounts-P19jm1lf.js";
|
|
3
|
-
import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-
|
|
4
|
-
import { n as normalizeCompatibilityConfig } from "./doctor-contract-
|
|
3
|
+
import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-BLYBt5SA.js";
|
|
4
|
+
import { n as normalizeCompatibilityConfig } from "./doctor-contract-wId6pV41.js";
|
|
5
5
|
import { t as isDiscordMutableAllowEntry } from "./security-doctor-uUo8hTD5.js";
|
|
6
6
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
7
8
|
import { collectProviderDangerousNameMatchingScopes } from "openclaw/plugin-sdk/runtime-doctor";
|
|
8
9
|
//#region extensions/discord/src/doctor.ts
|
|
9
10
|
function asObjectRecord$1(value) {
|
|
@@ -121,11 +122,11 @@ function collectDiscordNumericIdWarnings(params) {
|
|
|
121
122
|
else repairableHits.push(...hits);
|
|
122
123
|
const lines = [];
|
|
123
124
|
if (repairableHits.length > 0) {
|
|
124
|
-
const sample = repairableHits
|
|
125
|
+
const sample = expectDefined(repairableHits.at(0), "non-empty repairable Discord ID hits");
|
|
125
126
|
lines.push(`- Discord allowlists contain ${repairableHits.length} numeric ${repairableHits.length === 1 ? "entry" : "entries"} (e.g. ${sanitizeForLog(sample.path)}=${sanitizeForLog(String(sample.entry))}).`, `- Discord IDs must be strings; run "${params.doctorFixCommand}" to convert numeric IDs to quoted strings.`);
|
|
126
127
|
}
|
|
127
128
|
if (blockedHits.length > 0) {
|
|
128
|
-
const sample = blockedHits
|
|
129
|
+
const sample = expectDefined(blockedHits.at(0), "non-empty blocked Discord ID hits");
|
|
129
130
|
lines.push(`- Discord allowlists contain ${blockedHits.length} numeric ${blockedHits.length === 1 ? "entry" : "entries"} in lists that cannot be auto-repaired (e.g. ${sanitizeForLog(sample.path)}).`, `- These lists include invalid or precision-losing numeric IDs; manually quote the original values in your config file, then rerun "${params.doctorFixCommand}".`);
|
|
130
131
|
}
|
|
131
132
|
return lines;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-
|
|
1
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-wId6pV41.js";
|
|
2
2
|
export { legacyConfigRules, normalizeCompatibilityConfig };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { t as resolveDiscordPreviewStreamMode } from "./preview-streaming-DXT8oJdo.js";
|
|
2
1
|
import { isSupportedRealtimeVoiceActivationName, normalizeRealtimeVoiceActivationNamePrefix } from "openclaw/plugin-sdk/realtime-voice";
|
|
3
|
-
import { asObjectRecord,
|
|
2
|
+
import { asObjectRecord, defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
|
|
4
3
|
//#region extensions/discord/src/doctor-contract.ts
|
|
5
4
|
const LEGACY_TTS_PROVIDER_KEYS = [
|
|
6
5
|
"openai",
|
|
@@ -8,6 +7,33 @@ const LEGACY_TTS_PROVIDER_KEYS = [
|
|
|
8
7
|
"microsoft",
|
|
9
8
|
"edge"
|
|
10
9
|
];
|
|
10
|
+
const streamingAliasMigration = defineChannelAliasMigration({
|
|
11
|
+
channelId: "discord",
|
|
12
|
+
streaming: {
|
|
13
|
+
defaultMode: "off",
|
|
14
|
+
absentObjectDefault: "progress",
|
|
15
|
+
includePreviewChunk: true
|
|
16
|
+
},
|
|
17
|
+
accountStreamingReplacesRoot: true,
|
|
18
|
+
dm: {
|
|
19
|
+
root: true,
|
|
20
|
+
accounts: true
|
|
21
|
+
},
|
|
22
|
+
normalizeAccountExtra: ({ account, pathPrefix, changes }) => {
|
|
23
|
+
const accountVoice = asObjectRecord(account.voice);
|
|
24
|
+
if (!accountVoice || !migrateLegacyTtsConfig(asObjectRecord(accountVoice.tts), `${pathPrefix}.voice.tts`, changes)) return {
|
|
25
|
+
entry: account,
|
|
26
|
+
changed: false
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
entry: {
|
|
30
|
+
...account,
|
|
31
|
+
voice: accountVoice
|
|
32
|
+
},
|
|
33
|
+
changed: true
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
});
|
|
11
37
|
function hasLegacyTtsProviderKeys(value) {
|
|
12
38
|
const tts = asObjectRecord(value);
|
|
13
39
|
if (!tts) return false;
|
|
@@ -349,45 +375,23 @@ const legacyConfigRules = [
|
|
|
349
375
|
],
|
|
350
376
|
message: "channels.discord.accounts.<id>.voice.realtime.wakeNames entries longer than two words are unsupported; use one- or two-word activation names. Run \"openclaw doctor --fix\".",
|
|
351
377
|
match: hasUnsupportedDiscordAccountRealtimeWakeNames
|
|
352
|
-
}
|
|
378
|
+
},
|
|
379
|
+
...streamingAliasMigration.legacyConfigRules
|
|
353
380
|
];
|
|
354
381
|
function normalizeCompatibilityConfig({ cfg }) {
|
|
355
|
-
const
|
|
382
|
+
const changes = [];
|
|
383
|
+
const bindingsToAdd = [];
|
|
384
|
+
const aliases = streamingAliasMigration.normalizeChannelConfig({
|
|
385
|
+
cfg,
|
|
386
|
+
changes
|
|
387
|
+
});
|
|
388
|
+
const rawEntry = asObjectRecord(aliases.config.channels?.discord);
|
|
356
389
|
if (!rawEntry) return {
|
|
357
390
|
config: cfg,
|
|
358
391
|
changes: []
|
|
359
392
|
};
|
|
360
|
-
|
|
361
|
-
let
|
|
362
|
-
let changed;
|
|
363
|
-
const bindingsToAdd = [];
|
|
364
|
-
const aliases = normalizeLegacyChannelAliases({
|
|
365
|
-
entry: rawEntry,
|
|
366
|
-
pathPrefix: "channels.discord",
|
|
367
|
-
changes,
|
|
368
|
-
normalizeDm: true,
|
|
369
|
-
normalizeAccountDm: true,
|
|
370
|
-
resolveStreamingOptions: (entry) => ({
|
|
371
|
-
resolvedMode: resolveDiscordPreviewStreamMode(entry),
|
|
372
|
-
includePreviewChunk: true
|
|
373
|
-
}),
|
|
374
|
-
normalizeAccountExtra: ({ account, pathPrefix }) => {
|
|
375
|
-
const accountVoice = asObjectRecord(account.voice);
|
|
376
|
-
if (!accountVoice || !migrateLegacyTtsConfig(asObjectRecord(accountVoice.tts), `${pathPrefix}.voice.tts`, changes)) return {
|
|
377
|
-
entry: account,
|
|
378
|
-
changed: false
|
|
379
|
-
};
|
|
380
|
-
return {
|
|
381
|
-
entry: {
|
|
382
|
-
...account,
|
|
383
|
-
voice: accountVoice
|
|
384
|
-
},
|
|
385
|
-
changed: true
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
updated = aliases.entry;
|
|
390
|
-
changed = aliases.changed;
|
|
393
|
+
let updated = rawEntry;
|
|
394
|
+
let changed = aliases.config !== cfg;
|
|
391
395
|
const guildAliases = normalizeDiscordGuildChannelAllowAliases({
|
|
392
396
|
entry: updated,
|
|
393
397
|
pathPrefix: "channels.discord",
|
|
@@ -460,9 +464,9 @@ function normalizeCompatibilityConfig({ cfg }) {
|
|
|
460
464
|
};
|
|
461
465
|
return {
|
|
462
466
|
config: {
|
|
463
|
-
...
|
|
467
|
+
...aliases.config,
|
|
464
468
|
channels: {
|
|
465
|
-
...
|
|
469
|
+
...aliases.config.channels,
|
|
466
470
|
discord: updated
|
|
467
471
|
},
|
|
468
472
|
bindings: bindingsToAdd.length > 0 ? [...cfg.bindings ?? [], ...bindingsToAdd] : cfg.bindings
|
package/dist/{handle-action.guild-admin-CgJSNVui.js → handle-action.guild-admin-C_PQcBEV.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as readDiscordChannelCreateParams, n as isDiscordModerationAction, o as readDiscordChannelEditParams, r as readDiscordModerationCommand, s as readDiscordChannelMoveParams, t as handleDiscordAction } from "./runtime-
|
|
1
|
+
import { a as readDiscordChannelCreateParams, n as isDiscordModerationAction, o as readDiscordChannelEditParams, r as readDiscordModerationCommand, s as readDiscordChannelMoveParams, t as handleDiscordAction } from "./runtime-C618lis9.js";
|
|
2
2
|
import "./action-runtime-api.js";
|
|
3
|
-
import { n as isTrustedRequesterGuildAdminAction } from "./channel-actions-
|
|
3
|
+
import { n as isTrustedRequesterGuildAdminAction } from "./channel-actions-ChpBSRcu.js";
|
|
4
4
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { readNonNegativeIntegerParam, readPositiveIntegerParam, readStringArrayParam, readStringParam } from "openclaw/plugin-sdk/agent-runtime";
|
|
6
6
|
//#region extensions/discord/src/actions/handle-action.guild-admin.ts
|
|
@@ -13,7 +13,7 @@ function senderParam(senderUserId) {
|
|
|
13
13
|
return senderUserId ? { senderUserId } : {};
|
|
14
14
|
}
|
|
15
15
|
async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
16
|
-
const { ctx, resolveChannelId } = params;
|
|
16
|
+
const { ctx, resolveChannelId, readPolicyOptions } = params;
|
|
17
17
|
const { action, params: actionParams, cfg } = ctx;
|
|
18
18
|
const accountId = ctx.accountId ?? readStringParam(actionParams, "accountId");
|
|
19
19
|
const senderUserId = readDiscordRequesterSenderId(ctx);
|
|
@@ -25,7 +25,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
25
25
|
accountId: accountId ?? void 0,
|
|
26
26
|
guildId,
|
|
27
27
|
userId
|
|
28
|
-
}, cfg);
|
|
28
|
+
}, cfg, readPolicyOptions);
|
|
29
29
|
}
|
|
30
30
|
if (action === "role-info") {
|
|
31
31
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -33,7 +33,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
33
33
|
action: "roleInfo",
|
|
34
34
|
accountId: accountId ?? void 0,
|
|
35
35
|
guildId
|
|
36
|
-
}, cfg);
|
|
36
|
+
}, cfg, readPolicyOptions);
|
|
37
37
|
}
|
|
38
38
|
if (action === "emoji-list") {
|
|
39
39
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -41,7 +41,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
41
41
|
action: "emojiList",
|
|
42
42
|
accountId: accountId ?? void 0,
|
|
43
43
|
guildId
|
|
44
|
-
}, cfg);
|
|
44
|
+
}, cfg, readPolicyOptions);
|
|
45
45
|
}
|
|
46
46
|
if (action === "emoji-upload") {
|
|
47
47
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -100,7 +100,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
100
100
|
action: "channelInfo",
|
|
101
101
|
accountId: accountId ?? void 0,
|
|
102
102
|
channelId
|
|
103
|
-
}, cfg);
|
|
103
|
+
}, cfg, readPolicyOptions);
|
|
104
104
|
}
|
|
105
105
|
if (action === "channel-list") {
|
|
106
106
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -108,7 +108,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
108
108
|
action: "channelList",
|
|
109
109
|
accountId: accountId ?? void 0,
|
|
110
110
|
guildId
|
|
111
|
-
}, cfg);
|
|
111
|
+
}, cfg, readPolicyOptions);
|
|
112
112
|
}
|
|
113
113
|
if (action === "channel-create") {
|
|
114
114
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -200,7 +200,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
200
200
|
accountId: accountId ?? void 0,
|
|
201
201
|
guildId,
|
|
202
202
|
userId
|
|
203
|
-
}, cfg);
|
|
203
|
+
}, cfg, readPolicyOptions);
|
|
204
204
|
}
|
|
205
205
|
if (action === "event-list") {
|
|
206
206
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -208,7 +208,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
208
208
|
action: "eventList",
|
|
209
209
|
accountId: accountId ?? void 0,
|
|
210
210
|
guildId
|
|
211
|
-
}, cfg);
|
|
211
|
+
}, cfg, readPolicyOptions);
|
|
212
212
|
}
|
|
213
213
|
if (action === "event-create") {
|
|
214
214
|
const guildId = readStringParam(actionParams, "guildId", { required: true });
|
|
@@ -270,7 +270,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
270
270
|
includeArchived,
|
|
271
271
|
before,
|
|
272
272
|
limit
|
|
273
|
-
}, cfg);
|
|
273
|
+
}, cfg, readPolicyOptions);
|
|
274
274
|
}
|
|
275
275
|
if (action === "thread-reply") {
|
|
276
276
|
const content = readStringParam(actionParams, "message", { required: true });
|
|
@@ -305,7 +305,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
305
305
|
authorId: readStringParam(actionParams, "authorId"),
|
|
306
306
|
authorIds: readStringArrayParam(actionParams, "authorIds"),
|
|
307
307
|
limit: readPositiveIntegerParam(actionParams, "limit")
|
|
308
|
-
}, cfg);
|
|
308
|
+
}, cfg, readPolicyOptions);
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { registerDiscordSubagentHooks } from "./subagent-hooks-api.js";
|
|
2
|
-
import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-
|
|
2
|
+
import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-CLZ5X8fh.js";
|
|
3
3
|
import "./transcripts-source-api.js";
|
|
4
4
|
import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
5
5
|
//#region extensions/discord/index.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as THREAD_BINDINGS_MAX_ENTRIES, f as normalizePersistedBinding, j as toBindingRecordKey, o as THREAD_BINDINGS_NAMESPACE } from "./thread-bindings.state-
|
|
1
|
+
import { a as THREAD_BINDINGS_MAX_ENTRIES, f as normalizePersistedBinding, j as toBindingRecordKey, o as THREAD_BINDINGS_NAMESPACE } from "./thread-bindings.state-9VAxhVf6.js";
|
|
2
2
|
import { MAX_DATE_TIMESTAMP_MS, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import path from "node:path";
|
|
@@ -69,6 +69,28 @@ function legacyUpdatedAtForIndex(updatedAt, index, total) {
|
|
|
69
69
|
const baseMs = timestampMs(updatedAt);
|
|
70
70
|
return timestampMsToIsoString(Math.min(baseMs + Math.max(0, total), MAX_DATE_TIMESTAMP_MS) - Math.max(0, index)) ?? timestampMsToIsoString(baseMs) ?? timestampMsToIsoString(Math.max(0, total - index)) ?? "1970-01-01T00:00:00.000Z";
|
|
71
71
|
}
|
|
72
|
+
function readFiniteNumberField(entry, key) {
|
|
73
|
+
const value = entry[key];
|
|
74
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : void 0;
|
|
75
|
+
}
|
|
76
|
+
function upgradeLegacyThreadBindingShape(rawEntry) {
|
|
77
|
+
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) return rawEntry;
|
|
78
|
+
const entry = { ...rawEntry };
|
|
79
|
+
if (entry.targetSessionKey === void 0 && typeof entry.sessionKey === "string") entry.targetSessionKey = entry.sessionKey;
|
|
80
|
+
delete entry.sessionKey;
|
|
81
|
+
const expiresAt = readFiniteNumberField(entry, "expiresAt");
|
|
82
|
+
delete entry.expiresAt;
|
|
83
|
+
if (entry.idleTimeoutMs === void 0 && entry.maxAgeMs === void 0 && expiresAt !== void 0) {
|
|
84
|
+
entry.idleTimeoutMs = 0;
|
|
85
|
+
if (expiresAt <= 0) entry.maxAgeMs = 0;
|
|
86
|
+
else {
|
|
87
|
+
const boundAt = readFiniteNumberField(entry, "boundAt") ?? 0;
|
|
88
|
+
const lastActivityAt = readFiniteNumberField(entry, "lastActivityAt") ?? 0;
|
|
89
|
+
entry.maxAgeMs = Math.max(1, expiresAt - Math.max(0, boundAt > 0 ? boundAt : lastActivityAt));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return entry;
|
|
93
|
+
}
|
|
72
94
|
const detectDiscordLegacyStateMigrations = ({ stateDir }) => {
|
|
73
95
|
const plans = [];
|
|
74
96
|
const modelPickerSourcePath = path.join(stateDir, "discord", "model-picker-preferences.json");
|
|
@@ -119,7 +141,7 @@ const detectDiscordLegacyStateMigrations = ({ stateDir }) => {
|
|
|
119
141
|
if (store?.version !== 1 || !store.bindings || typeof store.bindings !== "object") throw new Error("legacy Discord thread bindings store must have version 1 bindings");
|
|
120
142
|
const out = [];
|
|
121
143
|
for (const [rawKey, rawEntry] of Object.entries(store.bindings)) {
|
|
122
|
-
const normalized = normalizePersistedBinding(rawKey, rawEntry);
|
|
144
|
+
const normalized = normalizePersistedBinding(rawKey, upgradeLegacyThreadBindingShape(rawEntry));
|
|
123
145
|
if (normalized) out.push({
|
|
124
146
|
key: toBindingRecordKey(normalized),
|
|
125
147
|
value: normalized
|