From f9fa1a7efd46453ad7d603262c42c1f266dc4bc9 Mon Sep 17 00:00:00 2001 From: Marius Date: Fri, 8 May 2026 12:06:24 +0200 Subject: [PATCH] fix(agent-manager): expand reviewable diffs by default (#10055) * fix(agent-manager): expand reviewable diffs by default * style(agent-manager): format diff panel --- .changeset/calm-diffs-fold.md | 5 ++++ .../unit/agent-manager-diff-state.test.ts | 21 +++++++++++++--- .../webview-ui/agent-manager/DiffPanel.tsx | 25 ++++++------------- .../agent-manager/FullScreenDiffView.tsx | 15 ++++++----- .../agent-manager/diff-open-policy.ts | 19 ++++++-------- 5 files changed, 45 insertions(+), 40 deletions(-) create mode 100644 .changeset/calm-diffs-fold.md diff --git a/.changeset/calm-diffs-fold.md b/.changeset/calm-diffs-fold.md new file mode 100644 index 0000000000..a03b972301 --- /dev/null +++ b/.changeset/calm-diffs-fold.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Open reviewable Agent Manager diffs by default while keeping generated or extreme files collapsed. diff --git a/packages/kilo-vscode/tests/unit/agent-manager-diff-state.test.ts b/packages/kilo-vscode/tests/unit/agent-manager-diff-state.test.ts index 9eba96efb0..1282d5b58c 100644 --- a/packages/kilo-vscode/tests/unit/agent-manager-diff-state.test.ts +++ b/packages/kilo-vscode/tests/unit/agent-manager-diff-state.test.ts @@ -1,6 +1,10 @@ import { describe, expect, it } from "bun:test" import { mergeWorktreeDiffs } from "../../webview-ui/agent-manager/diff-state" -import { initialOpenFiles } from "../../webview-ui/agent-manager/diff-open-policy" +import { + EXTREME_DIFF_CHANGED_LINES, + expandableOpenFiles, + initialOpenFiles, +} from "../../webview-ui/agent-manager/diff-open-policy" import type { WorktreeFileDiff } from "../../webview-ui/src/types/messages" function diff(overrides: Partial): WorktreeFileDiff { @@ -48,15 +52,26 @@ describe("agent manager diff state", () => { expect(result.stale).toEqual(new Set(["src/app.ts"])) }) - it("does not auto-open generated-like files or large diff sets", () => { + it("opens reviewable diffs initially", () => { expect( initialOpenFiles([ diff({ file: "src/app.ts", generatedLike: false, additions: 3 }), diff({ file: "node_modules/pkg/index.js", generatedLike: true, additions: 3 }), + diff({ file: "src/huge.ts", additions: EXTREME_DIFF_CHANGED_LINES + 1 }), ]), ).toEqual(["src/app.ts"]) const many = Array.from({ length: 26 }, (_, i) => diff({ file: `src/${i}.ts` })) - expect(initialOpenFiles(many)).toEqual([]) + expect(initialOpenFiles(many)).toHaveLength(26) + }) + + it("expands only reviewable files from the bulk action", () => { + expect( + expandableOpenFiles([ + diff({ file: "src/app.ts", generatedLike: false, additions: 3 }), + diff({ file: "src/generated.ts", generatedLike: true, additions: 3 }), + diff({ file: "src/huge.ts", additions: EXTREME_DIFF_CHANGED_LINES + 1 }), + ]), + ).toEqual(["src/app.ts"]) }) }) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx index f129eaf705..08e408e41c 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx @@ -21,7 +21,7 @@ import { type AnnotationLabels, type AnnotationMeta, } from "./review-annotations" -import { LONG_DIFF_MARKER_FILE_COUNT, initialOpenFiles, isLargeDiffFile } from "./diff-open-policy" +import { LONG_DIFF_MARKER_FILE_COUNT, expandableOpenFiles, initialOpenFiles, isLargeDiffFile } from "./diff-open-policy" import { DiffEndMarker } from "./DiffEndMarker" import { treeOrder } from "./file-tree-utils" import { isMarkdownFile, MarkdownDiffView } from "./MarkdownDiffView" @@ -71,8 +71,8 @@ export const DiffPanel: Component = (props) => { ) const [editing, setEditing] = createSignal(null) let nextId = 0 - // Tracks the session key for which auto-open has already run. When the - // key changes (different worktree) we re-expand. Within the same key, + // Tracks the session key for which initial open state has already run. When the + // key changes (different worktree) we expand reviewable files. Within the same key, // only pruning happens so the user's manual collapse state is preserved. let initializedKey: string | undefined @@ -132,9 +132,9 @@ export const DiffPanel: Component = (props) => { focusRoot() } - // Unified auto-open effect: tracks both sessionKey and diffs in a single effect + // Unified open-state effect: tracks both sessionKey and diffs in a single effect // to eliminate the race condition between the old separate sessionKey-reset and - // diffs-watch effects. Uses the session key to decide when auto-expand is needed + // diffs-watch effects. Uses the session key to decide when initialization is needed // vs when we just prune stale entries from the open list. createEffect( on( @@ -321,8 +321,7 @@ export const DiffPanel: Component = (props) => { } const handleExpandAll = () => { - const allOpen = open().length === props.diffs.length - setOpen(allOpen ? [] : props.diffs.map((d) => d.file)) + setOpen(open().length > 0 ? [] : expandableOpenFiles(props.diffs)) } const totals = createMemo(() => ({ @@ -374,22 +373,14 @@ export const DiffPanel: Component = (props) => {
0}> 0 ? t("ui.sessionReview.collapseAll") : t("ui.sessionReview.expandAll")} placement="bottom" > 0 ? t("ui.sessionReview.collapseAll") : t("ui.sessionReview.expandAll")} onClick={handleExpandAll} /> diff --git a/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx b/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx index 4b2885a5e3..06962fd739 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/FullScreenDiffView.tsx @@ -29,7 +29,7 @@ import { type AnnotationLabels, type AnnotationMeta, } from "./review-annotations" -import { LONG_DIFF_MARKER_FILE_COUNT, initialOpenFiles, isLargeDiffFile } from "./diff-open-policy" +import { LONG_DIFF_MARKER_FILE_COUNT, expandableOpenFiles, initialOpenFiles, isLargeDiffFile } from "./diff-open-policy" import { DiffEndMarker } from "./DiffEndMarker" import { isMarkdownFile, MarkdownDiffView } from "./MarkdownDiffView" @@ -84,8 +84,8 @@ export const FullScreenDiffView: Component = (props) => const [treeWidth, setTreeWidth] = createSignal(240) let nextId = 0 let draftMeta: AnnotationMeta | null = null - // Tracks the session key for which auto-open has already run. When the - // key changes (different worktree) we re-expand. Within the same key, + // Tracks the session key for which initial open state has already run. When the + // key changes (different worktree) we expand reviewable files. Within the same key, // only pruning happens so the user's manual collapse state is preserved. let initializedKey: string | undefined let rootRef: HTMLDivElement | undefined @@ -135,9 +135,9 @@ export const FullScreenDiffView: Component = (props) => focusRoot() } - // Unified auto-open effect: tracks both sessionKey and diffs in a single effect + // Unified open-state effect: tracks both sessionKey and diffs in a single effect // to eliminate the race condition between the old separate sessionKey-reset and - // diffs-watch effects. Uses the session key to decide when auto-expand is needed + // diffs-watch effects. Uses the session key to decide when initialization is needed // vs when we just prune stale entries from the open list. createEffect( on( @@ -349,8 +349,7 @@ export const FullScreenDiffView: Component = (props) => } const handleExpandAll = () => { - const allOpen = open().length === props.diffs.length - setOpen(allOpen ? [] : props.diffs.map((d) => d.file)) + setOpen(open().length > 0 ? [] : expandableOpenFiles(props.diffs)) } const syncActiveFileFromScroll = () => { @@ -456,7 +455,7 @@ export const FullScreenDiffView: Component = (props) =>
0 && props.canComment !== false}> LARGE_FILE_CHANGED_LINES + return diff.additions + diff.deletions > EXTREME_DIFF_CHANGED_LINES +} + +export function expandableOpenFiles(diffs: WorktreeFileDiff[]): string[] { + return diffs.filter((diff) => !isLargeDiffFile(diff) && diff.generatedLike !== true).map((diff) => diff.file) } export function initialOpenFiles(diffs: WorktreeFileDiff[]): string[] { - if (diffs.length === 0) return [] - if (diffs.length > AUTO_OPEN_FILE_COUNT) return [] - - const files = diffs - .filter((diff) => !isLargeDiffFile(diff) && diff.generatedLike !== true) - .slice(0, AUTO_OPEN_LIMIT) - .map((diff) => diff.file) - return files + return expandableOpenFiles(diffs) }