@@ -525,17 +525,17 @@ You are a helpful agent`;
525525 expect ( result ) . toEqual ( mockAgentFile ) ;
526526 } ) ;
527527
528- it ( "should fallback to file path when hub loading fails for slug-like path" , async ( ) => {
528+ it ( "should fallback to file path when hub loading fails for slug-like path with .md extension " , async ( ) => {
529529 mockLoadPackageFromHub . mockRejectedValue ( new Error ( "Hub error" ) ) ;
530530 mockPathResolve . mockImplementation ( ( p : string ) => `/resolved/${ p } ` ) ;
531531 mockReadFileSync . mockReturnValue ( mockFileContent ) ;
532532
533- const result = await agentFileService . getAgentFile ( "owner/agent" ) ;
533+ const result = await agentFileService . getAgentFile ( "owner/agent.md " ) ;
534534
535- expect ( mockLoadPackageFromHub ) . toHaveBeenCalled ( ) ;
536- expect ( mockPathResolve ) . toHaveBeenCalledWith ( "owner/agent" ) ;
535+ expect ( mockLoadPackageFromHub ) . toHaveBeenCalled ( ) ; // Two-part paths try hub first
536+ expect ( mockPathResolve ) . toHaveBeenCalledWith ( "owner/agent.md " ) ;
537537 expect ( mockReadFileSync ) . toHaveBeenCalledWith (
538- "/resolved/owner/agent" ,
538+ "/resolved/owner/agent.md " ,
539539 "utf-8" ,
540540 ) ;
541541 expect ( result ) . toBeDefined ( ) ;
@@ -641,13 +641,9 @@ You are a helpful agent`;
641641
642642 describe ( "path format edge cases" , ( ) => {
643643 it ( "should treat single-part path as file path, not hub slug" , async ( ) => {
644- const singlePath = "agent" ;
645- mockPathResolve . mockReturnValue ( "/resolved/agent" ) ;
644+ const singlePath = "agent.md " ;
645+ mockPathResolve . mockReturnValue ( "/resolved/agent.md " ) ;
646646 mockReadFileSync . mockReturnValue ( mockFileContent ) ;
647- // Make hub loading fail so it falls back to file system
648- mockLoadPackageFromHub . mockRejectedValueOnce (
649- new Error ( "Not a hub slug" ) ,
650- ) ;
651647
652648 const result = await agentFileService . getAgentFile ( singlePath ) ;
653649
@@ -658,13 +654,9 @@ You are a helpful agent`;
658654 } ) ;
659655
660656 it ( "should treat three-part path as file path, not hub slug" , async ( ) => {
661- const threePath = "path/to/agent" ;
662- mockPathResolve . mockReturnValue ( "/resolved/path/to/agent" ) ;
657+ const threePath = "path/to/agent.md " ;
658+ mockPathResolve . mockReturnValue ( "/resolved/path/to/agent.md " ) ;
663659 mockReadFileSync . mockReturnValue ( mockFileContent ) ;
664- // Make hub loading fail so it falls back to file system
665- mockLoadPackageFromHub . mockRejectedValueOnce (
666- new Error ( "Not a hub slug" ) ,
667- ) ;
668660
669661 const result = await agentFileService . getAgentFile ( threePath ) ;
670662
@@ -675,29 +667,20 @@ You are a helpful agent`;
675667 } ) ;
676668
677669 it ( "should not treat two-part path with empty part as hub slug" , async ( ) => {
678- const emptyPartPath = "owner/" ;
679- mockPathResolve . mockReturnValue ( "/resolved/owner/" ) ;
680- mockReadFileSync . mockReturnValue ( mockFileContent ) ;
681- // Make hub loading fail so it falls back to file system
682- mockLoadPackageFromHub . mockRejectedValueOnce (
683- new Error ( "Not a hub slug" ) ,
684- ) ;
670+ const emptyPartPath = "owner/" ; // Empty second part
685671
686- const result = await agentFileService . getAgentFile ( emptyPartPath ) ;
672+ // With the new behavior, non-markdown paths throw errors
673+ await expect (
674+ agentFileService . getAgentFile ( emptyPartPath ) ,
675+ ) . rejects . toThrow ( "Not a markdown file" ) ;
687676
688- expect ( mockLoadPackageFromHub ) . not . toHaveBeenCalled ( ) ;
689- expect ( mockPathResolve ) . toHaveBeenCalledWith ( emptyPartPath ) ;
690- expect ( result ) . toBeDefined ( ) ;
677+ expect ( mockLoadPackageFromHub ) . not . toHaveBeenCalled ( ) ; // Empty part means no hub attempt
691678 } ) ;
692679
693680 it ( "should not treat path starting with slash as hub slug" , async ( ) => {
694- const slashPath = "/owner/agent" ;
681+ const slashPath = "/owner/agent.md " ;
695682 mockPathResolve . mockReturnValue ( slashPath ) ;
696683 mockReadFileSync . mockReturnValue ( mockFileContent ) ;
697- // Make hub loading fail so it falls back to file system
698- mockLoadPackageFromHub . mockRejectedValueOnce (
699- new Error ( "Not a hub slug" ) ,
700- ) ;
701684
702685 const result = await agentFileService . getAgentFile ( slashPath ) ;
703686
@@ -741,19 +724,30 @@ You are a helpful agent`;
741724 ) . rejects . toThrow ( "Failed to load agent from ./invalid.md" ) ;
742725 } ) ;
743726
744- it ( "should throw error when hub loading fails and file fallback also fails " , async ( ) => {
727+ it ( "should throw error when file reading fails for markdown path " , async ( ) => {
745728 mockLoadPackageFromHub . mockRejectedValue ( new Error ( "Hub error" ) ) ;
746- mockPathResolve . mockReturnValue ( "/resolved/owner/agent" ) ;
729+ mockPathResolve . mockReturnValue ( "/resolved/owner/agent.md " ) ;
747730 mockReadFileSync . mockImplementation ( ( ) => {
748731 throw new Error ( "File not found" ) ;
749732 } ) ;
750733
734+ await expect (
735+ agentFileService . getAgentFile ( "owner/agent.md" ) ,
736+ ) . rejects . toThrow ( "Failed to load agent from owner/agent.md" ) ;
737+ await expect (
738+ agentFileService . getAgentFile ( "owner/agent.md" ) ,
739+ ) . rejects . toThrow ( "File not found" ) ;
740+ } ) ;
741+
742+ it ( "should throw error for non-markdown paths without trying file fallback" , async ( ) => {
743+ mockLoadPackageFromHub . mockRejectedValue ( new Error ( "Hub error" ) ) ;
744+
751745 await expect (
752746 agentFileService . getAgentFile ( "owner/agent" ) ,
753747 ) . rejects . toThrow ( "Failed to load agent from owner/agent" ) ;
754748 await expect (
755749 agentFileService . getAgentFile ( "owner/agent" ) ,
756- ) . rejects . toThrow ( "File not found " ) ;
750+ ) . rejects . toThrow ( "Not a markdown file " ) ;
757751 } ) ;
758752
759753 it ( "should handle permission errors when reading files" , async ( ) => {
0 commit comments