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

Method createCanUseTool

src/cli/structuredIO.ts:533–659  ·  view source on GitHub ↗
(
    onPermissionPrompt?: (details: RequiresActionDetails) => void,
  )

Source from the content-addressed store, hash-verified

531 }
532
533 createCanUseTool(
534 onPermissionPrompt?: (details: RequiresActionDetails) => void,
535 ): CanUseToolFn {
536 return async (
537 tool: Tool,
538 input: { [key: string]: unknown },
539 toolUseContext: ToolUseContext,
540 assistantMessage: AssistantMessage,
541 toolUseID: string,
542 forceDecision?: PermissionDecision,
543 ): Promise<PermissionDecision> => {
544 const mainPermissionResult =
545 forceDecision ??
546 (await hasPermissionsToUseTool(
547 tool,
548 input,
549 toolUseContext,
550 assistantMessage,
551 toolUseID,
552 ))
553 // If the tool is allowed or denied, return the result
554 if (
555 mainPermissionResult.behavior === 'allow' ||
556 mainPermissionResult.behavior === 'deny'
557 ) {
558 return mainPermissionResult
559 }
560
561 // Run PermissionRequest hooks in parallel with the SDK permission
562 // prompt. In the terminal CLI, hooks race against the interactive
563 // prompt so that e.g. a hook with --delay 20 doesn't block the UI.
564 // We need the same behavior here: the SDK host (VS Code, etc.) shows
565 // its permission dialog immediately while hooks run in the background.
566 // Whichever resolves first wins; the loser is cancelled/ignored.
567
568 // AbortController used to cancel the SDK request if a hook decides first
569 const hookAbortController = new AbortController()
570 const parentSignal = toolUseContext.abortController.signal
571 // Forward parent abort to our local controller
572 const onParentAbort = () => hookAbortController.abort()
573 parentSignal.addEventListener('abort', onParentAbort, { once: true })
574
575 try {
576 // Start the hook evaluation (runs in background)
577 const hookPromise = executePermissionRequestHooksForSDK(
578 tool.name,
579 toolUseID,
580 input,
581 toolUseContext,
582 mainPermissionResult.suggestions,
583 ).then(decision => ({ source: 'hook' as const, decision }))
584
585 // Start the SDK permission prompt immediately (don't wait for hooks)
586 const requestId = randomUUID()
587 onPermissionPrompt?.(
588 buildRequiresActionDetails(tool, input, toolUseID, requestId),
589 )
590 const sdkPromise = this.sendRequest<PermissionToolOutput>(

Callers 1

getCanUseToolFnFunction · 0.80

Tested by

no test coverage detected