fix: speed up status json channel detection

Signed-off-by: sallyom <somalley@redhat.com>
This commit is contained in:
sallyom
2026-05-08 00:05:50 -04:00
committed by Sally O'Malley
parent d29201fe4f
commit 07e8aecb39
4 changed files with 24 additions and 16 deletions

View File

@@ -180,6 +180,7 @@ Docs: https://docs.openclaw.ai
- Gateway/macOS: `openclaw gateway stop` now uses `launchctl bootout` by default instead of unconditionally calling `launchctl disable`, so KeepAlive auto-recovery still works after unexpected crashes; use the new `--disable` flag to opt into the persistent-disable behavior when a manual stop should survive reboots. Fixes #77934. Thanks @bmoran1022.
- Gateway/macOS: `repairLaunchAgentBootstrap` no longer kickstarts an already-running LaunchAgent, preventing unnecessary service restarts and session disconnects when repair runs against a healthy gateway. Fixes #77428. Thanks @ramitrkar-hash.
- Gateway/macOS: `openclaw gateway stop --disable` now persists the LaunchAgent disable bit even after a previous bootout left the service not loaded, keeping the explicit stay-down path reliable. (#78412) Thanks @wdeveloper16.
- CLI/status: keep lean `openclaw status --json` off manifest-backed channel discovery so configured-channel checks do not repeatedly rescan plugin metadata. Fixes #79129.
- Control UI/chat: hide retired and non-public Google Gemini model IDs from chat model catalogs and route the bare `gemini-3-pro` alias to Gemini 3.1 Pro Preview instead of the shut-down Gemini 3 Pro Preview. Thanks @BunsDev.
- CLI/install: refuse state-mutating OpenClaw CLI runs as root by default, keep an explicit `OPENCLAW_ALLOW_ROOT=1` escape hatch for intentional root/container use, and update DigitalOcean setup guidance to run OpenClaw as a non-root user. Fixes #67478. Thanks @Jerry-Xin and @natechicago.
- Auto-reply/media: resolve `scp` from `PATH` when staging sandbox media so nonstandard OpenSSH installs can copy remote attachments.

View File

@@ -55,6 +55,7 @@ describe("scanStatusJsonFast", () => {
await scanStatusJsonFast({}, {} as never);
expect(mocks.hasConfiguredChannelsForReadOnlyScope).not.toHaveBeenCalled();
expect(mocks.ensurePluginRegistryLoaded).not.toHaveBeenCalled();
expect(loggingStateRef.forceConsoleToStderr).toBe(false);
});

View File

@@ -1,5 +1,5 @@
import { hasPotentialConfiguredChannels } from "../channels/config-presence.js";
import type { OpenClawConfig } from "../config/types.js";
import { hasConfiguredChannelsForReadOnlyScope } from "../plugins/channel-plugin-ids.js";
import type { RuntimeEnv } from "../runtime.js";
import { executeStatusScanFromOverview } from "./status.scan-execute.ts";
import {
@@ -58,11 +58,8 @@ export async function scanStatusJsonFast(
commandName: "status --json",
allowMissingConfigFastPath: true,
includeChannelSummary: false,
resolveHasConfiguredChannels: (cfg, sourceConfig) =>
hasConfiguredChannelsForReadOnlyScope({
config: cfg,
activationSourceConfig: sourceConfig,
env: process.env,
resolveHasConfiguredChannels: (cfg) =>
hasPotentialConfiguredChannels(cfg, process.env, {
includePersistedAuthState: false,
}),
resolveMemory: async ({ cfg, agentStatus, memoryPlugin }) =>

View File

@@ -8,6 +8,7 @@ type ResolveConfigPathMock = Mock<() => string>;
type StatusScanSharedMocks = {
resolveConfigPath: ResolveConfigPathMock;
hasPotentialConfiguredChannels: UnknownMock;
hasConfiguredChannelsForReadOnlyScope: UnknownMock;
readBestEffortConfig: UnknownMock;
resolveCommandSecretRefsViaGateway: UnknownMock;
getUpdateCheckResult: UnknownMock;
@@ -26,6 +27,7 @@ export function createStatusScanSharedMocks(configPathLabel: string): StatusScan
return {
resolveConfigPath: vi.fn(() => `/tmp/openclaw-${configPathLabel}-missing-${process.pid}.json`),
hasPotentialConfiguredChannels: vi.fn(),
hasConfiguredChannelsForReadOnlyScope: vi.fn(),
readBestEffortConfig: vi.fn(),
resolveCommandSecretRefsViaGateway: vi.fn(),
getUpdateCheckResult: vi.fn(),
@@ -187,16 +189,7 @@ export async function loadStatusScanModuleForTest(
config: OpenClawConfig;
env?: NodeJS.ProcessEnv;
includePersistedAuthState?: boolean;
}) =>
Boolean(
mocks.hasPotentialConfiguredChannels(
params.config,
params.env,
params.includePersistedAuthState === undefined
? undefined
: { includePersistedAuthState: params.includePersistedAuthState },
),
),
}) => mocks.hasConfiguredChannelsForReadOnlyScope(params),
listConfiguredChannelIdsForReadOnlyScope: (params: {
config: OpenClawConfig;
env?: NodeJS.ProcessEnv;
@@ -409,6 +402,22 @@ export function applyStatusScanDefaults(
const resolvedConfig = options.resolvedConfig ?? sourceConfig;
mocks.hasPotentialConfiguredChannels.mockReturnValue(options.hasConfiguredChannels ?? false);
mocks.hasConfiguredChannelsForReadOnlyScope.mockImplementation((rawParams: unknown) => {
const params = rawParams as {
config: OpenClawConfig;
env?: NodeJS.ProcessEnv;
includePersistedAuthState?: boolean;
};
return Boolean(
mocks.hasPotentialConfiguredChannels(
params.config,
params.env,
params.includePersistedAuthState === undefined
? undefined
: { includePersistedAuthState: params.includePersistedAuthState },
),
);
});
mocks.readBestEffortConfig.mockResolvedValue(sourceConfig);
mocks.resolveCommandSecretRefsViaGateway.mockResolvedValue({
resolvedConfig,