diff --git a/.changeset/fix-review-comment-shortcut.md b/.changeset/fix-review-comment-shortcut.md new file mode 100644 index 000000000000..160e4fc53b10 --- /dev/null +++ b/.changeset/fix-review-comment-shortcut.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Restore sending all Agent Manager diff comments with a second Cmd+Enter or Ctrl+Enter, including quick consecutive presses. diff --git a/packages/kilo-vscode/tests/diff-scroll-preservation.spec.ts b/packages/kilo-vscode/tests/diff-scroll-preservation.spec.ts index 2bde7a20bdee..167071b88d62 100644 --- a/packages/kilo-vscode/tests/diff-scroll-preservation.spec.ts +++ b/packages/kilo-vscode/tests/diff-scroll-preservation.spec.ts @@ -131,6 +131,62 @@ test("preserves scroll while adding and editing a review comment", async ({ page await expect.poll(async () => scroller.evaluate((el) => el.scrollTop)).toBeCloseTo(saved, 0) }) +for (const modifier of ["Meta", "Control"] as const) { + test(`sends all review comments on the second ${modifier}+Enter before the next frame`, async ({ page }) => { + await openStory(page) + const target = await showTarget(page) + await alignTarget(page) + + for (const text of ["First comment", "Second comment"]) { + await target.locator('[data-line="1"]').last().hover() + await target.locator("[data-utility-button]").last().click() + await target.locator(".am-annotation-textarea").fill(text) + if (text === "First comment") { + await target.getByRole("button", { name: "Comment", exact: true }).click() + await expect(target.getByText(text, { exact: true })).toBeVisible() + } + } + + await page.keyboard.press("Shift+Enter") + await expect(target.locator(".am-annotation-textarea")).toHaveValue("Second comment\n") + + const result = await page.evaluate((modifier) => { + const sent: Array<{ comments: Array<{ comment: string }>; autoSend: boolean }> = [] + const listener = (event: MessageEvent) => { + if (event.data?.type === "appendReviewComments") sent.push(event.data) + } + window.addEventListener("message", listener) + const press = () => + document.activeElement?.dispatchEvent( + new KeyboardEvent("keydown", { + key: "Enter", + metaKey: modifier === "Meta", + ctrlKey: modifier === "Control", + bubbles: true, + composed: true, + cancelable: true, + }), + ) + press() + const first = sent.length + press() + const second = sent.length + press() + window.removeEventListener("message", listener) + return { first, second, sent } + }, modifier) + + expect(result.first).toBe(0) + expect(result.second).toBe(1) + expect(result.sent).toHaveLength(1) + expect(result.sent.at(0)).toMatchObject({ + comments: [{ comment: "First comment" }, { comment: "Second comment" }], + autoSend: true, + }) + await expect(page.locator(".am-annotation")).toHaveCount(0) + }) +} + test("resets virtual measurements and scroll when the review context changes", async ({ page }) => { const first = await openStory(page) const scroller = page.locator(".am-review-diff") diff --git a/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts b/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts index 16df86dc471b..023eb6bf2172 100644 --- a/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts +++ b/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts @@ -337,6 +337,7 @@ export function buildReviewAnnotation( } if (event.key === "Enter" && !event.shiftKey) { event.preventDefault() + event.stopPropagation() submit() } }) @@ -414,6 +415,7 @@ export function buildReviewAnnotation( } if (event.key === "Enter" && !event.shiftKey) { event.preventDefault() + event.stopPropagation() save() } }) diff --git a/packages/kilo-vscode/webview-ui/diff-viewer/review-setup.ts b/packages/kilo-vscode/webview-ui/diff-viewer/review-setup.ts index 1675055c88a0..22f4fdfdc8a5 100644 --- a/packages/kilo-vscode/webview-ui/diff-viewer/review-setup.ts +++ b/packages/kilo-vscode/webview-ui/diff-viewer/review-setup.ts @@ -42,9 +42,7 @@ export function createReviewSpeech(t: T): { } export function reviewFocus(root: () => HTMLElement | undefined): void { - requestAnimationFrame(() => { - requestAnimationFrame(() => root()?.focus()) - }) + root()?.focus({ preventScroll: true }) } export function keepsNativeFocus(target: EventTarget | null): boolean {