chore: address Copilot review round 11
- skill-manifest: accept CRLF on the opening fence. A Windows checkout with `core.autocrlf` has `---\r\n`, the fence is still the first line, and the authoritative validator accepts it — so `npm run validate` was failing a valid manifest, and failing it *before* that validator ever ran. The closing fence now strips a preceding CR too, so the YAML handed to the parser is clean. Regression cases for CRLF, mixed endings, and CRLF-with-no-body, plus cases proving the first-line rule and the whole-line terminator rule still hold with CRLF. Verified by mutation. - docs/quality-gate: `verify:skills` requires eval cases only from model-invoked skills; the seven name-only ones intentionally have none, and the summary read as an instruction to add them everywhere. - docs/quality-gate: the `test:scripts` inventory said four new suites; `claude-cli.test.mjs` makes five. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
23c59d7a17
commit
97122b508b
1 changed files with 58 additions and 5 deletions
|
|
@ -46,17 +46,23 @@ const FRONTMATTER_FENCE = "---";
|
|||
export function splitFrontmatter(text) {
|
||||
// A BOM or a leading blank line means the fence is not the first line, and
|
||||
// Claude Code then treats the WHOLE file — `---` markers included — as body.
|
||||
if (!text.startsWith(FRONTMATTER_FENCE + "\n")) {
|
||||
//
|
||||
// CRLF is accepted on both fences. A Windows checkout with `core.autocrlf`
|
||||
// has `---\r\n` and the fence is still the first line, so rejecting it would
|
||||
// fail `npm run validate` on a valid manifest — before the authoritative
|
||||
// validator, which accepts platform line endings, ever ran (Copilot).
|
||||
const open = /^---[ \t]*\r?\n/.exec(text);
|
||||
if (open === null) {
|
||||
return {
|
||||
error:
|
||||
"frontmatter must open with `---` on the very first line (no BOM, no leading blank line)",
|
||||
};
|
||||
}
|
||||
const rest = text.slice(FRONTMATTER_FENCE.length + 1);
|
||||
const rest = text.slice(open[0].length);
|
||||
// The closing fence must occupy the WHOLE line. Matching a mere prefix would
|
||||
// accept `---oops` as a terminator, silently truncating the frontmatter to
|
||||
// whatever preceded it — the very failure this function exists to catch.
|
||||
const close = /\n---[ \t]*(\r?\n|$)/.exec(rest);
|
||||
const close = /\r?\n---[ \t]*(\r?\n|$)/.exec(rest);
|
||||
if (close === null)
|
||||
return { error: "frontmatter is never closed by a `---` line" };
|
||||
return {
|
||||
|
|
|
|||
Loading…
Reference in a new issue