import { VSCodeButton, VSCodeCheckbox, VSCodeLink, VSCodeTextArea, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" import { memo, useEffect, useState } from "react" import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { onDone: () => void } const SettingsView = ({ onDone }: SettingsViewProps) => { const { apiConfiguration, version, customInstructions, setCustomInstructions, alwaysAllowReadOnly, setAlwaysAllowReadOnly, alwaysAllowWrite, setAlwaysAllowWrite, alwaysAllowExecute, setAlwaysAllowExecute, alwaysAllowBrowser, setAlwaysAllowBrowser, alwaysAllowMcp, setAlwaysAllowMcp, soundEnabled, setSoundEnabled, diffEnabled, setDiffEnabled, openRouterModels, setAllowedCommands, allowedCommands, } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) const [commandInput, setCommandInput] = useState("") const handleSubmit = () => { const apiValidationResult = validateApiConfiguration(apiConfiguration) const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) setApiErrorMessage(apiValidationResult) setModelIdErrorMessage(modelIdValidationResult) if (!apiValidationResult && !modelIdValidationResult) { vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) vscode.postMessage({ type: "customInstructions", text: customInstructions }) vscode.postMessage({ type: "alwaysAllowReadOnly", bool: alwaysAllowReadOnly }) vscode.postMessage({ type: "alwaysAllowWrite", bool: alwaysAllowWrite }) vscode.postMessage({ type: "alwaysAllowExecute", bool: alwaysAllowExecute }) vscode.postMessage({ type: "alwaysAllowBrowser", bool: alwaysAllowBrowser }) vscode.postMessage({ type: "alwaysAllowMcp", bool: alwaysAllowMcp }) vscode.postMessage({ type: "allowedCommands", commands: allowedCommands ?? [] }) vscode.postMessage({ type: "soundEnabled", bool: soundEnabled }) vscode.postMessage({ type: "diffEnabled", bool: diffEnabled }) onDone() } } useEffect(() => { setApiErrorMessage(undefined) setModelIdErrorMessage(undefined) }, [apiConfiguration]) // Initial validation on mount useEffect(() => { const apiValidationResult = validateApiConfiguration(apiConfiguration) const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) setApiErrorMessage(apiValidationResult) setModelIdErrorMessage(modelIdValidationResult) }, [apiConfiguration, openRouterModels]) const handleResetState = () => { vscode.postMessage({ type: "resetState" }) } const handleAddCommand = () => { const currentCommands = allowedCommands ?? [] if (commandInput && !currentCommands.includes(commandInput)) { const newCommands = [...currentCommands, commandInput] setAllowedCommands(newCommands) setCommandInput("") vscode.postMessage({ type: "allowedCommands", commands: newCommands }) } } return (

Settings

Done
setCustomInstructions(e.target?.value ?? "")}> Custom Instructions

These instructions are added to the end of the system prompt sent with every request. Custom instructions set in .clinerules and .cursorrules in the working directory are also included.

setDiffEnabled(e.target.checked)}> Enable editing through diffs

When enabled, Cline will be able to edit files more quickly and will automatically reject truncated full-file writes. Works best with the latest Claude 3.5 Sonnet model.

setAlwaysAllowReadOnly(e.target.checked)}> Always approve read-only operations

When enabled, Cline will automatically view directory contents and read files without requiring you to click the Approve button.

⚠️ High-Risk Auto-Approve Settings

The following settings allow Cline to automatically perform potentially dangerous operations without requiring approval. Enable these settings only if you fully trust the AI and understand the associated security risks.

setAlwaysAllowWrite(e.target.checked)}> Always approve write operations

Automatically create and edit files without requiring approval

setAlwaysAllowBrowser(e.target.checked)}> Always approve browser actions

Automatically perform browser actions without requiring approval
Note: Only applies when the model supports computer use

{ setAlwaysAllowMcp(e.target.checked) vscode.postMessage({ type: "alwaysAllowMcp", bool: e.target.checked }) }}> Always approve MCP tools

Enable auto-approval of individual MCP tools in the MCP Servers view (requires both this setting and the tool's individual "Always allow" checkbox)

setAlwaysAllowExecute(e.target.checked)}> Always approve allowed execute operations

Automatically execute allowed terminal commands without requiring approval

{alwaysAllowExecute && (
Allowed Auto-Execute Commands

Command prefixes that can be auto-executed when "Always approve execute operations" is enabled.

setCommandInput(e.target.value)} onKeyDown={(e: any) => { if (e.key === 'Enter') { e.preventDefault() handleAddCommand() } }} placeholder="Enter command prefix (e.g., 'git ')" style={{ flexGrow: 1 }} /> Add
{(allowedCommands ?? []).map((cmd, index) => (
{cmd} { const newCommands = (allowedCommands ?? []).filter((_, i) => i !== index) setAllowedCommands(newCommands) vscode.postMessage({ type: "allowedCommands", commands: newCommands }) }} >
))}
)}

Experimental Features

setSoundEnabled(e.target.checked)}> Enable sound effects

When enabled, Cline will play sound effects for notifications and events.

{IS_DEV && ( <>
Debug
Reset State

This will reset all global state and secret storage in the extension.

)}

If you have any questions or feedback, feel free to open an issue at{" "} https://github.com/RooVetGit/Roo-Cline

v{version}

) } export default memo(SettingsView)