From 996e9226e559afe8a5814e88b780b067d4773f20 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 25 Apr 2026 03:30:19 +0100 Subject: [PATCH] fix(skills): restore legacy skill metadata fallback (#71346) --- CHANGELOG.md | 1 + docs/tools/skills.md | 5 +++++ src/compat/legacy-names.test.ts | 10 ++++++++++ src/shared/frontmatter.test.ts | 11 +++++++++++ 4 files changed, 27 insertions(+) create mode 100644 src/compat/legacy-names.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b6a3e8e4bcf..b9141a0c01b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai - Dashboard/Windows: open Control UI and OAuth URLs through the system URL handler without `cmd.exe` parsing or PATH-based `rundll32` lookup, and reject non-HTTP browser-open inputs. Fixes #71098. Thanks @Sanjays2402. - Providers/OpenAI: separate API-key and Codex sign-in onboarding groups, and avoid replaying stale OpenAI Responses reasoning blocks after a model route switch. +- Skills: honor legacy `metadata.clawdbot` requirements and installer hints when `metadata.openclaw` is absent, so older skills no longer appear ready when required binaries are missing. Fixes #71323. Thanks @chen-zhang-cs-code. - Browser/config: expand `~` in `browser.executablePath` before Chromium launch, so home-relative custom browser paths no longer fail with `ENOENT`. Fixes #67264. Thanks @Quratulain-bilal. - Telegram/streaming: hide tool-progress status updates by default while keeping explicit `streaming.preview.toolProgress` opt-in support for edited preview messages. Fixes #71320. Thanks @neeravmakwana. - Gateway/sessions: copy the oversized `sessions.json` to a rotation backup before the atomic rewrite instead of renaming the live store away, so a crash during rotation keeps the existing session-to-transcript mapping authoritative. Fixes #68229. Thanks @jjjojoj. diff --git a/docs/tools/skills.md b/docs/tools/skills.md index 867a833831b..c9a03108074 100644 --- a/docs/tools/skills.md +++ b/docs/tools/skills.md @@ -203,6 +203,11 @@ Fields under `metadata.openclaw`: - `primaryEnv` — env var name associated with `skills.entries..apiKey`. - `install` — optional array of installer specs used by the macOS Skills UI (brew/node/go/uv/download). +Legacy `metadata.clawdbot` blocks are still accepted when +`metadata.openclaw` is absent, so older installed skills keep their dependency +gates and installer hints. New and updated skills should use +`metadata.openclaw`. + Note on sandboxing: - `requires.bins` is checked on the **host** at skill load time. diff --git a/src/compat/legacy-names.test.ts b/src/compat/legacy-names.test.ts new file mode 100644 index 00000000000..bc379e64b60 --- /dev/null +++ b/src/compat/legacy-names.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from "vitest"; +import { LEGACY_MANIFEST_KEYS, MANIFEST_KEY, PROJECT_NAME } from "./legacy-names.js"; + +describe("compat/legacy-names", () => { + it("keeps the current manifest key primary while exposing legacy fallbacks", () => { + expect(PROJECT_NAME).toBe("openclaw"); + expect(MANIFEST_KEY).toBe("openclaw"); + expect(LEGACY_MANIFEST_KEYS).toEqual(["clawdbot"]); + }); +}); diff --git a/src/shared/frontmatter.test.ts b/src/shared/frontmatter.test.ts index 778359b41c4..776b9b58194 100644 --- a/src/shared/frontmatter.test.ts +++ b/src/shared/frontmatter.test.ts @@ -59,6 +59,17 @@ describe("shared/frontmatter", () => { ).toEqual({ requires: { bins: ["op"] }, install: [] }); }); + test("resolveOpenClawManifestBlock prefers current manifest keys over legacy keys", () => { + expect( + resolveOpenClawManifestBlock({ + frontmatter: { + metadata: + "{ openclaw: { requires: { bins: ['current'] } }, clawdbot: { requires: { bins: ['legacy'] } } }", + }, + }), + ).toEqual({ requires: { bins: ["current"] } }); + }); + test("resolveOpenClawManifestBlock returns undefined for invalid input", () => { expect(resolveOpenClawManifestBlock({ frontmatter: {} })).toBeUndefined(); expect(