Windows CRLF checkouts cause false build-from-skills and validation failures
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 287
- Forks
- 58
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 17
Description
Bug description
On a clean Windows checkout with Git's normal core.autocrlf=true behavior, the repository's generated-content and structural validation gates report broad false failures even though the referenced headings, fenced CLI examples, and catalog rows are present.
This is separate from #118, which fixes Windows npm/Vercel CLI shim execution. This issue is limited to newline parsing in the repository's build and validation scripts.
Steps to reproduce
From a clean checkout of current main (de37d3199cd0f62cd7efdc4a9489e111e2deeedb, plugin 0.45.1) on Windows:
git config core.autocrlf true
bun install --frozen-lockfile
bun run build:from-skills:check
bun run validate
The affected files are checked out as CRLF while their index form remains LF:
i/lf w/crlf attr/ commands/bootstrap.md
i/lf w/crlf attr/ generated/skill-catalog.md
i/lf w/crlf attr/ scripts/build-from-skills.ts
i/lf w/crlf attr/ scripts/validate.ts
i/lf w/crlf attr/ skills/vercel-functions/SKILL.md
Actual behavior
bun run build:from-skills:check exits 1 with:
- 5 template failures
- 35 includes reported as missing headings
All 35 referenced headings exist in their source Markdown files.
bun run validate exits 1 with:
- 4 commands falsely reported as lacking fenced Vercel CLI examples
- all 30 skills falsely reported as missing from
generated/skill-catalog.md
The full test suite cascades into 74 failures on this baseline (828 pass, 74 fail).
Expected behavior
Markdown parsing and validation should produce the same result for LF and CRLF checkouts.
Root cause
The parsers assume LF-only text:
scripts/build-from-skills.tsusesmarkdown.split("\n"), leaving a trailing\ron each Windows line. The heading regex then fails against those lines.scripts/validate.tsrequires\nimmediately after a code-fence language tag.- Catalog parsing also uses LF-only section/table expressions.
A minimal example of the heading behavior:
const heading = "# Heading\r";
/^(#{1,6})\s+(.+)$/.test(heading); // false
/^(#{1,6})\s+(.+)$/.test(heading.replace(/\r$/, "")); // true
Suggested fix
Normalize Markdown input to LF before parsing (for example, content.replace(/\r\n?/g, "\n")) or make each relevant line/fence/catalog expression CRLF-aware. Please add regression coverage that runs the same parser fixtures with both LF and CRLF input.
Environment
- OS: Microsoft Windows NT 10.0.26200.0
- Git:
core.autocrlf=true - Bun:
1.3.14 - Node.js:
v24.15.0 - Upstream commit:
de37d3199cd0f62cd7efdc4a9489e111e2deeedb
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with scripts/build-from-skills.ts and scripts/validate.ts, then run the listed build:from-skills:check and validate commands on LF and CRLF fixtures. Trace the heading, fenced-example, and catalog parsing noted in the issue. Done means both checkouts produce the same results, with regression coverage for LF and CRLF input.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100