@openclaw/msteams 2026.9.1-beta.1 → 2026.9.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.
Files changed (26) hide show
  1. package/dist/{adapter.runtime-8g-MOPfb.cjs → adapter.runtime-DDuc7sKJ.cjs} +1 -1
  2. package/dist/api.cjs +2 -2
  3. package/dist/{approval-card-B6ZIMO83.cjs → approval-card-ClrTjCsL.cjs} +15 -5
  4. package/dist/{approval-handler.runtime-C3FXQ_6Z.cjs → approval-handler.runtime-9rMFhyLp.cjs} +9 -5
  5. package/dist/{channel-BsqcQ0E9.cjs → channel-CqRcu6kk.cjs} +22 -14
  6. package/dist/channel-config-api.cjs +1 -1
  7. package/dist/channel-plugin-api.cjs +1 -1
  8. package/dist/{channel.runtime-DuQWuKFd.cjs → channel.runtime-BAy59d1L.cjs} +64 -69
  9. package/dist/{channel.setup-BvYxZIFG.cjs → channel.setup-D2YO3F4O.cjs} +22 -18
  10. package/dist/{config-schema-C4CszdDi.cjs → config-schema-MyN2lamA.cjs} +12 -11
  11. package/dist/directory-contract-api.cjs +1 -1
  12. package/dist/doctor-contract-api.cjs +79 -42
  13. package/dist/{messenger-BJB30CC2.cjs → messenger-BvR2flEt.cjs} +23 -17
  14. package/dist/{oauth-BXQBTEta.cjs → oauth-BeROaYf0.cjs} +4 -3
  15. package/dist/{polls-DvuJvaDG.cjs → polls-P86qBpeV.cjs} +5 -4
  16. package/dist/qa-runner-api.cjs +1 -1
  17. package/dist/{reaction-types-dGkp4bkW.cjs → reaction-types-DcJBoyFP.cjs} +3 -2
  18. package/dist/{resolve-allowlist-B6FQAa3r.cjs → resolve-allowlist-CoKmLXYe.cjs} +37 -62
  19. package/dist/{rolldown-runtime-D6vf50IK.cjs → rolldown-runtime-VH7oDXx4.cjs} +1 -1
  20. package/dist/runtime-api.cjs +2 -1
  21. package/dist/{send-S0VPVSUi.cjs → send-CAKTR80N.cjs} +18 -14
  22. package/dist/setup-plugin-api.cjs +1 -1
  23. package/dist/{src-NMnaP_95.cjs → src-CyNCea9B.cjs} +124 -94
  24. package/dist/{sso-token-store-ChhO1f4i.cjs → sso-token-store-CNbRhz-A.cjs} +1 -1
  25. package/dist/{thread-session-DdWfgc8U.cjs → thread-session-p8FNgohv.cjs} +1 -1
  26. package/package.json +6 -6
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
2
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
3
3
  const require_delegated_state = require("./delegated-state-DiEz9JIa.cjs");
4
- const require_polls = require("./polls-DvuJvaDG.cjs");
5
- const require_sso_token_store = require("./sso-token-store-ChhO1f4i.cjs");
4
+ const require_polls = require("./polls-P86qBpeV.cjs");
5
+ const require_sso_token_store = require("./sso-token-store-CNbRhz-A.cjs");
6
6
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
7
7
  let node_crypto = require("node:crypto");
8
8
  node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
@@ -11,7 +11,7 @@ node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises, 1);
11
11
  let node_path = require("node:path");
12
12
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
13
13
  let openclaw_plugin_sdk_runtime_doctor_migrations = require("openclaw/plugin-sdk/runtime-doctor-migrations");
