Files
openclaw/src/commands/status.scan.fast-json.ts
2026-04-04 02:16:56 +01:00

140 lines
5.0 KiB
TypeScript

import { existsSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import { hasPotentialConfiguredChannels } from "../channels/config-presence.js";
import { resolveConfigPath, resolveStateDir } from "../config/paths.js";
import type { OpenClawConfig } from "../config/types.js";
import { resolveOsSummary } from "../infra/os-summary.js";
import type { RuntimeEnv } from "../runtime.js";
import type { getAgentLocalStatuses as getAgentLocalStatusesFn } from "./status.agent-local.js";
import type { StatusScanResult } from "./status.scan.js";
import { scanStatusJsonCore } from "./status.scan.json-core.js";
import {
resolveSharedMemoryStatusSnapshot,
type MemoryPluginStatus,
type MemoryStatusSnapshot,
} from "./status.scan.shared.js";
let configIoModulePromise: Promise<typeof import("../config/io.js")> | undefined;
let commandSecretTargetsModulePromise:
| Promise<typeof import("../cli/command-secret-targets.js")>
| undefined;
let commandSecretGatewayModulePromise:
| Promise<typeof import("../cli/command-secret-gateway.js")>
| undefined;
let memorySearchModulePromise: Promise<typeof import("../agents/memory-search.js")> | undefined;
let statusScanDepsRuntimeModulePromise:
| Promise<typeof import("./status.scan.deps.runtime.js")>
| undefined;
function loadConfigIoModule() {
configIoModulePromise ??= import("../config/io.js");
return configIoModulePromise;
}
function loadCommandSecretTargetsModule() {
commandSecretTargetsModulePromise ??= import("../cli/command-secret-targets.js");
return commandSecretTargetsModulePromise;
}
function loadCommandSecretGatewayModule() {
commandSecretGatewayModulePromise ??= import("../cli/command-secret-gateway.js");
return commandSecretGatewayModulePromise;
}
function loadMemorySearchModule() {
memorySearchModulePromise ??= import("../agents/memory-search.js");
return memorySearchModulePromise;
}
function loadStatusScanDepsRuntimeModule() {
statusScanDepsRuntimeModulePromise ??= import("./status.scan.deps.runtime.js");
return statusScanDepsRuntimeModulePromise;
}
function shouldSkipMissingConfigFastPath(): boolean {
return (
process.env.VITEST === "true" ||
process.env.VITEST_POOL_ID !== undefined ||
process.env.NODE_ENV === "test"
);
}
function isMissingConfigColdStart(): boolean {
return !shouldSkipMissingConfigFastPath() && !existsSync(resolveConfigPath(process.env));
}
function resolveDefaultMemoryStorePath(agentId: string): string {
return path.join(resolveStateDir(process.env, os.homedir), "memory", `${agentId}.sqlite`);
}
async function resolveMemoryStatusSnapshot(params: {
cfg: OpenClawConfig;
agentStatus: Awaited<ReturnType<typeof getAgentLocalStatusesFn>>;
memoryPlugin: MemoryPluginStatus;
}): Promise<MemoryStatusSnapshot | null> {
const { resolveMemorySearchConfig } = await loadMemorySearchModule();
const { getMemorySearchManager } = await loadStatusScanDepsRuntimeModule();
return await resolveSharedMemoryStatusSnapshot({
cfg: params.cfg,
agentStatus: params.agentStatus,
memoryPlugin: params.memoryPlugin,
resolveMemoryConfig: resolveMemorySearchConfig,
getMemorySearchManager,
requireDefaultStore: resolveDefaultMemoryStorePath,
});
}
async function readStatusSourceConfig(): Promise<OpenClawConfig> {
if (!shouldSkipMissingConfigFastPath() && !existsSync(resolveConfigPath(process.env))) {
return {};
}
const { readBestEffortConfig } = await loadConfigIoModule();
return await readBestEffortConfig();
}
async function resolveStatusConfig(params: {
sourceConfig: OpenClawConfig;
commandName: "status --json";
}): Promise<{ resolvedConfig: OpenClawConfig; diagnostics: string[] }> {
if (!shouldSkipMissingConfigFastPath() && !existsSync(resolveConfigPath(process.env))) {
return { resolvedConfig: params.sourceConfig, diagnostics: [] };
}
const [{ resolveCommandSecretRefsViaGateway }, { getStatusCommandSecretTargetIds }] =
await Promise.all([loadCommandSecretGatewayModule(), loadCommandSecretTargetsModule()]);
return await resolveCommandSecretRefsViaGateway({
config: params.sourceConfig,
commandName: params.commandName,
targetIds: getStatusCommandSecretTargetIds(),
mode: "read_only_status",
});
}
export async function scanStatusJsonFast(
opts: {
timeoutMs?: number;
all?: boolean;
},
runtime: RuntimeEnv,
): Promise<StatusScanResult> {
const coldStart = isMissingConfigColdStart();
const loadedRaw = await readStatusSourceConfig();
const { resolvedConfig: cfg, diagnostics: secretDiagnostics } = await resolveStatusConfig({
sourceConfig: loadedRaw,
commandName: "status --json",
});
return await scanStatusJsonCore({
coldStart,
cfg,
sourceConfig: loadedRaw,
secretDiagnostics,
hasConfiguredChannels: hasPotentialConfiguredChannels(cfg, process.env, {
includePersistedAuthState: false,
}),
opts,
resolveOsSummary,
resolveMemory: async ({ cfg, agentStatus, memoryPlugin }) =>
opts.all ? await resolveMemoryStatusSnapshot({ cfg, agentStatus, memoryPlugin }) : null,
runtime,
});
}