fix(raft): report missing CLI in channel status (#123140)

This commit is contained in:
Peter Steinberger
2026-08-13 04:21:13 -07:00
committed by GitHub
parent 57fabb2c9c
commit baf85e6868
2 changed files with 64 additions and 7 deletions
+51 -1
View File
@@ -1,7 +1,19 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { raftPlugin } from "./channel.js";
const detectBinaryMock = vi.hoisted(() => vi.fn());
vi.mock("openclaw/plugin-sdk/setup-tools", async (importOriginal) => ({
...(await importOriginal<typeof import("openclaw/plugin-sdk/setup-tools")>()),
detectBinary: detectBinaryMock,
}));
describe("Raft channel plugin", () => {
beforeEach(() => {
detectBinaryMock.mockReset();
});
it("declares a wake-only direct channel", () => {
expect(raftPlugin.meta).toMatchObject({
id: "raft",
@@ -13,4 +25,42 @@ describe("Raft channel plugin", () => {
expect(raftPlugin.message).toBeUndefined();
expect(raftPlugin.outbound).toBeUndefined();
});
it.each([
{
detected: true,
expected: { ok: true, cliFound: true, error: null },
},
{
detected: false,
expected: {
ok: false,
cliFound: false,
error: "Raft CLI not found on the Gateway PATH",
},
},
])(
"maps CLI detection to a coherent status outcome when detected=$detected",
async ({ detected, expected }) => {
detectBinaryMock.mockResolvedValueOnce(detected);
const cfg = {
channels: {
raft: {
profile: "test-profile",
},
},
} as OpenClawConfig;
const account = raftPlugin.config.resolveAccount(cfg, "default");
const result = await raftPlugin.status!.probeAccount!({
account,
timeoutMs: 1_000,
cfg,
});
expect(detectBinaryMock).toHaveBeenCalledOnce();
expect(detectBinaryMock).toHaveBeenCalledWith("raft");
expect(result).toEqual(expected);
},
);
});
+13 -6
View File
@@ -19,9 +19,9 @@ import { raftChannelConfigSchema } from "./config-schema.js";
import { startRaftGatewayAccount } from "./gateway.js";
import { raftSetupPlugin } from "./setup.js";
type RaftProbe = {
cliFound: boolean;
};
type RaftProbe =
| { ok: true; cliFound: true; error: null }
| { ok: false; cliFound: false; error: string };
export const raftPlugin: ChannelPlugin<ResolvedRaftAccount, RaftProbe> = createChatChannelPlugin({
base: {
@@ -61,9 +61,16 @@ export const raftPlugin: ChannelPlugin<ResolvedRaftAccount, RaftProbe> = createC
status: createComputedAccountStatusAdapter<ResolvedRaftAccount, RaftProbe>({
defaultRuntime: createDefaultChannelRuntimeState("default"),
buildChannelSummary: ({ snapshot }) => buildBaseChannelStatusSummary(snapshot),
probeAccount: async () => ({
cliFound: await detectBinary("raft"),
}),
probeAccount: async () => {
const cliFound = await detectBinary("raft");
return cliFound
? { ok: true, cliFound: true, error: null }
: {
ok: false,
cliFound: false,
error: "Raft CLI not found on the Gateway PATH",
};
},
formatCapabilitiesProbe: ({ probe }) => [
{
text: `Raft CLI: ${probe.cliFound ? "found" : "missing"}`,