From b9b15bec85fd832be7b9930e6bbb7159bad9b425 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 27 Apr 2026 09:30:14 +0100 Subject: [PATCH] fix(ci): stabilize full validation probes --- scripts/openclaw-cross-os-release-checks.ts | 21 ++++++++--- .../subagent-registry.persistence.test.ts | 37 ++++++++----------- src/plugins/bundle-commands.test.ts | 6 +++ src/plugins/plugin-registry-contributions.ts | 2 +- .../openclaw-cross-os-release-checks.test.ts | 7 ++++ 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/scripts/openclaw-cross-os-release-checks.ts b/scripts/openclaw-cross-os-release-checks.ts index bd9013f0687..05cee881b4c 100644 --- a/scripts/openclaw-cross-os-release-checks.ts +++ b/scripts/openclaw-cross-os-release-checks.ts @@ -17,7 +17,7 @@ import { createServer } from "node:http"; import { createConnection as createNetConnection, createServer as createNetServer } from "node:net"; import { tmpdir } from "node:os"; import { dirname, join, resolve, win32 as pathWin32 } from "node:path"; -import { fileURLToPath } from "node:url"; +import { fileURLToPath, pathToFileURL } from "node:url"; import { assertNoBundledRuntimeDepsStagingDebris } from "../src/infra/package-dist-inventory.ts"; const SCRIPT_PATH = fileURLToPath(import.meta.url); @@ -2228,10 +2228,12 @@ export function shouldRunWindowsInstalledBrowserOverrideImportSmoke(platform = p return platform === "win32"; } -export function buildInstalledBrowserOverrideImportProbeScript() { +export function buildInstalledBrowserOverrideImportProbeScript( + runtimeModuleSpecifier = "openclaw/plugin-sdk/browser-node-runtime", +) { return ` import { existsSync } from "node:fs"; -import { startLazyPluginServiceModule } from "openclaw/plugin-sdk/browser-node-runtime"; +import { startLazyPluginServiceModule } from ${JSON.stringify(runtimeModuleSpecifier)}; const startedPath = process.env.OPENCLAW_BROWSER_OVERRIDE_STARTED_PATH; const stoppedPath = process.env.OPENCLAW_BROWSER_OVERRIDE_STOPPED_PATH; @@ -2295,12 +2297,21 @@ async function runInstalledBrowserOverrideImportSmoke(params) { const probePath = join(probeDir, "run browser override probe.mjs"); const startedPath = join(probeDir, "started.txt"); const stoppedPath = join(probeDir, "stopped.txt"); + const packageRoot = installedPackageRoot(params.prefixDir); + const runtimeModulePath = join(packageRoot, "dist", "plugin-sdk", "browser-node-runtime.js"); + if (!existsSync(runtimeModulePath)) { + throw new Error(`Installed browser runtime module not found: ${runtimeModulePath}`); + } writeFileSync(overridePath, `${buildBrowserOverrideProbeServiceModule()}\n`, "utf8"); - writeFileSync(probePath, `${buildInstalledBrowserOverrideImportProbeScript()}\n`, "utf8"); + writeFileSync( + probePath, + `${buildInstalledBrowserOverrideImportProbeScript(pathToFileURL(runtimeModulePath).href)}\n`, + "utf8", + ); await runCommand(process.execPath, [probePath], { - cwd: installedPackageRoot(params.prefixDir), + cwd: packageRoot, env: { ...params.env, OPENCLAW_BROWSER_CONTROL_MODULE: overridePath, diff --git a/src/agents/subagent-registry.persistence.test.ts b/src/agents/subagent-registry.persistence.test.ts index 20a83e60112..82c0c226175 100644 --- a/src/agents/subagent-registry.persistence.test.ts +++ b/src/agents/subagent-registry.persistence.test.ts @@ -370,7 +370,9 @@ describe("subagent registry persistence", () => { tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-subagent-")); process.env.OPENCLAW_STATE_DIR = tempStateDir; - vi.mocked(callGateway).mockImplementationOnce(async () => await new Promise(() => {})); + vi.mocked(callGateway).mockResolvedValueOnce({ + status: "pending", + }); registerSubagentRun({ runId: " run-live ", @@ -631,34 +633,27 @@ describe("subagent registry persistence", () => { }); it("removes attachments when pruning orphaned restored runs", async () => { + tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-subagent-")); + process.env.OPENCLAW_STATE_DIR = tempStateDir; + const attachmentsRootDir = path.join(tempStateDir, "attachments"); + const attachmentsDir = path.join(attachmentsRootDir, "ghost"); + await fs.mkdir(attachmentsDir, { recursive: true }); + await fs.writeFile(path.join(attachmentsDir, "artifact.txt"), "artifact", "utf8"); + const persisted = createPersistedEndedRun({ runId: "run-orphan-attachments", childSessionKey: "agent:main:subagent:ghost-attachments", task: "orphan attachments", cleanup: "delete", }); - const registryPath = await writePersistedRegistry(persisted, { - seedChildSessions: false, - }); - if (!tempStateDir) { - throw new Error("tempStateDir not initialized"); - } - const attachmentsRootDir = path.join(tempStateDir, "attachments"); - const attachmentsDir = path.join(attachmentsRootDir, "ghost"); - await fs.mkdir(attachmentsDir, { recursive: true }); - await fs.writeFile(path.join(attachmentsDir, "artifact.txt"), "artifact", "utf8"); - const parsed = JSON.parse(await fs.readFile(registryPath, "utf8")) as { - runs?: Record>; - }; - if (!parsed.runs?.["run-orphan-attachments"]) { - throw new Error("expected orphaned run in persisted registry"); - } - parsed.runs["run-orphan-attachments"] = { - ...parsed.runs["run-orphan-attachments"], + Object.assign(persisted.runs["run-orphan-attachments"] as Record, { attachmentsRootDir, attachmentsDir, - }; - await fs.writeFile(registryPath, `${JSON.stringify(parsed)}\n`, "utf8"); + }); + + const registryPath = path.join(tempStateDir, "subagents", "runs.json"); + await fs.mkdir(path.dirname(registryPath), { recursive: true }); + await fs.writeFile(registryPath, `${JSON.stringify(persisted)}\n`, "utf8"); restartRegistry(); await waitForRegistryWork(async () => { diff --git a/src/plugins/bundle-commands.test.ts b/src/plugins/bundle-commands.test.ts index d29ad1e2469..5897b8cb356 100644 --- a/src/plugins/bundle-commands.test.ts +++ b/src/plugins/bundle-commands.test.ts @@ -21,6 +21,12 @@ vi.mock("./config-state.js", () => ({ hasExplicitPluginConfig: (plugins?: { entries?: Record }) => Boolean(plugins?.entries && Object.keys(plugins.entries).length > 0), normalizePluginsConfig: (plugins?: unknown) => plugins, + resolveEffectiveEnableState: (params: { + config?: { entries?: Record }; + id: string; + }) => ({ + enabled: params.config?.entries?.[params.id]?.enabled !== false, + }), resolveEffectivePluginActivationState: (params: { config?: { entries?: Record }; id: string; diff --git a/src/plugins/plugin-registry-contributions.ts b/src/plugins/plugin-registry-contributions.ts index 324af2b606b..01a524b1c82 100644 --- a/src/plugins/plugin-registry-contributions.ts +++ b/src/plugins/plugin-registry-contributions.ts @@ -103,7 +103,7 @@ export type ResolveManifestContractPluginIdsByCompatibilityRuntimePathParams = export type PluginRegistryIdNormalizerOptions = { manifestRegistry?: PluginManifestRegistry; - lookUpTable?: PluginLookUpTable; + lookUpTable?: Pick; }; function normalizeContributionId(value: string): string { diff --git a/test/scripts/openclaw-cross-os-release-checks.test.ts b/test/scripts/openclaw-cross-os-release-checks.test.ts index a940509ebf5..283756e5085 100644 --- a/test/scripts/openclaw-cross-os-release-checks.test.ts +++ b/test/scripts/openclaw-cross-os-release-checks.test.ts @@ -302,6 +302,13 @@ describe("scripts/openclaw-cross-os-release-checks", () => { expect(script).toContain("startBrowserControlService"); expect(script).toContain("stopBrowserControlService"); expect(script).toContain("Browser control override start sentinel was not written."); + + const installedScript = buildInstalledBrowserOverrideImportProbeScript( + "file:///C:/Users/runner/AppData/Roaming/npm/node_modules/openclaw/dist/plugin-sdk/browser-node-runtime.js", + ); + expect(installedScript).toContain( + 'from "file:///C:/Users/runner/AppData/Roaming/npm/node_modules/openclaw/dist/plugin-sdk/browser-node-runtime.js"', + ); }); it("normalizes Windows installed CLI paths to the cmd shim", () => {