authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-04 23:29:26-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-04 23:29:26-07:00
logeae770b125553275e1ccfe4aebd88df28e818aed
treeb4da16085d2afe2872ade096be06138a63ab037e
parent6b87ce3a0bd925edcbb26fbc6870a6ca81dead0b
signature Signed by PGP key B5690EEEBB952194

refactor(web): remove obsolete changed-files preview helpers (#9956)


2 files changed, 0 insertions(+), 171 deletions(-)

apps/web/src/components/chat/changedFilesPresentation.test.ts deleted-69
......@@ -1,69 +0,0 @@
1import { describe, expect, it } from "vite-plus/test";
2
3import {
4 changedFileName,
5 selectChangedFilePreview,
6 shouldAutoExpandChangedFiles,
7 summarizeChangedFileScopes,
8} from "./changedFilesPresentation";
9
10describe("changed-files presentation", () => {
11 it("auto-expands only small, low-churn latest changes", () => {
12 const smallFiles = [
13 { path: "src/a.ts", kind: "modified", additions: 80, deletions: 20 },
14 { path: "src/b.ts", kind: "modified", additions: 60, deletions: 20 },
15 ];
16
17 expect(shouldAutoExpandChangedFiles(smallFiles, true)).toBe(true);
18 expect(shouldAutoExpandChangedFiles(smallFiles, false)).toBe(false);
19 expect(
20 shouldAutoExpandChangedFiles(
21 [{ path: "src/a.ts", kind: "modified", additions: 201, deletions: 0 }],
22 true,
23 ),
24 ).toBe(false);
25 expect(
26 shouldAutoExpandChangedFiles(
27 Array.from({ length: 6 }, (_, index) => ({
28 path: `src/${index}.ts`,
29 kind: "modified",
30 additions: 1,
31 deletions: 0,
32 })),
33 true,
34 ),
35 ).toBe(false);
36 });
37
38 it("summarizes the most prominent top-level scopes", () => {
39 const files = [
40 { path: "apps/web/src/App.tsx", kind: "modified", additions: 1, deletions: 0 },
41 { path: "README.md", kind: "modified", additions: 1, deletions: 0 },
42 { path: "apps/server/src/index.ts", kind: "modified", additions: 1, deletions: 0 },
43 { path: "packages/shared/src/git.ts", kind: "modified", additions: 1, deletions: 0 },
44 { path: "apps\\mobile\\App.tsx", kind: "modified", additions: 1, deletions: 0 },
45 ];
46
47 expect(summarizeChangedFileScopes(files)).toEqual([
48 { label: "apps", fileCount: 3 },
49 { label: "root", fileCount: 1 },
50 { label: "packages", fileCount: 1 },
51 ]);
52 });
53
54 it("previews files across different scopes before filling from one scope", () => {
55 const files = [
56 { path: "apps/web/src/App.tsx", kind: "modified", additions: 1, deletions: 0 },
57 { path: "apps/web/src/App.test.tsx", kind: "modified", additions: 1, deletions: 0 },
58 { path: "packages/shared/src/git.ts", kind: "modified", additions: 1, deletions: 0 },
59 { path: "README.md", kind: "modified", additions: 1, deletions: 0 },
60 ];
61
62 expect(selectChangedFilePreview(files).map((file) => file.path)).toEqual([
63 "apps/web/src/App.tsx",
64 "packages/shared/src/git.ts",
65 "README.md",
66 ]);
67 expect(changedFileName("apps\\web\\src\\App.tsx")).toBe("App.tsx");
68 });
69});
apps/web/src/components/chat/changedFilesPresentation.ts deleted-102
......@@ -1,102 +0,0 @@
1import { type TurnDiffFileChange } from "../../types";
2import { summarizeTurnDiffStats } from "../../lib/turnDiffTree";
3
4export const CHANGED_FILES_AUTO_EXPAND_FILE_LIMIT = 5;
5export const CHANGED_FILES_AUTO_EXPAND_LINE_LIMIT = 200;
6export const CHANGED_FILES_PREVIEW_FILE_LIMIT = 3;
7export const CHANGED_FILES_PREVIEW_SCOPE_LIMIT = 4;
8
9export interface ChangedFilesScopeSummary {
10 readonly label: string;
11 readonly fileCount: number;
12}
13
14function pathSegments(pathValue: string): string[] {
15 return pathValue
16 .replaceAll("\\", "/")
17 .split("/")
18 .filter((segment) => segment.length > 0);
19}
20
21export function changedFileName(pathValue: string): string {
22 return pathSegments(pathValue).at(-1) ?? pathValue;
23}
24
25function changedFileScope(pathValue: string): string {
26 const segments = pathSegments(pathValue);
27 return segments.length > 1 ? (segments[0] ?? "root") : "root";
28}
29
30export function shouldAutoExpandChangedFiles(
31 files: ReadonlyArray<TurnDiffFileChange>,
32 isLatestTurn: boolean,
33): boolean {
34 if (!isLatestTurn || files.length > CHANGED_FILES_AUTO_EXPAND_FILE_LIMIT) {
35 return false;
36 }
37 const stat = summarizeTurnDiffStats(files);
38 return stat.additions + stat.deletions <= CHANGED_FILES_AUTO_EXPAND_LINE_LIMIT;
39}
40
41export function summarizeChangedFileScopes(
42 files: ReadonlyArray<TurnDiffFileChange>,
43 limit = CHANGED_FILES_PREVIEW_SCOPE_LIMIT,
44): ChangedFilesScopeSummary[] {
45 const scopes = new Map<string, { fileCount: number; firstIndex: number }>();
46 files.forEach((file, index) => {
47 const label = changedFileScope(file.path);
48 const current = scopes.get(label);
49 scopes.set(label, {
50 fileCount: (current?.fileCount ?? 0) + 1,
51 firstIndex: current?.firstIndex ?? index,
52 });
53 });
54
55 return Array.from(scopes, ([label, scope]) => ({
56 label,
57 fileCount: scope.fileCount,
58 firstIndex: scope.firstIndex,
59 }))
60 .toSorted(
61 (left, right) =>
62 right.fileCount - left.fileCount ||
63 left.firstIndex - right.firstIndex ||
64 left.label.localeCompare(right.label),
65 )
66 .slice(0, limit)
67 .map(({ label, fileCount }) => ({ label, fileCount }));
68}
69
70export function selectChangedFilePreview(
71 files: ReadonlyArray<TurnDiffFileChange>,
72 limit = CHANGED_FILES_PREVIEW_FILE_LIMIT,
73): TurnDiffFileChange[] {
74 const selected: TurnDiffFileChange[] = [];
75 const selectedPaths = new Set<string>();
76 const selectedScopes = new Set<string>();
77
78 for (const file of files) {
79 const scope = changedFileScope(file.path);
80 if (selectedScopes.has(scope)) {
81 continue;
82 }
83 selected.push(file);
84 selectedPaths.add(file.path);
85 selectedScopes.add(scope);
86 if (selected.length === limit) {
87 return selected;
88 }
89 }
90
91 for (const file of files) {
92 if (selectedPaths.has(file.path)) {
93 continue;
94 }
95 selected.push(file);
96 if (selected.length === limit) {
97 break;
98 }
99 }
100
101 return selected;
102}