mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:20:43 +00:00
fix(skills): require opt-in for coding-agent
This commit is contained in:
@@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- Agents/Anthropic: send implicit Anthropic beta headers only to direct public Anthropic endpoints, including OAuth, so custom Anthropic-compatible providers no longer mis-handle unsupported beta flags unless explicitly configured. Refs #73346. Thanks @byBrodowski.
|
||||
- Skills: require explicit `skills.entries.coding-agent.enabled` before exposing the bundled coding-agent skill, so installs with Codex on PATH but no OpenAI auth do not silently offer Codex delegation. Fixes #73358. Thanks @LaFleurAdvertising and @Sanjays2402.
|
||||
- Plugins/startup: precompute bundled runtime mirror fingerprints before taking the mirror lock, including dist-runtime canonical roots, so Docker Desktop/WSL cold starts no longer hold `.openclaw-runtime-mirror.lock` while scanning slow persisted volumes. Fixes #73339. Thanks @1yihui.
|
||||
- Channels/LINE: persist inbound image, video, audio, and file downloads in `~/.openclaw/media/inbound/` instead of temporary files so agents can still read LINE media after `/tmp` cleanup. Fixes #73370. Thanks @hijirii and @wenxu007.
|
||||
- Control UI/WebChat: keep large attachment payloads out of Lit state and optimistic chat messages, using object URL previews plus send-time payload serialization so PDF/image uploads no longer trigger `RangeError: Maximum call stack size exceeded`. Fixes #73360; refs #54378 and #63432. Thanks @hejunhui-73, @Ansub, and @christianhernandez3-afk.
|
||||
|
||||
@@ -324,6 +324,10 @@ under `skills.entries` in `~/.openclaw/openclaw.json`:
|
||||
|
||||
<ParamField path="enabled" type="boolean">
|
||||
`false` disables the skill even if it is bundled or installed.
|
||||
The bundled `coding-agent` skill is opt-in: set
|
||||
`skills.entries.coding-agent.enabled: true` before exposing it to agents,
|
||||
then make sure one of `claude`, `codex`, `opencode`, or `pi` is installed and
|
||||
authenticated for its own CLI.
|
||||
</ParamField>
|
||||
<ParamField path="apiKey" type='string | { source, provider, id }'>
|
||||
Convenience for skills that declare `metadata.openclaw.primaryEnv`. Supports plaintext or SecretRef.
|
||||
|
||||
@@ -6,7 +6,11 @@ metadata:
|
||||
"openclaw":
|
||||
{
|
||||
"emoji": "🧩",
|
||||
"requires": { "anyBins": ["claude", "codex", "opencode", "pi"] },
|
||||
"requires":
|
||||
{
|
||||
"anyBins": ["claude", "codex", "opencode", "pi"],
|
||||
"config": ["skills.entries.coding-agent.enabled"],
|
||||
},
|
||||
"install":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ import { buildWorkspaceSkillStatus } from "./skills-status.js";
|
||||
import { writeSkill } from "./skills.e2e-test-helpers.js";
|
||||
import { createCanonicalFixtureSkill } from "./skills.test-helpers.js";
|
||||
import type { SkillEntry } from "./skills/types.js";
|
||||
import { loadWorkspaceSkillEntries } from "./skills/workspace.js";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
@@ -166,6 +167,63 @@ describe("buildWorkspaceSkillStatus", () => {
|
||||
expect(skill?.bundled).toBe(true);
|
||||
});
|
||||
|
||||
it("requires explicit enablement before exposing bundled coding-agent", async () => {
|
||||
const workspaceDir = await createTempWorkspaceDir();
|
||||
const bundledSkillsDir = path.resolve("skills");
|
||||
const entries = loadWorkspaceSkillEntries(workspaceDir, {
|
||||
managedSkillsDir: path.join(workspaceDir, ".managed"),
|
||||
bundledSkillsDir,
|
||||
config: {
|
||||
skills: {
|
||||
allowBundled: ["coding-agent"],
|
||||
},
|
||||
},
|
||||
});
|
||||
const codingAgent = entries.find((entry) => entry.skill.name === "coding-agent");
|
||||
expect(codingAgent).toBeDefined();
|
||||
|
||||
const eligibility = {
|
||||
remote: {
|
||||
platforms: [process.platform],
|
||||
hasBin: () => false,
|
||||
hasAnyBin: (bins: string[]) => bins.includes("codex"),
|
||||
},
|
||||
};
|
||||
const defaultReport = withEnv({ PATH: "" }, () =>
|
||||
buildWorkspaceSkillStatus(workspaceDir, {
|
||||
entries: [codingAgent as SkillEntry],
|
||||
config: {
|
||||
skills: {
|
||||
allowBundled: ["coding-agent"],
|
||||
},
|
||||
},
|
||||
eligibility,
|
||||
}),
|
||||
);
|
||||
const defaultStatus = defaultReport.skills[0];
|
||||
expect(defaultStatus?.eligible).toBe(false);
|
||||
expect(defaultStatus?.requirements.config).toEqual(["skills.entries.coding-agent.enabled"]);
|
||||
expect(defaultStatus?.missing.config).toEqual(["skills.entries.coding-agent.enabled"]);
|
||||
|
||||
const enabledReport = withEnv({ PATH: "" }, () =>
|
||||
buildWorkspaceSkillStatus(workspaceDir, {
|
||||
entries: [codingAgent as SkillEntry],
|
||||
config: {
|
||||
skills: {
|
||||
allowBundled: ["coding-agent"],
|
||||
entries: {
|
||||
"coding-agent": { enabled: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
eligibility,
|
||||
}),
|
||||
);
|
||||
const enabledStatus = enabledReport.skills[0];
|
||||
expect(enabledStatus?.eligible).toBe(true);
|
||||
expect(enabledStatus?.missing.config).toEqual([]);
|
||||
});
|
||||
|
||||
it("does not mark an overridden workspace skill as bundled by bundled name alone", async () => {
|
||||
const bundledDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-bundled-"));
|
||||
tempDirs.push(bundledDir);
|
||||
|
||||
Reference in New Issue
Block a user