diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 030157f..bc19414 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -**References:** [Contributing guide](../CONTRIBUTING.md) · [Skill authoring guide](../README.md) +**References:** [Contributing guide](../CONTRIBUTING.md) · [Skill authoring guide](../README.md) · [Agent Skills spec](https://agentskills.io/specification) ## What changed @@ -35,9 +35,9 @@ ### Automated checks -Enforced by CI ([`npm run validate:skills`](../scripts/validate-skills.ts)): +Enforced by CI ([`npm run validate:skills`](../scripts/validate-skills.ts)) per the [Agent Skills spec](https://agentskills.io/specification): -- Directory is one level deep, named in kebab-case, contains `SKILL.md` -- Frontmatter `name` matches directory name; `description` is present, ≥ 20 words, and includes trigger language +- Directory is one level deep, named in kebab-case (max 64 chars), contains `SKILL.md` +- Frontmatter `name` matches directory name; `description` is present, ≥ 20 words, ≤ 1024 characters, and includes trigger language - Body is non-empty and under 500 lines - Name uses gerund form ⚠ (warning — does not block merge) diff --git a/scripts/validate-skills.ts b/scripts/validate-skills.ts index 4e1fa7d..d0e895d 100644 --- a/scripts/validate-skills.ts +++ b/scripts/validate-skills.ts @@ -81,6 +81,15 @@ const STRUCTURE_CHECKS: StructureCheck[] = [ return { errors: [] } }, }, + { + description: "Name must be at most 64 characters", + run(dirName) { + if (dirName.length > 64) { + return { errors: [`skills/${dirName}: name is ${dirName.length} characters (maximum 64)`] } + } + return { errors: [] } + }, + }, { description: "Name should use gerund form — first word should end in -ing (e.g. generating-apex-tests)", run(dirName) { @@ -176,6 +185,17 @@ const CONTENT_CHECKS: ContentCheck[] = [ return { errors: [] } }, }, + { + description: "Description must be at most 1024 characters", + run({ dirName, frontmatter }) { + if (!frontmatter) return { errors: [] } + const len = frontmatter.description?.length ?? 0 + if (len > 1024) { + return { errors: [`skills/${dirName}/SKILL.md: description is ${len} characters (maximum 1024)`] } + } + return { errors: [] } + }, + }, { description: 'Description must include trigger/activation language (contain "use")', run({ dirName, frontmatter }) { @@ -319,6 +339,9 @@ function main(): void { if (errors.length === 0) passed++ } + const hasIssues = allErrors.length > 0 || allWarnings.length > 0 + const footer = " Spec: https://agentskills.io/specification · Authoring guide: https://github.com/forcedotcom/afv-library#readme" + if (allWarnings.length > 0) { console.warn(`\n${allWarnings.length} warning(s):\n`) for (const w of allWarnings) { @@ -333,9 +356,12 @@ function main(): void { console.error(` ✗ ${err}`) } console.error("") + console.error(footer) + console.error("") process.exit(1) } else { console.log(`Skill validation passed: ${passed} of ${entries.length} skill(s) checked.`) + if (hasIssues) console.warn(footer) } }