14
- //#region extensions/msteams/doctor-contract-api.ts
14
+ //#region extensions/msteams/config-doctor-api.ts
15
15
  const streamingAliasMigration = (0, openclaw_plugin_sdk_runtime_doctor_migrations.defineChannelAliasMigration)({
16
16
  channelId: "msteams",
17
17
  streaming: { defaultMode: "partial" }
@@ -20,6 +20,8 @@ const legacyConfigRules = streamingAliasMigration.legacyConfigRules;
20
20
  function normalizeCompatibilityConfig({ cfg }) {
21
21
  return streamingAliasMigration.normalizeChannelConfig({ cfg });
22
22
  }
23
+ //#endregion
24
+ //#region extensions/msteams/doctor-contract-api.ts
23
25
  const LEARNINGS_NAMESPACE = "feedback-learnings";
24
26
  const MAX_LEARNING_ENTRIES = 1e4;
25
27
  const MSTEAMS_PLUGIN_ID = "Microsoft Teams";
@@ -165,6 +167,33 @@ function mergeLearnings(legacy, existing) {
165
167
  }
166
168
  return merged.slice(-10);
167
169
  }
170
+ async function completeLegacyKeyedImport(params) {
171
+ const { filePath, label, imported, warnings } = params;
172
+ const changes = [];
173
+ let missing = 0;
174
+ for (const { store, requiredKeys } of params.stores) {
175
+ const retainedKeys = new Set((await store.entries()).map((entry) => entry.key));
176
+ missing += [...requiredKeys].filter((key) => !retainedKeys.has(key)).length;
177
+ }
178
+ if (missing > 0) {
179
+ warnings.push(`Incomplete ${label} migration: plugin state failed to retain every required entry (${missing} missing); left legacy source in place`);
180
+ return {
181
+ changes,
182
+ warnings
183
+ };
184
+ }
185
+ changes.push(`Migrated ${imported} ${label} ${imported === 1 ? "entry" : "entries"} -> plugin state`);
186
+ await (0, openclaw_plugin_sdk_runtime_doctor_migrations.archiveLegacyStateSource)({
187
+ filePath,
188
+ label: params.archiveLabel ?? label,
189
+ changes,
190
+ warnings
191
+ });
192
+ return {
193
+ changes,
194
+ warnings
195
+ };
196
+ }
168
197
  const stateMigrations = [
169
198
  {
170
199
  id: "msteams-conversations-json-to-plugin-state",
@@ -175,35 +204,36 @@ const stateMigrations = [
175
204
  return { preview: [`- ${MSTEAMS_PLUGIN_ID} conversations: ${Object.keys(state.conversations).length} entries -> plugin state (${require_polls.MSTEAMS_CONVERSATIONS_NAMESPACE})`] };
176
205
  },
177
206
  async migrateLegacyState(params) {
178
- const changes = [];
179
- const warnings = [];
180
207
  const filePath = resolveStateFilePath(params.stateDir, require_polls.MSTEAMS_CONVERSATIONS_LEGACY_FILENAME);
181
208
  const state = await readLegacyJsonFile(filePath, parseLegacyConversationStore);
182
209
  if (!state) return {
183
- changes,
184
- warnings
210
+ changes: [],
211
+ warnings: []
185
212
  };
186
213
  const store = params.context.openPluginStateKeyedStore({
187
214
  namespace: require_polls.MSTEAMS_CONVERSATIONS_NAMESPACE,
188
215
  maxEntries: require_polls.MSTEAMS_SQLITE_MAX_CONVERSATION_ROWS
189
216
  });
217
+ const requiredKeys = new Set((await store.entries()).map((entry) => entry.key));
190
218
  let imported = 0;
191
219
  for (const [rawConversationId, reference] of require_polls.selectRetainedMSTeamsConversations(state.conversations)) {
192
220
  const conversationId = require_polls.normalizeStoredConversationId(rawConversationId);
193
221
  if (!conversationId) continue;
194
- if (await store.registerIfAbsent(require_polls.buildMSTeamsConversationStateKey(conversationId), require_polls.prepareMSTeamsConversationReferenceForStorage(conversationId, reference))) imported++;
222
+ const key = require_polls.buildMSTeamsConversationStateKey(conversationId);
223
+ requiredKeys.add(key);
224
+ const storedReference = require_polls.prepareMSTeamsConversationReferenceForStorage(conversationId, reference);
225
+ if (await store.registerIfAbsent(key, storedReference)) imported++;
195
226
  }
196
- changes.push(`Migrated ${imported} ${MSTEAMS_PLUGIN_ID} conversation ${imported === 1 ? "entry" : "entries"} -> plugin state`);
197
- await (0, openclaw_plugin_sdk_runtime_doctor_migrations.archiveLegacyStateSource)({
227
+ return completeLegacyKeyedImport({
198
228
  filePath,
199
229
  label: `${MSTEAMS_PLUGIN_ID} conversation`,
200
- changes,
201
- warnings
230
+ imported,
231
+ warnings: [],
232
+ stores: [{
233
+ store,
234
+ requiredKeys
235
+ }]
202
236
  });
203
- return {
204
- changes,
205
- warnings
206
- };
207
237
  }
208
238
  },
209
239
  {
@@ -215,13 +245,11 @@ const stateMigrations = [
215
245
  return { preview: [`- ${MSTEAMS_PLUGIN_ID} polls: ${Object.keys(state.polls).length} entries -> plugin state (${require_polls.MSTEAMS_POLLS_NAMESPACE})`] };
216
246
  },
217
247
  async migrateLegacyState(params) {
218
- const changes = [];
219
- const warnings = [];
220
248
  const filePath = resolveStateFilePath(params.stateDir, require_polls.MSTEAMS_POLLS_LEGACY_FILENAME);
221
249
  const state = await readLegacyJsonFile(filePath, parseLegacyPollStore);
222
250
  if (!state) return {
223
- changes,
224
- warnings
251
+ changes: [],
252
+ warnings: []
225
253
  };
226
254
  const pollStore = params.context.openPluginStateKeyedStore({
227
255
  namespace: require_polls.MSTEAMS_POLLS_NAMESPACE,
@@ -231,10 +259,14 @@ const stateMigrations = [
231
259
  namespace: require_polls.MSTEAMS_POLL_VOTE_BUCKETS_NAMESPACE,
232
260
  maxEntries: require_polls.MSTEAMS_MAX_POLL_VOTE_BUCKET_ROWS
233
261
  });
262
+ const requiredPollKeys = new Set((await pollStore.entries()).map((entry) => entry.key));
263
+ const requiredVoteKeys = new Set((await voteBucketStore.entries()).map((entry) => entry.key));
234
264
  let imported = 0;
235
265
  for (const [pollId, poll] of require_polls.selectRetainedMSTeamsPolls(state.polls)) {
236
266
  const { metadata, votes } = require_polls.splitMSTeamsPoll(poll);
237
- const didImportPoll = await pollStore.registerIfAbsent(require_polls.buildMSTeamsPollStateKey(pollId), metadata);
267
+ const pollKey = require_polls.buildMSTeamsPollStateKey(pollId);
268
+ requiredPollKeys.add(pollKey);
269
+ const didImportPoll = await pollStore.registerIfAbsent(pollKey, metadata);
238
270
  const buckets = /* @__PURE__ */ new Map();
239
271
  for (const [voterId, selections] of Object.entries(votes)) {
240
272
  const bucket = require_polls.selectMSTeamsPollVoteBucket(pollId, voterId);
@@ -245,6 +277,7 @@ const stateMigrations = [
245
277
  let importedVoteBucket = false;
246
278
  for (const [bucket, bucketVotes] of buckets) {
247
279
  const key = require_polls.buildMSTeamsPollVoteBucketKey(pollId, bucket);
280
+ requiredVoteKeys.add(key);
248
281
  const existing = await voteBucketStore.lookup(key);
249
282
  await voteBucketStore.register(key, {
250
283
  pollId,
@@ -259,17 +292,19 @@ const stateMigrations = [
259
292
  }
260
293
  if (didImportPoll || importedVoteBucket) imported++;
261
294
  }
262
- changes.push(`Migrated ${imported} ${MSTEAMS_PLUGIN_ID} poll ${imported === 1 ? "entry" : "entries"} -> plugin state`);
263
- await (0, openclaw_plugin_sdk_runtime_doctor_migrations.archiveLegacyStateSource)({
295
+ return completeLegacyKeyedImport({
264
296
  filePath,
265
297
  label: `${MSTEAMS_PLUGIN_ID} poll`,
266
- changes,
267
- warnings
298
+ imported,
299
+ warnings: [],
300
+ stores: [{
301
+ store: pollStore,
302
+ requiredKeys: requiredPollKeys
303
+ }, {
304
+ store: voteBucketStore,
305
+ requiredKeys: requiredVoteKeys
306
+ }]
268
307
  });
269
- return {
270
- changes,
271
- warnings
272
- };
273
308
  }
274
309
  },
275
310
  {
@@ -281,18 +316,18 @@ const stateMigrations = [
281
316
  return { preview: [`- ${MSTEAMS_PLUGIN_ID} SSO tokens: ${Object.keys(state.tokens).length} entries -> plugin state (${require_sso_token_store.MSTEAMS_SSO_TOKENS_NAMESPACE})`] };
282
317
  },
283
318
  async migrateLegacyState(params) {
284
- const changes = [];
285
319
  const warnings = [];
286
320
  const filePath = resolveStateFilePath(params.stateDir, require_sso_token_store.MSTEAMS_SSO_TOKENS_LEGACY_FILENAME);
287
321
  const state = await readLegacyJsonFile(filePath, (value) => require_sso_token_store.isMSTeamsSsoStoreData(value) ? value : null);
288
322
  if (!state) return {
289
- changes,
323
+ changes: [],
290
324
  warnings
291
325
  };
292
326
  const store = params.context.openPluginStateKeyedStore({
293
327
  namespace: require_sso_token_store.MSTEAMS_SSO_TOKENS_NAMESPACE,
294
328
  maxEntries: require_sso_token_store.MSTEAMS_MAX_SSO_TOKENS
295
329
  });
330
+ const requiredKeys = new Set((await store.entries()).map((entry) => entry.key));
296
331
  let imported = 0;
297
332
  let skipped = 0;
298
333
  for (const token of Object.values(state.tokens)) {
@@ -301,20 +336,22 @@ const stateMigrations = [
301
336
  skipped++;
302
337
  continue;
303
338
  }
304
- if (await store.registerIfAbsent(require_sso_token_store.makeMSTeamsSsoTokenStoreKey(normalized.connectionName, normalized.userId), normalized)) imported++;
339
+ const key = require_sso_token_store.makeMSTeamsSsoTokenStoreKey(normalized.connectionName, normalized.userId);
340
+ requiredKeys.add(key);
341
+ if (await store.registerIfAbsent(key, normalized)) imported++;
305
342
  }
306
- changes.push(`Migrated ${imported} ${MSTEAMS_PLUGIN_ID} SSO token ${imported === 1 ? "entry" : "entries"} -> plugin state`);
307
343
  if (skipped > 0) warnings.push(`Skipped ${skipped} malformed ${MSTEAMS_PLUGIN_ID} SSO token ${skipped === 1 ? "entry" : "entries"} during migration`);
308
- await (0, openclaw_plugin_sdk_runtime_doctor_migrations.archiveLegacyStateSource)({
344
+ return completeLegacyKeyedImport({
309
345
  filePath,
310
- label: `${MSTEAMS_PLUGIN_ID} SSO-token`,
311
- changes,
312
- warnings
346
+ label: `${MSTEAMS_PLUGIN_ID} SSO token`,
347
+ archiveLabel: `${MSTEAMS_PLUGIN_ID} SSO-token`,
348
+ imported,
349
+ warnings,
350
+ stores: [{
351
+ store,
352
+ requiredKeys
353
+ }]
313
354
  });
314
- return {
315
- changes,
316
- warnings
317
- };
318
355
  }
319
356
  },
320
357
  {
@@ -1,9 +1,9 @@
1
- const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
2
  const require_runtime = require("./runtime-gZTAuFux.cjs");
3
3
  require("./runtime-api.cjs");
4
- const require_resolve_allowlist = require("./resolve-allowlist-B6FQAa3r.cjs");
5
- const require_channel_setup = require("./channel.setup-BvYxZIFG.cjs");
6
- const require_polls = require("./polls-DvuJvaDG.cjs");
4
+ const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
5
+ const require_channel_setup = require("./channel.setup-D2YO3F4O.cjs");
6
+ const require_polls = require("./polls-P86qBpeV.cjs");
7
7
  let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
8
8
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
9
9
  let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
@@ -161,12 +161,12 @@ async function uploadToConsentUrl(params) {
161
161
  //#endregion
162
162
  //#region extensions/msteams/src/pending-uploads-fs.ts
163
163
  /** TTL for persisted pending uploads (matches in-memory store). */
164
- const PENDING_UPLOAD_TTL_MS$1 = 300 * 1e3;
164
+ const PENDING_UPLOAD_TTL_MS$1 = 3e5;
165
165
  /** Cap to avoid unbounded growth if a process crashes mid-flow. */
166
166
  const MAX_PENDING_UPLOADS = 100;
167
167
  const MAX_CHUNKS_PER_UPLOAD = 3072;
168
168
  const MAX_PENDING_UPLOAD_CHUNK_ROWS = 45e3;
169
- const RAW_CHUNK_BYTES = 36 * 1024;
169
+ const RAW_CHUNK_BYTES = 36864;
170
170
  const PENDING_UPLOAD_META_MAX_ENTRIES = 200;
171
171
  const PENDING_UPLOAD_META_NAMESPACE = "pending-uploads";
172
172
  const PENDING_UPLOAD_CHUNKS_NAMESPACE = "pending-upload-chunks";
@@ -357,7 +357,7 @@ const { pendingUploads, pendingUploadTimers } = (0, openclaw_plugin_sdk_global_s
357
357
  state.pendingUploads.clear();
358
358
  });
359
359
  /** TTL for pending uploads: 5 minutes */
360
- const PENDING_UPLOAD_TTL_MS = 300 * 1e3;
360
+ const PENDING_UPLOAD_TTL_MS = 3e5;
361
361
  /**
362
362
  * Store a file pending user consent.
363
363
  * Returns the upload ID to include in the FileConsentCard context.
@@ -540,10 +540,10 @@ const MSTEAMS_MARKERS = {
540
540
  }
541
541
  };
542
542
  function createTokenPrefix(text, label) {
543
- const normalized = (0, openclaw_plugin_sdk_text_chunking.markdownToIR)(text, {
543
+ const normalized = /[\u{E000}&]/u.test(text) ? (0, openclaw_plugin_sdk_text_chunking.markdownToIR)(text, {
544
544
  autolink: false,
545
545
  linkify: false
546
- }).text;
546
+ }).text : "";
547
547
  let prefix;
548
548
  do
549
549
  prefix = `\u{E000}${label}-${(0, node_crypto.randomUUID)()}\u{E001}`;
@@ -887,14 +887,16 @@ function formatMSTeamsMarkdown(markdown, tableMode) {
887
887
  const mentions = [];
888
888
  const entities = [];
889
889
  const tokenPrefix = createTokenPrefix(markdown, "msteamsformat");
890
- const tableInput = (0, openclaw_plugin_sdk_text_chunking.convertMarkdownTables)(protectMSTeamsMentions(protectMarkdownImages(markdown.replace(MARKDOWN_ENTITY_RE, (entity) => {
890
+ const mentionsProtected = protectMSTeamsMentions(protectMarkdownImages(markdown.replace(MARKDOWN_ENTITY_RE, (entity) => {
891
891
  const index = entities.push(entity) - 1;
892
892
  return `${tokenPrefix}h${index}${TOKEN_END}`;
893
- }), tokenPrefix, images), tokenPrefix, mentions), tableMode);
894
- let restored = restoreTokens((0, openclaw_plugin_sdk_text_chunking.renderMarkdownWithMarkers)(prefixMSTeamsBlockquotes(protectMSTeamsCode((0, openclaw_plugin_sdk_text_chunking.markdownToIR)((tableMode === "off" ? protectRawTablesOutsideFences(tableInput, tokenPrefix, rawTables) : tableInput).replace(ESCAPED_MARKDOWN_RE, (escaped) => {
893
+ }), tokenPrefix, images), tokenPrefix, mentions);
894
+ const tableInput = (0, openclaw_plugin_sdk_text_chunking.convertMarkdownTables)(mentionsProtected, tableMode);
895
+ const protectedMarkdown = (tableMode === "off" ? protectRawTablesOutsideFences(tableInput, tokenPrefix, rawTables) : tableInput).replace(ESCAPED_MARKDOWN_RE, (escaped) => {
895
896
  const index = escapedMarkdown.push(escaped) - 1;
896
897
  return `${tokenPrefix}e${index}${TOKEN_END}`;
897
- }), {
898
+ });
899
+ const ir = prefixMSTeamsBlockquotes(protectMSTeamsCode((0, openclaw_plugin_sdk_text_chunking.markdownToIR)(protectedMarkdown, {
898
900
  autolink: false,
899
901
  enableSpoilers: true,
900
902
  enableTaskLists: true,
@@ -922,7 +924,8 @@ function formatMSTeamsMarkdown(markdown, tableMode) {
922
924
  prefix: `${tokenPrefix}h`,
923
925
  values: entities
924
926
  }
925
- ])), {
927
+ ]));
928
+ let restored = restoreTokens((0, openclaw_plugin_sdk_text_chunking.renderMarkdownWithMarkers)(ir, {
926
929
  styleMarkers: MSTEAMS_MARKERS,
927
930
  escapeText: (text) => text,
928
931
  buildLink: (link) => ({
@@ -1068,7 +1071,10 @@ async function getChatMembers(params) {
1068
1071
  },
1069
1072
  signal
1070
1073
  });
1071
- if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, res.status === 403 ? "Get chat members failed; verify Graph chat-member permissions and tenant access policies" : "Get chat members failed");
1074
+ if (!res.ok) {
1075
+ const message = res.status === 403 ? "Get chat members failed; verify Graph chat-member permissions and tenant access policies" : "Get chat members failed";
1076
+ throw await require_resolve_allowlist.createMSTeamsHttpError(res, message);
1077
+ }
1072
1078
  return ((await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.getChatMembers")).value ?? []).map((member) => ({ aadObjectId: member.userId ?? "" })).filter((member) => member.aadObjectId);
1073
1079
  }
1074
1080
  });
@@ -1423,12 +1429,12 @@ async function deleteMSTeamsActivityWithReference(app, source, activityId, optio
1423
1429
  * MSTeams-specific media size limit (100MB).
1424
1430
  * Higher than the default to support Teams file-consent and SharePoint uploads.
1425
1431
  */
1426
- const MSTEAMS_MAX_MEDIA_BYTES = 100 * 1024 * 1024;
1432
+ const MSTEAMS_MAX_MEDIA_BYTES = 104857600;
1427
1433
  /**
1428
1434
  * Threshold for large files that require FileConsentCard flow in personal chats.
1429
1435
  * Files >= 4MB use consent flow; smaller images can use inline base64.
1430
1436
  */
1431
- const FILE_CONSENT_THRESHOLD_BYTES = 4 * 1024 * 1024;
1437
+ const FILE_CONSENT_THRESHOLD_BYTES = 4194304;
1432
1438
  function normalizeConversationId(rawId) {
1433
1439
  return rawId.split(";")[0] ?? rawId;
1434
1440
  }
@@ -1,4 +1,4 @@
1
- const require_resolve_allowlist = require("./resolve-allowlist-B6FQAa3r.cjs");
1
+ const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
2
2
  let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
3
3
  let openclaw_plugin_sdk_provider_auth = require("openclaw/plugin-sdk/provider-auth");
4
4
  let openclaw_plugin_sdk_provider_auth_runtime = require("openclaw/plugin-sdk/provider-auth-runtime");
@@ -52,7 +52,7 @@ async function loginMSTeamsDelegated(ctx, params) {
52
52
  try {
53
53
  const { code } = await (0, openclaw_plugin_sdk_provider_auth_runtime.waitForLocalOAuthCallback)({
54
54
  expectedState: state,
55
- timeoutMs: 300 * 1e3,
55
+ timeoutMs: 3e5,
56
56
  port: require_resolve_allowlist.MSTEAMS_OAUTH_CALLBACK_PORT,
57
57
  callbackPath: require_resolve_allowlist.MSTEAMS_OAUTH_CALLBACK_PATH,
58
58
  redirectUri: require_resolve_allowlist.MSTEAMS_OAUTH_REDIRECT_URI,
@@ -81,7 +81,8 @@ async function manualFlow(ctx, authUrl, state, verifier, params, cause) {
81
81
  ctx.progress.update("OAuth URL ready");
82
82
  ctx.log(`\nOpen this URL in your LOCAL browser:\n\n${authUrl}\n`);
83
83
  ctx.progress.update("Waiting for you to paste the callback URL...");
84
- const parsed = (0, openclaw_plugin_sdk_provider_auth_runtime.parseOAuthCallbackInput)(await ctx.prompt("Paste the redirect URL here: "), {
84
+ const callbackInput = await ctx.prompt("Paste the redirect URL here: ");
85
+ const parsed = (0, openclaw_plugin_sdk_provider_auth_runtime.parseOAuthCallbackInput)(callbackInput, {
85
86
  missingState: "Missing 'state' parameter in URL. Paste the full redirect URL.",
86
87
  invalidInput: "Paste the full redirect URL (including code and state parameters), not just the authorization code."
87
88
  });
@@ -1,4 +1,4 @@
1
- const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.cjs");
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
2
  const require_runtime = require("./runtime-gZTAuFux.cjs");
3
3
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
4
4
  let openclaw_plugin_sdk_file_lock = require("openclaw/plugin-sdk/file-lock");
@@ -96,7 +96,7 @@ const MSTEAMS_CONVERSATIONS_LEGACY_FILENAME = "msteams-conversations.json";
96
96
  const MSTEAMS_CONVERSATIONS_NAMESPACE = "conversations";
97
97
  const MSTEAMS_MAX_CONVERSATIONS = 1e3;
98
98
  const MSTEAMS_SQLITE_MAX_CONVERSATION_ROWS = 2e3;
99
- const MSTEAMS_CONVERSATION_TTL_MS = 365 * 24 * 60 * 60 * 1e3;
99
+ const MSTEAMS_CONVERSATION_TTL_MS = 31536e6;
100
100
  const CONVERSATION_MUTATION_KEY = "conversations";
101
101
  function createConversationStateStore(params) {
102
102
  return require_runtime.getMSTeamsRuntime().state.openKeyedStore({
@@ -226,7 +226,7 @@ const MSTEAMS_MAX_POLLS = 1e3;
226
226
  const MSTEAMS_SQLITE_MAX_POLL_ROWS = 2e3;
227
227
  const MSTEAMS_POLL_VOTE_BUCKET_COUNT = 32;
228
228
  const MSTEAMS_MAX_POLL_VOTE_BUCKET_ROWS = 1001 * MSTEAMS_POLL_VOTE_BUCKET_COUNT;
229
- const MSTEAMS_POLL_TTL_MS = 720 * 60 * 60 * 1e3;
229
+ const MSTEAMS_POLL_TTL_MS = 2592e6;
230
230
  const POLL_MUTATION_KEY = "polls";
231
231
  function normalizeChoiceValue(value) {
232
232
  if (typeof value === "string") {
@@ -379,7 +379,8 @@ function selectRetainedMSTeamsPolls(polls) {
379
379
  }
380
380
  function normalizeMSTeamsPollSelections(poll, selections) {
381
381
  const maxSelections = Math.max(1, poll.maxSelections);
382
- return (0, openclaw_plugin_sdk_string_coerce_runtime.uniqueStrings)(selections.map((entry) => (0, openclaw_plugin_sdk_number_runtime.parseStrictNonNegativeInteger)(entry)).filter((value) => value !== void 0).filter((value) => value >= 0 && value < poll.options.length).map((value) => String(value))).slice(0, maxSelections);
382
+ const mapped = selections.map((entry) => (0, openclaw_plugin_sdk_number_runtime.parseStrictNonNegativeInteger)(entry)).filter((value) => value !== void 0).filter((value) => value >= 0 && value < poll.options.length).map((value) => String(value));
383
+ return (0, openclaw_plugin_sdk_string_coerce_runtime.uniqueStrings)(mapped).slice(0, maxSelections);
383
384
  }
384
385
  function splitMSTeamsPoll(poll) {
385
386
  const { votes, ...metadata } = poll;
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let openclaw_plugin_sdk_qa_runner_runtime = require("openclaw/plugin-sdk/qa-runner-runtime");
3
3
  //#region extensions/msteams/src/qa/cli.ts
4
4
  const DEFAULT_MSTEAMS_QA_SCENARIOS = ["channel-canary"];
5
- const loadMSTeamsQaAdapterRuntime = (0, openclaw_plugin_sdk_qa_runner_runtime.createLazyCliRuntimeLoader)(() => Promise.resolve().then(() => require("./adapter.runtime-8g-MOPfb.cjs")));
5
+ const loadMSTeamsQaAdapterRuntime = (0, openclaw_plugin_sdk_qa_runner_runtime.createLazyCliRuntimeLoader)(() => Promise.resolve().then(() => require("./adapter.runtime-DDuc7sKJ.cjs")));
6
6
  async function runQaMSTeams(options) {
7
7
  await (0, openclaw_plugin_sdk_qa_runner_runtime.runLiveTransportQaSuiteCommand)({
8
8
  channelId: "msteams",
@@ -1,4 +1,4 @@
1
- const require_resolve_allowlist = require("./resolve-allowlist-B6FQAa3r.cjs");
1
+ const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
2
2
  let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
3
3
  //#region extensions/msteams/src/graph-thread.ts
4
4
  /**
@@ -62,9 +62,10 @@ async function fetchChatMessageText(token, chatId, messageId, deadline) {
62
62
  * replies but still in ascending order only.
63
63
  */
64
64
  async function fetchThreadReplies(token, groupId, channelId, messageId, limit = 50, deadline) {
65
+ const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=${Math.min(Math.max(limit, 1), 50)}`;
65
66
  return (await require_resolve_allowlist.fetchGraphJson({
66
67
  token,
67
- path: `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=${Math.min(Math.max(limit, 1), 50)}`,
68
+ path,
68
69
  ...deadline ? { deadline } : {}
69
70
  })).value ?? [];
70
71
  }
@@ -19,8 +19,8 @@ let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-
19
19
  let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
20
20
  //#region extensions/msteams/src/request-timeout.ts
21
21
  const MSTEAMS_REQUEST_TIMEOUT_MS = 3e4;
22
- const MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS = 5 * 6e4;
23
- const MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND = 256 * 1024;
22
+ const MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS = 3e5;
23
+ const MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND = 262144;
24
24
  const MSTEAMS_INBOUND_PREPROCESS_TIMEOUT_MS = 1e4;
25
25
  function createMSTeamsInboundDeadline() {
26
26
  return (0, openclaw_plugin_sdk_provider_http.createProviderOperationDeadline)({
@@ -111,25 +111,6 @@ const DEFAULT_MEDIA_AUTH_HOST_ALLOWLIST = [
111
111
  "graph.microsoft.cn"
112
112
  ];
113
113
  const GRAPH_ROOT = "https://graph.microsoft.com/v1.0";
114
- function estimateBase64DecodedBytes(base64) {
115
- let effectiveLen = 0;
116
- for (let i = 0; i < base64.length; i += 1) {
117
- if (base64.charCodeAt(i) <= 32) continue;
118
- effectiveLen += 1;
119
- }
120
- if (effectiveLen === 0) return 0;
121
- let padding = 0;
122
- let end = base64.length - 1;
123
- while (end >= 0 && base64.charCodeAt(end) <= 32) end -= 1;
124
- if (end >= 0 && base64[end] === "=") {
125
- padding = 1;
126
- end -= 1;
127
- while (end >= 0 && base64.charCodeAt(end) <= 32) end -= 1;
128
- if (end >= 0 && base64[end] === "=") padding = 2;
129
- }
130
- const estimated = Math.floor(effectiveLen * 3 / 4) - padding;
131
- return Math.max(0, estimated);
132
- }
133
114
  /**
134
115
  * Host suffixes for SharePoint/OneDrive shared links that must be fetched via
135
116
  * the Graph `/shares/{shareId}/driveItem/content` endpoint instead of directly.
@@ -276,7 +257,7 @@ function decodeDataImageWithLimits(src, opts) {
276
257
  candidate: null,
277
258
  estimatedBytes: 0
278
259
  };
279
- const estimatedBytes = estimateBase64DecodedBytes(canonicalPayload);
260
+ const estimatedBytes = node_buffer.Buffer.byteLength(canonicalPayload, "base64");
280
261
  if (estimatedBytes <= 0) return {
281
262
  candidate: null,
282
263
  estimatedBytes: 0
@@ -449,7 +430,7 @@ async function safeFetch(params) {
449
430
  const resolveFn = params.resolveFn ?? node_dns_promises.lookup;
450
431
  const hasDispatcher = Boolean(params.requestInit && typeof params.requestInit === "object" && "dispatcher" in params.requestInit);
451
432
  const currentHeaders = new Headers(params.requestInit?.headers);
452
- let currentUrl = params.url;
433
+ const currentUrl = params.url;
453
434
  if (!isUrlAllowed(currentUrl, params.allowHosts)) throw new Error(`Initial download URL blocked: ${currentUrl}`);
454
435
  if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(currentUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
455
436
  if (!hasDispatcher) {
@@ -480,37 +461,29 @@ async function safeFetch(params) {
480
461
  });
481
462
  return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(guarded.response, guarded.release);
482
463
  }
483
- if (resolveFn) try {
464
+ try {
484
465
  const initialHost = new URL(currentUrl).hostname;
485
466
  await resolveAndValidateIP(initialHost, resolveFn);
486
467
  } catch {
487
468
  throw new Error(`Initial download URL blocked: ${currentUrl}`);
488
469
  }
489
- for (let i = 0; i <= MAX_SAFE_REDIRECTS; i++) {
490
- const res = await (params.fetchFn ?? fetch)(currentUrl, {
491
- ...params.requestInit,
492
- headers: currentHeaders,
493
- redirect: "manual"
494
- });
495
- if (!isRedirectStatus(res.status)) return res;
496
- const location = res.headers.get("location");
497
- if (!location) return res;
498
- let redirectUrl;
499
- try {
500
- redirectUrl = new URL(location, currentUrl).toString();
501
- } catch {
502
- throw new Error(`Invalid redirect URL: ${location}`);
503
- }
504
- if (!isUrlAllowed(redirectUrl, params.allowHosts)) throw new Error(`Media redirect target blocked by allowlist: ${redirectUrl}`);
505
- if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(redirectUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
506
- if (hasDispatcher) return res;
507
- if (resolveFn) {
508
- const redirectHost = new URL(redirectUrl).hostname;
509
- await resolveAndValidateIP(redirectHost, resolveFn);
510
- }
511
- currentUrl = redirectUrl;
470
+ const res = await (params.fetchFn ?? fetch)(currentUrl, {
471
+ ...params.requestInit,
472
+ headers: currentHeaders,
473
+ redirect: "manual"
474
+ });
475
+ if (!isRedirectStatus(res.status)) return res;
476
+ const location = res.headers.get("location");
477
+ if (!location) return res;
478
+ let redirectUrl;
479
+ try {
480
+ redirectUrl = new URL(location, currentUrl).toString();
481
+ } catch {
482
+ throw new Error(`Invalid redirect URL: ${location}`);
512
483
  }
513
- throw new Error(`Too many redirects (>${MAX_SAFE_REDIRECTS})`);
484
+ if (!isUrlAllowed(redirectUrl, params.allowHosts)) throw new Error(`Media redirect target blocked by allowlist: ${redirectUrl}`);
485
+ if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(redirectUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
486
+ return res;
514
487
  }
515
488
  async function safeFetchWithPolicy(params) {
516
489
  return await safeFetch({
@@ -920,7 +893,7 @@ function buildMSTeamsTokenEndpoint(tenantId) {
920
893
  //#endregion
921
894
  //#region extensions/msteams/src/oauth.token.ts
922
895
  /** Five-minute buffer subtracted from token expiry to avoid edge-case clock drift. */
923
- const EXPIRY_BUFFER_MS = 300 * 1e3;
896
+ const EXPIRY_BUFFER_MS = 3e5;
924
897
  function createMSTeamsTokenBody(params) {
925
898
  const body = new URLSearchParams({
926
899
  client_id: params.clientId,
@@ -1115,8 +1088,9 @@ function escapeOData(value) {
1115
1088
  }
1116
1089
  async function requestGraph(params) {
1117
1090
  const hasBody = params.body !== void 0;
1091
+ const url = `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`;
1118
1092
  const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
1119
- url: `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`,
1093
+ url,
1120
1094
  init: {
1121
1095
  method: params.method,
1122
1096
  headers: {
@@ -1199,18 +1173,13 @@ async function fetchAllGraphPages(params) {
1199
1173
  headers: params.headers
1200
1174
  });
1201
1175
  const pageItems = res.value ?? [];
1202
- if (params.findOne) {
1203
- const match = pageItems.find(params.findOne);
1204
- if (match) {
1205
- items.push(...pageItems);
1206
- return {
1207
- items,
1208
- truncated: false,
1209
- found: match
1210
- };
1211
- }
1212
- }
1213
- items.push(...pageItems);
1176
+ const match = params.findOne ? pageItems.find(params.findOne) : void 0;
1177
+ if (params.collectItems !== false) items.push(...pageItems);
1178
+ if (match) return {
1179
+ items,
1180
+ truncated: false,
1181
+ found: match
1182
+ };
1214
1183
  const rawNext = res["@odata.nextLink"];
1215
1184
  if (rawNext) nextPath = rawNext.replace("https://graph.microsoft.com/v1.0", "").replace("https://graph.microsoft.com/beta", "");
1216
1185
  else nextPath = void 0;
@@ -1953,6 +1922,12 @@ Object.defineProperty(exports, "extractMSTeamsQuoteInfo", {
1953
1922
  return extractMSTeamsQuoteInfo;
1954
1923
  }
1955
1924
  });
1925
+ Object.defineProperty(exports, "fetchAllGraphPages", {
1926
+ enumerable: true,
1927
+ get: function() {
1928
+ return fetchAllGraphPages;
1929
+ }
1930
+ });
1956
1931
  Object.defineProperty(exports, "fetchGraphAbsoluteUrl", {
1957
1932
  enumerable: true,
1958
1933
  get: function() {
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
19
  value: mod,
20
20
  enumerable: true
21
21
  }) : target, mod));
@@ -11,6 +11,7 @@ let openclaw_plugin_sdk_dangerous_name_runtime = require("openclaw/plugin-sdk/da
11
11
  let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runtime-group-policy");
12
12
  let openclaw_plugin_sdk_file_lock = require("openclaw/plugin-sdk/file-lock");
13
13
  let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runtime");
14
+ let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
14
15
  let openclaw_plugin_sdk_outbound_media = require("openclaw/plugin-sdk/outbound-media");
15
16
  let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
16
17
  let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
@@ -164,7 +165,7 @@ Object.defineProperty(exports, "resolveChannelEntryMatchWithFallback", {
164
165
  Object.defineProperty(exports, "resolveChannelMediaMaxBytes", {
165
166
  enumerable: true,
166
167
  get: function() {
167
- return openclaw_plugin_sdk_media_runtime.resolveChannelMediaMaxBytes;
168
+ return openclaw_plugin_sdk_account_helpers.resolveChannelMediaMaxBytes;
168
169
  }
169
170
  });
170
171
  Object.defineProperty(exports, "resolveDefaultGroupPolicy", {