MCPcopy
hub / github.com/codeaashu/claude-code / validatePermissionRule

Function validatePermissionRule

src/utils/settings/permissionValidation.ts:58–239  ·  view source on GitHub ↗
(rule: string)

Source from the content-addressed store, hash-verified

56 * Validates permission rule format and content
57 */
58export function validatePermissionRule(rule: string): {
59 valid: boolean
60 error?: string
61 suggestion?: string
62 examples?: string[]
63} {
64 // Empty rule check
65 if (!rule || rule.trim() === '') {
66 return { valid: false, error: 'Permission rule cannot be empty' }
67 }
68
69 // Check parentheses matching first (only count unescaped parens)
70 const openCount = countUnescapedChar(rule, '(')
71 const closeCount = countUnescapedChar(rule, ')')
72 if (openCount !== closeCount) {
73 return {
74 valid: false,
75 error: 'Mismatched parentheses',
76 suggestion:
77 'Ensure all opening parentheses have matching closing parentheses',
78 }
79 }
80
81 // Check for empty parentheses (escape-aware)
82 if (hasUnescapedEmptyParens(rule)) {
83 const toolName = rule.substring(0, rule.indexOf('('))
84 if (!toolName) {
85 return {
86 valid: false,
87 error: 'Empty parentheses with no tool name',
88 suggestion: 'Specify a tool name before the parentheses',
89 }
90 }
91 return {
92 valid: false,
93 error: 'Empty parentheses',
94 suggestion: `Either specify a pattern or use just "${toolName}" without parentheses`,
95 examples: [`${toolName}`, `${toolName}(some-pattern)`],
96 }
97 }
98
99 // Parse the rule
100 const parsed = permissionRuleValueFromString(rule)
101
102 // MCP validation - must be done before general tool validation
103 const mcpInfo = mcpInfoFromString(parsed.toolName)
104 if (mcpInfo) {
105 // MCP rules support server-level, tool-level, and wildcard permissions
106 // Valid formats:
107 // - mcp__server (server-level, all tools)
108 // - mcp__server__* (wildcard, all tools - equivalent to server-level)
109 // - mcp__server__tool (specific tool)
110
111 // MCP rules cannot have any pattern/content (parentheses)
112 // Check both parsed content and raw string since the parser normalizes
113 // standalone wildcards (e.g., "mcp__server(*)") to undefined ruleContent
114 if (parsed.ruleContent !== undefined || countUnescapedChar(rule, '(') > 0) {
115 return {

Callers 2

Calls 8

countUnescapedCharFunction · 0.85
hasUnescapedEmptyParensFunction · 0.85
mcpInfoFromStringFunction · 0.85
capitalizeFunction · 0.85
getCustomValidationFunction · 0.85
isBashPrefixToolFunction · 0.85
isFilePatternToolFunction · 0.85

Tested by

no test coverage detected