From 85bc291046611ef42003fa951b2229c868f41221 Mon Sep 17 00:00:00 2001 From: Marius Date: Mon, 23 Mar 2026 13:40:33 +0100 Subject: [PATCH] feat(vscode): auto-send review comments when input is empty (#7442) * feat(vscode): auto-send review comments when input is empty When clicking 'Send all to chat' or per-comment 'Send to chat' in diff views, comments are now sent directly to the AI if the input field is empty, instead of requiring a manual send. If the input has text, the existing behavior (append as chips) is preserved. * fix(vscode): only auto-send review comments when chat is truly empty Check for pre-existing review chips and image attachments before auto-sending, not just the text field. --- packages/kilo-vscode/src/DiffViewerProvider.ts | 6 +++--- packages/kilo-vscode/src/KiloProvider.ts | 10 +++++----- packages/kilo-vscode/src/extension.ts | 4 ++-- .../kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx | 4 +++- .../webview-ui/agent-manager/FullScreenDiffView.tsx | 4 +++- .../webview-ui/agent-manager/review-annotations.ts | 6 +++++- .../webview-ui/diff-viewer/DiffViewerApp.tsx | 2 +- .../webview-ui/src/components/chat/PromptInput.tsx | 7 ++++++- packages/kilo-vscode/webview-ui/src/types/messages.ts | 1 + 9 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/kilo-vscode/src/DiffViewerProvider.ts b/packages/kilo-vscode/src/DiffViewerProvider.ts index 78005a93125..f9f143f7467 100644 --- a/packages/kilo-vscode/src/DiffViewerProvider.ts +++ b/packages/kilo-vscode/src/DiffViewerProvider.ts @@ -24,7 +24,7 @@ export class DiffViewerProvider implements vscode.Disposable { private cachedDiffTarget: { directory: string; baseBranch: string } | undefined private gitOps: GitOps private outputChannel: vscode.OutputChannel - private onSendComments: ((comments: unknown[]) => void) | undefined + private onSendComments: ((comments: unknown[], autoSend: boolean) => void) | undefined constructor( private readonly extensionUri: vscode.Uri, @@ -38,7 +38,7 @@ export class DiffViewerProvider implements vscode.Disposable { appendOutput(this.outputChannel, "DiffViewer", ...args) } - public setCommentHandler(handler: (comments: unknown[]) => void): void { + public setCommentHandler(handler: (comments: unknown[], autoSend: boolean) => void): void { this.onSendComments = handler } @@ -95,7 +95,7 @@ export class DiffViewerProvider implements vscode.Disposable { } if (type === "diffViewer.sendComments" && Array.isArray(msg.comments)) { - this.onSendComments?.(msg.comments) + this.onSendComments?.(msg.comments, !!msg.autoSend) return } diff --git a/packages/kilo-vscode/src/KiloProvider.ts b/packages/kilo-vscode/src/KiloProvider.ts index 3f036658d13..c1adb623d41 100644 --- a/packages/kilo-vscode/src/KiloProvider.ts +++ b/packages/kilo-vscode/src/KiloProvider.ts @@ -109,7 +109,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper private pending = 0 /** Cached notificationsLoaded payload */ private cachedNotificationsMessage: unknown = null - private pendingReviewComments: unknown[][] = [] + private pendingReviewComments: { comments: unknown[]; autoSend: boolean }[] = [] private readyResolvers: (() => void)[] = [] private trackedSessionIds: Set = new Set() private syncedChildSessions: Set = new Set() @@ -2371,8 +2371,8 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper }) } - public async appendReviewComments(comments: unknown[]): Promise { - this.pendingReviewComments.push(comments) + public async appendReviewComments(comments: unknown[], autoSend = false): Promise { + this.pendingReviewComments.push({ comments, autoSend }) if (!this.webview) { await vscode.commands.executeCommand(`${KiloProvider.viewType}.focus`) @@ -2387,8 +2387,8 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper const pending = this.pendingReviewComments this.pendingReviewComments = [] - for (const comments of pending) { - this.postMessage({ type: "appendReviewComments", comments }) + for (const entry of pending) { + this.postMessage({ type: "appendReviewComments", comments: entry.comments, autoSend: entry.autoSend }) } } diff --git a/packages/kilo-vscode/src/extension.ts b/packages/kilo-vscode/src/extension.ts index 66261401745..c19ab635e11 100644 --- a/packages/kilo-vscode/src/extension.ts +++ b/packages/kilo-vscode/src/extension.ts @@ -87,8 +87,8 @@ export function activate(context: vscode.ExtensionContext) { // Create standalone diff viewer provider for the sidebar "Show Changes" action const diffViewerProvider = new DiffViewerProvider(context.extensionUri, connectionService) - diffViewerProvider.setCommentHandler((comments) => { - void provider.appendReviewComments(comments) + diffViewerProvider.setCommentHandler((comments, autoSend) => { + void provider.appendReviewComments(comments, autoSend) }) context.subscriptions.push(diffViewerProvider) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx index 679abf1995f..e8bdb52097d 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx @@ -292,7 +292,9 @@ export const DiffPanel: Component = (props) => { const sendAllToChat = () => { const all = comments() if (all.length === 0) return - window.dispatchEvent(new MessageEvent("message", { data: { type: "appendReviewComments", comments: all } })) + window.dispatchEvent( + new MessageEvent("message", { data: { type: "appendReviewComments", comments: all, autoSend: true } }), + ) preserveScroll(() => setComments([])) props.onSendAll?.() } diff --git a/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx b/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx index ff9f4ab7ae2..aff9eae7450 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx @@ -289,7 +289,9 @@ export const FullScreenDiffView: Component = (props) => const sendAllToChat = () => { const all = comments() if (all.length === 0) return - window.dispatchEvent(new MessageEvent("message", { data: { type: "appendReviewComments", comments: all } })) + window.dispatchEvent( + new MessageEvent("message", { data: { type: "appendReviewComments", comments: all, autoSend: true } }), + ) preserveScroll(() => setComments([])) props.onSendAll?.() } diff --git a/packages/kilo-vscode/webview-ui/agent-manager/review-annotations.ts b/packages/kilo-vscode/webview-ui/agent-manager/review-annotations.ts index 47aa955ed4c..028b68440c3 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/review-annotations.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/review-annotations.ts @@ -221,7 +221,11 @@ export function buildReviewAnnotation( actions.appendChild( makeActionButton(handlers.labels.sendToChat, makeIcon("M1 1l14 7-14 7V9l10-1L1 7z"), () => { - window.dispatchEvent(new MessageEvent("message", { data: { type: "appendReviewComments", comments: [comment] } })) + window.dispatchEvent( + new MessageEvent("message", { + data: { type: "appendReviewComments", comments: [comment], autoSend: true }, + }), + ) handlers.deleteComment(comment.id) }), ) diff --git a/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx b/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx index d767dc560b3..e8aecd76bad 100644 --- a/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx +++ b/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx @@ -42,7 +42,7 @@ const DiffViewerContent: Component = () => { const handler = (event: MessageEvent) => { const msg = event.data if (msg?.type !== "appendReviewComments" || !Array.isArray(msg.comments)) return - post({ type: "diffViewer.sendComments", comments: msg.comments }) + post({ type: "diffViewer.sendComments", comments: msg.comments, autoSend: !!msg.autoSend }) } window.addEventListener("message", handler) diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx index 6ab4a50dab0..eb246e806ed 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx @@ -246,9 +246,14 @@ export const PromptInput: Component = (props) => { } if (message.type === "appendReviewComments") { + const empty = !text().trim() && reviewComments().length === 0 && imageAttach.images().length === 0 const merged = mergeReviewComments(reviewComments(), message.comments) replaceReviewComments(merged) - textareaRef?.focus() + if (message.autoSend && empty && !isDisabled() && !props.blocked?.()) { + handleSend() + } else { + textareaRef?.focus() + } } if (message.type === "triggerTask") { diff --git a/packages/kilo-vscode/webview-ui/src/types/messages.ts b/packages/kilo-vscode/webview-ui/src/types/messages.ts index 76fba58f609..8c2f558c8c7 100644 --- a/packages/kilo-vscode/webview-ui/src/types/messages.ts +++ b/packages/kilo-vscode/webview-ui/src/types/messages.ts @@ -586,6 +586,7 @@ export interface ReviewComment { export interface AppendReviewCommentsMessage { type: "appendReviewComments" comments: ReviewComment[] + autoSend?: boolean } export interface TriggerTaskMessage {