@openclaw/msteams 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/api.cjs +8 -0
- package/dist/{channel-Cf5LJ4aO.js → channel-BKc8zroK.cjs} +648 -240
- package/dist/channel-config-api.cjs +3 -0
- package/dist/channel-plugin-api.cjs +3 -0
- package/dist/channel.runtime-hd1Zsoo2.cjs +1372 -0
- package/dist/{config-schema-BL4qQZiA.js → config-schema-BSNLJUta.cjs} +13 -3
- package/dist/{directory-contract-api.js → directory-contract-api.cjs} +8 -7
- package/dist/{doctor-contract-api.js → doctor-contract-api.cjs} +73 -57
- package/dist/index.cjs +21 -0
- package/dist/{probe-BnyZRZsD.js → messenger-BVcKl6dv.cjs} +436 -891
- package/dist/{oauth-BifWxWzq.js → oauth-yNoKtU_3.cjs} +21 -21
- package/dist/{polls-B_hs4aKm.js → polls-BhoI4VaN.cjs} +188 -38
- package/dist/{resolve-allowlist-Dnw4aNOu.js → resolve-allowlist-DXd097EP.cjs} +849 -140
- package/dist/rolldown-runtime-D6vf50IK.cjs +28 -0
- package/dist/runtime-api.cjs +207 -0
- package/dist/runtime-gZTAuFux.cjs +24 -0
- package/dist/secret-contract-api.cjs +31 -0
- package/dist/setup-entry.cjs +14 -0
- package/dist/setup-plugin-api.cjs +65 -0
- package/dist/{setup-surface-qW-ECHL-.js → setup-surface-D4f6x5cx.cjs} +127 -61
- package/dist/{src-DZFs5XtZ.js → src-20YasZEp.cjs} +686 -748
- package/dist/{sso-token-store-DrVbnCUF.js → sso-token-store-CktCz88k.cjs} +51 -10
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +10 -31
- package/package.json +8 -7
- package/dist/api.js +0 -3
- package/dist/channel-config-api.js +0 -2
- package/dist/channel-plugin-api.js +0 -2
- package/dist/channel.runtime-Bwu6Tjhf.js +0 -664
- package/dist/index.js +0 -22
- package/dist/runtime-BS5AZrKK.js +0 -8
- package/dist/runtime-api.js +0 -20
- package/dist/secret-contract-api.js +0 -35
- package/dist/setup-entry.js +0 -15
- package/dist/setup-plugin-api.js +0 -64
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
let openclaw_plugin_sdk_channel_config_schema = require("openclaw/plugin-sdk/channel-config-schema");
|
|
2
|
+
let openclaw_plugin_sdk_bundled_channel_config_schema = require("openclaw/plugin-sdk/bundled-channel-config-schema");
|
|
2
3
|
//#endregion
|
|
3
4
|
//#region extensions/msteams/src/config-schema.ts
|
|
4
|
-
const MSTeamsChannelConfigSchema = buildChannelConfigSchema(MSTeamsConfigSchema, { uiHints: {
|
|
5
|
+
const MSTeamsChannelConfigSchema = (0, openclaw_plugin_sdk_channel_config_schema.buildChannelConfigSchema)(openclaw_plugin_sdk_bundled_channel_config_schema.MSTeamsConfigSchema, { uiHints: {
|
|
5
6
|
"": {
|
|
6
7
|
label: "MS Teams",
|
|
7
8
|
help: "Microsoft Teams channel provider configuration and provider-specific policy toggles. Use this section to isolate Teams behavior from other enterprise chat providers."
|
|
@@ -18,6 +19,10 @@ const MSTeamsChannelConfigSchema = buildChannelConfigSchema(MSTeamsConfigSchema,
|
|
|
18
19
|
label: "MS Teams Service URL",
|
|
19
20
|
help: "Bot Connector service URL for SDK proactive sends/edits/deletes. Set with cloud for USGov/DoD; set alone for GCC."
|
|
20
21
|
},
|
|
22
|
+
graphMediaFallback: {
|
|
23
|
+
label: "MS Teams Graph Media Fallback",
|
|
24
|
+
help: "Query Microsoft Graph for unresolved channel or group-chat HTML media. Adds one lookup per matching message when enabled (default: false)."
|
|
25
|
+
},
|
|
21
26
|
streaming: {
|
|
22
27
|
label: "MS Teams Streaming",
|
|
23
28
|
help: "Microsoft Teams preview/progress streaming mode: \"off\" | \"partial\" | \"block\" | \"progress\". Personal chats use Teams native streaminfo progress when available."
|
|
@@ -48,4 +53,9 @@ const MSTeamsChannelConfigSchema = buildChannelConfigSchema(MSTeamsConfigSchema,
|
|
|
48
53
|
}
|
|
49
54
|
} });
|
|
50
55
|
//#endregion
|
|
51
|
-
|
|
56
|
+
Object.defineProperty(exports, "MSTeamsChannelConfigSchema", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
get: function() {
|
|
59
|
+
return MSTeamsChannelConfigSchema;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_resolve_allowlist = require("./resolve-allowlist-DXd097EP.cjs");
|
|
3
|
+
let openclaw_plugin_sdk_directory_runtime = require("openclaw/plugin-sdk/directory-runtime");
|
|
3
4
|
const msteamsDirectoryContractPlugin = {
|
|
4
5
|
id: "msteams",
|
|
5
6
|
directory: {
|
|
6
7
|
self: async ({ cfg }) => {
|
|
7
|
-
const creds = resolveMSTeamsCredentials(cfg.channels?.msteams);
|
|
8
|
+
const creds = require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams);
|
|
8
9
|
return creds ? {
|
|
9
10
|
kind: "user",
|
|
10
11
|
id: creds.appId,
|
|
11
12
|
name: creds.appId
|
|
12
13
|
} : null;
|
|
13
14
|
},
|
|
14
|
-
listPeers: async ({ cfg, query, limit }) => listDirectoryEntriesFromSources({
|
|
15
|
+
listPeers: async ({ cfg, query, limit }) => (0, openclaw_plugin_sdk_directory_runtime.listDirectoryEntriesFromSources)({
|
|
15
16
|
kind: "user",
|
|
16
17
|
sources: [cfg.channels?.msteams?.allowFrom ?? [], Object.keys(cfg.channels?.msteams?.dms ?? {})],
|
|
17
18
|
query,
|
|
18
19
|
limit,
|
|
19
20
|
normalizeId: (raw) => {
|
|
20
|
-
const normalized = normalizeMSTeamsMessagingTarget(raw) ?? raw;
|
|
21
|
+
const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(raw) ?? raw;
|
|
21
22
|
const lowered = normalized.toLowerCase();
|
|
22
23
|
return lowered.startsWith("user:") || lowered.startsWith("conversation:") ? normalized : `user:${normalized}`;
|
|
23
24
|
}
|
|
24
25
|
}),
|
|
25
|
-
listGroups: async ({ cfg, query, limit }) => listDirectoryEntriesFromSources({
|
|
26
|
+
listGroups: async ({ cfg, query, limit }) => (0, openclaw_plugin_sdk_directory_runtime.listDirectoryEntriesFromSources)({
|
|
26
27
|
kind: "group",
|
|
27
28
|
sources: [Object.values(cfg.channels?.msteams?.teams ?? {}).flatMap((team) => Object.keys(team.channels ?? {}))],
|
|
28
29
|
query,
|
|
@@ -32,4 +33,4 @@ const msteamsDirectoryContractPlugin = {
|
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
35
|
//#endregion
|
|
35
|
-
|
|
36
|
+
exports.msteamsDirectoryContractPlugin = msteamsDirectoryContractPlugin;
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
|
|
3
|
+
const require_polls = require("./polls-BhoI4VaN.cjs");
|
|
4
|
+
const require_sso_token_store = require("./sso-token-store-CktCz88k.cjs");
|
|
5
|
+
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
8
|
+
let node_crypto = require("node:crypto");
|
|
9
|
+
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
10
|
+
let node_fs_promises = require("node:fs/promises");
|
|
11
|
+
node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises, 1);
|
|
12
|
+
let openclaw_plugin_sdk_runtime_doctor = require("openclaw/plugin-sdk/runtime-doctor");
|
|
13
|
+
let openclaw_plugin_sdk_session_store_runtime = require("openclaw/plugin-sdk/session-store-runtime");
|
|
9
14
|
//#region extensions/msteams/doctor-contract-api.ts
|
|
15
|
+
const streamingAliasMigration = (0, openclaw_plugin_sdk_runtime_doctor.defineChannelAliasMigration)({
|
|
16
|
+
channelId: "msteams",
|
|
17
|
+
streaming: { defaultMode: "partial" }
|
|
18
|
+
});
|
|
19
|
+
const legacyConfigRules = streamingAliasMigration.legacyConfigRules;
|
|
20
|
+
function normalizeCompatibilityConfig({ cfg }) {
|
|
21
|
+
return streamingAliasMigration.normalizeChannelConfig({ cfg });
|
|
22
|
+
}
|
|
10
23
|
const LEARNINGS_NAMESPACE = "feedback-learnings";
|
|
11
24
|
const MAX_LEARNING_ENTRIES = 1e4;
|
|
12
25
|
const MSTEAMS_PLUGIN_ID = "Microsoft Teams";
|
|
@@ -14,7 +27,7 @@ function encodeSessionKey(sessionKey) {
|
|
|
14
27
|
return Buffer.from(sessionKey, "utf8").toString("base64url");
|
|
15
28
|
}
|
|
16
29
|
function learningStoreKey(storePath, sessionKey) {
|
|
17
|
-
return
|
|
30
|
+
return node_crypto.default.createHash("sha256").update(`${storePath}\0${sessionKey}`, "utf8").digest("hex");
|
|
18
31
|
}
|
|
19
32
|
function decodeSessionKey(fileStem) {
|
|
20
33
|
try {
|
|
@@ -31,9 +44,9 @@ function legacySanitizeSessionKey(sessionKey) {
|
|
|
31
44
|
return sessionKey.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
32
45
|
}
|
|
33
46
|
async function listKnownSessionKeys(storePath) {
|
|
34
|
-
const candidates = [storePath,
|
|
47
|
+
const candidates = [storePath, node_path.default.join(storePath, "sessions.json")];
|
|
35
48
|
for (const candidate of candidates) try {
|
|
36
|
-
const parsed = JSON.parse(await
|
|
49
|
+
const parsed = JSON.parse(await node_fs_promises.default.readFile(candidate, "utf8"));
|
|
37
50
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
|
|
38
51
|
const sessions = parsed.sessions && typeof parsed.sessions === "object" && !Array.isArray(parsed.sessions) ? parsed.sessions : parsed;
|
|
39
52
|
return Object.keys(sessions).filter((key) => key.trim());
|
|
@@ -42,7 +55,8 @@ async function listKnownSessionKeys(storePath) {
|
|
|
42
55
|
}
|
|
43
56
|
function resolveLegacySanitizedSessionKey(fileStem, knownSessionKeys) {
|
|
44
57
|
const matches = knownSessionKeys.filter((sessionKey) => legacySanitizeSessionKey(sessionKey) === fileStem);
|
|
45
|
-
|
|
58
|
+
const [match] = matches;
|
|
59
|
+
return matches.length === 1 && match ? match : null;
|
|
46
60
|
}
|
|
47
61
|
function listAgentIds(config) {
|
|
48
62
|
const ids = /* @__PURE__ */ new Set(["main"]);
|
|
@@ -51,19 +65,19 @@ function listAgentIds(config) {
|
|
|
51
65
|
}
|
|
52
66
|
function listCandidateStorePaths(params) {
|
|
53
67
|
const paths = /* @__PURE__ */ new Set();
|
|
54
|
-
paths.add(resolveStorePath(params.config.session?.store, { env: params.env }));
|
|
55
|
-
for (const agentId of listAgentIds(params.config)) paths.add(resolveStorePath(params.config.session?.store, {
|
|
68
|
+
paths.add((0, openclaw_plugin_sdk_session_store_runtime.resolveStorePath)(params.config.session?.store, { env: params.env }));
|
|
69
|
+
for (const agentId of listAgentIds(params.config)) paths.add((0, openclaw_plugin_sdk_session_store_runtime.resolveStorePath)(params.config.session?.store, {
|
|
56
70
|
agentId,
|
|
57
71
|
env: params.env
|
|
58
72
|
}));
|
|
59
73
|
return [...paths];
|
|
60
74
|
}
|
|
61
75
|
function resolveStateFilePath(stateDir, filename) {
|
|
62
|
-
return
|
|
76
|
+
return node_path.default.join(stateDir, filename);
|
|
63
77
|
}
|
|
64
78
|
async function readLegacyJsonFile(filePath, parse) {
|
|
65
79
|
try {
|
|
66
|
-
return parse(JSON.parse(await
|
|
80
|
+
return parse(JSON.parse(await node_fs_promises.default.readFile(filePath, "utf8")));
|
|
67
81
|
} catch {
|
|
68
82
|
return null;
|
|
69
83
|
}
|
|
@@ -72,15 +86,15 @@ function isStringArray(value) {
|
|
|
72
86
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
73
87
|
}
|
|
74
88
|
function parseLegacyConversationStore(value) {
|
|
75
|
-
if (!isRecord(value) || value.version !== 1 || !isRecord(value.conversations)) return null;
|
|
76
|
-
return normalizeMSTeamsLegacyConversationStore({
|
|
89
|
+
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value) || value.version !== 1 || !(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value.conversations)) return null;
|
|
90
|
+
return require_polls.normalizeMSTeamsLegacyConversationStore({
|
|
77
91
|
version: 1,
|
|
78
92
|
conversations: value.conversations
|
|
79
93
|
});
|
|
80
94
|
}
|
|
81
95
|
function parseLegacyPoll(value) {
|
|
82
|
-
if (!isRecord(value)) return null;
|
|
83
|
-
const votes = isRecord(value.votes) ? value.votes : null;
|
|
96
|
+
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value)) return null;
|
|
97
|
+
const votes = (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value.votes) ? value.votes : null;
|
|
84
98
|
if (typeof value.id !== "string" || !value.id || typeof value.question !== "string" || !value.question || !isStringArray(value.options) || typeof value.maxSelections !== "number" || !Number.isFinite(value.maxSelections) || typeof value.createdAt !== "string" || !votes) return null;
|
|
85
99
|
const normalizedVotes = {};
|
|
86
100
|
for (const [voterId, selections] of Object.entries(votes)) if (typeof voterId === "string" && isStringArray(selections)) normalizedVotes[voterId] = selections;
|
|
@@ -97,7 +111,7 @@ function parseLegacyPoll(value) {
|
|
|
97
111
|
};
|
|
98
112
|
}
|
|
99
113
|
function parseLegacyPollStore(value) {
|
|
100
|
-
if (!isRecord(value) || value.version !== 1 || !isRecord(value.polls)) return null;
|
|
114
|
+
if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value) || value.version !== 1 || !(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value.polls)) return null;
|
|
101
115
|
const polls = {};
|
|
102
116
|
for (const [pollId, poll] of Object.entries(value.polls)) {
|
|
103
117
|
const parsed = parseLegacyPoll(poll);
|
|
@@ -111,7 +125,7 @@ function parseLegacyPollStore(value) {
|
|
|
111
125
|
async function listLegacyLearningFiles(storePath) {
|
|
112
126
|
let entries;
|
|
113
127
|
try {
|
|
114
|
-
entries = await
|
|
128
|
+
entries = await node_fs_promises.default.readdir(storePath, { withFileTypes: true });
|
|
115
129
|
} catch {
|
|
116
130
|
return [];
|
|
117
131
|
}
|
|
@@ -122,9 +136,9 @@ async function listLegacyLearningFiles(storePath) {
|
|
|
122
136
|
if (!entry.isFile() || !entry.name.endsWith(suffix)) continue;
|
|
123
137
|
const fileStem = entry.name.slice(0, -15);
|
|
124
138
|
const sessionKey = resolveLearningSessionKey(fileStem) ?? resolveLegacySanitizedSessionKey(fileStem, knownSessionKeys);
|
|
125
|
-
const filePath =
|
|
139
|
+
const filePath = node_path.default.join(storePath, entry.name);
|
|
126
140
|
try {
|
|
127
|
-
const parsed = JSON.parse(await
|
|
141
|
+
const parsed = JSON.parse(await node_fs_promises.default.readFile(filePath, "utf8"));
|
|
128
142
|
if (Array.isArray(parsed)) {
|
|
129
143
|
const learnings = parsed.filter((item) => typeof item === "string");
|
|
130
144
|
if (learnings.length > 0) files.push({
|
|
@@ -153,31 +167,31 @@ const stateMigrations = [
|
|
|
153
167
|
id: "msteams-conversations-json-to-plugin-state",
|
|
154
168
|
label: "Microsoft Teams conversations",
|
|
155
169
|
async detectLegacyState(params) {
|
|
156
|
-
const state = await readLegacyJsonFile(resolveStateFilePath(params.stateDir, MSTEAMS_CONVERSATIONS_LEGACY_FILENAME), parseLegacyConversationStore);
|
|
170
|
+
const state = await readLegacyJsonFile(resolveStateFilePath(params.stateDir, require_polls.MSTEAMS_CONVERSATIONS_LEGACY_FILENAME), parseLegacyConversationStore);
|
|
157
171
|
if (!state || Object.keys(state.conversations).length === 0) return null;
|
|
158
|
-
return { preview: [`- ${MSTEAMS_PLUGIN_ID} conversations: ${Object.keys(state.conversations).length} entries -> plugin state (${MSTEAMS_CONVERSATIONS_NAMESPACE})`] };
|
|
172
|
+
return { preview: [`- ${MSTEAMS_PLUGIN_ID} conversations: ${Object.keys(state.conversations).length} entries -> plugin state (${require_polls.MSTEAMS_CONVERSATIONS_NAMESPACE})`] };
|
|
159
173
|
},
|
|
160
174
|
async migrateLegacyState(params) {
|
|
161
175
|
const changes = [];
|
|
162
176
|
const warnings = [];
|
|
163
|
-
const filePath = resolveStateFilePath(params.stateDir, MSTEAMS_CONVERSATIONS_LEGACY_FILENAME);
|
|
177
|
+
const filePath = resolveStateFilePath(params.stateDir, require_polls.MSTEAMS_CONVERSATIONS_LEGACY_FILENAME);
|
|
164
178
|
const state = await readLegacyJsonFile(filePath, parseLegacyConversationStore);
|
|
165
179
|
if (!state) return {
|
|
166
180
|
changes,
|
|
167
181
|
warnings
|
|
168
182
|
};
|
|
169
183
|
const store = params.context.openPluginStateKeyedStore({
|
|
170
|
-
namespace: MSTEAMS_CONVERSATIONS_NAMESPACE,
|
|
171
|
-
maxEntries: MSTEAMS_SQLITE_MAX_CONVERSATION_ROWS
|
|
184
|
+
namespace: require_polls.MSTEAMS_CONVERSATIONS_NAMESPACE,
|
|
185
|
+
maxEntries: require_polls.MSTEAMS_SQLITE_MAX_CONVERSATION_ROWS
|
|
172
186
|
});
|
|
173
187
|
let imported = 0;
|
|
174
|
-
for (const [rawConversationId, reference] of selectRetainedMSTeamsConversations(state.conversations)) {
|
|
175
|
-
const conversationId = normalizeStoredConversationId(rawConversationId);
|
|
188
|
+
for (const [rawConversationId, reference] of require_polls.selectRetainedMSTeamsConversations(state.conversations)) {
|
|
189
|
+
const conversationId = require_polls.normalizeStoredConversationId(rawConversationId);
|
|
176
190
|
if (!conversationId) continue;
|
|
177
|
-
if (await store.registerIfAbsent(buildMSTeamsConversationStateKey(conversationId), prepareMSTeamsConversationReferenceForStorage(conversationId, reference))) imported++;
|
|
191
|
+
if (await store.registerIfAbsent(require_polls.buildMSTeamsConversationStateKey(conversationId), require_polls.prepareMSTeamsConversationReferenceForStorage(conversationId, reference))) imported++;
|
|
178
192
|
}
|
|
179
193
|
changes.push(`Migrated ${imported} ${MSTEAMS_PLUGIN_ID} conversation ${imported === 1 ? "entry" : "entries"} -> plugin state`);
|
|
180
|
-
await archiveLegacyStateSource({
|
|
194
|
+
await (0, openclaw_plugin_sdk_runtime_doctor.archiveLegacyStateSource)({
|
|
181
195
|
filePath,
|
|
182
196
|
label: `${MSTEAMS_PLUGIN_ID} conversation`,
|
|
183
197
|
changes,
|
|
@@ -193,41 +207,41 @@ const stateMigrations = [
|
|
|
193
207
|
id: "msteams-polls-json-to-plugin-state",
|
|
194
208
|
label: "Microsoft Teams polls",
|
|
195
209
|
async detectLegacyState(params) {
|
|
196
|
-
const state = await readLegacyJsonFile(resolveStateFilePath(params.stateDir, MSTEAMS_POLLS_LEGACY_FILENAME), parseLegacyPollStore);
|
|
210
|
+
const state = await readLegacyJsonFile(resolveStateFilePath(params.stateDir, require_polls.MSTEAMS_POLLS_LEGACY_FILENAME), parseLegacyPollStore);
|
|
197
211
|
if (!state || Object.keys(state.polls).length === 0) return null;
|
|
198
|
-
return { preview: [`- ${MSTEAMS_PLUGIN_ID} polls: ${Object.keys(state.polls).length} entries -> plugin state (${MSTEAMS_POLLS_NAMESPACE})`] };
|
|
212
|
+
return { preview: [`- ${MSTEAMS_PLUGIN_ID} polls: ${Object.keys(state.polls).length} entries -> plugin state (${require_polls.MSTEAMS_POLLS_NAMESPACE})`] };
|
|
199
213
|
},
|
|
200
214
|
async migrateLegacyState(params) {
|
|
201
215
|
const changes = [];
|
|
202
216
|
const warnings = [];
|
|
203
|
-
const filePath = resolveStateFilePath(params.stateDir, MSTEAMS_POLLS_LEGACY_FILENAME);
|
|
217
|
+
const filePath = resolveStateFilePath(params.stateDir, require_polls.MSTEAMS_POLLS_LEGACY_FILENAME);
|
|
204
218
|
const state = await readLegacyJsonFile(filePath, parseLegacyPollStore);
|
|
205
219
|
if (!state) return {
|
|
206
220
|
changes,
|
|
207
221
|
warnings
|
|
208
222
|
};
|
|
209
223
|
const pollStore = params.context.openPluginStateKeyedStore({
|
|
210
|
-
namespace: MSTEAMS_POLLS_NAMESPACE,
|
|
211
|
-
maxEntries: MSTEAMS_SQLITE_MAX_POLL_ROWS
|
|
224
|
+
namespace: require_polls.MSTEAMS_POLLS_NAMESPACE,
|
|
225
|
+
maxEntries: require_polls.MSTEAMS_SQLITE_MAX_POLL_ROWS
|
|
212
226
|
});
|
|
213
227
|
const voteBucketStore = params.context.openPluginStateKeyedStore({
|
|
214
|
-
namespace: MSTEAMS_POLL_VOTE_BUCKETS_NAMESPACE,
|
|
215
|
-
maxEntries: MSTEAMS_MAX_POLL_VOTE_BUCKET_ROWS
|
|
228
|
+
namespace: require_polls.MSTEAMS_POLL_VOTE_BUCKETS_NAMESPACE,
|
|
229
|
+
maxEntries: require_polls.MSTEAMS_MAX_POLL_VOTE_BUCKET_ROWS
|
|
216
230
|
});
|
|
217
231
|
let imported = 0;
|
|
218
|
-
for (const [pollId, poll] of selectRetainedMSTeamsPolls(state.polls)) {
|
|
219
|
-
const { metadata, votes } = splitMSTeamsPoll(poll);
|
|
220
|
-
const didImportPoll = await pollStore.registerIfAbsent(buildMSTeamsPollStateKey(pollId), metadata);
|
|
232
|
+
for (const [pollId, poll] of require_polls.selectRetainedMSTeamsPolls(state.polls)) {
|
|
233
|
+
const { metadata, votes } = require_polls.splitMSTeamsPoll(poll);
|
|
234
|
+
const didImportPoll = await pollStore.registerIfAbsent(require_polls.buildMSTeamsPollStateKey(pollId), metadata);
|
|
221
235
|
const buckets = /* @__PURE__ */ new Map();
|
|
222
236
|
for (const [voterId, selections] of Object.entries(votes)) {
|
|
223
|
-
const bucket = selectMSTeamsPollVoteBucket(pollId, voterId);
|
|
237
|
+
const bucket = require_polls.selectMSTeamsPollVoteBucket(pollId, voterId);
|
|
224
238
|
const bucketVotes = buckets.get(bucket) ?? {};
|
|
225
239
|
bucketVotes[voterId] = selections;
|
|
226
240
|
buckets.set(bucket, bucketVotes);
|
|
227
241
|
}
|
|
228
242
|
let importedVoteBucket = false;
|
|
229
243
|
for (const [bucket, bucketVotes] of buckets) {
|
|
230
|
-
const key = buildMSTeamsPollVoteBucketKey(pollId, bucket);
|
|
244
|
+
const key = require_polls.buildMSTeamsPollVoteBucketKey(pollId, bucket);
|
|
231
245
|
const existing = await voteBucketStore.lookup(key);
|
|
232
246
|
await voteBucketStore.register(key, {
|
|
233
247
|
pollId,
|
|
@@ -243,7 +257,7 @@ const stateMigrations = [
|
|
|
243
257
|
if (didImportPoll || importedVoteBucket) imported++;
|
|
244
258
|
}
|
|
245
259
|
changes.push(`Migrated ${imported} ${MSTEAMS_PLUGIN_ID} poll ${imported === 1 ? "entry" : "entries"} -> plugin state`);
|
|
246
|
-
await archiveLegacyStateSource({
|
|
260
|
+
await (0, openclaw_plugin_sdk_runtime_doctor.archiveLegacyStateSource)({
|
|
247
261
|
filePath,
|
|
248
262
|
label: `${MSTEAMS_PLUGIN_ID} poll`,
|
|
249
263
|
changes,
|
|
@@ -259,36 +273,36 @@ const stateMigrations = [
|
|
|
259
273
|
id: "msteams-sso-tokens-json-to-plugin-state",
|
|
260
274
|
label: "Microsoft Teams SSO tokens",
|
|
261
275
|
async detectLegacyState(params) {
|
|
262
|
-
const state = await readLegacyJsonFile(resolveStateFilePath(params.stateDir, MSTEAMS_SSO_TOKENS_LEGACY_FILENAME), (value) => isMSTeamsSsoStoreData(value) ? value : null);
|
|
276
|
+
const state = await readLegacyJsonFile(resolveStateFilePath(params.stateDir, require_sso_token_store.MSTEAMS_SSO_TOKENS_LEGACY_FILENAME), (value) => require_sso_token_store.isMSTeamsSsoStoreData(value) ? value : null);
|
|
263
277
|
if (!state || Object.keys(state.tokens).length === 0) return null;
|
|
264
|
-
return { preview: [`- ${MSTEAMS_PLUGIN_ID} SSO tokens: ${Object.keys(state.tokens).length} entries -> plugin state (${MSTEAMS_SSO_TOKENS_NAMESPACE})`] };
|
|
278
|
+
return { preview: [`- ${MSTEAMS_PLUGIN_ID} SSO tokens: ${Object.keys(state.tokens).length} entries -> plugin state (${require_sso_token_store.MSTEAMS_SSO_TOKENS_NAMESPACE})`] };
|
|
265
279
|
},
|
|
266
280
|
async migrateLegacyState(params) {
|
|
267
281
|
const changes = [];
|
|
268
282
|
const warnings = [];
|
|
269
|
-
const filePath = resolveStateFilePath(params.stateDir, MSTEAMS_SSO_TOKENS_LEGACY_FILENAME);
|
|
270
|
-
const state = await readLegacyJsonFile(filePath, (value) => isMSTeamsSsoStoreData(value) ? value : null);
|
|
283
|
+
const filePath = resolveStateFilePath(params.stateDir, require_sso_token_store.MSTEAMS_SSO_TOKENS_LEGACY_FILENAME);
|
|
284
|
+
const state = await readLegacyJsonFile(filePath, (value) => require_sso_token_store.isMSTeamsSsoStoreData(value) ? value : null);
|
|
271
285
|
if (!state) return {
|
|
272
286
|
changes,
|
|
273
287
|
warnings
|
|
274
288
|
};
|
|
275
289
|
const store = params.context.openPluginStateKeyedStore({
|
|
276
|
-
namespace: MSTEAMS_SSO_TOKENS_NAMESPACE,
|
|
277
|
-
maxEntries: MSTEAMS_MAX_SSO_TOKENS
|
|
290
|
+
namespace: require_sso_token_store.MSTEAMS_SSO_TOKENS_NAMESPACE,
|
|
291
|
+
maxEntries: require_sso_token_store.MSTEAMS_MAX_SSO_TOKENS
|
|
278
292
|
});
|
|
279
293
|
let imported = 0;
|
|
280
294
|
let skipped = 0;
|
|
281
295
|
for (const token of Object.values(state.tokens)) {
|
|
282
|
-
const normalized = normalizeMSTeamsSsoStoredToken(token);
|
|
296
|
+
const normalized = require_sso_token_store.normalizeMSTeamsSsoStoredToken(token);
|
|
283
297
|
if (!normalized) {
|
|
284
298
|
skipped++;
|
|
285
299
|
continue;
|
|
286
300
|
}
|
|
287
|
-
if (await store.registerIfAbsent(makeMSTeamsSsoTokenStoreKey(normalized.connectionName, normalized.userId), normalized)) imported++;
|
|
301
|
+
if (await store.registerIfAbsent(require_sso_token_store.makeMSTeamsSsoTokenStoreKey(normalized.connectionName, normalized.userId), normalized)) imported++;
|
|
288
302
|
}
|
|
289
303
|
changes.push(`Migrated ${imported} ${MSTEAMS_PLUGIN_ID} SSO token ${imported === 1 ? "entry" : "entries"} -> plugin state`);
|
|
290
304
|
if (skipped > 0) warnings.push(`Skipped ${skipped} malformed ${MSTEAMS_PLUGIN_ID} SSO token ${skipped === 1 ? "entry" : "entries"} during migration`);
|
|
291
|
-
await archiveLegacyStateSource({
|
|
305
|
+
await (0, openclaw_plugin_sdk_runtime_doctor.archiveLegacyStateSource)({
|
|
292
306
|
filePath,
|
|
293
307
|
label: `${MSTEAMS_PLUGIN_ID} SSO-token`,
|
|
294
308
|
changes,
|
|
@@ -341,7 +355,7 @@ const stateMigrations = [
|
|
|
341
355
|
updatedAt: Date.now()
|
|
342
356
|
});
|
|
343
357
|
imported++;
|
|
344
|
-
await archiveLegacyStateSource({
|
|
358
|
+
await (0, openclaw_plugin_sdk_runtime_doctor.archiveLegacyStateSource)({
|
|
345
359
|
filePath: file.filePath,
|
|
346
360
|
label: "Microsoft Teams feedback-learning",
|
|
347
361
|
changes,
|
|
@@ -357,4 +371,6 @@ const stateMigrations = [
|
|
|
357
371
|
}
|
|
358
372
|
];
|
|
359
373
|
//#endregion
|
|
360
|
-
|
|
374
|
+
exports.legacyConfigRules = legacyConfigRules;
|
|
375
|
+
exports.normalizeCompatibilityConfig = normalizeCompatibilityConfig;
|
|
376
|
+
exports.stateMigrations = stateMigrations;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region extensions/msteams/index.ts
|
|
2
|
+
var msteams_default = (0, require("openclaw/plugin-sdk/channel-entry-contract").defineBundledChannelEntry)({
|
|
3
|
+
id: "msteams",
|
|
4
|
+
name: "Microsoft Teams",
|
|
5
|
+
description: "Microsoft Teams channel plugin (Bot Framework)",
|
|
6
|
+
importMetaUrl: require("url").pathToFileURL(__filename).href,
|
|
7
|
+
plugin: {
|
|
8
|
+
specifier: "./channel-plugin-api.cjs",
|
|
9
|
+
exportName: "msteamsPlugin"
|
|
10
|
+
},
|
|
11
|
+
secrets: {
|
|
12
|
+
specifier: "./secret-contract-api.cjs",
|
|
13
|
+
exportName: "channelSecrets"
|
|
14
|
+
},
|
|
15
|
+
runtime: {
|
|
16
|
+
specifier: "./runtime-api.cjs",
|
|
17
|
+
exportName: "setMSTeamsRuntime"
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
//#endregion
|
|
21
|
+
module.exports = msteams_default;
|