fix: normalize heartbeat targets

This commit is contained in:
Peter Steinberger
2026-01-24 13:17:02 +00:00
parent 9d742ba51f
commit ef7971e3a4
13 changed files with 163 additions and 42 deletions

View File

@@ -9,6 +9,7 @@ async function writePluginFixture(params: {
dir: string;
id: string;
schema: Record<string, unknown>;
channels?: string[];
}) {
await fs.mkdir(params.dir, { recursive: true });
await fs.writeFile(
@@ -16,16 +17,16 @@ async function writePluginFixture(params: {
`export default { id: "${params.id}", register() {} };`,
"utf-8",
);
const manifest: Record<string, unknown> = {
id: params.id,
configSchema: params.schema,
};
if (params.channels) {
manifest.channels = params.channels;
}
await fs.writeFile(
path.join(params.dir, "clawdbot.plugin.json"),
JSON.stringify(
{
id: params.id,
configSchema: params.schema,
},
null,
2,
),
JSON.stringify(manifest, null, 2),
"utf-8",
);
}
@@ -149,4 +150,43 @@ describe("config plugin validation", () => {
expect(res.ok).toBe(true);
});
});
it("accepts plugin heartbeat targets", async () => {
await withTempHome(async (home) => {
process.env.CLAWDBOT_STATE_DIR = path.join(home, ".clawdbot");
const pluginDir = path.join(home, "bluebubbles-plugin");
await writePluginFixture({
dir: pluginDir,
id: "bluebubbles-plugin",
channels: ["bluebubbles"],
schema: { type: "object" },
});
vi.resetModules();
const { validateConfigObjectWithPlugins } = await import("./config.js");
const res = validateConfigObjectWithPlugins({
agents: { defaults: { heartbeat: { target: "bluebubbles" } }, list: [{ id: "pi" }] },
plugins: { enabled: false, load: { paths: [pluginDir] } },
});
expect(res.ok).toBe(true);
});
});
it("rejects unknown heartbeat targets", async () => {
await withTempHome(async (home) => {
process.env.CLAWDBOT_STATE_DIR = path.join(home, ".clawdbot");
vi.resetModules();
const { validateConfigObjectWithPlugins } = await import("./config.js");
const res = validateConfigObjectWithPlugins({
agents: { defaults: { heartbeat: { target: "not-a-channel" } }, list: [{ id: "pi" }] },
});
expect(res.ok).toBe(false);
if (!res.ok) {
expect(res.issues).toContainEqual({
path: "agents.defaults.heartbeat.target",
message: "unknown heartbeat target: not-a-channel",
});
}
});
});
});