File tree Expand file tree Collapse file tree 3 files changed +42
-3
lines changed
Sources/CodexSkillManager/Workers
Tests/CodexSkillManagerTests Expand file tree Collapse file tree 3 files changed +42
-3
lines changed Original file line number Diff line number Diff line change @@ -26,7 +26,7 @@ let package = Package(
2626 ] ) ,
2727 . testTarget(
2828 name: " CodexSkillManagerTests " ,
29- dependencies: [ ] ,
29+ dependencies: [ " CodexSkillManager " ] ,
3030 path: " Tests/CodexSkillManagerTests " ,
3131 swiftSettings: [
3232 . unsafeFlags( [ " -strict-concurrency=complete " ] ) ,
Original file line number Diff line number Diff line change @@ -86,12 +86,16 @@ actor SkillFileWorker {
8686
8787 func scanSkills( at baseURL: URL , storageKey: String ) throws -> [ ScannedSkillData ] {
8888 let fileManager = FileManager . default
89- guard fileManager. fileExists ( atPath: baseURL. path) else {
89+
90+ // Directory symlinks can fail URL-based enumeration on macOS.
91+ let directoryURL = baseURL. resolvingSymlinksInPath ( )
92+
93+ guard fileManager. fileExists ( atPath: directoryURL. path) else {
9094 return [ ]
9195 }
9296
9397 let items = try fileManager. contentsOfDirectory (
94- at: baseURL ,
98+ at: directoryURL ,
9599 includingPropertiesForKeys: [ . isDirectoryKey] ,
96100 options: [ . skipsHiddenFiles]
97101 )
Original file line number Diff line number Diff line change 1+ import Foundation
2+ import Testing
3+
4+ @testable import CodexSkillManager
5+
6+ @Suite ( " Symlink Scan " )
7+ struct SymlinkScanTests {
8+ @Test ( " scanSkills follows directory symlinks " )
9+ func scanSkillsFollowsDirectorySymlinks( ) async throws {
10+ let fileManager = FileManager . default
11+ let tempRoot = fileManager. temporaryDirectory. appendingPathComponent ( UUID ( ) . uuidString)
12+ defer { try ? fileManager. removeItem ( at: tempRoot) }
13+
14+ let realRoot = tempRoot. appendingPathComponent ( " real " )
15+ let symlinkRoot = tempRoot. appendingPathComponent ( " link " )
16+
17+ try fileManager. createDirectory ( at: realRoot, withIntermediateDirectories: true )
18+
19+ let skillRoot = realRoot. appendingPathComponent ( " my-skill " )
20+ try fileManager. createDirectory ( at: skillRoot, withIntermediateDirectories: true )
21+ try " # My Skill \n " . write (
22+ to: skillRoot. appendingPathComponent ( " SKILL.md " ) ,
23+ atomically: true ,
24+ encoding: . utf8
25+ )
26+
27+ try fileManager. createSymbolicLink ( at: symlinkRoot, withDestinationURL: realRoot)
28+
29+ let worker = SkillFileWorker ( )
30+ let scanned = try await worker. scanSkills ( at: symlinkRoot, storageKey: " test " )
31+
32+ #expect( scanned. count == 1 )
33+ #expect( scanned. first? . name == " my-skill " )
34+ }
35+ }
You can’t perform that action at this time.
0 commit comments