Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/browser/features/RightSidebar/CodeReview/HunkViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ export const HunkViewer = React.memo<HunkViewerProps>(
const hasManualState = hunkId in expandStateMap;
const manualExpandState = expandStateMap[hunkId];

// Agent-flagged hunks should default to expanded even when they're "large"
// or in a heavy review where everything else is collapsed — otherwise the
// assisted-review focus signal gets buried.
// Agent-flagged hunks should default to expanded even when they're already
// read, "large", or in a heavy review where everything else is collapsed —
// otherwise the assisted-review focus signal gets buried.
const shouldAutoExpand =
!isRead &&
(!isRead || isAssisted) &&
(!isLargeHunk || Boolean(visibleNewLineRange)) &&
(!preferCollapsed || Boolean(isSelected) || Boolean(visibleNewLineRange));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { describe, expect, test } from "bun:test";

import type { AssistedReviewHunk, DiffHunk } from "@/common/types/review";
import { countUnreadAssistedHunks } from "./ReviewPanel";
import {
buildReviewDiffPathFilter,
buildReviewDiffPathFilterSpecs,
countUnreadAssistedHunks,
getEffectiveReviewFrontendFilters,
getEffectiveReviewIncludeUncommitted,
} from "./ReviewPanel";

function hunk(overrides: Partial<DiffHunk>): DiffHunk {
return {
Expand Down Expand Up @@ -43,3 +49,128 @@ describe("countUnreadAssistedHunks", () => {
expect(countUnreadAssistedHunks(hunks, assisted, () => false)).toBe(1);
});
});

describe("buildReviewDiffPathFilter", () => {
test("assisted mode fetches agent-pinned files instead of the stale selected file", () => {
const pathFilter = buildReviewDiffPathFilter({
isImmersive: false,
assistedOnly: true,
assistedHunks: [
{ path: "src/agent.ts" },
{ path: "src/agent.ts", range: { start: 3, end: 4 } },
],
selectedFilePath: "src/user-selected.ts",
selectedDiffPath: "src/user-selected.ts",
workspaceMetadata: null,
repoRootProjectPath: "/repo",
});

expect(pathFilter).toBe(" -- 'src/agent.ts'");
});

test("non-assisted mode preserves the selected file pathspec", () => {
const pathFilter = buildReviewDiffPathFilter({
isImmersive: false,
assistedOnly: false,
assistedHunks: [{ path: "src/agent.ts" }],
selectedFilePath: "src/user-selected.ts",
selectedDiffPath: "src/user-selected.ts",
workspaceMetadata: null,
repoRootProjectPath: "/repo",
});

expect(pathFilter).toBe(" -- 'src/user-selected.ts'");
});
});

describe("buildReviewDiffPathFilterSpecs", () => {
const workspaceMetadata = {
projects: [
{ projectName: "project-a", projectPath: "/repo/project-a" },
{ projectName: "project-b", projectPath: "/repo/project-b" },
],
};

test("assisted mode roots each multi-project pathspec in the pinned file's repository", () => {
const specs = buildReviewDiffPathFilterSpecs({
isImmersive: false,
assistedOnly: true,
assistedHunks: [{ path: "project-b/src/agent.ts" }, { path: "project-a/src/main.ts" }],
selectedFilePath: "project-b/src/stale-selection.ts",
selectedDiffPath: "src/stale-selection.ts",
selectedRepoRootProjectPath: "/repo/project-b",
workspaceMetadata,
projectPath: "/repo/project-a",
});

expect(specs).toEqual([
{
repoRootProjectPath: "/repo/project-b",
pathFilter: " -- 'src/agent.ts'",
selectedFilePath: "src/agent.ts",
},
{
repoRootProjectPath: "/repo/project-a",
pathFilter: " -- 'src/main.ts'",
selectedFilePath: "src/main.ts",
},
]);
});

test("non-assisted mode keeps selected file rooting for truncation recovery", () => {
const specs = buildReviewDiffPathFilterSpecs({
isImmersive: false,
assistedOnly: false,
assistedHunks: [{ path: "project-a/src/main.ts" }],
selectedFilePath: "project-b/src/user-selected.ts",
selectedDiffPath: "src/user-selected.ts",
selectedRepoRootProjectPath: "/repo/project-b",
workspaceMetadata,
projectPath: "/repo/project-a",
});

expect(specs).toEqual([
{
repoRootProjectPath: "/repo/project-b",
pathFilter: " -- 'src/user-selected.ts'",
selectedFilePath: "project-b/src/user-selected.ts",
},
]);
});
});

describe("getEffectiveReviewIncludeUncommitted", () => {
test("assisted mode includes working-tree edits even when the user toggle is off", () => {
expect(
getEffectiveReviewIncludeUncommitted({ assistedOnly: true, includeUncommitted: false })
).toBe(true);
});

test("non-assisted mode keeps the user include-uncommitted toggle", () => {
expect(
getEffectiveReviewIncludeUncommitted({ assistedOnly: false, includeUncommitted: false })
).toBe(false);
});
});

describe("getEffectiveReviewFrontendFilters", () => {
test("assisted mode bypasses user filters that could hide accepted pins", () => {
expect(
getEffectiveReviewFrontendFilters({
assistedOnly: true,
showReadHunks: false,
searchTerm: "does-not-match",
})
).toEqual({ showReadHunks: true, searchTerm: "" });
});

test("non-assisted mode keeps user filters", () => {
expect(
getEffectiveReviewFrontendFilters({
assistedOnly: false,
showReadHunks: false,
searchTerm: "needle",
})
).toEqual({ showReadHunks: false, searchTerm: "needle" });
});
});
Loading
Loading