@openclaw/mattermost 2026.7.1 → 2026.7.2-beta.2
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/accounts-C4Azn6rA.js +83 -0
- package/dist/api.js +3 -2
- package/dist/channel-plugin-api.js +3 -3
- package/dist/{channel-plugin-runtime-DhS8rwfs.js → channel-plugin-runtime-BXmjNn6B.js} +131 -167
- package/dist/channel-plugin-runtime.js +1 -1
- package/dist/{channel.runtime-D0SJSEei.js → channel.runtime-CKb2-z0p.js} +560 -296
- package/dist/{accounts-ITTlduDO.js → client-BzLj4dyf.js} +52 -102
- package/dist/doctor-contract-BaUvVh8e.js +19 -0
- package/dist/doctor-contract-api.js +1 -1
- package/dist/gateway-auth-api.js +1 -1
- package/dist/{gateway-auth-bypass-BIXLORHU.js → gateway-auth-bypass-CL1PxV3z.js} +3 -2
- package/dist/interactions-DO7J-ND1.js +375 -0
- package/dist/policy-api.js +1 -1
- package/dist/secret-contract-B4R5Bmhv.js +28 -0
- package/dist/secret-contract-api.js +1 -1
- package/dist/slash-route-api.js +1 -1
- package/dist/{slash-state-BfOSlkmn.js → slash-state-C9bpBN40.js} +124 -470
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +209 -209
- package/package.json +4 -4
- package/dist/doctor-contract-ttH0DCuq.js +0 -7
- package/dist/secret-contract-Cx0LUNXy.js +0 -44
- package/dist/{monitor-auth-BiDuyvOc.js → monitor-auth-dEHa1_On.js} +3 -3
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { f as normalizeMattermostBaseUrl } from "./client-BzLj4dyf.js";
|
|
2
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { resolveChannelPreviewStreamMode, resolveChannelStreamingBlockCoalesce, resolveChannelStreamingBlockEnabled, resolveChannelStreamingChunkMode } from "openclaw/plugin-sdk/channel-outbound";
|
|
4
|
+
import { createAccountListHelpers, hasConfiguredAccountValue } from "openclaw/plugin-sdk/account-helpers";
|
|
5
|
+
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
6
|
+
import { resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
|
|
7
|
+
import { buildSecretInputSchema, hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
8
|
+
//#region extensions/mattermost/src/mattermost/accounts.ts
|
|
9
|
+
const mattermostAccountHelpers = createAccountListHelpers("mattermost", { hasImplicitDefaultAccount: (cfg) => {
|
|
10
|
+
const mattermost = cfg.channels?.mattermost;
|
|
11
|
+
return Boolean(mattermost?.baseUrl?.trim() && (hasConfiguredAccountValue(mattermost.botToken) || process.env.MATTERMOST_BOT_TOKEN?.trim()));
|
|
12
|
+
} });
|
|
13
|
+
function listMattermostAccountIds(cfg) {
|
|
14
|
+
return mattermostAccountHelpers.listAccountIds(cfg);
|
|
15
|
+
}
|
|
16
|
+
function resolveDefaultMattermostAccountId(cfg) {
|
|
17
|
+
return mattermostAccountHelpers.resolveDefaultAccountId(cfg);
|
|
18
|
+
}
|
|
19
|
+
function mergeMattermostAccountConfig(cfg, accountId) {
|
|
20
|
+
return resolveMergedAccountConfig({
|
|
21
|
+
channelConfig: cfg.channels?.mattermost,
|
|
22
|
+
accounts: cfg.channels?.mattermost?.accounts,
|
|
23
|
+
accountId,
|
|
24
|
+
omitKeys: ["defaultAccount"],
|
|
25
|
+
nestedObjectKeys: ["commands"]
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function resolveMattermostRequireMention(config) {
|
|
29
|
+
if (config.chatmode === "oncall") return true;
|
|
30
|
+
if (config.chatmode === "onmessage") return false;
|
|
31
|
+
if (config.chatmode === "onchar") return true;
|
|
32
|
+
return config.requireMention;
|
|
33
|
+
}
|
|
34
|
+
function resolveMattermostAccount(params) {
|
|
35
|
+
const accountId = normalizeAccountId(params.accountId ?? resolveDefaultMattermostAccountId(params.cfg));
|
|
36
|
+
const baseEnabled = params.cfg.channels?.mattermost?.enabled !== false;
|
|
37
|
+
const merged = mergeMattermostAccountConfig(params.cfg, accountId);
|
|
38
|
+
const accountEnabled = merged.enabled !== false;
|
|
39
|
+
const enabled = baseEnabled && accountEnabled;
|
|
40
|
+
const allowEnv = accountId === DEFAULT_ACCOUNT_ID;
|
|
41
|
+
const envToken = allowEnv ? process.env.MATTERMOST_BOT_TOKEN?.trim() : void 0;
|
|
42
|
+
const envUrl = allowEnv ? process.env.MATTERMOST_URL?.trim() : void 0;
|
|
43
|
+
const configToken = params.allowUnresolvedSecretRef ? normalizeSecretInputString(merged.botToken) : normalizeResolvedSecretInputString({
|
|
44
|
+
value: merged.botToken,
|
|
45
|
+
path: `channels.mattermost.accounts.${accountId}.botToken`
|
|
46
|
+
});
|
|
47
|
+
const configUrl = merged.baseUrl?.trim();
|
|
48
|
+
const botToken = configToken || envToken;
|
|
49
|
+
const baseUrl = normalizeMattermostBaseUrl(configUrl || envUrl);
|
|
50
|
+
const requireMention = resolveMattermostRequireMention(merged);
|
|
51
|
+
const botTokenSource = configToken ? "config" : envToken ? "env" : "none";
|
|
52
|
+
const baseUrlSource = configUrl ? "config" : envUrl ? "env" : "none";
|
|
53
|
+
return {
|
|
54
|
+
accountId,
|
|
55
|
+
enabled,
|
|
56
|
+
name: normalizeOptionalString(merged.name),
|
|
57
|
+
botToken,
|
|
58
|
+
baseUrl,
|
|
59
|
+
botTokenSource,
|
|
60
|
+
baseUrlSource,
|
|
61
|
+
config: merged,
|
|
62
|
+
chatmode: merged.chatmode,
|
|
63
|
+
oncharPrefixes: merged.oncharPrefixes,
|
|
64
|
+
requireMention,
|
|
65
|
+
textChunkLimit: merged.textChunkLimit,
|
|
66
|
+
chunkMode: resolveChannelStreamingChunkMode(merged),
|
|
67
|
+
streamingMode: resolveChannelPreviewStreamMode(merged, "partial"),
|
|
68
|
+
blockStreaming: resolveChannelStreamingBlockEnabled(merged),
|
|
69
|
+
blockStreamingCoalesce: resolveChannelStreamingBlockCoalesce(merged)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the effective replyToMode for a given chat type.
|
|
74
|
+
* Direct messages stay flat unless explicitly opted into a per-chat-type mode.
|
|
75
|
+
*/
|
|
76
|
+
function resolveMattermostReplyToMode(account, kind) {
|
|
77
|
+
const scopedMode = account.config.replyToModeByChatType?.[kind];
|
|
78
|
+
if (scopedMode !== void 0) return scopedMode;
|
|
79
|
+
if (kind === "direct") return "off";
|
|
80
|
+
return account.config.replyToMode ?? "off";
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { buildSecretInputSchema as a, resolveMattermostReplyToMode as i, resolveDefaultMattermostAccountId as n, hasConfiguredSecretInput as o, resolveMattermostAccount as r, listMattermostAccountIds as t };
|
package/dist/api.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { r as isMattermostSenderAllowed } from "./monitor-auth-
|
|
2
|
-
|
|
1
|
+
import { r as isMattermostSenderAllowed } from "./monitor-auth-dEHa1_On.js";
|
|
2
|
+
import { t as buildButtonAttachments } from "./interactions-DO7J-ND1.js";
|
|
3
|
+
export { buildButtonAttachments, isMattermostSenderAllowed };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-
|
|
1
|
+
import { a as MattermostChannelConfigSchema, c as mattermostConfigAdapter, l as mattermostMeta, n as mattermostSetupWizard, o as describeMattermostAccount, r as mattermostSetupAdapter, s as isMattermostConfigured, t as mattermostPlugin } from "./channel-plugin-runtime-BXmjNn6B.js";
|
|
2
|
+
import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-CL1PxV3z.js";
|
|
3
3
|
//#region extensions/mattermost/src/channel.setup.ts
|
|
4
4
|
const mattermostSetupPlugin = {
|
|
5
5
|
id: "mattermost",
|
|
@@ -23,7 +23,7 @@ const mattermostSetupPlugin = {
|
|
|
23
23
|
isConfigured: isMattermostConfigured,
|
|
24
24
|
describeAccount: describeMattermostAccount
|
|
25
25
|
},
|
|
26
|
-
gateway: { resolveGatewayAuthBypassPaths:
|
|
26
|
+
gateway: { resolveGatewayAuthBypassPaths: resolveMattermostGatewayAuthBypassPaths },
|
|
27
27
|
setup: mattermostSetupAdapter,
|
|
28
28
|
setupWizard: mattermostSetupWizard
|
|
29
29
|
};
|
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
4
|
-
import { n as
|
|
1
|
+
import { f as normalizeMattermostBaseUrl } from "./client-BzLj4dyf.js";
|
|
2
|
+
import { a as buildSecretInputSchema, i as resolveMattermostReplyToMode, n as resolveDefaultMattermostAccountId, o as hasConfiguredSecretInput, r as resolveMattermostAccount, t as listMattermostAccountIds } from "./accounts-C4Azn6rA.js";
|
|
3
|
+
import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-CL1PxV3z.js";
|
|
4
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BaUvVh8e.js";
|
|
5
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-B4R5Bmhv.js";
|
|
5
6
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
import { buildPassiveProbedChannelStatusSummary } from "openclaw/plugin-sdk/extension-shared";
|
|
8
|
+
import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
9
|
+
import { z } from "zod";
|
|
6
10
|
import { formatNormalizedAllowFromEntries } from "openclaw/plugin-sdk/allow-from";
|
|
7
11
|
import { createLoggedPairingApprovalNotifier } from "openclaw/plugin-sdk/channel-pairing";
|
|
8
12
|
import { createAccountStatusSink, createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-outbound";
|
|
9
13
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, buildChannelOutboundSessionRoute, buildThreadAwareOutboundSessionRoute, stripChannelTargetPrefix, stripTargetKindPrefix } from "openclaw/plugin-sdk/core";
|
|
10
|
-
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
11
|
-
import { createDangerousNameMatchingMutableAllowlistWarningCollector, createRestrictSendersChannelSecurity,
|
|
14
|
+
import { createChannelConfigUiHints, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
15
|
+
import { buildChannelGroupsScopeTree, buildMutableAllowEntryDetector, collectStandardAllowlistLists, createDangerousNameMatchingMutableAllowlistWarningCollector, createRestrictSendersChannelSecurity, resolveScopeRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
12
16
|
import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
|
|
13
17
|
import { createChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime";
|
|
14
|
-
import {
|
|
15
|
-
import { normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveMessagePresentationControlValue } from "openclaw/plugin-sdk/interactive-runtime";
|
|
18
|
+
import { normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveMessagePresentationButtonAction, resolveMessagePresentationControlValue } from "openclaw/plugin-sdk/interactive-runtime";
|
|
16
19
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
17
20
|
import { resolvePayloadMediaUrls, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
|
|
18
|
-
import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
19
21
|
import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
20
22
|
import { chunkTextForOutbound, sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
21
|
-
import {
|
|
23
|
+
import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
22
24
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
23
25
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
24
|
-
import { z } from "zod";
|
|
25
26
|
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
26
|
-
import { BlockStreamingCoalesceSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, buildChannelConfigSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-
|
|
27
|
-
import { applyAccountNameToChannelSection, applySetupAccountConfigPatch, createSetupTranslator, createStandardChannelSetupStatus, formatDocsLink, migrateBaseNameToDefaultAccount } from "openclaw/plugin-sdk/setup";
|
|
27
|
+
import { BlockStreamingCoalesceSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
28
|
+
import { applyAccountNameToChannelSection, applySetupAccountConfigPatch, baseUrlTextInput, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, migrateBaseNameToDefaultAccount, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
|
|
28
29
|
import { createSetupInputPresenceValidator } from "openclaw/plugin-sdk/setup-runtime";
|
|
29
30
|
//#region extensions/mattermost/src/approval-auth.ts
|
|
30
31
|
const MATTERMOST_USER_ID_RE = /^[a-z0-9]{26}$/;
|
|
@@ -32,20 +33,16 @@ function normalizeMattermostApproverId(value) {
|
|
|
32
33
|
const lowered = normalizeLowercaseStringOrEmpty(String(value).trim().replace(/^(mattermost|user):/i, "").replace(/^@/, "").trim());
|
|
33
34
|
return MATTERMOST_USER_ID_RE.test(lowered) ? lowered : void 0;
|
|
34
35
|
}
|
|
35
|
-
const mattermostApprovalAuth =
|
|
36
|
+
const mattermostApprovalAuth = createChannelApprovalAuth({
|
|
36
37
|
channelLabel: "Mattermost",
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
resolveInputs: ({ cfg, accountId }) => {
|
|
39
|
+
return { allowFrom: resolveMattermostAccount({
|
|
39
40
|
cfg,
|
|
40
41
|
accountId
|
|
41
|
-
}).config;
|
|
42
|
-
return resolveApprovalApprovers({
|
|
43
|
-
allowFrom: account.allowFrom,
|
|
44
|
-
normalizeApprover: normalizeMattermostApproverId
|
|
45
|
-
});
|
|
42
|
+
}).config.allowFrom };
|
|
46
43
|
},
|
|
47
|
-
|
|
48
|
-
});
|
|
44
|
+
normalizeApprover: normalizeMattermostApproverId
|
|
45
|
+
}).approvalAuth;
|
|
49
46
|
//#endregion
|
|
50
47
|
//#region extensions/mattermost/src/channel-config-shared.ts
|
|
51
48
|
const mattermostMeta = {
|
|
@@ -103,9 +100,14 @@ function describeMattermostAccount(account) {
|
|
|
103
100
|
}
|
|
104
101
|
//#endregion
|
|
105
102
|
//#region extensions/mattermost/src/config-schema-core.ts
|
|
106
|
-
const MattermostGroupSchema =
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
const MattermostGroupSchema = buildGroupEntrySchema().omit({
|
|
104
|
+
tools: true,
|
|
105
|
+
toolsBySender: true,
|
|
106
|
+
skills: true,
|
|
107
|
+
enabled: true,
|
|
108
|
+
allowFrom: true,
|
|
109
|
+
systemPrompt: true
|
|
110
|
+
});
|
|
109
111
|
function requireMattermostOpenAllowFrom(params) {
|
|
110
112
|
requireOpenAllowFrom({
|
|
111
113
|
policy: params.policy,
|
|
@@ -155,25 +157,38 @@ const MattermostStreamingProgressSchema = z.object({
|
|
|
155
157
|
labels: z.array(z.string()).optional(),
|
|
156
158
|
maxLines: z.number().int().positive().optional(),
|
|
157
159
|
maxLineChars: z.number().int().positive().optional(),
|
|
158
|
-
toolProgress: z.boolean().optional()
|
|
160
|
+
toolProgress: z.boolean().optional(),
|
|
161
|
+
commandText: z.enum(["raw", "status"]).optional()
|
|
162
|
+
}).strict();
|
|
163
|
+
const MattermostStreamingPreviewSchema = z.object({
|
|
164
|
+
toolProgress: z.boolean().optional(),
|
|
165
|
+
commandText: z.enum(["raw", "status"]).optional()
|
|
159
166
|
}).strict();
|
|
160
|
-
const MattermostStreamingPreviewSchema = z.object({ toolProgress: z.boolean().optional() }).strict();
|
|
161
167
|
const MattermostStreamingBlockSchema = z.object({
|
|
162
168
|
enabled: z.boolean().optional(),
|
|
163
169
|
coalesce: BlockStreamingCoalesceSchema.optional()
|
|
164
170
|
}).strict();
|
|
165
|
-
const MattermostStreamingSchema = z.
|
|
166
|
-
MattermostStreamingModeSchema,
|
|
167
|
-
z.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
const MattermostStreamingSchema = z.object({
|
|
172
|
+
mode: MattermostStreamingModeSchema.optional(),
|
|
173
|
+
chunkMode: z.enum(["length", "newline"]).optional(),
|
|
174
|
+
preview: MattermostStreamingPreviewSchema.optional(),
|
|
175
|
+
progress: MattermostStreamingProgressSchema.optional(),
|
|
176
|
+
block: MattermostStreamingBlockSchema.optional()
|
|
177
|
+
}).strict();
|
|
178
|
+
const MattermostReplyToModeSchema = z.enum([
|
|
179
|
+
"off",
|
|
180
|
+
"first",
|
|
181
|
+
"all",
|
|
182
|
+
"batched"
|
|
175
183
|
]);
|
|
176
|
-
const
|
|
184
|
+
const MattermostReplyToModeByChatTypeSchema = z.object({
|
|
185
|
+
direct: MattermostReplyToModeSchema.optional(),
|
|
186
|
+
group: MattermostReplyToModeSchema.optional(),
|
|
187
|
+
channel: MattermostReplyToModeSchema.optional()
|
|
188
|
+
}).strict();
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region extensions/mattermost/src/config-surface.ts
|
|
191
|
+
const MattermostChannelConfigSchema = buildChannelConfigSchema(buildMultiAccountChannelSchema(z.object({
|
|
177
192
|
name: z.string().optional(),
|
|
178
193
|
capabilities: z.array(z.string()).optional(),
|
|
179
194
|
dangerouslyAllowNameMatching: z.boolean().optional(),
|
|
@@ -194,16 +209,9 @@ const MattermostAccountSchemaBase = z.object({
|
|
|
194
209
|
groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
|
195
210
|
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
|
196
211
|
textChunkLimit: z.number().int().positive().optional(),
|
|
197
|
-
chunkMode: z.enum(["length", "newline"]).optional(),
|
|
198
212
|
streaming: MattermostStreamingSchema.optional(),
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
replyToMode: z.enum([
|
|
202
|
-
"off",
|
|
203
|
-
"first",
|
|
204
|
-
"all",
|
|
205
|
-
"batched"
|
|
206
|
-
]).optional(),
|
|
213
|
+
replyToMode: MattermostReplyToModeSchema.optional(),
|
|
214
|
+
replyToModeByChatType: MattermostReplyToModeByChatTypeSchema.optional(),
|
|
207
215
|
responsePrefix: z.string().optional(),
|
|
208
216
|
actions: z.object({ reactions: z.boolean().optional() }).optional(),
|
|
209
217
|
commands: MattermostSlashCommandsSchema,
|
|
@@ -217,34 +225,24 @@ const MattermostAccountSchemaBase = z.object({
|
|
|
217
225
|
network: MattermostNetworkSchema,
|
|
218
226
|
/** Retry configuration for DM channel creation */
|
|
219
227
|
dmChannelRetry: DmChannelRetrySchema
|
|
220
|
-
}).strict()
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
//#region extensions/mattermost/src/config-surface.ts
|
|
230
|
-
const MattermostChannelConfigSchema = buildChannelConfigSchema(MattermostAccountSchemaBase.extend({
|
|
231
|
-
accounts: z.record(z.string(), MattermostAccountSchema.optional()).optional(),
|
|
232
|
-
defaultAccount: z.string().optional()
|
|
233
|
-
}).superRefine((value, ctx) => {
|
|
234
|
-
requireMattermostOpenAllowFrom({
|
|
235
|
-
policy: value.dmPolicy,
|
|
236
|
-
allowFrom: value.allowFrom,
|
|
237
|
-
ctx
|
|
238
|
-
});
|
|
228
|
+
}).strict(), {
|
|
229
|
+
optionalAccount: true,
|
|
230
|
+
refine: (value, ctx) => {
|
|
231
|
+
requireMattermostOpenAllowFrom({
|
|
232
|
+
policy: value.dmPolicy,
|
|
233
|
+
allowFrom: value.allowFrom,
|
|
234
|
+
ctx
|
|
235
|
+
});
|
|
236
|
+
}
|
|
239
237
|
}), { uiHints: {
|
|
240
238
|
"": {
|
|
241
239
|
label: "Mattermost",
|
|
242
240
|
help: "Mattermost channel provider configuration for bot auth, access policy, slash commands, and preview streaming."
|
|
243
241
|
},
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
},
|
|
242
|
+
...createChannelConfigUiHints({
|
|
243
|
+
channelLabel: "Mattermost",
|
|
244
|
+
dmPolicy: { channelKey: "mattermost" }
|
|
245
|
+
}),
|
|
248
246
|
streaming: {
|
|
249
247
|
label: "Mattermost Streaming Mode",
|
|
250
248
|
help: "Unified Mattermost stream preview mode: \"off\" | \"partial\" | \"block\" | \"progress\". \"progress\" keeps a single editable progress draft until final delivery."
|
|
@@ -253,30 +251,10 @@ const MattermostChannelConfigSchema = buildChannelConfigSchema(MattermostAccount
|
|
|
253
251
|
label: "Mattermost Streaming Mode",
|
|
254
252
|
help: "Canonical Mattermost preview mode: \"off\" | \"partial\" | \"block\" | \"progress\"."
|
|
255
253
|
},
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
},
|
|
260
|
-
"streaming.progress.labels": {
|
|
261
|
-
label: "Mattermost Progress Label Pool",
|
|
262
|
-
help: "Candidate labels for streaming.progress.label=\"auto\". Leave unset to use OpenClaw built-in progress labels."
|
|
263
|
-
},
|
|
264
|
-
"streaming.progress.maxLines": {
|
|
265
|
-
label: "Mattermost Progress Max Lines",
|
|
266
|
-
help: "Maximum number of compact progress lines to keep below the draft label (default: 8)."
|
|
267
|
-
},
|
|
268
|
-
"streaming.progress.maxLineChars": {
|
|
269
|
-
label: "Mattermost Progress Max Line Chars",
|
|
270
|
-
help: "Maximum characters per compact progress line before truncation (default: 120). Prose cuts at word boundaries; commands and paths keep useful suffixes."
|
|
271
|
-
},
|
|
272
|
-
"streaming.progress.toolProgress": {
|
|
273
|
-
label: "Mattermost Progress Tool Lines",
|
|
274
|
-
help: "Show compact tool/progress lines in progress draft mode (default: true). Set false to keep only the label until final delivery."
|
|
275
|
-
},
|
|
276
|
-
"streaming.progress.commandText": {
|
|
277
|
-
label: "Mattermost Progress Command Text",
|
|
278
|
-
help: "Command/exec detail in progress draft lines: \"raw\" preserves released behavior; \"status\" shows only the tool label."
|
|
279
|
-
},
|
|
254
|
+
...createChannelConfigUiHints({
|
|
255
|
+
channelLabel: "Mattermost",
|
|
256
|
+
progress: {}
|
|
257
|
+
}),
|
|
280
258
|
"streaming.preview.toolProgress": {
|
|
281
259
|
label: "Mattermost Draft Tool Progress",
|
|
282
260
|
help: "Show tool/progress activity in the live draft preview post (default: true). Set false to hide interim tool updates while the draft preview stays active."
|
|
@@ -294,28 +272,13 @@ const MattermostChannelConfigSchema = buildChannelConfigSchema(MattermostAccount
|
|
|
294
272
|
help: "Merge streamed Mattermost block replies before final delivery."
|
|
295
273
|
}
|
|
296
274
|
} });
|
|
297
|
-
//#endregion
|
|
298
|
-
//#region extensions/mattermost/src/doctor.ts
|
|
299
|
-
function isMattermostMutableAllowEntry(raw) {
|
|
300
|
-
const text = raw.trim();
|
|
301
|
-
if (!text || text === "*") return false;
|
|
302
|
-
const lowered = normalizeLowercaseStringOrEmpty(text.replace(/^(mattermost|user):/i, "").replace(/^@/, "").trim());
|
|
303
|
-
if (/^[a-z0-9]{26}$/.test(lowered)) return false;
|
|
304
|
-
return true;
|
|
305
|
-
}
|
|
306
275
|
const mattermostDoctor = {
|
|
307
276
|
legacyConfigRules,
|
|
308
277
|
normalizeCompatibilityConfig,
|
|
309
278
|
collectMutableAllowlistWarnings: createDangerousNameMatchingMutableAllowlistWarningCollector({
|
|
310
279
|
channel: "mattermost",
|
|
311
|
-
detector:
|
|
312
|
-
collectLists: (scope) =>
|
|
313
|
-
pathLabel: `${scope.prefix}.allowFrom`,
|
|
314
|
-
list: scope.account.allowFrom
|
|
315
|
-
}, {
|
|
316
|
-
pathLabel: `${scope.prefix}.groupAllowFrom`,
|
|
317
|
-
list: scope.account.groupAllowFrom
|
|
318
|
-
}]
|
|
280
|
+
detector: buildMutableAllowEntryDetector({ stableIdPattern: /^(?:(?:mattermost|user):)?@?[a-z0-9]{26}$/i }),
|
|
281
|
+
collectLists: (scope) => collectStandardAllowlistLists(scope)
|
|
319
282
|
})
|
|
320
283
|
};
|
|
321
284
|
//#endregion
|
|
@@ -325,13 +288,11 @@ function resolveMattermostGroupRequireMention(params) {
|
|
|
325
288
|
cfg: params.cfg,
|
|
326
289
|
accountId: params.accountId
|
|
327
290
|
});
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
accountId: params.accountId,
|
|
334
|
-
requireMentionOverride
|
|
291
|
+
return resolveScopeRequireMention({
|
|
292
|
+
tree: buildChannelGroupsScopeTree(params.cfg, "mattermost", params.accountId),
|
|
293
|
+
path: params.groupId ? [params.groupId] : [],
|
|
294
|
+
requireMentionOverride: params.requireMentionOverride ?? account.requireMention,
|
|
295
|
+
overrideOrder: "after-config"
|
|
335
296
|
});
|
|
336
297
|
}
|
|
337
298
|
//#endregion
|
|
@@ -515,60 +476,50 @@ const mattermostSetupWizard = {
|
|
|
515
476
|
patch: {}
|
|
516
477
|
})
|
|
517
478
|
},
|
|
518
|
-
credentials: [{
|
|
479
|
+
credentials: [defineTokenCredential({
|
|
519
480
|
inputKey: "botToken",
|
|
481
|
+
configKey: "botToken",
|
|
520
482
|
providerHint: channel,
|
|
521
483
|
credentialLabel: t("wizard.mattermost.botToken"),
|
|
522
484
|
preferredEnvVar: "MATTERMOST_BOT_TOKEN",
|
|
523
485
|
envPrompt: t("wizard.mattermost.envPrompt"),
|
|
524
486
|
keepPrompt: t("wizard.mattermost.botTokenKeep"),
|
|
525
487
|
inputPrompt: t("wizard.mattermost.botTokenInput"),
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
accountConfigured: isMattermostConfigured(resolvedAccount),
|
|
530
|
-
hasConfiguredValue: hasConfiguredSecretInput(resolvedAccount.config.botToken)
|
|
531
|
-
};
|
|
532
|
-
},
|
|
533
|
-
applySet: async ({ cfg, accountId, value }) => applyMattermostSetupConfigPatch({
|
|
488
|
+
resolveAccount: ({ cfg, accountId }) => resolveMattermostAccountWithSecrets(cfg, accountId),
|
|
489
|
+
accountConfigured: isMattermostConfigured,
|
|
490
|
+
patchAccount: ({ cfg, accountId, patch }) => applyMattermostSetupConfigPatch({
|
|
534
491
|
cfg,
|
|
535
492
|
accountId,
|
|
536
|
-
patch
|
|
537
|
-
})
|
|
538
|
-
|
|
539
|
-
|
|
493
|
+
patch
|
|
494
|
+
}),
|
|
495
|
+
set: {}
|
|
496
|
+
})],
|
|
497
|
+
textInputs: [baseUrlTextInput({
|
|
540
498
|
inputKey: "httpUrl",
|
|
499
|
+
configKey: "baseUrl",
|
|
541
500
|
message: t("wizard.mattermost.baseUrlPrompt"),
|
|
542
501
|
confirmCurrentValue: false,
|
|
543
|
-
|
|
544
|
-
|
|
502
|
+
resolveAccount: ({ cfg, accountId }) => resolveMattermostAccountWithSecrets(cfg, accountId),
|
|
503
|
+
currentValue: (account) => account.baseUrl ?? process.env.MATTERMOST_URL?.trim(),
|
|
504
|
+
includeInitialValue: true,
|
|
545
505
|
shouldPrompt: ({ cfg, accountId, credentialValues, currentValue }) => {
|
|
546
506
|
const resolvedAccount = resolveMattermostAccountWithSecrets(cfg, accountId);
|
|
547
507
|
const tokenConfigured = Boolean(resolvedAccount.botToken?.trim()) || hasConfiguredSecretInput(resolvedAccount.config.botToken);
|
|
548
508
|
return Boolean(credentialValues.botToken) || !tokenConfigured || !currentValue;
|
|
549
509
|
},
|
|
550
|
-
validate: (
|
|
551
|
-
|
|
552
|
-
|
|
510
|
+
validate: (value) => normalizeMattermostBaseUrl(value) ? void 0 : "Mattermost base URL must include a valid base URL.",
|
|
511
|
+
normalize: (value) => normalizeMattermostBaseUrl(value) ?? value.trim(),
|
|
512
|
+
patchAccount: ({ cfg, accountId, patch }) => applyMattermostSetupConfigPatch({
|
|
553
513
|
cfg,
|
|
554
514
|
accountId,
|
|
555
|
-
patch
|
|
515
|
+
patch
|
|
556
516
|
})
|
|
557
|
-
}],
|
|
558
|
-
disable: (cfg) => (
|
|
559
|
-
...cfg,
|
|
560
|
-
channels: {
|
|
561
|
-
...cfg.channels,
|
|
562
|
-
mattermost: {
|
|
563
|
-
...cfg.channels?.mattermost,
|
|
564
|
-
enabled: false
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
})
|
|
517
|
+
})],
|
|
518
|
+
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
|
|
568
519
|
};
|
|
569
520
|
//#endregion
|
|
570
521
|
//#region extensions/mattermost/src/channel.ts
|
|
571
|
-
const loadMattermostChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-
|
|
522
|
+
const loadMattermostChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-CKb2-z0p.js"));
|
|
572
523
|
function buildMattermostPresentationButtons(presentation) {
|
|
573
524
|
return presentation.blocks.filter((block) => block.type === "buttons").map((block) => block.buttons.flatMap((button) => {
|
|
574
525
|
if (button.action) return [];
|
|
@@ -590,8 +541,11 @@ const MATTERMOST_PRESENTATION_CAPABILITIES = {
|
|
|
590
541
|
divider: false,
|
|
591
542
|
limits: { text: { markdownDialect: "markdown" } }
|
|
592
543
|
};
|
|
593
|
-
function
|
|
594
|
-
return
|
|
544
|
+
function hasMattermostPresentationNavigation(presentation) {
|
|
545
|
+
return presentation.blocks.some((block) => block.type === "buttons" && block.buttons.some((button) => {
|
|
546
|
+
const action = resolveMessagePresentationButtonAction(button);
|
|
547
|
+
return action?.type === "url" || action?.type === "web-app" && Boolean(action.url);
|
|
548
|
+
}));
|
|
595
549
|
}
|
|
596
550
|
function readMattermostPresentationButtons(payload) {
|
|
597
551
|
const buttons = (payload.channelData?.mattermost)?.presentationButtons;
|
|
@@ -728,21 +682,26 @@ const mattermostMessageActions = {
|
|
|
728
682
|
supportsAction: ({ action }) => {
|
|
729
683
|
return action === "send" || action === "react";
|
|
730
684
|
},
|
|
731
|
-
handleAction: async ({ action, params, cfg, accountId, mediaAccess, mediaLocalRoots, mediaReadFile }) => {
|
|
685
|
+
handleAction: async ({ action, params, cfg, accountId, mediaAccess, mediaLocalRoots, mediaReadFile, conversationReadOrigin }) => {
|
|
732
686
|
if (action === "react") {
|
|
733
687
|
const resolvedAccountId = accountId ?? resolveDefaultMattermostAccountId(cfg);
|
|
734
688
|
const mattermostConfig = cfg.channels?.mattermost;
|
|
735
|
-
|
|
689
|
+
const account = resolveMattermostAccount({
|
|
736
690
|
cfg,
|
|
737
691
|
accountId: resolvedAccountId
|
|
738
|
-
})
|
|
692
|
+
});
|
|
693
|
+
if (!account.enabled) throw new Error(`Mattermost account "${resolvedAccountId}" is disabled`);
|
|
694
|
+
if (!(account.config.actions?.reactions ?? mattermostConfig?.actions?.reactions ?? true)) throw new Error("Mattermost reactions are disabled in config");
|
|
739
695
|
const { postId, emojiName, remove } = parseMattermostReactActionParams(params);
|
|
696
|
+
const authorizedTarget = normalizeOptionalString(params.to);
|
|
740
697
|
if (remove) {
|
|
741
698
|
const result = await (await loadMattermostChannelRuntime()).removeMattermostReaction({
|
|
742
699
|
cfg,
|
|
743
700
|
postId,
|
|
744
701
|
emojiName,
|
|
745
|
-
accountId: resolvedAccountId
|
|
702
|
+
accountId: resolvedAccountId,
|
|
703
|
+
authorizedTarget,
|
|
704
|
+
conversationReadOrigin
|
|
746
705
|
});
|
|
747
706
|
if (!result.ok) throw new Error(result.error);
|
|
748
707
|
return {
|
|
@@ -757,7 +716,9 @@ const mattermostMessageActions = {
|
|
|
757
716
|
cfg,
|
|
758
717
|
postId,
|
|
759
718
|
emojiName,
|
|
760
|
-
accountId: resolvedAccountId
|
|
719
|
+
accountId: resolvedAccountId,
|
|
720
|
+
authorizedTarget,
|
|
721
|
+
conversationReadOrigin
|
|
761
722
|
});
|
|
762
723
|
if (!result.ok) throw new Error(result.error);
|
|
763
724
|
return {
|
|
@@ -871,13 +832,12 @@ function collectMattermostAttachmentMedia(params) {
|
|
|
871
832
|
readMattermostStringParam(params, "fileUrl")
|
|
872
833
|
];
|
|
873
834
|
mediaUrlCandidates.push(...readMattermostStringArrayParam(params, "mediaUrls"));
|
|
874
|
-
let hasUnsupportedAttachmentPayload =
|
|
835
|
+
let hasUnsupportedAttachmentPayload = Boolean(readMattermostStringParam(params, "buffer") ?? readMattermostStringParam(params, "base64"));
|
|
875
836
|
if (Array.isArray(params.attachments)) for (const attachment of params.attachments) {
|
|
876
837
|
if (!attachment || typeof attachment !== "object" || Array.isArray(attachment)) continue;
|
|
877
838
|
const record = attachment;
|
|
878
839
|
mediaUrlCandidates.push(readMattermostStringParam(record, "media"), readMattermostStringParam(record, "mediaUrl"), readMattermostStringParam(record, "path"), readMattermostStringParam(record, "filePath"), readMattermostStringParam(record, "fileUrl"), readMattermostStringParam(record, "url"));
|
|
879
|
-
hasUnsupportedAttachmentPayload ||=
|
|
880
|
-
hasUnsupportedAttachmentPayload ||= typeof record.base64 === "string";
|
|
840
|
+
hasUnsupportedAttachmentPayload ||= Boolean(readMattermostStringParam(record, "buffer") ?? readMattermostStringParam(record, "base64"));
|
|
881
841
|
}
|
|
882
842
|
return {
|
|
883
843
|
mediaUrls: collectNonBlankStrings(mediaUrlCandidates),
|
|
@@ -902,20 +862,21 @@ const mattermostOutbound = {
|
|
|
902
862
|
renderPresentation: ({ payload, presentation }) => {
|
|
903
863
|
if (payload.mediaUrls && payload.mediaUrls.length > 1) return null;
|
|
904
864
|
const buttons = buildMattermostPresentationButtons(presentation);
|
|
905
|
-
|
|
865
|
+
const hasButtons = buttons.some((row) => row.length > 0);
|
|
866
|
+
if (!hasButtons && !hasMattermostPresentationNavigation(presentation)) return null;
|
|
906
867
|
return {
|
|
907
868
|
...payload,
|
|
908
869
|
text: renderMessagePresentationFallbackText({
|
|
909
870
|
text: payload.text,
|
|
910
871
|
presentation
|
|
911
872
|
}),
|
|
912
|
-
channelData: {
|
|
873
|
+
...hasButtons ? { channelData: {
|
|
913
874
|
...payload.channelData,
|
|
914
875
|
mattermost: {
|
|
915
876
|
...payload.channelData?.mattermost,
|
|
916
877
|
presentationButtons: buttons
|
|
917
878
|
}
|
|
918
|
-
}
|
|
879
|
+
} } : {}
|
|
919
880
|
};
|
|
920
881
|
},
|
|
921
882
|
sendPayload: async (ctx) => {
|
|
@@ -1035,6 +996,8 @@ const mattermostPlugin = createChatChannelPlugin({
|
|
|
1035
996
|
}),
|
|
1036
997
|
messaging: {
|
|
1037
998
|
targetPrefixes: ["mattermost"],
|
|
999
|
+
directTargetStyle: "user-prefixed",
|
|
1000
|
+
targetIdComparison: "case-sensitive",
|
|
1038
1001
|
defaultMarkdownTableMode: "off",
|
|
1039
1002
|
normalizeTarget: normalizeMattermostMessagingTarget,
|
|
1040
1003
|
resolveDeliveryTarget: ({ conversationId, parentConversationId }) => {
|
|
@@ -1100,7 +1063,7 @@ const mattermostPlugin = createChatChannelPlugin({
|
|
|
1100
1063
|
})
|
|
1101
1064
|
}),
|
|
1102
1065
|
gateway: {
|
|
1103
|
-
resolveGatewayAuthBypassPaths:
|
|
1066
|
+
resolveGatewayAuthBypassPaths: resolveMattermostGatewayAuthBypassPaths,
|
|
1104
1067
|
startAccount: async (ctx) => {
|
|
1105
1068
|
const account = ctx.account;
|
|
1106
1069
|
const statusSink = createAccountStatusSink({
|
|
@@ -1150,9 +1113,10 @@ const mattermostPlugin = createChatChannelPlugin({
|
|
|
1150
1113
|
}),
|
|
1151
1114
|
resolveReplyTransport: ({ threadId, replyToId, replyToIsExplicit, replyDelivery }) => {
|
|
1152
1115
|
const ambientThreadId = threadId != null ? String(threadId) : void 0;
|
|
1153
|
-
const
|
|
1116
|
+
const isFlatDirect = replyDelivery?.chatType === "direct" && replyDelivery.replyToMode === "off";
|
|
1117
|
+
const resolvedThreadId = isFlatDirect ? void 0 : replyDelivery ? replyToIsExplicit ? replyToId ?? ambientThreadId : ambientThreadId ?? replyToId ?? void 0 : ambientThreadId ?? replyToId;
|
|
1154
1118
|
return {
|
|
1155
|
-
replyToId:
|
|
1119
|
+
replyToId: isFlatDirect ? null : resolvedThreadId,
|
|
1156
1120
|
threadId: resolvedThreadId ?? null
|
|
1157
1121
|
};
|
|
1158
1122
|
}
|
|
@@ -1161,4 +1125,4 @@ const mattermostPlugin = createChatChannelPlugin({
|
|
|
1161
1125
|
outbound: mattermostOutbound
|
|
1162
1126
|
});
|
|
1163
1127
|
//#endregion
|
|
1164
|
-
export {
|
|
1128
|
+
export { MattermostChannelConfigSchema as a, mattermostConfigAdapter as c, normalizeMattermostMessagingTarget as i, mattermostMeta as l, mattermostSetupWizard as n, describeMattermostAccount as o, mattermostSetupAdapter as r, isMattermostConfigured$1 as s, mattermostPlugin as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as mattermostPlugin } from "./channel-plugin-runtime-
|
|
1
|
+
import { t as mattermostPlugin } from "./channel-plugin-runtime-BXmjNn6B.js";
|
|
2
2
|
export { mattermostPlugin };
|