mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
Add 'Always allow read-only' option
This commit is contained in:
@@ -233,6 +233,7 @@ export class ClaudeDev {
|
|||||||
private api: ApiHandler
|
private api: ApiHandler
|
||||||
private maxRequestsPerTask: number
|
private maxRequestsPerTask: number
|
||||||
private customInstructions?: string
|
private customInstructions?: string
|
||||||
|
private alwaysAllowReadOnly: boolean
|
||||||
private requestCount = 0
|
private requestCount = 0
|
||||||
apiConversationHistory: Anthropic.MessageParam[] = []
|
apiConversationHistory: Anthropic.MessageParam[] = []
|
||||||
claudeMessages: ClaudeMessage[] = []
|
claudeMessages: ClaudeMessage[] = []
|
||||||
@@ -249,6 +250,7 @@ export class ClaudeDev {
|
|||||||
apiConfiguration: ApiConfiguration,
|
apiConfiguration: ApiConfiguration,
|
||||||
maxRequestsPerTask?: number,
|
maxRequestsPerTask?: number,
|
||||||
customInstructions?: string,
|
customInstructions?: string,
|
||||||
|
alwaysAllowReadOnly?: boolean,
|
||||||
task?: string,
|
task?: string,
|
||||||
images?: string[],
|
images?: string[],
|
||||||
historyItem?: HistoryItem
|
historyItem?: HistoryItem
|
||||||
@@ -257,6 +259,7 @@ export class ClaudeDev {
|
|||||||
this.api = buildApiHandler(apiConfiguration)
|
this.api = buildApiHandler(apiConfiguration)
|
||||||
this.maxRequestsPerTask = maxRequestsPerTask ?? DEFAULT_MAX_REQUESTS_PER_TASK
|
this.maxRequestsPerTask = maxRequestsPerTask ?? DEFAULT_MAX_REQUESTS_PER_TASK
|
||||||
this.customInstructions = customInstructions
|
this.customInstructions = customInstructions
|
||||||
|
this.alwaysAllowReadOnly = alwaysAllowReadOnly ?? false
|
||||||
|
|
||||||
if (historyItem) {
|
if (historyItem) {
|
||||||
this.taskId = historyItem.id
|
this.taskId = historyItem.id
|
||||||
@@ -281,6 +284,10 @@ export class ClaudeDev {
|
|||||||
this.customInstructions = customInstructions
|
this.customInstructions = customInstructions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAlwaysAllowReadOnly(alwaysAllowReadOnly: boolean | undefined) {
|
||||||
|
this.alwaysAllowReadOnly = alwaysAllowReadOnly ?? false
|
||||||
|
}
|
||||||
|
|
||||||
async handleWebviewAskResponse(askResponse: ClaudeAskResponse, text?: string, images?: string[]) {
|
async handleWebviewAskResponse(askResponse: ClaudeAskResponse, text?: string, images?: string[]) {
|
||||||
this.askResponse = askResponse
|
this.askResponse = askResponse
|
||||||
this.askResponseText = text
|
this.askResponseText = text
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ type GlobalStateKey =
|
|||||||
| "maxRequestsPerTask"
|
| "maxRequestsPerTask"
|
||||||
| "lastShownAnnouncementId"
|
| "lastShownAnnouncementId"
|
||||||
| "customInstructions"
|
| "customInstructions"
|
||||||
|
| "alwaysAllowReadOnly"
|
||||||
| "taskHistory"
|
| "taskHistory"
|
||||||
|
|
||||||
export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
||||||
@@ -144,18 +145,27 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
|
|
||||||
async initClaudeDevWithTask(task?: string, images?: string[]) {
|
async initClaudeDevWithTask(task?: string, images?: string[]) {
|
||||||
await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one
|
await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one
|
||||||
const { maxRequestsPerTask, apiConfiguration, customInstructions } = await this.getState()
|
const { maxRequestsPerTask, apiConfiguration, customInstructions, alwaysAllowReadOnly } = await this.getState()
|
||||||
this.claudeDev = new ClaudeDev(this, apiConfiguration, maxRequestsPerTask, customInstructions, task, images)
|
|
||||||
}
|
|
||||||
|
|
||||||
async initClaudeDevWithHistoryItem(historyItem: HistoryItem) {
|
|
||||||
await this.clearTask()
|
|
||||||
const { maxRequestsPerTask, apiConfiguration, customInstructions } = await this.getState()
|
|
||||||
this.claudeDev = new ClaudeDev(
|
this.claudeDev = new ClaudeDev(
|
||||||
this,
|
this,
|
||||||
apiConfiguration,
|
apiConfiguration,
|
||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
customInstructions,
|
customInstructions,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
|
task,
|
||||||
|
images
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async initClaudeDevWithHistoryItem(historyItem: HistoryItem) {
|
||||||
|
await this.clearTask()
|
||||||
|
const { maxRequestsPerTask, apiConfiguration, customInstructions, alwaysAllowReadOnly } = await this.getState()
|
||||||
|
this.claudeDev = new ClaudeDev(
|
||||||
|
this,
|
||||||
|
apiConfiguration,
|
||||||
|
maxRequestsPerTask,
|
||||||
|
customInstructions,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
historyItem
|
historyItem
|
||||||
@@ -312,6 +322,11 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
this.claudeDev?.updateCustomInstructions(message.text || undefined)
|
this.claudeDev?.updateCustomInstructions(message.text || undefined)
|
||||||
await this.postStateToWebview()
|
await this.postStateToWebview()
|
||||||
break
|
break
|
||||||
|
case "alwaysAllowReadOnly":
|
||||||
|
await this.updateGlobalState("alwaysAllowReadOnly", message.bool || undefined)
|
||||||
|
this.claudeDev?.updateAlwaysAllowReadOnly(message.bool || undefined)
|
||||||
|
await this.postStateToWebview()
|
||||||
|
break
|
||||||
case "askResponse":
|
case "askResponse":
|
||||||
this.claudeDev?.handleWebviewAskResponse(message.askResponse!, message.text, message.images)
|
this.claudeDev?.handleWebviewAskResponse(message.askResponse!, message.text, message.images)
|
||||||
break
|
break
|
||||||
@@ -481,6 +496,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
lastShownAnnouncementId,
|
lastShownAnnouncementId,
|
||||||
customInstructions,
|
customInstructions,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
taskHistory,
|
taskHistory,
|
||||||
koduCredits,
|
koduCredits,
|
||||||
} = await this.getState()
|
} = await this.getState()
|
||||||
@@ -491,6 +507,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
apiConfiguration,
|
apiConfiguration,
|
||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
customInstructions,
|
customInstructions,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
themeName: vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"),
|
themeName: vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"),
|
||||||
claudeMessages: this.claudeDev?.claudeMessages || [],
|
claudeMessages: this.claudeDev?.claudeMessages || [],
|
||||||
taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),
|
taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),
|
||||||
@@ -601,6 +618,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
lastShownAnnouncementId,
|
lastShownAnnouncementId,
|
||||||
customInstructions,
|
customInstructions,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
taskHistory,
|
taskHistory,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||||
@@ -616,6 +634,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
this.getGlobalState("maxRequestsPerTask") as Promise<number | undefined>,
|
this.getGlobalState("maxRequestsPerTask") as Promise<number | undefined>,
|
||||||
this.getGlobalState("lastShownAnnouncementId") as Promise<string | undefined>,
|
this.getGlobalState("lastShownAnnouncementId") as Promise<string | undefined>,
|
||||||
this.getGlobalState("customInstructions") as Promise<string | undefined>,
|
this.getGlobalState("customInstructions") as Promise<string | undefined>,
|
||||||
|
this.getGlobalState("alwaysAllowReadOnly") as Promise<boolean | undefined>,
|
||||||
this.getGlobalState("taskHistory") as Promise<HistoryItem[] | undefined>,
|
this.getGlobalState("taskHistory") as Promise<HistoryItem[] | undefined>,
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -648,6 +667,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
lastShownAnnouncementId,
|
lastShownAnnouncementId,
|
||||||
customInstructions,
|
customInstructions,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
taskHistory,
|
taskHistory,
|
||||||
koduCredits,
|
koduCredits,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface ExtensionState {
|
|||||||
apiConfiguration?: ApiConfiguration
|
apiConfiguration?: ApiConfiguration
|
||||||
maxRequestsPerTask?: number
|
maxRequestsPerTask?: number
|
||||||
customInstructions?: string
|
customInstructions?: string
|
||||||
|
alwaysAllowReadOnly?: boolean
|
||||||
themeName?: string
|
themeName?: string
|
||||||
claudeMessages: ClaudeMessage[]
|
claudeMessages: ClaudeMessage[]
|
||||||
taskHistory: HistoryItem[]
|
taskHistory: HistoryItem[]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export interface WebviewMessage {
|
|||||||
| "apiConfiguration"
|
| "apiConfiguration"
|
||||||
| "maxRequestsPerTask"
|
| "maxRequestsPerTask"
|
||||||
| "customInstructions"
|
| "customInstructions"
|
||||||
|
| "alwaysAllowReadOnly"
|
||||||
| "webviewDidLaunch"
|
| "webviewDidLaunch"
|
||||||
| "newTask"
|
| "newTask"
|
||||||
| "askResponse"
|
| "askResponse"
|
||||||
@@ -23,6 +24,7 @@ export interface WebviewMessage {
|
|||||||
askResponse?: ClaudeAskResponse
|
askResponse?: ClaudeAskResponse
|
||||||
apiConfiguration?: ApiConfiguration
|
apiConfiguration?: ApiConfiguration
|
||||||
images?: string[]
|
images?: string[]
|
||||||
|
bool?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ClaudeAskResponse = "yesButtonTapped" | "noButtonTapped" | "messageResponse"
|
export type ClaudeAskResponse = "yesButtonTapped" | "noButtonTapped" | "messageResponse"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const App: React.FC = () => {
|
|||||||
const [apiConfiguration, setApiConfiguration] = useState<ApiConfiguration | undefined>(undefined)
|
const [apiConfiguration, setApiConfiguration] = useState<ApiConfiguration | undefined>(undefined)
|
||||||
const [maxRequestsPerTask, setMaxRequestsPerTask] = useState<string>("")
|
const [maxRequestsPerTask, setMaxRequestsPerTask] = useState<string>("")
|
||||||
const [customInstructions, setCustomInstructions] = useState<string>("")
|
const [customInstructions, setCustomInstructions] = useState<string>("")
|
||||||
|
const [alwaysAllowReadOnly, setAlwaysAllowReadOnly] = useState<boolean>(false)
|
||||||
const [vscodeThemeName, setVscodeThemeName] = useState<string | undefined>(undefined)
|
const [vscodeThemeName, setVscodeThemeName] = useState<string | undefined>(undefined)
|
||||||
const [claudeMessages, setClaudeMessages] = useState<ClaudeMessage[]>([])
|
const [claudeMessages, setClaudeMessages] = useState<ClaudeMessage[]>([])
|
||||||
const [taskHistory, setTaskHistory] = useState<HistoryItem[]>([])
|
const [taskHistory, setTaskHistory] = useState<HistoryItem[]>([])
|
||||||
@@ -52,6 +53,7 @@ const App: React.FC = () => {
|
|||||||
message.state!.maxRequestsPerTask !== undefined ? message.state!.maxRequestsPerTask.toString() : ""
|
message.state!.maxRequestsPerTask !== undefined ? message.state!.maxRequestsPerTask.toString() : ""
|
||||||
)
|
)
|
||||||
setCustomInstructions(message.state!.customInstructions || "")
|
setCustomInstructions(message.state!.customInstructions || "")
|
||||||
|
setAlwaysAllowReadOnly(message.state!.alwaysAllowReadOnly || false)
|
||||||
setVscodeThemeName(message.state!.themeName)
|
setVscodeThemeName(message.state!.themeName)
|
||||||
setClaudeMessages(message.state!.claudeMessages)
|
setClaudeMessages(message.state!.claudeMessages)
|
||||||
setTaskHistory(message.state!.taskHistory)
|
setTaskHistory(message.state!.taskHistory)
|
||||||
@@ -112,6 +114,8 @@ const App: React.FC = () => {
|
|||||||
setMaxRequestsPerTask={setMaxRequestsPerTask}
|
setMaxRequestsPerTask={setMaxRequestsPerTask}
|
||||||
customInstructions={customInstructions}
|
customInstructions={customInstructions}
|
||||||
setCustomInstructions={setCustomInstructions}
|
setCustomInstructions={setCustomInstructions}
|
||||||
|
alwaysAllowReadOnly={alwaysAllowReadOnly}
|
||||||
|
setAlwaysAllowReadOnly={setAlwaysAllowReadOnly}
|
||||||
onDone={() => setShowSettings(false)}
|
onDone={() => setShowSettings(false)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { VSCodeButton, VSCodeLink, VSCodeTextArea, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
import {
|
||||||
|
VSCodeButton,
|
||||||
|
VSCodeLink,
|
||||||
|
VSCodeTextArea,
|
||||||
|
VSCodeTextField,
|
||||||
|
VSCodeCheckbox,
|
||||||
|
} from "@vscode/webview-ui-toolkit/react"
|
||||||
import React, { useEffect, useState } from "react"
|
import React, { useEffect, useState } from "react"
|
||||||
import { ApiConfiguration } from "../../../src/shared/api"
|
import { ApiConfiguration } from "../../../src/shared/api"
|
||||||
import { validateApiConfiguration, validateMaxRequestsPerTask } from "../utils/validate"
|
import { validateApiConfiguration, validateMaxRequestsPerTask } from "../utils/validate"
|
||||||
@@ -15,6 +21,8 @@ type SettingsViewProps = {
|
|||||||
customInstructions: string
|
customInstructions: string
|
||||||
setCustomInstructions: React.Dispatch<React.SetStateAction<string>>
|
setCustomInstructions: React.Dispatch<React.SetStateAction<string>>
|
||||||
onDone: () => void
|
onDone: () => void
|
||||||
|
alwaysAllowReadOnly: boolean
|
||||||
|
setAlwaysAllowReadOnly: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const SettingsView = ({
|
const SettingsView = ({
|
||||||
@@ -27,6 +35,8 @@ const SettingsView = ({
|
|||||||
customInstructions,
|
customInstructions,
|
||||||
setCustomInstructions,
|
setCustomInstructions,
|
||||||
onDone,
|
onDone,
|
||||||
|
alwaysAllowReadOnly,
|
||||||
|
setAlwaysAllowReadOnly,
|
||||||
}: SettingsViewProps) => {
|
}: SettingsViewProps) => {
|
||||||
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
||||||
const [maxRequestsErrorMessage, setMaxRequestsErrorMessage] = useState<string | undefined>(undefined)
|
const [maxRequestsErrorMessage, setMaxRequestsErrorMessage] = useState<string | undefined>(undefined)
|
||||||
@@ -42,6 +52,7 @@ const SettingsView = ({
|
|||||||
vscode.postMessage({ type: "apiConfiguration", apiConfiguration })
|
vscode.postMessage({ type: "apiConfiguration", apiConfiguration })
|
||||||
vscode.postMessage({ type: "maxRequestsPerTask", text: maxRequestsPerTask })
|
vscode.postMessage({ type: "maxRequestsPerTask", text: maxRequestsPerTask })
|
||||||
vscode.postMessage({ type: "customInstructions", text: customInstructions })
|
vscode.postMessage({ type: "customInstructions", text: customInstructions })
|
||||||
|
vscode.postMessage({ type: "alwaysAllowReadOnly", bool: alwaysAllowReadOnly })
|
||||||
onDone()
|
onDone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,6 +136,23 @@ const SettingsView = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: 5 }}>
|
||||||
|
<VSCodeCheckbox
|
||||||
|
checked={alwaysAllowReadOnly}
|
||||||
|
onChange={(e: any) => setAlwaysAllowReadOnly(e.target.checked)}>
|
||||||
|
<span style={{ fontWeight: "500" }}>Always allow read-only operations</span>
|
||||||
|
</VSCodeCheckbox>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontSize: "12px",
|
||||||
|
marginTop: "5px",
|
||||||
|
color: "var(--vscode-descriptionForeground)",
|
||||||
|
}}>
|
||||||
|
When enabled, Claude will automatically read files and view directories without requiring you to
|
||||||
|
click the Allow button.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style={{ marginBottom: 5 }}>
|
<div style={{ marginBottom: 5 }}>
|
||||||
<VSCodeTextArea
|
<VSCodeTextArea
|
||||||
value={customInstructions}
|
value={customInstructions}
|
||||||
|
|||||||
Reference in New Issue
Block a user