diff --git a/.changeset/fuzzy-horses-run.md b/.changeset/fuzzy-horses-run.md new file mode 100644 index 00000000000..7bea3a99622 --- /dev/null +++ b/.changeset/fuzzy-horses-run.md @@ -0,0 +1,5 @@ +--- +"roo-cline": patch +--- + +Fix bug with auto-approving commands diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 50954bacfdd..f4d26d254c9 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -834,7 +834,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie const autoApprove = async () => { if (isAutoApproved(lastMessage)) { // Add delay for write operations - if (alwaysAllowWrite && isWriteToolAction(lastMessage)) { + if (lastMessage?.ask === "tool" && isWriteToolAction(lastMessage)) { await new Promise(resolve => setTimeout(resolve, writeDelayMs)) } handlePrimaryButtonClick() diff --git a/webview-ui/src/components/chat/__tests__/ChatView.test.tsx b/webview-ui/src/components/chat/__tests__/ChatView.test.tsx index 63c1ac673eb..99d12bfb95d 100644 --- a/webview-ui/src/components/chat/__tests__/ChatView.test.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatView.test.tsx @@ -247,54 +247,108 @@ describe('ChatView - Auto Approval Tests', () => { }) }) - it('auto-approves write tools when alwaysAllowWrite is enabled', async () => { - render( - - {}} - showHistoryView={() => {}} - /> - - ) + describe('Write Tool Auto-Approval Tests', () => { + it('auto-approves write tools when alwaysAllowWrite is enabled and message is a tool request', async () => { + render( + + {}} + showHistoryView={() => {}} + /> + + ) - // First hydrate state with initial task - mockPostMessage({ - alwaysAllowWrite: true, - clineMessages: [ - { - type: 'say', - say: 'task', - ts: Date.now() - 2000, - text: 'Initial task' - } - ] - }) + // First hydrate state with initial task + mockPostMessage({ + alwaysAllowWrite: true, + clineMessages: [ + { + type: 'say', + say: 'task', + ts: Date.now() - 2000, + text: 'Initial task' + } + ] + }) - // Then send the write tool ask message - mockPostMessage({ - alwaysAllowWrite: true, - clineMessages: [ - { - type: 'say', - say: 'task', - ts: Date.now() - 2000, - text: 'Initial task' - }, - { - type: 'ask', - ask: 'tool', - ts: Date.now(), - text: JSON.stringify({ tool: 'editedExistingFile', path: 'test.txt' }), - partial: false - } - ] + // Then send the write tool ask message + mockPostMessage({ + alwaysAllowWrite: true, + clineMessages: [ + { + type: 'say', + say: 'task', + ts: Date.now() - 2000, + text: 'Initial task' + }, + { + type: 'ask', + ask: 'tool', + ts: Date.now(), + text: JSON.stringify({ tool: 'editedExistingFile', path: 'test.txt' }), + partial: false + } + ] + }) + + // Wait for the auto-approval message + await waitFor(() => { + expect(vscode.postMessage).toHaveBeenCalledWith({ + type: 'askResponse', + askResponse: 'yesButtonClicked' + }) + }) }) - // Wait for the auto-approval message - await waitFor(() => { - expect(vscode.postMessage).toHaveBeenCalledWith({ + it('does not auto-approve write operations when alwaysAllowWrite is enabled but message is not a tool request', () => { + render( + + {}} + showHistoryView={() => {}} + /> + + ) + + // First hydrate state with initial task + mockPostMessage({ + alwaysAllowWrite: true, + clineMessages: [ + { + type: 'say', + say: 'task', + ts: Date.now() - 2000, + text: 'Initial task' + } + ] + }) + + // Then send a non-tool write operation message + mockPostMessage({ + alwaysAllowWrite: true, + clineMessages: [ + { + type: 'say', + say: 'task', + ts: Date.now() - 2000, + text: 'Initial task' + }, + { + type: 'ask', + ask: 'write_operation', + ts: Date.now(), + text: JSON.stringify({ path: 'test.txt', content: 'test content' }), + partial: false + } + ] + }) + + // Verify no auto-approval message was sent + expect(vscode.postMessage).not.toHaveBeenCalledWith({ type: 'askResponse', askResponse: 'yesButtonClicked' })