mirror of
https://github.com/addyosmani/agent-skills.git
synced 2026-10-26 15:05:04 +00:00
fix(linter): ignore comments and nested metadata keys in skill frontmatter
This commit is contained in:
1 parent
1401c8b803
commit
1ab25ea1c8
2 files changed
+55
-7
No files matched your search
@@ -9,7 +9,7 @@ const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
|
||||
const { lintSkillContent, lintSkillLayout, topLevelFrontmatterKeys } = require('./skill-lint.js');
|
||||
const { lintSkillContent, lintSkillLayout, topLevelFrontmatterKeys, parseFrontmatter, frontmatterYamlErrors } = require('./skill-lint.js');
|
||||
|
||||
const KNOWN = new Set(['alpha', 'beta']);
|
||||
|
||||
@@ -648,3 +648,50 @@ test('the spec-key check tolerates CRLF frontmatter', () => {
|
||||
const { errors } = lintSkillContent('alpha', content, KNOWN);
|
||||
assert.equal(errors.filter(e => /key 'temperature'/.test(e)).length, 1);
|
||||
});
|
||||
|
||||
test('parseFrontmatter ignores comments and nested metadata keys', () => {
|
||||
const content = [
|
||||
'---',
|
||||
'name: alpha',
|
||||
'# note: this is a comment',
|
||||
'description: Designs alphas. Use when building one.',
|
||||
'metadata:',
|
||||
' name: beta',
|
||||
' description: Nested details without trigger',
|
||||
'---',
|
||||
'',
|
||||
].join('\n');
|
||||
assert.deepEqual(parseFrontmatter(content), {
|
||||
name: 'alpha',
|
||||
description: 'Designs alphas. Use when building one.',
|
||||
metadata: '',
|
||||
});
|
||||
});
|
||||
|
||||
test('frontmatterYamlErrors ignores comment lines containing colons or quotes', () => {
|
||||
const content = [
|
||||
'---',
|
||||
'name: alpha',
|
||||
'# note: a comment: with a colon and "unclosed quote',
|
||||
'description: "Designs alphas. Use when building one."',
|
||||
'---',
|
||||
'',
|
||||
].join('\n');
|
||||
assert.deepEqual(frontmatterYamlErrors(content), []);
|
||||
});
|
||||
|
||||
test('a skill with frontmatter comments and nested metadata passes validation', () => {
|
||||
const content = withAllSections([
|
||||
'---',
|
||||
'name: alpha',
|
||||
'# Note: keep description up to date: check docs',
|
||||
'description: Designs alphas. Use when building one.',
|
||||
'metadata:',
|
||||
' name: beta',
|
||||
' description: Internal notes',
|
||||
'---',
|
||||
].join('\n'));
|
||||
const { errors } = lintSkillContent('alpha', content, KNOWN);
|
||||
assert.deepEqual(errors, []);
|
||||
});
|
||||
|
||||
@@ -184,11 +184,12 @@ function parseFrontmatter(content) {
|
||||
|
||||
const result = {};
|
||||
for (const line of match[1].split(/\r?\n/)) {
|
||||
const colonIdx = line.indexOf(':');
|
||||
if (colonIdx === -1) continue;
|
||||
const key = line.slice(0, colonIdx).trim();
|
||||
const value = line.slice(colonIdx + 1).trim().replace(/^['"]|['"]$/g, '');
|
||||
if (key) result[key] = value;
|
||||
if (/^\s*#/.test(line)) continue;
|
||||
const m = line.match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);
|
||||
if (!m) continue;
|
||||
const key = m[1];
|
||||
const value = m[2].trim().replace(/^['"]|['"]$/g, '');
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -234,7 +235,7 @@ function frontmatterYamlErrors(content) {
|
||||
const lines = match[1].split(/\r?\n/);
|
||||
lines.forEach((line, i) => {
|
||||
const lineNo = i + 2; // the opening `---` is line 1
|
||||
if (!line.trim()) return;
|
||||
if (!line.trim() || /^\s*#/.test(line)) return;
|
||||
|
||||
if (/^[ ]*\t/.test(line)) {
|
||||
errors.push(
|
||||
|
||||
Reference in new issue
Block a user