@@ -506,15 +506,27 @@ mod embedded_skill {
506506 . 1
507507 }
508508
509- /// Top-level frontmatter keys, without pulling in a YAML dependency.
510- fn frontmatter_keys ( manifest : & str ) -> Vec < String > {
511- let body = manifest
509+ /// The manifest with LF endings.
510+ ///
511+ /// Git checks the repository out with CRLF on Windows, so the frontmatter
512+ /// parsing below must not assume the separator it happens to see on Unix.
513+ fn skill_manifest_lf ( ) -> String {
514+ skill_manifest ( ) . replace ( "\r \n " , "\n " )
515+ }
516+
517+ /// The frontmatter block, between the opening and closing fences.
518+ fn frontmatter ( manifest : & str ) -> & str {
519+ manifest
512520 . strip_prefix ( "---\n " )
513- . expect ( "SKILL.md opens with a frontmatter fence" ) ;
514- let ( frontmatter, _) = body
521+ . expect ( "SKILL.md opens with a frontmatter fence" )
515522 . split_once ( "\n ---\n " )
516- . expect ( "SKILL.md closes its frontmatter fence" ) ;
517- frontmatter
523+ . expect ( "SKILL.md closes its frontmatter fence" )
524+ . 0
525+ }
526+
527+ /// Top-level frontmatter keys, without pulling in a YAML dependency.
528+ fn frontmatter_keys ( manifest : & str ) -> Vec < String > {
529+ frontmatter ( manifest)
518530 . lines ( )
519531 . filter ( |line| !line. starts_with ( char:: is_whitespace) && !line. trim ( ) . is_empty ( ) )
520532 . filter_map ( |line| line. split_once ( ':' ) )
@@ -540,7 +552,7 @@ mod embedded_skill {
540552
541553 #[ test]
542554 fn skill_frontmatter_uses_only_agent_skills_spec_fields ( ) {
543- let keys = frontmatter_keys ( skill_manifest ( ) ) ;
555+ let keys = frontmatter_keys ( & skill_manifest_lf ( ) ) ;
544556 for key in & keys {
545557 assert ! (
546558 SPEC_FRONTMATTER_FIELDS . contains( & key. as_str( ) ) ,
@@ -554,7 +566,7 @@ mod embedded_skill {
554566
555567 #[ test]
556568 fn skill_declares_its_name_and_stays_within_the_listing_budget ( ) {
557- let manifest = skill_manifest ( ) ;
569+ let manifest = skill_manifest_lf ( ) ;
558570 assert ! (
559571 manifest. contains( & format!( "name: {SKILL_NAME}" ) ) ,
560572 "SKILL.md must declare name: {SKILL_NAME}"
@@ -565,12 +577,7 @@ mod embedded_skill {
565577 upgrade can replace an installed copy without --force"
566578 ) ;
567579
568- let frontmatter = manifest
569- . strip_prefix ( "---\n " )
570- . and_then ( |body| body. split_once ( "\n ---\n " ) )
571- . expect ( "SKILL.md has frontmatter" )
572- . 0 ;
573- let description = frontmatter
580+ let description = frontmatter ( & manifest)
574581 . split_once ( "description:" )
575582 . expect ( "SKILL.md declares a description" )
576583 . 1 ;
0 commit comments