public async requiresAcceptance()

in server/aws-lsp-codewhisperer/src/language-server/agenticChat/tools/executeBash.ts [180:289]


    public async requiresAcceptance(
        params: ExecuteBashParams,
        approvedPaths?: Set<string>
    ): Promise<CommandValidation> {
        try {
            const args = split(params.command)
            if (!args || args.length === 0) {
                return { requiresAcceptance: true }
            }

            // Split commands by operators and process each segment
            let currentCmd: string[] = []
            const allCommands: string[][] = []

            for (const arg of args) {
                if (splitOperators.has(arg)) {
                    if (currentCmd.length > 0) {
                        allCommands.push(currentCmd)
                    }
                    currentCmd = []
                } else if (splitOperatorsArray.some(op => arg.includes(op))) {
                    return { requiresAcceptance: true }
                } else {
                    currentCmd.push(arg)
                }
            }

            if (currentCmd.length > 0) {
                allCommands.push(currentCmd)
            }

            for (const cmdArgs of allCommands) {
                if (cmdArgs.length === 0) {
                    return { requiresAcceptance: true }
                }

                // For each command, validate arguments for path safety within workspace
                for (const arg of cmdArgs) {
                    if (this.looksLikePath(arg)) {
                        // Special handling for tilde paths in Unix-like systems
                        let fullPath: string
                        if (!IS_WINDOWS_PLATFORM && arg.startsWith('~')) {
                            // Treat tilde paths as absolute paths (they will be expanded by the shell)
                            return { requiresAcceptance: true, warning: destructiveCommandWarningMessage }
                        } else if (!isAbsolute(arg) && params.cwd) {
                            // If not absolute, resolve using workingDirectory if available
                            fullPath = join(params.cwd, arg)
                        } else {
                            fullPath = arg
                        }

                        // Check if the path is already approved
                        if (approvedPaths && isPathApproved(fullPath, approvedPaths)) {
                            continue
                        }

                        const isInWorkspace = workspaceUtils.isInWorkspace(getWorkspaceFolderPaths(this.lsp), fullPath)
                        if (!isInWorkspace) {
                            return { requiresAcceptance: true, warning: outOfWorkspaceWarningmessage }
                        }
                    }
                }

                const command = cmdArgs[0]
                const category = commandCategories.get(command)

                switch (category) {
                    case CommandCategory.Destructive:
                        return { requiresAcceptance: true, warning: destructiveCommandWarningMessage }
                    case CommandCategory.Mutate:
                        return { requiresAcceptance: true, warning: mutateCommandWarningMessage }
                    case CommandCategory.ReadOnly:
                        continue
                    default:
                        return { requiresAcceptance: true }
                }
            }
            // Finally, check if the cwd is outside the workspace
            if (params.cwd) {
                // Check if the cwd is already approved
                if (!(approvedPaths && isPathApproved(params.cwd, approvedPaths))) {
                    const workspaceFolders = getWorkspaceFolderPaths(this.lsp)

                    // If there are no workspace folders, we can't validate the path
                    if (!workspaceFolders || workspaceFolders.length === 0) {
                        return { requiresAcceptance: true, warning: outOfWorkspaceWarningmessage }
                    }

                    // Normalize paths for consistent comparison
                    const normalizedCwd = params.cwd.replace(/\\/g, '/')
                    const normalizedWorkspaceFolders = workspaceFolders.map(folder => folder.replace(/\\/g, '/'))

                    // Check if the normalized cwd is in any of the normalized workspace folders
                    const isInWorkspace = normalizedWorkspaceFolders.some(
                        folder => normalizedCwd === folder || normalizedCwd.startsWith(folder + '/')
                    )

                    if (!isInWorkspace) {
                        return { requiresAcceptance: true, warning: outOfWorkspaceWarningmessage }
                    }
                }
            }

            // If we've checked all commands and none required acceptance, we're good
            return { requiresAcceptance: false }
        } catch (error) {
            this.logging.warn(`Error while checking acceptance: ${(error as Error).message}`)
            return { requiresAcceptance: true }
        }
    }