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

Function canUseTool

src/cli/print.ts:4152–4261  ·  view source on GitHub ↗
(
    tool,
    input,
    toolUseContext,
    assistantMessage,
    toolUseId,
    forceDecision,
  )

Source from the content-addressed store, hash-verified

4150 permissionPromptTool: PermissionPromptTool,
4151): CanUseToolFn {
4152 const canUseTool: CanUseToolFn = async (
4153 tool,
4154 input,
4155 toolUseContext,
4156 assistantMessage,
4157 toolUseId,
4158 forceDecision,
4159 ) => {
4160 const mainPermissionResult =
4161 forceDecision ??
4162 (await hasPermissionsToUseTool(
4163 tool,
4164 input,
4165 toolUseContext,
4166 assistantMessage,
4167 toolUseId,
4168 ))
4169
4170 // If the tool is allowed or denied, return the result
4171 if (
4172 mainPermissionResult.behavior === 'allow' ||
4173 mainPermissionResult.behavior === 'deny'
4174 ) {
4175 return mainPermissionResult
4176 }
4177
4178 // Race the permission prompt tool against the abort signal.
4179 //
4180 // Why we need this: The permission prompt tool may block indefinitely waiting
4181 // for user input (e.g., via stdin or a UI dialog). If the user triggers an
4182 // interrupt (Ctrl+C), we need to detect it even while the tool is blocked.
4183 // Without this race, the abort check would only run AFTER the tool completes,
4184 // which may never happen if the tool is waiting for input that will never come.
4185 //
4186 // The second check (combinedSignal.aborted) handles a race condition where
4187 // abort fires after Promise.race resolves but before we reach this check.
4188 const { signal: combinedSignal, cleanup: cleanupAbortListener } =
4189 createCombinedAbortSignal(toolUseContext.abortController.signal)
4190
4191 // Check if already aborted before starting the race
4192 if (combinedSignal.aborted) {
4193 cleanupAbortListener()
4194 return {
4195 behavior: 'deny',
4196 message: 'Permission prompt was aborted.',
4197 decisionReason: {
4198 type: 'permissionPromptTool' as const,
4199 permissionPromptToolName: tool.name,
4200 toolResult: undefined,
4201 },
4202 }
4203 }
4204
4205 const abortPromise = new Promise<'aborted'>(resolve => {
4206 combinedSignal.addEventListener('abort', () => resolve('aborted'), {
4207 once: true,
4208 })
4209 })

Callers 1

wrappedCanUseToolMethod · 0.50

Calls 5

hasPermissionsToUseToolFunction · 0.85
resolveFunction · 0.50
parseMethod · 0.45

Tested by

no test coverage detected