mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-13 09:46:14 +00:00
feat(skills): diagnose skill_workshop hidden by tool policy (#100654)
* feat(skills): diagnose skill_workshop hidden by tool policy (#87570) Workshop can be enabled and auto-capturing while tools.profile hides the skill_workshop tool; every inspection surface looked healthy. plugins inspect and openclaw doctor now name the excluding policy layer (global/ agent/provider profile, allowlist, denylist) and the exact alsoAllow grant to add, via a shared resolveSkillWorkshopToolPolicyAvailability helper that /learn's guard now reuses instead of composing policy itself. Diagnosis only; no policy behavior change. * ci: retrigger
This commit is contained in:
committed by
GitHub
parent
eda99cb8df
commit
133ca4b469
@@ -1,5 +1,6 @@
|
||||
// Plugins CLI list tests cover plugin listing output and installed-state formatting.
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { createPluginRecord } from "../plugins/status.test-helpers.js";
|
||||
import {
|
||||
buildPluginDiagnosticsReport,
|
||||
@@ -17,9 +18,18 @@ import {
|
||||
setInstalledPluginIndexInstallRecords,
|
||||
} from "./plugins-cli-test-helpers.js";
|
||||
|
||||
const workshopMocks = vi.hoisted(() => ({
|
||||
detectToolPolicyDiagnostic: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../skills/workshop/tool-policy-diagnostic.js", () => ({
|
||||
detectSkillWorkshopToolPolicyDiagnostic: workshopMocks.detectToolPolicyDiagnostic,
|
||||
}));
|
||||
|
||||
describe("plugins cli list", () => {
|
||||
beforeEach(() => {
|
||||
resetPluginsCliTestState();
|
||||
workshopMocks.detectToolPolicyDiagnostic.mockReset();
|
||||
});
|
||||
|
||||
it("includes imported state in JSON output", async () => {
|
||||
@@ -620,4 +630,39 @@ describe("plugins cli list", () => {
|
||||
expect(buildPluginDiagnosticsReport).not.toHaveBeenCalled();
|
||||
expect(runtimeErrors.at(-1)).toContain("Plugin not found: missing-plugin");
|
||||
});
|
||||
|
||||
it("explains a policy-hidden built-in Skill Workshop at the legacy inspect surface", async () => {
|
||||
const config: OpenClawConfig = {
|
||||
tools: { profile: "messaging" },
|
||||
};
|
||||
loadConfig.mockReturnValue(config);
|
||||
workshopMocks.detectToolPolicyDiagnostic.mockReturnValue({
|
||||
agentId: "main",
|
||||
source: "tools.profile",
|
||||
detail: 'tools.profile: "messaging" does not include "skill_workshop".',
|
||||
fix: 'Add tools.alsoAllow: ["skill_workshop"].',
|
||||
message:
|
||||
'Skill Workshop is active, but "skill_workshop" is hidden for agent "main": tools.profile: "messaging" does not include "skill_workshop". Add tools.alsoAllow: ["skill_workshop"].',
|
||||
});
|
||||
buildPluginSnapshotReport.mockReturnValue({
|
||||
plugins: [],
|
||||
diagnostics: [],
|
||||
});
|
||||
|
||||
await expect(runPluginsCommand(["plugins", "inspect", "skill-workshop"])).rejects.toThrow(
|
||||
"__exit__:1",
|
||||
);
|
||||
|
||||
expect(runtimeErrors.at(-1)).toContain(
|
||||
"Skill Workshop is built into OpenClaw, not a plugin; configure it under skills.workshop.",
|
||||
);
|
||||
expect(workshopMocks.detectToolPolicyDiagnostic).toHaveBeenCalledWith({
|
||||
config,
|
||||
workshopEnabled: true,
|
||||
});
|
||||
expect(runtimeErrors.at(-1)).toContain(
|
||||
'tools.profile: "messaging" does not include "skill_workshop".',
|
||||
);
|
||||
expect(runtimeErrors.at(-1)).toContain('Add tools.alsoAllow: ["skill_workshop"].');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user