mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
232 lines
7.4 KiB
TypeScript
232 lines
7.4 KiB
TypeScript
import { VSCodeButton, VSCodeCheckbox, VSCodeLink, VSCodeTextArea } 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,
|
|
openRouterModels,
|
|
} = useExtensionState()
|
|
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
|
const [modelIdErrorMessage, setModelIdErrorMessage] = useState<string | undefined>(undefined)
|
|
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 })
|
|
onDone()
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
setApiErrorMessage(undefined)
|
|
setModelIdErrorMessage(undefined)
|
|
}, [apiConfiguration])
|
|
|
|
// validate as soon as the component is mounted
|
|
/*
|
|
useEffect will use stale values of variables if they are not included in the dependency array. so trying to use useEffect with a dependency array of only one value for example will use any other variables' old values. In most cases you don't want this, and should opt to use react-use hooks.
|
|
|
|
useEffect(() => {
|
|
// uses someVar and anotherVar
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [someVar])
|
|
|
|
If we only want to run code once on mount we can use react-use's useEffectOnce or useMount
|
|
*/
|
|
|
|
const handleResetState = () => {
|
|
vscode.postMessage({ type: "resetState" })
|
|
}
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
position: "fixed",
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
padding: "10px 0px 0px 20px",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
overflow: "hidden",
|
|
}}>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
marginBottom: "17px",
|
|
paddingRight: 17,
|
|
}}>
|
|
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>Settings</h3>
|
|
<VSCodeButton onClick={handleSubmit}>Done</VSCodeButton>
|
|
</div>
|
|
<div
|
|
style={{ flexGrow: 1, overflowY: "scroll", paddingRight: 8, display: "flex", flexDirection: "column" }}>
|
|
<div style={{ marginBottom: 5 }}>
|
|
<ApiOptions
|
|
showModelOptions={true}
|
|
apiErrorMessage={apiErrorMessage}
|
|
modelIdErrorMessage={modelIdErrorMessage}
|
|
/>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: 5 }}>
|
|
<VSCodeTextArea
|
|
value={customInstructions ?? ""}
|
|
style={{ width: "100%" }}
|
|
rows={4}
|
|
placeholder={
|
|
'e.g. "Run unit tests at the end", "Use TypeScript with async/await", "Speak in Spanish"'
|
|
}
|
|
onInput={(e: any) => setCustomInstructions(e.target?.value ?? "")}>
|
|
<span style={{ fontWeight: "500" }}>Custom Instructions</span>
|
|
</VSCodeTextArea>
|
|
<p
|
|
style={{
|
|
fontSize: "12px",
|
|
marginTop: "5px",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
}}>
|
|
These instructions are added to the end of the system prompt sent with every request.
|
|
</p>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: 5 }}>
|
|
<VSCodeCheckbox
|
|
checked={alwaysAllowReadOnly}
|
|
onChange={(e: any) => setAlwaysAllowReadOnly(e.target.checked)}>
|
|
<span style={{ fontWeight: "500" }}>Always approve read-only operations</span>
|
|
</VSCodeCheckbox>
|
|
<p
|
|
style={{
|
|
fontSize: "12px",
|
|
marginTop: "5px",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
}}>
|
|
When enabled, Cline will automatically view directory contents and read files without requiring
|
|
you to click the Approve button.
|
|
</p>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: 5 }}>
|
|
<VSCodeCheckbox
|
|
checked={alwaysAllowWrite}
|
|
onChange={(e: any) => setAlwaysAllowWrite(e.target.checked)}>
|
|
<span style={{ fontWeight: "500" }}>Always approve write operations</span>
|
|
</VSCodeCheckbox>
|
|
<p
|
|
style={{
|
|
fontSize: "12px",
|
|
marginTop: "5px",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
}}>
|
|
When enabled, Cline will automatically write to files and create directories
|
|
without requiring you to click the Approve button.
|
|
</p>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: 5 }}>
|
|
<VSCodeCheckbox
|
|
checked={alwaysAllowExecute}
|
|
onChange={(e: any) => setAlwaysAllowExecute(e.target.checked)}>
|
|
<span style={{ fontWeight: "500" }}>Always approve execute operations</span>
|
|
</VSCodeCheckbox>
|
|
<p
|
|
style={{
|
|
fontSize: "12px",
|
|
marginTop: "5px",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
}}>
|
|
When enabled, Cline will automatically CLI commands without requiring
|
|
you to click the Approve button.
|
|
</p>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: 5 }}>
|
|
<VSCodeCheckbox
|
|
checked={alwaysAllowBrowser}
|
|
onChange={(e: any) => setAlwaysAllowBrowser(e.target.checked)}>
|
|
<span style={{ fontWeight: "500" }}>Always approve browser actions</span>
|
|
</VSCodeCheckbox>
|
|
<p
|
|
style={{
|
|
fontSize: "12px",
|
|
marginTop: "5px",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
}}>
|
|
When enabled, Cline will automatically perform browser actions without requiring
|
|
you to click the Approve button.
|
|
</p>
|
|
</div>
|
|
|
|
{IS_DEV && (
|
|
<>
|
|
<div style={{ marginTop: "10px", marginBottom: "4px" }}>Debug</div>
|
|
<VSCodeButton onClick={handleResetState} style={{ marginTop: "5px", width: "auto" }}>
|
|
Reset State
|
|
</VSCodeButton>
|
|
<p
|
|
style={{
|
|
fontSize: "12px",
|
|
marginTop: "5px",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
}}>
|
|
This will reset all global state and secret storage in the extension.
|
|
</p>
|
|
</>
|
|
)}
|
|
|
|
<div
|
|
style={{
|
|
textAlign: "center",
|
|
color: "var(--vscode-descriptionForeground)",
|
|
fontSize: "12px",
|
|
lineHeight: "1.2",
|
|
marginTop: "auto",
|
|
padding: "10px 8px 15px 0px",
|
|
}}>
|
|
<p style={{ wordWrap: "break-word", margin: 0, padding: 0 }}>
|
|
If you have any questions or feedback, feel free to open an issue at{" "}
|
|
<VSCodeLink href="https://github.com/cline/cline" style={{ display: "inline" }}>
|
|
https://github.com/cline/cline
|
|
</VSCodeLink>
|
|
</p>
|
|
<p style={{ fontStyle: "italic", margin: "10px 0 0 0", padding: 0 }}>v{version}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default memo(SettingsView)
|