diff --git a/CHANGELOG.md b/CHANGELOG.md index c11df205000..8e13b3d144d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Docs: https://docs.openclaw.ai ### Fixes +- Agents/cron: suppress the default heartbeat system prompt for cron-triggered embedded runs even when they target non-cron session keys, so cron tasks stop reading `HEARTBEAT.md` and polluting unrelated threads. (#53152) Thanks @Protocol-zero-0. + ## 2026.3.23 ### Breaking diff --git a/src/infra/update-global.test.ts b/src/infra/update-global.test.ts index e9007bf28d1..22100d270c1 100644 --- a/src/infra/update-global.test.ts +++ b/src/infra/update-global.test.ts @@ -5,6 +5,7 @@ import { afterEach, describe, expect, it } from "vitest"; import { captureEnv } from "../test-utils/env.js"; import { canResolveRegistryVersionForPackageTarget, + collectInstalledGlobalPackageErrors, cleanupGlobalRenameDirs, detectGlobalInstallManagerByPresence, detectGlobalInstallManagerForRoot, @@ -185,4 +186,33 @@ describe("update global helpers", () => { await expect(fs.stat(path.join(root, "openclaw"))).resolves.toBeDefined(); await expect(fs.stat(path.join(root, ".openclaw-file"))).resolves.toBeDefined(); }); + + it("checks bundled runtime sidecars, including Matrix helper-api", async () => { + const packageRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-update-global-pkg-")); + const sidecars = [ + "dist/extensions/whatsapp/light-runtime-api.js", + "dist/extensions/whatsapp/runtime-api.js", + "dist/extensions/matrix/helper-api.js", + "dist/extensions/matrix/runtime-api.js", + "dist/extensions/matrix/thread-bindings-runtime.js", + "dist/extensions/msteams/runtime-api.js", + ] as const; + await fs.writeFile( + path.join(packageRoot, "package.json"), + JSON.stringify({ name: "openclaw", version: "1.0.0" }), + "utf-8", + ); + for (const relativePath of sidecars) { + const absolutePath = path.join(packageRoot, relativePath); + await fs.mkdir(path.dirname(absolutePath), { recursive: true }); + await fs.writeFile(absolutePath, "export {};\n", "utf-8"); + } + + await expect(collectInstalledGlobalPackageErrors({ packageRoot })).resolves.toEqual([]); + + await fs.rm(path.join(packageRoot, "dist/extensions/matrix/helper-api.js")); + await expect(collectInstalledGlobalPackageErrors({ packageRoot })).resolves.toContain( + "missing bundled runtime sidecar dist/extensions/matrix/helper-api.js", + ); + }); }); diff --git a/src/plugin-sdk/channel-import-guardrails.test.ts b/src/plugin-sdk/channel-import-guardrails.test.ts index c5b20b7bdc9..d8c3e481341 100644 --- a/src/plugin-sdk/channel-import-guardrails.test.ts +++ b/src/plugin-sdk/channel-import-guardrails.test.ts @@ -11,6 +11,7 @@ const ALLOWED_EXTENSION_PUBLIC_SURFACES = new Set([ "allow-from.js", "api.js", "auth-presence.js", + "helper-api.js", "index.js", "light-runtime-api.js", "login-qr-api.js", @@ -22,6 +23,7 @@ const ALLOWED_EXTENSION_PUBLIC_SURFACES = new Set([ "setup-api.js", "setup-entry.js", "timeouts.js", + "thread-bindings-runtime.js", ]); const GUARDED_CHANNEL_EXTENSIONS = new Set([ "bluebubbles",