refactor(matrix): remove obsolete private runtime forwarding layers (#130129)

* refactor(matrix): remove obsolete private runtime forwarding layers

* test(commands): preserve filesystem safety exports in delete mocks
This commit is contained in:
Peter Steinberger
2026-08-26 07:33:52 -07:00
committed by GitHub
parent c91edb5cd5
commit eb17c8da5a
40 changed files with 81 additions and 506 deletions
-2
View File
@@ -749,8 +749,6 @@ const config = {
[`${BUNDLED_PLUGIN_ROOT_DIR}/kilocode`]: bundledPluginWorkspace(),
[`${BUNDLED_PLUGIN_ROOT_DIR}/kimi-coding`]: bundledPluginWorkspace(),
[`${BUNDLED_PLUGIN_ROOT_DIR}/matrix`]: bundledPluginWorkspace([
// Native import wrapper shipped alongside the Matrix runtime bundle.
"src/plugin-entry.runtime.js!",
// The monitor lazy-loads outbound behavior on inbound-only processes.
"src/matrix/send.ts!",
]),
@@ -1,3 +1,4 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime";
// Matrix tests cover approval reactions plugin behavior.
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
@@ -8,7 +9,6 @@ import {
resolveMatrixApprovalReactionTargetWithPersistence as resolveMatrixApprovalReactionTargetWithPersistenceRaw,
unregisterMatrixApprovalReactionTarget as unregisterMatrixApprovalReactionTargetRaw,
} from "./approval-reactions.js";
import type { PluginRuntime } from "./runtime-api.js";
import { setMatrixRuntime } from "./runtime.js";
const { clearRuntime: clearMatrixRuntime } = createPluginRuntimeStore<PluginRuntime>({
+1 -1
View File
@@ -2,12 +2,12 @@ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { parseStrictInteger } from "openclaw/plugin-sdk/number-runtime";
import { readByteStreamWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
import { formatZonedTimestamp } from "openclaw/plugin-sdk/time-runtime";
import { resolveMatrixRoomKeyBackupIssue } from "./matrix/backup-health.js";
import { resolveMatrixAuthContext } from "./matrix/client.js";
import { setMatrixSdkConsoleLogging, setMatrixSdkLogMode } from "./matrix/client/logging.js";
import type { MatrixOwnDeviceVerificationStatus, MatrixRoomKeyBackupStatus } from "./matrix/sdk.js";
import type { MatrixVerificationSummary } from "./matrix/sdk/verification-manager.js";
import { formatZonedTimestamp } from "./runtime-api.js";
import { getMatrixRuntime } from "./runtime.js";
import type { CoreConfig } from "./types.js";
+1 -1
View File
@@ -1,8 +1,8 @@
// Matrix tests cover cli plugin behavior.
import { Command } from "commander";
import { formatZonedTimestamp } from "openclaw/plugin-sdk/time-runtime";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { registerMatrixCli } from "./cli.js";
import { formatZonedTimestamp } from "./runtime-api.js";
import type { CoreConfig } from "./types.js";
const bootstrapMatrixVerificationMock = vi.fn();
+2 -1
View File
@@ -24,11 +24,13 @@ import {
resolveInboundMentionDecision,
} from "openclaw/plugin-sdk/channel-mention-gating";
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime";
import {
chunkMarkdownTextWithMode,
resolveChunkMode,
resolveTextChunkLimit,
} from "openclaw/plugin-sdk/reply-chunking";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
import { beforeAll, describe, it, vi } from "vitest";
import {
@@ -36,7 +38,6 @@ import {
createMatrixTextMessageEvent,
} from "./matrix/monitor/handler.test-helpers.js";
import type { MatrixClient } from "./matrix/sdk.js";
import type { PluginRuntime, ReplyPayload } from "./runtime-api.js";
import { installMatrixTestRuntime } from "./test-runtime.js";
const ROOM_ID = "!room:example.org";
+1 -1
View File
@@ -1,3 +1,4 @@
import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/channel-contract";
// Matrix plugin module implements directory live behavior.
import {
normalizeLowercaseStringOrEmpty,
@@ -6,7 +7,6 @@ import {
import { resolveMatrixAuth } from "./matrix/client.js";
import { MatrixAuthedHttpClient } from "./matrix/sdk/http-client.js";
import { isMatrixQualifiedUserId, normalizeMatrixMessagingTarget } from "./matrix/target-ids.js";
import type { ChannelDirectoryEntry } from "./runtime-api.js";
type MatrixUserResult = {
user_id?: string;
+1 -1
View File
@@ -1,3 +1,4 @@
import type { ChannelGroupContext } from "openclaw/plugin-sdk/channel-contract";
// Matrix plugin module implements group mentions behavior.
import {
resolveScopeRequireMention,
@@ -7,7 +8,6 @@ import {
import { resolveMatrixAccountConfig } from "./matrix/accounts.js";
import { buildMatrixRoomScopeTree, resolveMatrixRoomScopePath } from "./matrix/monitor/rooms.js";
import { normalizeMatrixResolvableTarget } from "./matrix/target-ids.js";
import type { ChannelGroupContext } from "./runtime-api.js";
import type { CoreConfig } from "./types.js";
function resolveMatrixGroupScope(params: ChannelGroupContext) {
@@ -23,7 +23,7 @@ function installMatrixActionTestRuntime(): void {
convertMarkdownTables: (text: string) => text,
},
},
} as unknown as import("../../runtime-api.js").PluginRuntime);
} as unknown as import("openclaw/plugin-sdk/plugin-runtime").PluginRuntime);
}
function createPollResponseEvent(): Record<string, unknown> {
@@ -1,10 +0,0 @@
// Matrix API module exposes the plugin public contract.
export {
DEFAULT_ACCOUNT_ID,
normalizeAccountId,
normalizeOptionalAccountId,
} from "openclaw/plugin-sdk/account-id";
export {
isPrivateNetworkOptInEnabled,
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
} from "openclaw/plugin-sdk/ssrf-runtime";
@@ -1,7 +1,7 @@
import type { LookupFn } from "openclaw/plugin-sdk/ssrf-runtime";
// Matrix tests cover config plugin behavior.
import { beforeEach, describe, expect, it, vi } from "vitest";
import { getMatrixScopedEnvVarNames } from "../../env-vars.js";
import type { LookupFn } from "../../runtime-api.js";
import { installMatrixTestRuntime } from "../../test-runtime.js";
import type { CoreConfig } from "../../types.js";
import {
@@ -1,4 +1,9 @@
// Matrix helper module supports config behavior.
import {
DEFAULT_ACCOUNT_ID,
normalizeAccountId,
normalizeOptionalAccountId,
} from "openclaw/plugin-sdk/account-id";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
@@ -10,6 +15,10 @@ import {
normalizeResolvedSecretInputString,
} from "openclaw/plugin-sdk/secret-input-runtime";
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import {
isPrivateNetworkOptInEnabled,
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
} from "openclaw/plugin-sdk/ssrf-runtime";
import {
requiresExplicitMatrixDefaultAccount,
resolveMatrixDefaultOrOnlyAccountId,
@@ -27,13 +36,6 @@ import {
} from "../account-config.js";
import { resolveMatrixConfigFieldPath } from "../config-paths.js";
import type { MatrixStoredCredentials } from "../credentials-state.js";
import {
DEFAULT_ACCOUNT_ID,
isPrivateNetworkOptInEnabled,
normalizeAccountId,
normalizeOptionalAccountId,
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
} from "./config-runtime-api.js";
import { resolveGlobalMatrixEnvConfig, resolveScopedMatrixEnvConfig } from "./env-auth.js";
import { repairCurrentTokenStorageMetaDeviceId } from "./storage.js";
import type { MatrixAuth, MatrixResolvedConfig } from "./types.js";
+1 -1
View File
@@ -1,6 +1,6 @@
// Matrix type declarations define plugin contracts.
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import type { SsrFPolicy } from "../../runtime-api.js";
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
export type MatrixResolvedConfig = {
homeserver: string;
@@ -1,6 +1,6 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime";
// Matrix tests cover draft stream plugin behavior.
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { PluginRuntime } from "../runtime-api.js";
const sendModuleMocks = vi.hoisted(() => {
const loadConfigMock = vi.fn(() => ({}));
@@ -1,6 +1,6 @@
import type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";
// Matrix plugin module implements events behavior.
import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
import type { PluginRuntime, RuntimeLogger } from "../../runtime-api.js";
import type { CoreConfig } from "../../types.js";
import type { MatrixAuth } from "../client.js";
import { formatMatrixEncryptedEventDisabledWarning } from "../encryption-guidance.js";
@@ -3,10 +3,10 @@ import {
runChannelInboundEvent,
type ChannelInboundEventRunnerParams,
} from "openclaw/plugin-sdk/channel-inbound";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import type { FinalizedMsgContext, GetReplyOptions } from "openclaw/plugin-sdk/reply-runtime";
import { useAutoCleanupTempDirTracker } from "openclaw/plugin-sdk/test-env";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../runtime-api.js";
import { installMatrixMonitorTestRuntime } from "../../test-runtime.js";
import type { MatrixMonitorHandlerParams } from "./handler-types.js";
import {
@@ -3,9 +3,10 @@ import {
buildChannelInboundEventContext,
type PreparedInboundReply,
} from "openclaw/plugin-sdk/channel-inbound";
import type { RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";
import { finalizeInboundContext as finalizeCoreInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
import { vi, type Mock } from "vitest";
import type { RuntimeEnv, RuntimeLogger } from "../../runtime-api.js";
import type {
MatrixConfig,
MatrixRoomConfig,
@@ -1,5 +1,4 @@
import { vi } from "vitest";
import { z } from "zod";
import type { MatrixRoomInfo } from "./room-info.js";
export type DirectRoomTrackerOptions = {
@@ -223,73 +222,20 @@ vi.mock("openclaw/plugin-sdk/channel-runtime-context", () => ({
registerChannelRuntimeContext: hoisted.registerChannelRuntimeContext,
}));
vi.mock("../../runtime-api.js", () => {
const normalizeAccountId = (value: string | null | undefined) => value?.trim() || "default";
return {
DEFAULT_ACCOUNT_ID: "default",
GROUP_POLICY_BLOCKED_LABEL: {
room: "room",
},
MarkdownConfigSchema: z.any().optional(),
PAIRING_APPROVED_MESSAGE: "paired",
ToolPolicySchema: z.any().optional(),
addAllowlistUserEntriesFromConfigEntry: vi.fn(),
buildChannelConfigSchema: (schema: unknown) => schema,
buildChannelKeyCandidates: (...keys: Array<string | undefined | null>) => {
const seen = new Set<string>();
return keys
.map((key) => (typeof key === "string" ? key.trim() : ""))
.filter((key) => {
if (!key || seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
},
buildProbeChannelStatusSummary: (
snapshot: Record<string, unknown>,
extra?: Record<string, unknown>,
) => ({
...snapshot,
...extra,
}),
buildSecretInputSchema: () => z.string(),
chunkTextForOutbound: vi.fn((text: string) => [text]),
collectStatusIssuesFromLastError: () => [],
createActionGate: () => () => true,
createReplyPrefixOptions: () => ({}),
createTypingCallbacks: () => ({}),
formatDocsLink: (input: string) => input,
formatZonedTimestamp: () => "2026-03-27T00:00:00.000Z",
getAgentScopedMediaLocalRoots: () => [],
getSessionBindingService: () => ({}),
hasConfiguredSecretInput: (value: unknown) => Boolean(value),
mergeAllowlist: ({ existing, additions }: { existing: string[]; additions: string[] }) => [
...existing,
...additions,
],
normalizeAccountId,
normalizeOptionalAccountId: normalizeAccountId,
resolveThreadBindingIdleTimeoutMsForChannel: () => 24 * 60 * 60 * 1000,
resolveThreadBindingMaxAgeMsForChannel: () => 0,
resolveAllowlistProviderRuntimeGroupPolicy: () => ({
groupPolicy: "allowlist",
providerMissingFallbackApplied: false,
}),
resolveDefaultGroupPolicy: () => "allowlist",
resolveOutboundSendDep: () => null,
resolveThreadBindingFarewellText: () => null,
resolveAckReaction: () => null,
readJsonFileWithFallback: vi.fn(),
readNumberParam: vi.fn(),
readReactionParams: vi.fn(),
readStringArrayParam: vi.fn(),
readStringParam: vi.fn(),
summarizeMapping: vi.fn(),
warnMissingProviderGroupPolicyFallbackOnce: vi.fn(),
};
});
vi.mock("openclaw/plugin-sdk/runtime-group-policy", () => ({
GROUP_POLICY_BLOCKED_LABEL: { room: "room" },
resolveAllowlistProviderRuntimeGroupPolicy: () => ({
groupPolicy: "allowlist",
providerMissingFallbackApplied: false,
}),
resolveDefaultGroupPolicy: () => "allowlist",
warnMissingProviderGroupPolicyFallbackOnce: vi.fn(),
}));
vi.mock("openclaw/plugin-sdk/thread-bindings-runtime", () => ({
resolveThreadBindingIdleTimeoutMsForChannel: () => 24 * 60 * 60 * 1000,
resolveThreadBindingMaxAgeMsForChannel: () => 0,
}));
vi.mock("../../resolve-targets.js", () => ({
resolveMatrixTargets: vi.fn(async () => []),
@@ -8,15 +8,17 @@ import {
} from "openclaw/plugin-sdk/channel-outbound";
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
import { resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
import {
GROUP_POLICY_BLOCKED_LABEL,
resolveThreadBindingIdleTimeoutMsForChannel,
resolveThreadBindingMaxAgeMsForChannel,
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
warnMissingProviderGroupPolicyFallbackOnce,
type RuntimeEnv,
} from "../../runtime-api.js";
} from "openclaw/plugin-sdk/runtime-group-policy";
import {
resolveThreadBindingIdleTimeoutMsForChannel,
resolveThreadBindingMaxAgeMsForChannel,
} from "openclaw/plugin-sdk/thread-bindings-runtime";
import { getMatrixRuntime } from "../../runtime.js";
import type {
CoreConfig,
@@ -2,13 +2,13 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime";
import type { OpenKeyedStoreOptions } from "openclaw/plugin-sdk/plugin-state-runtime";
import {
createPluginStateKeyedStoreForTests,
resetPluginStateStoreForTests,
} from "openclaw/plugin-sdk/plugin-state-test-runtime";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { PluginRuntime } from "../../runtime-api.js";
import { setMatrixRuntime } from "../../runtime.js";
import { ensureMatrixStartupVerification } from "./startup-verification.js";
@@ -1,6 +1,6 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements startup behavior.
import type { RuntimeLogger } from "../../runtime-api.js";
import type { RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";
import type { CoreConfig, MatrixConfig } from "../../types.js";
import type { MatrixAuth } from "../client.js";
import type { MatrixClient } from "../sdk.js";
@@ -1,5 +1,5 @@
// Matrix plugin module implements task runner behavior.
import type { RuntimeLogger } from "../../runtime-api.js";
import type { RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";
export function createMatrixMonitorTaskRunner(params: {
logger: RuntimeLogger;
+2 -1
View File
@@ -1,10 +1,11 @@
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-contract";
// Matrix plugin module implements probe behavior.
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { runChannelProbe } from "openclaw/plugin-sdk/text-utility-runtime";
import type { SsrFPolicy, BaseProbeResult } from "../runtime-api.js";
import { isBunRuntime } from "./client/runtime.js";
const loadMatrixProbeRuntimeDeps = createLazyRuntimeModule(() =>
+2 -2
View File
@@ -1,10 +1,10 @@
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import { ToolAuthorizationError } from "openclaw/plugin-sdk/channel-actions";
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-contract";
import {
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
ToolAuthorizationError,
} from "../runtime-api.js";
} from "openclaw/plugin-sdk/runtime-group-policy";
import type { CoreConfig } from "../types.js";
import { resolveMatrixBaseConfig } from "./account-config.js";
import { resolveMatrixAccount } from "./accounts.js";
@@ -10,7 +10,7 @@ import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import type { SsrFPolicy } from "../../runtime-api.js";
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
import { SqliteBackedMatrixSyncStore } from "../client/file-sync-store.js";
import { createMatrixJsSdkClientLogger } from "../client/logging.js";
import { createMatrixStartupAbortError, throwIfMatrixStartupAborted } from "../startup-abort.js";
@@ -1,6 +1,6 @@
// Matrix plugin module implements http client behavior.
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import type { SsrFPolicy } from "../../runtime-api.js";
import type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
import { buildHttpError } from "./event-helpers.js";
import { type HttpMethod, type QueryParams, performMatrixRequest } from "./transport.js";
+1 -1
View File
@@ -4,7 +4,7 @@ import {
type MessageReceiptPartKind,
} from "openclaw/plugin-sdk/channel-outbound";
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
import type { PollInput } from "../runtime-api.js";
import type { PollInput } from "openclaw/plugin-sdk/poll-runtime";
import type { CoreConfig } from "../types.js";
import {
createMatrixPlannedEvents,
+2 -1
View File
@@ -1,5 +1,6 @@
// Matrix setup module handles plugin onboarding behavior.
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
import {
type ChannelSetupWizardAdapter,
formatDocsLink,
@@ -9,6 +10,7 @@ import {
promptAccountId,
promptChannelAccessConfig,
splitSetupEntries,
type WizardPrompter,
} from "openclaw/plugin-sdk/setup";
import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-policy";
import {
@@ -33,7 +35,6 @@ import {
import { updateMatrixAccountConfig } from "./matrix/config-update.js";
import { ensureMatrixSdkInstalled, isMatrixSdkAvailable } from "./matrix/deps.js";
import { isMatrixRoomId } from "./matrix/target-ids.js";
import type { RuntimeEnv, WizardPrompter } from "./runtime-api.js";
import { moveSingleMatrixAccountConfigToNamedAccount } from "./setup-config.js";
import { createMatrixSetupDmPolicy } from "./setup-dm-policy.js";
import type { CoreConfig, MatrixConfig } from "./types.js";
+3 -5
View File
@@ -1,7 +1,9 @@
import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/channel-contract";
// Matrix plugin module implements outbound behavior.
import {
createMessageReceiptFromOutboundResults,
createReplyToFanout,
resolveOutboundSendDep,
} from "openclaw/plugin-sdk/channel-outbound";
import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
import {
@@ -14,13 +16,9 @@ import {
} from "openclaw/plugin-sdk/reply-payload";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
import { sendMessageMatrix, sendPollMatrix } from "./matrix/send.js";
import type { MatrixExtraContentFields } from "./matrix/send/types.js";
import {
chunkTextForOutbound,
resolveOutboundSendDep,
type ChannelOutboundAdapter,
} from "./runtime-api.js";
const MATRIX_OPENCLAW_PRESENTATION_KEY = "com.openclaw.presentation" as const;
const MATRIX_OPENCLAW_PRESENTATION_TYPE = "message.presentation" as const;
@@ -1,115 +0,0 @@
// Thin ESM wrapper so native dynamic import() resolves in source-checkout mode
// while packaged dist builds resolve a distinct runtime entry that cannot loop
// back into this wrapper through the stable root runtime alias.
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
const PLUGIN_ID = "matrix";
const PLUGIN_ENTRY_RUNTIME_BASENAME = "plugin-entry.handlers.runtime";
const NATIVE_RUNTIME_EXTENSIONS = [".js", ".mjs", ".cjs"];
function readPackageJson(packageRoot) {
try {
return JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
} catch {
return null;
}
}
function lowercaseStringOrEmptyWithoutTrim(value) {
return typeof value === "string" ? value.toLowerCase() : "";
}
function hasTrustedOpenClawRootIndicator(packageRoot, packageJson) {
const packageExports = packageJson?.exports ?? {};
if (!Object.hasOwn(packageExports, "./plugin-sdk/core")) {
return false;
}
const hasCliEntryExport = Object.hasOwn(packageExports, "./cli-entry");
const hasOpenClawBin =
(typeof packageJson?.bin === "string" &&
lowercaseStringOrEmptyWithoutTrim(packageJson.bin).includes("openclaw")) ||
(typeof packageJson?.bin === "object" &&
packageJson.bin !== null &&
typeof packageJson.bin.openclaw === "string");
const hasOpenClawEntrypoint = fs.existsSync(path.join(packageRoot, "openclaw.mjs"));
return hasCliEntryExport || hasOpenClawBin || hasOpenClawEntrypoint;
}
function findOpenClawPackageRoot(startDir) {
let cursor = path.resolve(startDir);
for (let i = 0; i < 12; i += 1) {
const pkg = readPackageJson(cursor);
if (pkg?.name === "openclaw" && hasTrustedOpenClawRootIndicator(cursor, pkg)) {
return { packageRoot: cursor, packageJson: pkg };
}
const parent = path.dirname(cursor);
if (parent === cursor) {
break;
}
cursor = parent;
}
return null;
}
function resolveExistingFile(basePath, extensions) {
for (const ext of extensions) {
const candidate = `${basePath}${ext}`;
if (fs.existsSync(candidate)) {
return candidate;
}
}
return null;
}
function resolveBundledPluginRuntimeModulePath(moduleUrl, params) {
const modulePath = fileURLToPath(moduleUrl);
const moduleDir = path.dirname(modulePath);
const localCandidates = [
path.join(moduleDir, "..", params.runtimeBasename),
path.join(moduleDir, "extensions", params.pluginId, params.runtimeBasename),
];
for (const candidate of localCandidates) {
const resolved = resolveExistingFile(candidate, NATIVE_RUNTIME_EXTENSIONS);
if (resolved) {
return resolved;
}
}
const location = findOpenClawPackageRoot(moduleDir);
if (location) {
const { packageRoot } = location;
const packageCandidates = [
path.join(packageRoot, "extensions", params.pluginId, params.runtimeBasename),
path.join(packageRoot, "dist", "extensions", params.pluginId, params.runtimeBasename),
];
for (const candidate of packageCandidates) {
const resolved = resolveExistingFile(candidate, NATIVE_RUNTIME_EXTENSIONS);
if (resolved) {
return resolved;
}
}
}
throw new Error(
`Cannot resolve ${params.pluginId} plugin runtime module ${params.runtimeBasename} from ${modulePath}`,
);
}
async function loadRuntimeModule(modulePath) {
return import(pathToFileURL(modulePath).href);
}
const mod = await loadRuntimeModule(
resolveBundledPluginRuntimeModulePath(import.meta.url, {
pluginId: PLUGIN_ID,
runtimeBasename: PLUGIN_ENTRY_RUNTIME_BASENAME,
}),
);
export const ensureMatrixCryptoRuntime = mod.ensureMatrixCryptoRuntime;
export const handleVerifyRecoveryKey = mod.handleVerifyRecoveryKey;
export const handleVerificationBootstrap = mod.handleVerificationBootstrap;
export const handleVerificationStatus = mod.handleVerificationStatus;
@@ -1,135 +0,0 @@
// Matrix tests cover plugin entry plugin behavior.
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { afterEach, expect, it } from "vitest";
const tempDirs: string[] = [];
const REPO_ROOT = process.cwd();
const MATRIX_RUNTIME_WRAPPER_SOURCE = fs.readFileSync(
path.join(REPO_ROOT, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
"utf8",
);
const PACKAGED_RUNTIME_STUB = [
"export async function ensureMatrixCryptoRuntime() {}",
"export async function handleVerifyRecoveryKey() {}",
"export async function handleVerificationBootstrap() {}",
"export async function handleVerificationStatus() {}",
"",
].join("\n");
function makeFixtureRoot(prefix: string) {
const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
tempDirs.push(fixtureRoot);
return fixtureRoot;
}
function writeFixtureFile(fixtureRoot: string, relativePath: string, value: string) {
const fullPath = path.join(fixtureRoot, relativePath);
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
fs.writeFileSync(fullPath, value, "utf8");
}
function writeOpenClawPackageFixture(fixtureRoot: string) {
writeFixtureFile(
fixtureRoot,
"package.json",
JSON.stringify(
{
name: "openclaw",
type: "module",
exports: {
"./plugin-sdk/core": "./dist/plugin-sdk/core.js",
},
},
null,
2,
) + "\n",
);
writeFixtureFile(fixtureRoot, "openclaw.mjs", "export {};\n");
writeFixtureFile(fixtureRoot, "dist/plugin-sdk/core.js", "export {};\n");
}
function writeSourceRuntimeWrapperFixture(
fixtureRoot: string,
options: { runtimeExtension?: ".js" | ".ts" } = {},
) {
const runtimeExtension = options.runtimeExtension ?? ".js";
writeFixtureFile(
fixtureRoot,
"extensions/matrix/src/plugin-entry.runtime.js",
MATRIX_RUNTIME_WRAPPER_SOURCE,
);
writeFixtureFile(
fixtureRoot,
`extensions/matrix/plugin-entry.handlers.runtime${runtimeExtension}`,
PACKAGED_RUNTIME_STUB,
);
}
function importFixtureModule(fixtureRoot: string, relativePath: string) {
const wrapperUrl = pathToFileURL(path.join(fixtureRoot, relativePath));
return import(`${wrapperUrl.href}?t=${Date.now()}`);
}
function expectRuntimeWrapperExports(mod: unknown) {
const exports = mod as Record<string, unknown>;
expect(exports.ensureMatrixCryptoRuntime).toBeTypeOf("function");
expect(exports.handleVerifyRecoveryKey).toBeTypeOf("function");
expect(exports.handleVerificationBootstrap).toBeTypeOf("function");
expect(exports.handleVerificationStatus).toBeTypeOf("function");
}
afterEach(() => {
for (const dir of tempDirs.splice(0)) {
fs.rmSync(dir, { recursive: true, force: true });
}
});
it("loads the source-checkout runtime wrapper through native ESM import", async () => {
const fixtureRoot = makeFixtureRoot(".tmp-matrix-source-runtime-");
writeOpenClawPackageFixture(fixtureRoot);
writeSourceRuntimeWrapperFixture(fixtureRoot);
expectRuntimeWrapperExports(
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js"),
);
}, 240_000);
it("loads the packaged runtime wrapper without recursing through the stable root alias", async () => {
const fixtureRoot = makeFixtureRoot(".tmp-matrix-runtime-");
writeOpenClawPackageFixture(fixtureRoot);
writeFixtureFile(
fixtureRoot,
"dist/plugin-entry.runtime-C88YIa_v.js",
MATRIX_RUNTIME_WRAPPER_SOURCE,
);
writeFixtureFile(
fixtureRoot,
"dist/plugin-entry.runtime.js",
'export * from "./plugin-entry.runtime-C88YIa_v.js";\n',
);
writeFixtureFile(
fixtureRoot,
"dist/extensions/matrix/plugin-entry.handlers.runtime.js",
PACKAGED_RUNTIME_STUB,
);
expectRuntimeWrapperExports(
await importFixtureModule(fixtureRoot, "dist/plugin-entry.runtime-C88YIa_v.js"),
);
}, 240_000);
it("does not load when only a TypeScript Matrix runtime shim exists", async () => {
const fixtureRoot = makeFixtureRoot(".tmp-matrix-runtime-ts-only-");
writeOpenClawPackageFixture(fixtureRoot);
writeSourceRuntimeWrapperFixture(fixtureRoot, { runtimeExtension: ".ts" });
await expect(
importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js"),
).rejects.toThrow("Cannot resolve matrix plugin runtime module plugin-entry.handlers.runtime");
}, 240_000);
+6 -6
View File
@@ -1,13 +1,13 @@
// Matrix plugin module implements resolve targets behavior.
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js";
import { isMatrixQualifiedUserId, normalizeMatrixMessagingTarget } from "./matrix/target-ids.js";
import type {
ChannelDirectoryEntry,
ChannelResolveKind,
ChannelResolveResult,
RuntimeEnv,
} from "./runtime-api.js";
} from "openclaw/plugin-sdk/channel-contract";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
// Matrix plugin module implements resolve targets behavior.
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js";
import { isMatrixQualifiedUserId, normalizeMatrixMessagingTarget } from "./matrix/target-ids.js";
function normalizeLookupQuery(query: string): string {
return normalizeOptionalLowercaseString(query) ?? "";
-107
View File
@@ -1,107 +0,0 @@
// Matrix API module exposes the plugin public contract.
export {
DEFAULT_ACCOUNT_ID,
normalizeAccountId,
normalizeOptionalAccountId,
} from "openclaw/plugin-sdk/account-id";
export {
createActionGate,
jsonResult,
readNumberParam,
readPositiveIntegerParam,
readReactionParams,
readStringArrayParam,
readStringParam,
ToolAuthorizationError,
} from "openclaw/plugin-sdk/channel-actions";
export { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
export type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core";
export type {
BaseProbeResult,
ChannelDirectoryEntry,
ChannelGroupContext,
ChannelMessageActionAdapter,
ChannelMessageActionContext,
ChannelMessageActionName,
ChannelMessageToolDiscovery,
ChannelOutboundAdapter,
ChannelResolveKind,
ChannelResolveResult,
ChannelToolSend,
} from "openclaw/plugin-sdk/channel-contract";
export {
formatLocationText,
toLocationContext,
type NormalizedLocation,
} from "openclaw/plugin-sdk/channel-inbound";
export { logInboundDrop } from "openclaw/plugin-sdk/channel-inbound";
export { logTypingFailure } from "openclaw/plugin-sdk/channel-outbound";
export { resolveAckReaction } from "openclaw/plugin-sdk/channel-feedback";
export type { ChannelSetupInput } from "openclaw/plugin-sdk/setup";
export type {
OpenClawConfig,
ContextVisibilityMode,
DmPolicy,
GroupPolicy,
} from "openclaw/plugin-sdk/config-contracts";
export type { GroupToolPolicyConfig } from "openclaw/plugin-sdk/config-contracts";
export type { WizardPrompter } from "openclaw/plugin-sdk/setup";
export type { SecretInput } from "openclaw/plugin-sdk/secret-input";
export {
GROUP_POLICY_BLOCKED_LABEL,
resolveAllowlistProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
warnMissingProviderGroupPolicyFallbackOnce,
} from "openclaw/plugin-sdk/runtime-group-policy";
export {
addWildcardAllowFrom,
formatDocsLink,
hasConfiguredSecretInput,
mergeAllowFromEntries,
moveSingleAccountChannelSectionToDefaultAccount,
promptAccountId,
promptChannelAccessConfig,
splitSetupEntries,
} from "openclaw/plugin-sdk/setup";
export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
export {
assertHttpUrlTargetsPrivateNetwork,
closeDispatcher,
createPinnedDispatcher,
isPrivateOrLoopbackHost,
resolvePinnedHostnameWithPolicy,
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
type LookupFn,
type SsrFPolicy,
} from "openclaw/plugin-sdk/ssrf-runtime";
export {
ensureConfiguredAcpBindingReady,
resolveConfiguredAcpBindingRecord,
} from "openclaw/plugin-sdk/acp-binding-runtime";
export {
buildProbeChannelStatusSummary,
collectStatusIssuesFromLastError,
PAIRING_APPROVED_MESSAGE,
} from "openclaw/plugin-sdk/channel-status";
export {
getSessionBindingService,
resolveThreadBindingIdleTimeoutMsForChannel,
resolveThreadBindingMaxAgeMsForChannel,
} from "openclaw/plugin-sdk/conversation-runtime";
export { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
export { resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
export { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
export { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-outbound";
export { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
export { normalizePollInput, type PollInput } from "openclaw/plugin-sdk/poll-runtime";
export { writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";
export {
buildChannelKeyCandidates,
resolveChannelEntryMatch,
} from "openclaw/plugin-sdk/channel-targets";
export { buildTimeoutAbortSignal } from "./matrix/sdk/timeout-abort-signal.js";
export { formatZonedTimestamp } from "openclaw/plugin-sdk/time-runtime";
export type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";
export type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
// resolveMatrixAccountStringValues already comes from the Matrix API barrel.
// Re-exporting auth-precedence here makes TS source loaders define the export twice.
+1 -1
View File
@@ -1,6 +1,6 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime";
// Matrix plugin module implements runtime behavior.
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
import type { PluginRuntime } from "./runtime-api.js";
const {
setRuntime: setMatrixRuntime,
+1 -1
View File
@@ -2,13 +2,13 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import {
normalizeSessionDeliveryState,
upsertSessionEntry,
} from "openclaw/plugin-sdk/session-store-runtime";
import type { SessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
import { afterEach, describe, expect, it } from "vitest";
import type { OpenClawConfig } from "./runtime-api.js";
import { resolveMatrixOutboundSessionRoute } from "./session-route.js";
const tempDirs = new Set<string>();
+1 -1
View File
@@ -1,9 +1,9 @@
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
// Matrix plugin module implements setup bootstrap behavior.
import { hasExplicitMatrixAccountConfig } from "./matrix/account-config.js";
import { resolveMatrixAccountConfig } from "./matrix/accounts.js";
import { bootstrapMatrixVerification } from "./matrix/actions/verification.js";
import type { RuntimeEnv } from "./runtime-api.js";
import type { CoreConfig } from "./types.js";
type MatrixSetupVerificationBootstrapResult = {
+1 -1
View File
@@ -5,6 +5,7 @@ import {
implicitMentionKindWhen,
resolveInboundMentionDecision,
} from "openclaw/plugin-sdk/channel-mention-gating";
import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime";
import type {
OpenBlobStoreOptions,
OpenKeyedStoreOptions,
@@ -17,7 +18,6 @@ import {
} from "openclaw/plugin-sdk/plugin-state-test-runtime";
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
import { afterAll, vi } from "vitest";
import type { PluginRuntime } from "./runtime-api.js";
import { setMatrixRuntime } from "./runtime.js";
const defaultStateDir = fs.realpathSync(
+8 -8
View File
@@ -1,5 +1,13 @@
// Matrix plugin module implements tool actions behavior.
import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core";
import {
createActionGate,
jsonResult,
readPositiveIntegerParam,
readReactionParams,
readStringArrayParam,
readStringParam,
} from "openclaw/plugin-sdk/channel-actions";
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { resolveMatrixAccountConfig } from "./matrix/accounts.js";
import {
@@ -39,14 +47,6 @@ import { withAuthorizedMatrixReadTarget, type MatrixReadContext } from "./matrix
import type { MatrixClient } from "./matrix/sdk.js";
import { reactMatrixMessage } from "./matrix/send.js";
import { applyMatrixProfileUpdate } from "./profile-update.js";
import {
createActionGate,
jsonResult,
readPositiveIntegerParam,
readReactionParams,
readStringArrayParam,
readStringParam,
} from "./runtime-api.js";
import type { CoreConfig } from "./types.js";
const messageActions = new Set(["sendMessage", "editMessage", "deleteMessage", "readMessages"]);
+3 -5
View File
@@ -1,15 +1,13 @@
// Matrix type declarations define plugin contracts.
import type {
ChannelBotLoopProtectionConfig,
MentionPatternsPolicyConfig,
} from "openclaw/plugin-sdk/config-contracts";
import type {
ContextVisibilityMode,
DmPolicy,
GroupPolicy,
MentionPatternsPolicyConfig,
OpenClawConfig,
SecretInput,
} from "./runtime-api.js";
} from "openclaw/plugin-sdk/config-contracts";
import type { SecretInput } from "openclaw/plugin-sdk/secret-input";
export type ReplyToMode = "off" | "first" | "all" | "batched";
@@ -1103,10 +1103,7 @@ describe("bundled channel entry shape guards", () => {
});
it("keeps bundled hot runtime barrels off the broad core SDK surface", () => {
const offenders = [
"extensions/googlechat/runtime-api.ts",
"extensions/matrix/src/runtime-api.ts",
].filter((filePath) =>
const offenders = ["extensions/googlechat/runtime-api.ts"].filter((filePath) =>
fs.readFileSync(path.resolve(filePath), "utf8").includes("openclaw/plugin-sdk/core"),
);
@@ -241,9 +241,6 @@ describe("check-deadcode-exports", () => {
]),
);
expect(knipConfig.workspaces["extensions/diffs"].entry).toContain("src/viewer-client.ts!");
expect(knipConfig.workspaces["extensions/matrix"].entry).toContain(
"src/plugin-entry.runtime.js!",
);
expect(knipConfig.workspaces["extensions/mxc"].entry).toContain("src/mxc-spawn-launcher.mjs!");
expect(knipConfig.workspaces["extensions/qa-lab"].entry).toContain("src/ci-smoke-plan.ts!");
});