diff --git a/extensions/slack/src/channel.test.ts b/extensions/slack/src/channel.test.ts index bf6aaecd81a..b05c2db6772 100644 --- a/extensions/slack/src/channel.test.ts +++ b/extensions/slack/src/channel.test.ts @@ -3,8 +3,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { createRuntimeEnv } from "../../../test/helpers/extensions/runtime-env.js"; import { slackPlugin } from "./channel.js"; import { slackOutbound } from "./outbound-adapter.js"; +import * as probeModule from "./probe.js"; import type { OpenClawConfig } from "./runtime-api.js"; -import { setSlackRuntime } from "./runtime.js"; +import { clearSlackRuntime, setSlackRuntime } from "./runtime.js"; const handleSlackActionMock = vi.fn(); @@ -144,6 +145,41 @@ describe("slackPlugin actions", () => { }); }); +describe("slackPlugin status", () => { + it("uses the direct Slack probe helper when runtime is not initialized", async () => { + const probeSpy = vi.spyOn(probeModule, "probeSlack").mockResolvedValueOnce({ + ok: true, + status: 200, + bot: { id: "B1", name: "openclaw-bot" }, + team: { id: "T1", name: "OpenClaw" }, + }); + clearSlackRuntime(); + const cfg = { + channels: { + slack: { + botToken: "xoxb-test", + appToken: "xapp-test", + }, + }, + } as OpenClawConfig; + const account = slackPlugin.config.resolveAccount(cfg, "default"); + + const result = await slackPlugin.status!.probeAccount!({ + account, + timeoutMs: 2500, + cfg, + }); + + expect(probeSpy).toHaveBeenCalledWith("xoxb-test", 2500); + expect(result).toEqual({ + ok: true, + status: 200, + bot: { id: "B1", name: "openclaw-bot" }, + team: { id: "T1", name: "OpenClaw" }, + }); + }); +}); + describe("slackPlugin security", () => { it("normalizes dm allowlist entries with trimmed prefixes", () => { const resolveDmPolicy = slackPlugin.security?.resolveDmPolicy; diff --git a/extensions/slack/src/channel.ts b/extensions/slack/src/channel.ts index ca62cb5e91e..58d6f459557 100644 --- a/extensions/slack/src/channel.ts +++ b/extensions/slack/src/channel.ts @@ -49,7 +49,7 @@ import { resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy } from "./ import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js"; import { SLACK_TEXT_LIMIT } from "./limits.js"; import { slackOutbound } from "./outbound-adapter.js"; -import type { SlackProbe } from "./probe.js"; +import { probeSlack, type SlackProbe } from "./probe.js"; import { resolveSlackUserAllowlist } from "./resolve-users.js"; import { DEFAULT_ACCOUNT_ID, @@ -86,6 +86,17 @@ const resolveSlackDmPolicy = createScopedDmSecurityResolver = crea if (!token) { return { ok: false, error: "missing token" }; } - return await getSlackRuntime().channel.slack.probeSlack(token, timeoutMs); + return await resolveSlackProbe()(token, timeoutMs); }, formatCapabilitiesProbe: ({ probe }) => { const slackProbe = probe as SlackProbe | undefined; diff --git a/extensions/slack/src/runtime.ts b/extensions/slack/src/runtime.ts index 2121ee9f902..7b623eaafb5 100644 --- a/extensions/slack/src/runtime.ts +++ b/extensions/slack/src/runtime.ts @@ -1,6 +1,9 @@ import type { PluginRuntime } from "openclaw/plugin-sdk/core"; import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; -const { setRuntime: setSlackRuntime, getRuntime: getSlackRuntime } = - createPluginRuntimeStore("Slack runtime not initialized"); -export { getSlackRuntime, setSlackRuntime }; +const { + setRuntime: setSlackRuntime, + clearRuntime: clearSlackRuntime, + getRuntime: getSlackRuntime, +} = createPluginRuntimeStore("Slack runtime not initialized"); +export { clearSlackRuntime, getSlackRuntime, setSlackRuntime };