Plugins: internalize msteams SDK imports

This commit is contained in:
Vincent Koc 2026-03-17 20:06:54 -07:00
parent a41840f717
commit 3cc83cb81e
27 changed files with 31 additions and 32 deletions

View File

@ -114,6 +114,7 @@
- Never add `@ts-nocheck` and do not disable `no-explicit-any`; fix root causes and update Oxlint/Oxfmt config only when required.
- Dynamic import guardrail: do not mix `await import("x")` and static `import ... from "x"` for the same module in production code paths. If you need lazy loading, create a dedicated `*.runtime.ts` boundary (that re-exports from `x`) and dynamically import that boundary from lazy callers only.
- Dynamic import verification: after refactors that touch lazy-loading/module boundaries, run `pnpm build` and check for `[INEFFECTIVE_DYNAMIC_IMPORT]` warnings before submitting.
- Extension SDK self-import guardrail: inside an extension package, do not import that same extension via `openclaw/plugin-sdk/<extension>` from production files. Route internal imports through a local barrel such as `./api.ts` or `./runtime-api.ts`, and keep the `plugin-sdk/<extension>` path as the external contract only.
- Never share class behavior via prototype mutation (`applyPrototypeMixins`, `Object.defineProperty` on `.prototype`, or exporting `Class.prototype` for merges). Use explicit inheritance/composition (`A extends B extends C`) or helper composition so TypeScript can typecheck.
- If this pattern is needed, stop and get explicit approval before shipping; default behavior is to split/refactor into an explicit class hierarchy and keep members strongly typed.
- In tests, prefer per-instance stubs over prototype mutation (`SomeClass.prototype.method = ...`) unless a test explicitly documents why prototype-level patching is required.

View File

@ -0,0 +1 @@
export * from "openclaw/plugin-sdk/msteams";

View File

@ -1,4 +1,4 @@
import { fetchWithSsrFGuard, type SsrFPolicy } from "openclaw/plugin-sdk/msteams";
import { fetchWithSsrFGuard, type SsrFPolicy } from "../../runtime-api.js";
import { getMSTeamsRuntime } from "../runtime.js";
import { downloadMSTeamsAttachments } from "./download.js";
import { downloadAndStoreMSTeamsRemoteMedia } from "./remote-media.js";

View File

@ -1,4 +1,4 @@
import { buildMediaPayload } from "openclaw/plugin-sdk/msteams";
import { buildMediaPayload } from "../../runtime-api.js";
export function buildMSTeamsMediaPayload(
mediaList: Array<{ path: string; contentType?: string }>,

View File

@ -1,4 +1,4 @@
import type { SsrFPolicy } from "openclaw/plugin-sdk/msteams";
import type { SsrFPolicy } from "../../runtime-api.js";
import { getMSTeamsRuntime } from "../runtime.js";
import { inferPlaceholder } from "./shared.js";
import type { MSTeamsInboundMedia } from "./types.js";

View File

@ -4,8 +4,8 @@ import {
isHttpsUrlAllowedByHostnameSuffixAllowlist,
isPrivateIpAddress,
normalizeHostnameSuffixAllowlist,
} from "openclaw/plugin-sdk/msteams";
import type { SsrFPolicy } from "openclaw/plugin-sdk/msteams";
} from "../../runtime-api.js";
import type { SsrFPolicy } from "../../runtime-api.js";
import type { MSTeamsAttachmentLike } from "./types.js";
type InlineImageCandidate =

View File

