Skip to content

Commit 100d7b0

Browse files
committed
Doctor: add bundle plugin capability summary to workspace status
1 parent b48413e commit 100d7b0

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

src/commands/doctor-workspace-status.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,75 @@ describe("noteWorkspaceStatus", () => {
9898
}
9999
});
100100

101+
it("surfaces bundle plugin capabilities in the plugins note", async () => {
102+
resolveDefaultAgentIdMock.mockReturnValue("default");
103+
resolveAgentWorkspaceDirMock.mockReturnValue("/workspace");
104+
buildWorkspaceSkillStatusMock.mockReturnValue({
105+
skills: [],
106+
});
107+
loadOpenClawPluginsMock.mockReturnValue({
108+
plugins: [
109+
{
110+
id: "claude-bundle",
111+
name: "Claude Bundle",
112+
source: "/tmp/claude-bundle",
113+
origin: "workspace",
114+
enabled: true,
115+
status: "loaded",
116+
format: "bundle",
117+
bundleFormat: "claude",
118+
bundleCapabilities: ["skills", "commands", "agents"],
119+
toolNames: [],
120+
hookNames: [],
121+
channelIds: [],
122+
providerIds: [],
123+
speechProviderIds: [],
124+
mediaUnderstandingProviderIds: [],
125+
imageGenerationProviderIds: [],
126+
webSearchProviderIds: [],
127+
gatewayMethods: [],
128+
cliCommands: [],
129+
services: [],
130+
commands: [],
131+
httpRoutes: 0,
132+
hookCount: 0,
133+
configSchema: false,
134+
},
135+
],
136+
diagnostics: [],
137+
channels: [],
138+
channelSetups: [],
139+
providers: [],
140+
speechProviders: [],
141+
mediaUnderstandingProviders: [],
142+
imageGenerationProviders: [],
143+
webSearchProviders: [],
144+
tools: [],
145+
hooks: [],
146+
typedHooks: [],
147+
httpRoutes: [],
148+
gatewayHandlers: {},
149+
cliRegistrars: [],
150+
services: [],
151+
commands: [],
152+
conversationBindingResolvedHandlers: [],
153+
});
154+
155+
const noteSpy = vi.spyOn(noteModule, "note").mockImplementation(() => {});
156+
try {
157+
const { noteWorkspaceStatus } = await import("./doctor-workspace-status.js");
158+
noteWorkspaceStatus({});
159+
160+
const pluginCalls = noteSpy.mock.calls.filter(([, title]) => title === "Plugins");
161+
expect(pluginCalls).toHaveLength(1);
162+
const body = String(pluginCalls[0]?.[0]);
163+
expect(body).toContain("Bundle plugins: 1");
164+
expect(body).toContain("agents, commands, skills");
165+
} finally {
166+
noteSpy.mockRestore();
167+
}
168+
});
169+
101170
it("omits plugin compatibility note when no legacy compatibility paths are present", async () => {
102171
resolveDefaultAgentIdMock.mockReturnValue("default");
103172
resolveAgentWorkspaceDirMock.mockReturnValue("/workspace");

src/commands/doctor-workspace-status.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ export function noteWorkspaceStatus(cfg: OpenClawConfig) {
5353
: null,
5454
].filter((line): line is string => Boolean(line));
5555

56+
const bundlePlugins = loaded.filter(
57+
(p) => p.format === "bundle" && (p.bundleCapabilities?.length ?? 0) > 0,
58+
);
59+
if (bundlePlugins.length > 0) {
60+
const allCaps = new Set(bundlePlugins.flatMap((p) => p.bundleCapabilities ?? []));
61+
lines.push(`Bundle plugins: ${bundlePlugins.length} (${[...allCaps].toSorted().join(", ")})`);
62+
}
63+
5664
note(lines.join("\n"), "Plugins");
5765
}
5866
const compatibilityWarnings = buildPluginCompatibilityWarnings({

0 commit comments

Comments
 (0)