fix(ce-release-notes): backtick-wrap <skill-name> token in description (#603)
Some checks failed
CI / pr-title (push) Has been cancelled
CI / test (push) Has been cancelled
Release PR / release-pr (push) Has been cancelled
Release PR / publish-cli (push) Has been cancelled

This commit is contained in:
Trevin Chow
2026-04-19 00:38:15 -07:00
committed by GitHub
parent b575e49c29
commit 2aee4d4203
3 changed files with 13 additions and 1 deletions

View File

@@ -83,6 +83,7 @@ When adding or modifying skills, verify compliance with the skill spec:
- [ ] `name:` present and matches directory name (lowercase-with-hyphens)
- [ ] `description:` present and describes **what it does and when to use it** (per official spec: "Explains code with diagrams. Use when exploring how code works.")
- [ ] `description:` value is quoted (single or double) if it contains colons -- unquoted colons break `js-yaml` strict parsing and crash `install --to opencode/codex`. Run `bun test tests/frontmatter.test.ts` to verify.
- [ ] `description:` value does not contain raw angle-bracket tokens like `<skill-name>`, `<tag>`, or `<placeholder>` -- Cowork's plugin validator parses descriptions as HTML and rejects unknown tags with a generic "Plugin validation failed" banner (see issue #602). Claude Code tolerates them, so the bug only surfaces downstream. Backtick-wrap the token (`` `<skill-name>` ``) or rephrase. Enforced by `tests/frontmatter.test.ts`.
### Reference File Inclusion (Required if references/ exists)

View File

@@ -1,6 +1,6 @@
---
name: ce-release-notes
description: Summarize recent compound-engineering plugin releases, or answer a specific question about a past release with a version citation. Use when the user types `/ce-release-notes` or asks "what changed in compound-engineering recently?" or "what happened to <skill-name>?".
description: Summarize recent compound-engineering plugin releases, or answer a specific question about a past release with a version citation. Use when the user types `/ce-release-notes` or asks "what changed in compound-engineering recently?" or "what happened to `<skill-name>`?".
argument-hint: "[optional: question about a past release]"
disable-model-invocation: true
---

View File

@@ -72,6 +72,17 @@ describe("frontmatter YAML validity", () => {
test(`${pluginRoot}/${rel} has valid strict YAML frontmatter`, () => {
expect(() => load(yaml)).not.toThrow()
})
test(`${pluginRoot}/${rel} description has no unwrapped angle-bracket tokens`, () => {
const parsed = load(yaml) as Record<string, unknown> | null
const description = parsed && typeof parsed.description === "string" ? parsed.description : ""
// Strip backtick-delimited spans; what remains must not contain a bare <tag>.
// Cowork's plugin validator parses descriptions as HTML and rejects
// unknown tags with a silent "Plugin validation failed" banner. See issue #602.
const stripped = description.replace(/`[^`]*`/g, "")
const bareTag = stripped.match(/<[A-Za-z][\w-]*>/)
expect(bareTag, `Backtick-wrap or rephrase: ${bareTag?.[0] ?? ""}`).toBeNull()
})
}
}
})