Skip to content

Commit 95f30cf

Browse files
Reject an empty skill body on every publish path
Escalate an empty or whitespace-only body from info to error in the shared checkFormat validator, so skill and workflow publishes fail before minting on any path, not just the webview.
1 parent 052c6e9 commit 95f30cf

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

packages/core/src/nft/checkFormat.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ describe("nft/checkFormat — checkFormat", () => {
3535
expect(r.errors.some((e) => e.field === "description")).toBe(true);
3636
});
3737

38+
it("errors on an empty body (the permanent mint would carry no instructions)", () => {
39+
const r = checkFormat(VALID.replace(/\n\nThis skill teaches.*\n/, "\n\n"));
40+
expect(r.ok).toBe(false);
41+
expect(r.errors.some((e) => e.field === "body")).toBe(true);
42+
});
43+
3844
it("does NOT error on a long skill (codeIn auto-chunks; no size rule)", () => {
3945
const r = checkFormat(VALID + "x".repeat(5000));
4046
expect(r.errors.some((e) => e.field === "size")).toBe(false);

packages/core/src/nft/checkFormat.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ function isValidBase58(s: string): boolean {
107107
* Check a skill's SKILL.md format. NO size limit (codeIn auto-chunks). Rules:
108108
* name — required; 1–64 chars; kebab-case (error)
109109
* description — required; ≥20 chars (error); >500 (warning)
110-
* body — <50 chars (info)
110+
* body — empty (error); <50 chars (info)
111111
* license — present but not SPDX-like (warning)
112112
* repository — present but not an http(s) URL (warning)
113113
* category — missing (warning, search trait)
@@ -135,8 +135,11 @@ export function checkFormat(skillMd: string): FormatResult {
135135
add(result, "description", "warning", `"description" is long (${description.length} chars); keep it under 500`);
136136
}
137137

138-
if (body.trim().length < 50) {
139-
add(result, "body", "info", `Skill body is very short (${body.trim().length} chars); consider expanding it`);
138+
const bodyLen = body.trim().length;
139+
if (bodyLen === 0) {
140+
add(result, "body", "error", "body is empty — it holds the instructions the agent runs, and the mint is permanent");
141+
} else if (bodyLen < 50) {
142+
add(result, "body", "info", `Skill body is very short (${bodyLen} chars); consider expanding it`);
140143
}
141144

142145
const license = frontmatter.license;

0 commit comments

Comments
 (0)