(input, context)
| 102 | return input.prompt ? `${input.url}: ${input.prompt}` : input.url |
| 103 | }, |
| 104 | async checkPermissions(input, context): Promise<PermissionDecision> { |
| 105 | const appState = context.getAppState() |
| 106 | const permissionContext = appState.toolPermissionContext |
| 107 | |
| 108 | // Check if the hostname is in the preapproved list |
| 109 | try { |
| 110 | const { url } = input as { url: string } |
| 111 | const parsedUrl = new URL(url) |
| 112 | if (isPreapprovedHost(parsedUrl.hostname, parsedUrl.pathname)) { |
| 113 | return { |
| 114 | behavior: 'allow', |
| 115 | updatedInput: input, |
| 116 | decisionReason: { type: 'other', reason: 'Preapproved host' }, |
| 117 | } |
| 118 | } |
| 119 | } catch { |
| 120 | // If URL parsing fails, continue with normal permission checks |
| 121 | } |
| 122 | |
| 123 | // Check for a rule specific to the tool input (matching hostname) |
| 124 | const ruleContent = webFetchToolInputToPermissionRuleContent(input) |
| 125 | |
| 126 | const denyRule = getRuleByContentsForTool( |
| 127 | permissionContext, |
| 128 | WebFetchTool, |
| 129 | 'deny', |
| 130 | ).get(ruleContent) |
| 131 | if (denyRule) { |
| 132 | return { |
| 133 | behavior: 'deny', |
| 134 | message: `${WebFetchTool.name} denied access to ${ruleContent}.`, |
| 135 | decisionReason: { |
| 136 | type: 'rule', |
| 137 | rule: denyRule, |
| 138 | }, |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | const askRule = getRuleByContentsForTool( |
| 143 | permissionContext, |
| 144 | WebFetchTool, |
| 145 | 'ask', |
| 146 | ).get(ruleContent) |
| 147 | if (askRule) { |
| 148 | return { |
| 149 | behavior: 'ask', |
| 150 | message: `Claude requested permissions to use ${WebFetchTool.name}, but you haven't granted it yet.`, |
| 151 | decisionReason: { |
| 152 | type: 'rule', |
| 153 | rule: askRule, |
| 154 | }, |
| 155 | suggestions: buildSuggestions(ruleContent), |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | const allowRule = getRuleByContentsForTool( |
| 160 | permissionContext, |
| 161 | WebFetchTool, |
nothing calls this directly
no test coverage detected