From f6c424af584caa8144b58436acac584f5b4cdd58 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 20 Apr 2026 14:44:14 -0600 Subject: [PATCH 1/2] fix(skill): fix clerk skill install failing on published releases The bundled SKILL.md description contained a colon-space (`raw HTTP: it handles`) which made strict YAML frontmatter parsers treat it as a nested mapping and reject the skill as invalid, so `skills add` reported `No valid skills found` and `clerk skill install` aborted. Wrap the description in single quotes so it parses as a plain scalar regardless of internal punctuation, and add a regression test that parses the staged frontmatter with the `yaml` dep. --- .changeset/skill-install-frontmatter.md | 5 +++++ .../src/commands/skill/install.test.ts | 22 +++++++++++++++++++ skills/clerk/SKILL.md | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset/skill-install-frontmatter.md diff --git a/.changeset/skill-install-frontmatter.md b/.changeset/skill-install-frontmatter.md new file mode 100644 index 00000000..9ec40f79 --- /dev/null +++ b/.changeset/skill-install-frontmatter.md @@ -0,0 +1,5 @@ +--- +"clerk": patch +--- + +Fix `clerk skill install` failing with `No valid skills found` on published releases. The bundled skill's frontmatter now parses as strict YAML. diff --git a/packages/cli-core/src/commands/skill/install.test.ts b/packages/cli-core/src/commands/skill/install.test.ts index c3338677..73b13be1 100644 --- a/packages/cli-core/src/commands/skill/install.test.ts +++ b/packages/cli-core/src/commands/skill/install.test.ts @@ -2,6 +2,7 @@ import { test, expect, describe } from "bun:test"; import { existsSync } from "node:fs"; import { readFile, stat } from "node:fs/promises"; import { join } from "node:path"; +import YAML from "yaml"; import { buildSkillsArgs, renderSkillVersionPlaceholder, withStagedClerkSkill } from "./install.ts"; describe("buildSkillsArgs", () => { @@ -136,6 +137,27 @@ describe("withStagedClerkSkill version rendering", () => { }); }); +describe("bundled SKILL.md frontmatter", () => { + // Regression guard: the upstream `skills` CLI parses SKILL.md frontmatter as + // strict YAML and silently drops skills whose frontmatter fails to parse. + // An unquoted `: ` inside the description (e.g. `raw HTTP: it handles`) + // triggers "Nested mappings are not allowed in compact mappings" and makes + // `clerk skill install` fail with "No valid skills found". + test("parses as YAML with name and description strings", async () => { + await withStagedClerkSkill(undefined, async (stageDir) => { + const content = await readFile(join(stageDir, "clerk/SKILL.md"), "utf8"); + const frontmatter = content.match(/^---\n([\s\S]*?)\n---/)?.[1]; + expect(frontmatter, "SKILL.md must have YAML frontmatter").toBeDefined(); + + const parsed = YAML.parse(frontmatter!); + expect(typeof parsed.name).toBe("string"); + expect(typeof parsed.description).toBe("string"); + expect(parsed.name.length).toBeGreaterThan(0); + expect(parsed.description.length).toBeGreaterThan(0); + }); + }); +}); + describe("renderSkillVersionPlaceholder", () => { test("replaces {{CLI_VERSION}} with the provided version", () => { const result = renderSkillVersionPlaceholder("Pinned: `bunx clerk@{{CLI_VERSION}}`.", "1.2.3"); diff --git a/skills/clerk/SKILL.md b/skills/clerk/SKILL.md index 9d09b88f..dcb1ce78 100644 --- a/skills/clerk/SKILL.md +++ b/skills/clerk/SKILL.md @@ -1,6 +1,6 @@ --- name: clerk -description: Operate the Clerk CLI (`clerk` binary) for authentication, user/org/session management, instance config, env keys, and any Clerk Backend or Platform API call. Use when the user mentions Clerk management tasks, "list clerk users", "create a clerk user", "update organization", "pull clerk config", "clerk env pull", "clerk doctor", "clerk api", or any ad-hoc Clerk API request. Prefer the CLI over raw HTTP: it handles auth, key resolution, app/instance targeting, and formatting automatically. +description: 'Operate the Clerk CLI (`clerk` binary) for authentication, user/org/session management, instance config, env keys, and any Clerk Backend or Platform API call. Use when the user mentions Clerk management tasks, "list clerk users", "create a clerk user", "update organization", "pull clerk config", "clerk env pull", "clerk doctor", "clerk api", or any ad-hoc Clerk API request. Prefer the CLI over raw HTTP: it handles auth, key resolution, app/instance targeting, and formatting automatically.' --- # Clerk CLI From ebeb00837db34f55a540dc70e0bc39b239978b62 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 20 Apr 2026 15:11:51 -0600 Subject: [PATCH 2/2] refactor(skill): use folded block scalar for description frontmatter Switch the SKILL.md description from a single-quoted scalar to a folded block scalar (>-). Folded block scalars accept any characters in the body, so future prose containing an apostrophe (e.g. "the user's app") cannot silently reintroduce the parse failure this branch fixes. The folded value is identical to the previous single-line string. --- skills/clerk/SKILL.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/skills/clerk/SKILL.md b/skills/clerk/SKILL.md index dcb1ce78..0ce9f6f3 100644 --- a/skills/clerk/SKILL.md +++ b/skills/clerk/SKILL.md @@ -1,6 +1,12 @@ --- name: clerk -description: 'Operate the Clerk CLI (`clerk` binary) for authentication, user/org/session management, instance config, env keys, and any Clerk Backend or Platform API call. Use when the user mentions Clerk management tasks, "list clerk users", "create a clerk user", "update organization", "pull clerk config", "clerk env pull", "clerk doctor", "clerk api", or any ad-hoc Clerk API request. Prefer the CLI over raw HTTP: it handles auth, key resolution, app/instance targeting, and formatting automatically.' +description: >- + Operate the Clerk CLI (`clerk` binary) for authentication, user/org/session management, + instance config, env keys, and any Clerk Backend or Platform API call. Use when the user + mentions Clerk management tasks, "list clerk users", "create a clerk user", "update + organization", "pull clerk config", "clerk env pull", "clerk doctor", "clerk api", or + any ad-hoc Clerk API request. Prefer the CLI over raw HTTP: it handles auth, key + resolution, app/instance targeting, and formatting automatically. --- # Clerk CLI