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