@ -6,11 +6,7 @@ import type {
ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-runtime";
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
import type {
ChannelMessageActionName,
ChannelPlugin,
OpenClawConfig,
} from "openclaw/plugin-sdk/msteams";
import type { ChannelMessageActionName, ChannelPlugin, OpenClawConfig } from "../runtime-api.js";
import {
buildProbeChannelStatusSummary,
buildRuntimeAccountStatusSnapshot,
@ -19,7 +15,7 @@ import {
DEFAULT_ACCOUNT_ID,
MSTeamsConfigSchema,
PAIRING_APPROVED_MESSAGE,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import { resolveMSTeamsGroupToolPolicy } from "./policy.js";
import type { ProbeMSTeamsResult } from "./probe.js";
import {

View File

@ -1,4 +1,4 @@
import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/msteams";
import type { ChannelDirectoryEntry } from "../runtime-api.js";
import { searchGraphUsers } from "./graph-users.js";
import {
type GraphChannel,

View File

@ -1 +1 @@
export { withFileLock } from "openclaw/plugin-sdk/msteams";
export { withFileLock } from "../runtime-api.js";

View File

@ -1,4 +1,4 @@
import type { MSTeamsConfig } from "openclaw/plugin-sdk/msteams";
import type { MSTeamsConfig } from "../runtime-api.js";
import { GRAPH_ROOT } from "./attachments/shared.js";
import { loadMSTeamsSdkWithAuth } from "./sdk.js";
import { readAccessToken } from "./token-response.js";

View File

@ -8,7 +8,7 @@ import {
extensionForMime,
extractOriginalFilename,
getFileExtension,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
/**
* Detect MIME type from URL extension or data URL.

View File

@ -7,7 +7,7 @@ import {
type ReplyPayload,
SILENT_REPLY_TOKEN,
sleep,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
import type { StoredConversationReference } from "./conversation-store.js";
import { classifyMSTeamsSendError } from "./errors.js";

View File

@ -1,4 +1,4 @@
import type { OpenClawConfig, RuntimeEnv } from "openclaw/plugin-sdk/msteams";
import type { OpenClawConfig, RuntimeEnv } from "../runtime-api.js";
import type { MSTeamsConversationStore } from "./conversation-store.js";
import { buildFileInfoCard, parseFileConsentInvoke, uploadToConsentUrl } from "./file-consent.js";
import { normalizeMSTeamsConversationId } from "./inbound.js";

View File

@ -19,7 +19,7 @@ import {
resolveEffectiveAllowFromLists,
resolveDmGroupAccessWithLists,
type HistoryEntry,
} from "openclaw/plugin-sdk/msteams";
} from "../../runtime-api.js";
import {
buildMSTeamsAttachmentPlaceholder,
buildMSTeamsMediaPayload,

View File

@ -7,7 +7,7 @@ import {
summarizeMapping,
type OpenClawConfig,
type RuntimeEnv,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import { createMSTeamsConversationStoreFs } from "./conversation-store-fs.js";
import type { MSTeamsConversationStore } from "./conversation-store.js";
import { formatUnknownError } from "./errors.js";

View File

@ -1,5 +1,5 @@
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime";
import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/msteams";
import type { ChannelOutboundAdapter } from "../runtime-api.js";
import { createMSTeamsPollStoreFs } from "./polls.js";
import { getMSTeamsRuntime } from "./runtime.js";
import { sendMessageMSTeams, sendPollMSTeams } from "./send.js";

View File

@ -7,7 +7,7 @@ import type {
MSTeamsConfig,
MSTeamsReplyStyle,
MSTeamsTeamConfig,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import {
buildChannelKeyCandidates,
evaluateSenderGroupAccessForPolicy,
@ -17,7 +17,7 @@ import {
resolveChannelEntryMatchWithFallback,
resolveNestedAllowlistDecision,
isDangerousNameMatchingEnabled,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
export type MSTeamsResolvedRouteConfig = {
teamConfig?: MSTeamsTeamConfig;

View File

@ -2,7 +2,7 @@ import {
normalizeStringEntries,
type BaseProbeResult,
type MSTeamsConfig,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import { formatUnknownError } from "./errors.js";
import { loadMSTeamsSdkWithAuth } from "./sdk.js";
import { readAccessToken } from "./token-response.js";

View File

@ -6,7 +6,7 @@ import {
type OpenClawConfig,
type MSTeamsReplyStyle,
type RuntimeEnv,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
import type { StoredConversationReference } from "./conversation-store.js";
import {

View File

@ -1,5 +1,5 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/msteams";
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
import type { PluginRuntime } from "../runtime-api.js";
const { setRuntime: setMSTeamsRuntime, getRuntime: getMSTeamsRuntime } =
createPluginRuntimeStore<PluginRuntime>("MSTeams runtime not initialized");

View File

@ -2,6 +2,6 @@ import {
hasConfiguredSecretInput,
normalizeResolvedSecretInputString,
normalizeSecretInputString,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
export { hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString };

View File

@ -2,7 +2,7 @@ import {
resolveChannelMediaMaxBytes,
type OpenClawConfig,
type PluginRuntime,
} from "openclaw/plugin-sdk/msteams";
} from "../runtime-api.js";
import type { MSTeamsAccessTokenProvider } from "./attachments/types.js";
import { createMSTeamsConversationStoreFs } from "./conversation-store-fs.js";
import type {

View File

@ -1,5 +1,5 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/msteams";
import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/msteams";
import type { OpenClawConfig } from "../runtime-api.js";
import { loadOutboundMediaFromUrl } from "../runtime-api.js";
import { createMSTeamsConversationStoreFs } from "./conversation-store-fs.js";
import {
classifyMSTeamsSendError,

View File

@ -1,4 +1,3 @@
import type { MSTeamsTeamConfig } from "openclaw/plugin-sdk/msteams";
import {
DEFAULT_ACCOUNT_ID,
formatDocsLink,
@ -13,6 +12,7 @@ import {
type OpenClawConfig,
type WizardPrompter,
} from "openclaw/plugin-sdk/setup";
import type { MSTeamsTeamConfig } from "../runtime-api.js";
import {
parseMSTeamsTeamEntry,
resolveMSTeamsChannelAllowlist,

View File

@ -1,5 +1,5 @@
import fs from "node:fs";
import { readJsonFileWithFallback, writeJsonFileAtomically } from "openclaw/plugin-sdk/msteams";
import { readJsonFileWithFallback, writeJsonFileAtomically } from "../runtime-api.js";
import { withFileLock as withPathLock } from "./file-lock.js";
const STORE_LOCK_OPTIONS = {

View File

@ -1,4 +1,4 @@
import type { MSTeamsConfig } from "openclaw/plugin-sdk/msteams";
import type { MSTeamsConfig } from "../runtime-api.js";
import {
hasConfiguredSecretInput,
normalizeResolvedSecretInputString,

View File

@ -128,6 +128,7 @@ const LOCAL_EXTENSION_API_BARREL_GUARDS = [
"matrix",
"mattermost",
"memory-lancedb",
"msteams",
"nextcloud-talk",
"synology-chat",
"talk-voice",