( path: string, toolPermissionContext: ToolPermissionContext, toolType: 'edit' | 'read', behavior: 'allow' | 'deny' | 'ask', )
| 963 | } |
| 964 | |
| 965 | export function matchingRuleForInput( |
| 966 | path: string, |
| 967 | toolPermissionContext: ToolPermissionContext, |
| 968 | toolType: 'edit' | 'read', |
| 969 | behavior: 'allow' | 'deny' | 'ask', |
| 970 | ): PermissionRule | null { |
| 971 | let fileAbsolutePath = expandPath(path) |
| 972 | |
| 973 | // On Windows, convert to POSIX format to match against permission patterns |
| 974 | if (getPlatform() === 'windows' && fileAbsolutePath.includes('\\')) { |
| 975 | fileAbsolutePath = windowsPathToPosixPath(fileAbsolutePath) |
| 976 | } |
| 977 | |
| 978 | const patternsByRoot = getPatternsByRoot( |
| 979 | toolPermissionContext, |
| 980 | toolType, |
| 981 | behavior, |
| 982 | ) |
| 983 | |
| 984 | // Check each root for a matching pattern |
| 985 | for (const [root, patternMap] of patternsByRoot.entries()) { |
| 986 | // Transform patterns for the ignore library |
| 987 | const patterns = Array.from(patternMap.keys()).map(pattern => { |
| 988 | let adjustedPattern = pattern |
| 989 | |
| 990 | // Remove /** suffix - ignore library treats 'path' as matching both |
| 991 | // the path itself and everything inside it |
| 992 | if (adjustedPattern.endsWith('/**')) { |
| 993 | adjustedPattern = adjustedPattern.slice(0, -3) |
| 994 | } |
| 995 | |
| 996 | return adjustedPattern |
| 997 | }) |
| 998 | |
| 999 | const ig = ignore().add(patterns) |
| 1000 | |
| 1001 | // Use cross-platform relative path helper for POSIX-style patterns |
| 1002 | const relativePathStr = relativePath( |
| 1003 | root ?? getCwd(), |
| 1004 | fileAbsolutePath ?? getCwd(), |
| 1005 | ) |
| 1006 | |
| 1007 | if (relativePathStr.startsWith(`..${DIR_SEP}`)) { |
| 1008 | // The path is outside the root, so ignore it |
| 1009 | continue |
| 1010 | } |
| 1011 | |
| 1012 | // Important: ig.test throws if you give it an empty string |
| 1013 | if (!relativePathStr) { |
| 1014 | continue |
| 1015 | } |
| 1016 | |
| 1017 | const igResult = ig.test(relativePathStr) |
| 1018 | |
| 1019 | if (igResult.ignored && igResult.rule) { |
| 1020 | // Map the matched pattern back to the original rule |
| 1021 | const originalPattern = igResult.rule.pattern |
| 1022 |
no test coverage detected