diff --git a/src/channels/config-presence.test.ts b/src/channels/config-presence.test.ts index acfac5380c33..beff93d31563 100644 --- a/src/channels/config-presence.test.ts +++ b/src/channels/config-presence.test.ts @@ -6,7 +6,6 @@ import { afterEach, describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { hasMeaningfulChannelConfig, - hasPotentialConfiguredChannels, listExplicitlyDisabledChannelIdsForConfig, listPotentialConfiguredChannelPresenceSignals, listPotentialConfiguredChannelIds, @@ -33,16 +32,12 @@ function expectPotentialConfiguredChannelCase(params: { cfg: OpenClawConfig; env: NodeJS.ProcessEnv; expectedIds: string[]; - expectedConfigured: boolean; options?: Parameters[2]; }) { const options = params.options ?? matrixPresenceOptions; expect(listPotentialConfiguredChannelIds(params.cfg, params.env, options)).toEqual( params.expectedIds, ); - expect(hasPotentialConfiguredChannels(params.cfg, params.env, options)).toBe( - params.expectedConfigured, - ); } afterEach(() => { @@ -70,7 +65,6 @@ describe("config presence", () => { cfg, env, expectedIds: [], - expectedConfigured: false, options: { includePersistedAuthState: false }, }); }); @@ -97,7 +91,6 @@ describe("config presence", () => { cfg: {}, env, expectedIds: ["matrix"], - expectedConfigured: true, options: { includePersistedAuthState: false }, }); expect( @@ -120,7 +113,6 @@ describe("config presence", () => { cfg: {}, env, expectedIds: ["matrix"], - expectedConfigured: true, options: { persistedAuthStateProbe: { listChannelIds: () => ["matrix"], diff --git a/src/channels/config-presence.ts b/src/channels/config-presence.ts index 41eb7e6708eb..8b7208ceda90 100644 --- a/src/channels/config-presence.ts +++ b/src/channels/config-presence.ts @@ -186,46 +186,3 @@ export function listPotentialConfiguredChannelPresenceSignals( return signals.filter((signal) => configuredChannelIds.has(signal.channelId)); } - -function hasEnvConfiguredChannel( - cfg: OpenClawConfig, - env: NodeJS.ProcessEnv, - options: ChannelPresenceOptions = {}, -): boolean { - const channelIds = options.channelIds ?? listBundledChannelIds(env, options.discovery); - const channelEnvPrefixes = listChannelEnvPrefixes(channelIds); - for (const [key, value] of Object.entries(env)) { - if (!hasNonEmptyString(value)) { - continue; - } - if (channelEnvPrefixes.some(([prefix]) => key.startsWith(prefix))) { - return true; - } - } - if (options.includePersistedAuthState === false || !hasPersistedChannelState(env)) { - return false; - } - return listPersistedAuthStateChannelIds(options).some((channelId) => - hasPersistedAuthState({ channelId, cfg, env, options }), - ); -} - -/** Returns true when any channel appears configured from config, env, or persisted auth state. */ -export function hasPotentialConfiguredChannels( - cfg: OpenClawConfig | null | undefined, - env: NodeJS.ProcessEnv = process.env, - options: ChannelPresenceOptions = {}, -): boolean { - const channels = isRecord(cfg?.channels) ? cfg.channels : null; - if (channels) { - for (const [key, value] of Object.entries(channels)) { - if (IGNORED_CHANNEL_CONFIG_KEYS.has(key)) { - continue; - } - if (hasMeaningfulChannelConfig(value)) { - return true; - } - } - } - return hasEnvConfiguredChannel(cfg ?? {}, env, options); -} diff --git a/src/commands/status.scan-overview.test.ts b/src/commands/status.scan-overview.test.ts index d95e63fe007d..e226cd0b6678 100644 --- a/src/commands/status.scan-overview.test.ts +++ b/src/commands/status.scan-overview.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { collectStatusScanOverview } from "./status.scan-overview.ts"; const mocks = vi.hoisted(() => ({ - hasPotentialConfiguredChannels: vi.fn(), + hasConfiguredChannelsForReadOnlyScope: vi.fn(), resolveCommandConfigWithSecrets: vi.fn(), getStatusCommandSecretTargetIds: vi.fn(), readBestEffortConfigSnapshot: vi.fn(), @@ -15,7 +15,7 @@ const mocks = vi.hoisted(() => ({ })); vi.mock("../plugins/channel-plugin-ids.js", () => ({ - hasConfiguredChannelsForReadOnlyScope: mocks.hasPotentialConfiguredChannels, + hasConfiguredChannelsForReadOnlyScope: mocks.hasConfiguredChannelsForReadOnlyScope, })); vi.mock("../cli/command-config-resolution.js", () => ({ @@ -78,7 +78,7 @@ describe("collectStatusScanOverview", () => { beforeEach(() => { vi.clearAllMocks(); - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannelsForReadOnlyScope.mockReturnValue(true); mocks.getStatusCommandSecretTargetIds.mockReturnValue([]); mocks.readBestEffortConfigSnapshot.mockResolvedValue({ config: { session: {} }, diff --git a/src/commands/status.scan.fast-json.test.ts b/src/commands/status.scan.fast-json.test.ts index 419a2bb0f999..dccee3f05218 100644 --- a/src/commands/status.scan.fast-json.test.ts +++ b/src/commands/status.scan.fast-json.test.ts @@ -82,7 +82,7 @@ afterEach(() => { describe("scanStatusJsonFast", () => { it("does not preload configured channel plugins for the lean JSON path", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); await scanStatusJsonFast({}, {} as never); @@ -97,7 +97,7 @@ describe("scanStatusJsonFast", () => { }); it("keeps resolved and source channel configs available without loading runtime plugins", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); applyStatusScanDefaults(mocks, { hasConfiguredChannels: true, sourceConfig: { @@ -128,7 +128,7 @@ describe("scanStatusJsonFast", () => { }); it("skips plugin compatibility loading even when configured channels are present", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); await scanStatusJsonFast({}, {} as never); @@ -136,7 +136,7 @@ describe("scanStatusJsonFast", () => { }); it("keeps default fast JSON update scans local-only", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); await scanStatusJsonFast({ timeoutMs: 1234 }, {} as never); @@ -150,7 +150,7 @@ describe("scanStatusJsonFast", () => { }); it("restores registry-backed update checks and remote git fetches when --all is requested", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); await scanStatusJsonFast({ all: true }, {} as never); @@ -164,7 +164,7 @@ describe("scanStatusJsonFast", () => { }); it("keeps the local status RPC fallback off the default fast JSON path", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); mocks.callGateway.mockResolvedValue({ sessions: 1 }); await scanStatusJsonFast({}, {} as never); @@ -174,7 +174,7 @@ describe("scanStatusJsonFast", () => { }); it("honors explicit gateway probe timeouts on the lean JSON path", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); await scanStatusJsonFast({ timeoutMs: 5000 }, {} as never); @@ -182,7 +182,7 @@ describe("scanStatusJsonFast", () => { }); it("keeps configured gateway handshake timeouts on the lean JSON path", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); applyStatusScanDefaults(mocks, { resolvedConfig: { ...createStatusMemorySearchConfig(), @@ -201,7 +201,7 @@ describe("scanStatusJsonFast", () => { }); it("restores the local status RPC fallback when --all is requested", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); mocks.callGateway.mockResolvedValue({ sessions: 1 }); await scanStatusJsonFast({ all: true }, {} as never); @@ -215,7 +215,7 @@ describe("scanStatusJsonFast", () => { }); it("keeps the fast JSON summary off the channel plugin summary path", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); + mocks.hasConfiguredChannels.mockReturnValue(true); await scanStatusJsonFast({}, {} as never); @@ -230,7 +230,7 @@ describe("scanStatusJsonFast", () => { const result = await scanStatusJsonFast({}, {} as never); expect(result.memory).toBeNull(); - expect(mocks.hasPotentialConfiguredChannels).not.toHaveBeenCalled(); + expect(mocks.hasConfiguredChannels).not.toHaveBeenCalled(); expect(mocks.resolveMemorySearchConfig).not.toHaveBeenCalled(); expect(mocks.getMemorySearchManager).not.toHaveBeenCalled(); }); diff --git a/src/commands/status.scan.test-helpers.ts b/src/commands/status.scan.test-helpers.ts index 55db10b51bc4..471bee4f121d 100644 --- a/src/commands/status.scan.test-helpers.ts +++ b/src/commands/status.scan.test-helpers.ts @@ -9,7 +9,7 @@ type ResolveConfigPathMock = Mock<() => string>; type StatusScanSharedMocks = { resolveConfigPath: ResolveConfigPathMock; - hasPotentialConfiguredChannels: UnknownMock; + hasConfiguredChannels: UnknownMock; hasConfiguredChannelsForReadOnlyScope: UnknownMock; readBestEffortConfig: UnknownMock; resolveCommandSecretRefsViaGateway: UnknownMock; @@ -28,7 +28,7 @@ type StatusScanSharedMocks = { export function createStatusScanSharedMocks(configPathLabel: string): StatusScanSharedMocks { return { resolveConfigPath: vi.fn(() => `/tmp/openclaw-${configPathLabel}-missing-${process.pid}.json`), - hasPotentialConfiguredChannels: vi.fn(), + hasConfiguredChannels: vi.fn(), hasConfiguredChannelsForReadOnlyScope: vi.fn(), readBestEffortConfig: vi.fn(), resolveCommandSecretRefsViaGateway: vi.fn(), @@ -182,9 +182,6 @@ export async function loadStatusScanModuleForTest( mocks.resolveMemorySearchConfig ?? vi.fn(() => ({ store: { databasePath: "/tmp/main.sqlite" } })); - vi.doMock("../channels/config-presence.js", () => ({ - hasPotentialConfiguredChannels: mocks.hasPotentialConfiguredChannels, - })); vi.doMock("../plugins/channel-plugin-ids.js", () => ({ hasConfiguredChannelsForReadOnlyScope: (params: { config: OpenClawConfig; @@ -196,7 +193,7 @@ export async function loadStatusScanModuleForTest( env?: NodeJS.ProcessEnv; includePersistedAuthState?: boolean; }) => - mocks.hasPotentialConfiguredChannels( + mocks.hasConfiguredChannels( params.config, params.env, params.includePersistedAuthState === undefined @@ -408,7 +405,7 @@ export function applyStatusScanDefaults( const sourceConfig = options.sourceConfig ?? createStatusScanConfig(); const resolvedConfig = options.resolvedConfig ?? sourceConfig; - mocks.hasPotentialConfiguredChannels.mockReturnValue(options.hasConfiguredChannels ?? false); + mocks.hasConfiguredChannels.mockReturnValue(options.hasConfiguredChannels ?? false); mocks.hasConfiguredChannelsForReadOnlyScope.mockImplementation((rawParams: unknown) => { const params = rawParams as { config: OpenClawConfig; @@ -416,7 +413,7 @@ export function applyStatusScanDefaults( includePersistedAuthState?: boolean; }; return Boolean( - mocks.hasPotentialConfiguredChannels( + mocks.hasConfiguredChannels( params.config, params.env, params.includePersistedAuthState === undefined diff --git a/src/commands/status.test.ts b/src/commands/status.test.ts index 3e60dc51f81a..d1036fc27bc0 100644 --- a/src/commands/status.test.ts +++ b/src/commands/status.test.ts @@ -407,7 +407,6 @@ async function withEnvVar(key: string, value: string, run: () => Promise): } const mocks = vi.hoisted(() => ({ - hasPotentialConfiguredChannels: vi.fn(() => true), loadConfig: vi.fn().mockReturnValue({ session: {} }), loadSessionStore: vi.fn().mockReturnValue({ "+1000": createDefaultSessionStoreEntry(), @@ -501,7 +500,6 @@ const mocks = vi.hoisted(() => ({ })); vi.mock("../channels/config-presence.js", () => ({ - hasPotentialConfiguredChannels: mocks.hasPotentialConfiguredChannels, hasMeaningfulChannelConfig: (entry: unknown) => Boolean( entry && typeof entry === "object" && Object.keys(entry as Record).length, @@ -896,8 +894,6 @@ vi.mock("./status.daemon.js", () => ({ describe("statusCommand", () => { afterEach(() => { - mocks.hasPotentialConfiguredChannels.mockReset(); - mocks.hasPotentialConfiguredChannels.mockReturnValue(true); mocks.loadConfig.mockReset(); mocks.loadConfig.mockReturnValue({ session: {} }); mocks.loadSessionStore.mockReset(); @@ -1002,7 +998,6 @@ describe("statusCommand", () => { }); it("prints JSON and includes security audit only when all is requested", async () => { - mocks.hasPotentialConfiguredChannels.mockReturnValue(false); mocks.buildPluginCompatibilityNotices.mockReturnValue([ createCompatibilityNotice({ pluginId: "legacy-plugin", code: "legacy-before-agent-start" }), ]); diff --git a/src/plugins/channel-plugin-ids.test.ts b/src/plugins/channel-plugin-ids.test.ts index 94013a0f3e52..a7b2a9d8933e 100644 --- a/src/plugins/channel-plugin-ids.test.ts +++ b/src/plugins/channel-plugin-ids.test.ts @@ -20,7 +20,6 @@ const listExplicitlyDisabledChannelIdsForConfig = vi.hoisted(() => }), ); const listPotentialConfiguredChannelPresenceSignals = vi.hoisted(() => vi.fn()); -const hasPotentialConfiguredChannels = vi.hoisted(() => vi.fn()); const hasMeaningfulChannelConfig = vi.hoisted(() => vi.fn((value: unknown) => { return ( @@ -40,7 +39,6 @@ vi.mock("../channels/config-presence.js", () => ({ listPotentialConfiguredChannelIds, listExplicitlyDisabledChannelIdsForConfig, listPotentialConfiguredChannelPresenceSignals, - hasPotentialConfiguredChannels, hasMeaningfulChannelConfig, })); @@ -739,12 +737,6 @@ describe("resolveGatewayStartupPluginIds", () => { source: "config", })); }); - hasPotentialConfiguredChannels.mockReset().mockImplementation((config: OpenClawConfig) => { - if (Object.hasOwn(config, "channels")) { - return Object.keys(config.channels ?? {}).length > 0; - } - return true; - }); useManifestRegistryFixture(); loadPluginManifestRegistryForInstalledIndex .mockReset() @@ -2813,12 +2805,6 @@ describe("resolveConfiguredChannelPluginIds", () => { source: "config", })); }); - hasPotentialConfiguredChannels.mockReset().mockImplementation((config: OpenClawConfig) => { - if (Object.hasOwn(config, "channels")) { - return Object.keys(config.channels ?? {}).length > 0; - } - return false; - }); useManifestRegistryFixture(); }); @@ -2995,7 +2981,6 @@ describe("listConfiguredChannelIdsForReadOnlyScope", () => { beforeEach(() => { listPotentialConfiguredChannelIds.mockReset().mockReturnValue([]); listPotentialConfiguredChannelPresenceSignals.mockReset().mockReturnValue([]); - hasPotentialConfiguredChannels.mockReset().mockReturnValue(false); hasMeaningfulChannelConfig.mockClear(); useManifestRegistryFixture(); }); @@ -3592,7 +3577,6 @@ describe("listConfiguredChannelIdsForReadOnlyScope", () => { it("uses manifest env vars for read-only channel presence checks", () => { listPotentialConfiguredChannelIds.mockReturnValue([]); listPotentialConfiguredChannelPresenceSignals.mockReturnValue([]); - hasPotentialConfiguredChannels.mockReturnValue(false); expect( hasConfiguredChannelsForReadOnlyScope({