fix(linter): ignore comments and nested metadata keys in skill frontmatter

This commit is contained in:
root committed 2026-10-07 15:51:07 +00:00
1 parent 1401c8b803
commit 1ab25ea1c8
2 files changed
+55 -7

No files matched your search

+48 -1
View File
@@ -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, []);
});
+7 -6
View File
@@ -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(