From 5a5a175f00f86b6b03fc35c5d3e759fac6c1a922 Mon Sep 17 00:00:00 2001 From: chinesepowered Date: Wed, 8 Apr 2026 07:18:22 -0700 Subject: [PATCH] fix(ui): Remove dead dirs state and unused hook parameter from InputPrompt (#2891) * fix(ui): prevent useEffect from running every render in InputPrompt getDirectories() returns a new array reference each call, causing the useEffect dependency check to fail on every render. Move the call inside the effect body and use stable dependencies [config, dirs] so the effect only re-runs when they actually change. * fix(ui): use serialized dep key for directory change detection Move from [config, dirs] deps (both stable refs that miss external changes) to a dirKey string (join of current directories). This preserves the perf fix (no new array ref in deps) while still detecting directory additions/removals from /add-dir etc. * refactor(cli): remove unused dirs state from InputPrompt The dirs parameter passed to useCommandCompletion() was never read inside that hook, making the dirs state and sync effect in InputPrompt dead code. Remove the parameter, the state, the effect, and all test call-site args. --- .../cli/src/ui/components/InputPrompt.test.tsx | 14 -------------- packages/cli/src/ui/components/InputPrompt.tsx | 10 ---------- .../src/ui/hooks/useCommandCompletion.test.ts | 18 ------------------ .../cli/src/ui/hooks/useCommandCompletion.tsx | 1 - 4 files changed, 43 deletions(-) diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx index 7162ee072..b4bfae4e1 100644 --- a/packages/cli/src/ui/components/InputPrompt.test.tsx +++ b/packages/cli/src/ui/components/InputPrompt.test.tsx @@ -849,7 +849,6 @@ describe('InputPrompt', () => { // Verify useCompletion was called with correct signature expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -878,7 +877,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -907,7 +905,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -936,7 +933,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -965,7 +961,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -995,7 +990,6 @@ describe('InputPrompt', () => { // Verify useCompletion was called with the buffer expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1024,7 +1018,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1054,7 +1047,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1084,7 +1076,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1114,7 +1105,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1144,7 +1134,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1176,7 +1165,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1206,7 +1194,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, @@ -1238,7 +1225,6 @@ describe('InputPrompt', () => { expect(mockedUseCommandCompletion).toHaveBeenCalledWith( mockBuffer, - ['/test/project/src'], path.join('test', 'project', 'src'), mockSlashCommands, mockCommandContext, diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx index 56448f85b..aa2004c72 100644 --- a/packages/cli/src/ui/components/InputPrompt.tsx +++ b/packages/cli/src/ui/components/InputPrompt.tsx @@ -168,15 +168,6 @@ export const InputPrompt: React.FC = ({ } }, []); - const [dirs, setDirs] = useState( - config.getWorkspaceContext().getDirectories(), - ); - const dirsChanged = config.getWorkspaceContext().getDirectories(); - useEffect(() => { - if (dirs.length !== dirsChanged.length) { - setDirs(dirsChanged); - } - }, [dirs.length, dirsChanged]); const [reverseSearchActive, setReverseSearchActive] = useState(false); const [commandSearchActive, setCommandSearchActive] = useState(false); const [textBeforeReverseSearch, setTextBeforeReverseSearch] = useState(''); @@ -190,7 +181,6 @@ export const InputPrompt: React.FC = ({ const completion = useCommandCompletion( buffer, - dirs, config.getTargetDir(), slashCommands, commandContext, diff --git a/packages/cli/src/ui/hooks/useCommandCompletion.test.ts b/packages/cli/src/ui/hooks/useCommandCompletion.test.ts index fed160343..74e5e942d 100644 --- a/packages/cli/src/ui/hooks/useCommandCompletion.test.ts +++ b/packages/cli/src/ui/hooks/useCommandCompletion.test.ts @@ -84,7 +84,6 @@ const setupMocks = ({ describe('useCommandCompletion', () => { const mockCommandContext = {} as CommandContext; const mockConfig = {} as Config; - const testDirs: string[] = []; const testRootDir = '/'; // Helper to create real TextBuffer objects within renderHook @@ -114,7 +113,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest(''), - testDirs, testRootDir, [], mockCommandContext, @@ -139,7 +137,6 @@ describe('useCommandCompletion', () => { const textBuffer = useTextBufferForTest('@file'); const completion = useCommandCompletion( textBuffer, - testDirs, testRootDir, [], mockCommandContext, @@ -172,7 +169,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('@files'), - testDirs, testRootDir, [], mockCommandContext, @@ -200,7 +196,6 @@ describe('useCommandCompletion', () => { renderHook(() => useCommandCompletion( useTextBufferForTest(text), - testDirs, testRootDir, [], mockCommandContext, @@ -226,7 +221,6 @@ describe('useCommandCompletion', () => { renderHook(() => useCommandCompletion( useTextBufferForTest(text, cursorOffset), - testDirs, testRootDir, [], mockCommandContext, @@ -265,7 +259,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('/'), - testDirs, testRootDir, [], mockCommandContext, @@ -286,7 +279,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('/'), - testDirs, testRootDir, [], mockCommandContext, @@ -306,7 +298,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('/'), - testDirs, testRootDir, [], mockCommandContext, @@ -332,7 +323,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('/'), - testDirs, testRootDir, [], mockCommandContext, @@ -361,7 +351,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('/'), - testDirs, testRootDir, [], mockCommandContext, @@ -398,7 +387,6 @@ describe('useCommandCompletion', () => { const { result } = renderHook(() => useCommandCompletion( useTextBufferForTest('/'), - testDirs, testRootDir, [], mockCommandContext, @@ -427,7 +415,6 @@ describe('useCommandCompletion', () => { renderHook(() => useCommandCompletion( useTextBufferForTest(text), - testDirs, testRootDir, [], mockCommandContext, @@ -455,7 +442,6 @@ describe('useCommandCompletion', () => { renderHook(() => useCommandCompletion( useTextBufferForTest(text), - testDirs, testRootDir, [], mockCommandContext, @@ -484,7 +470,6 @@ describe('useCommandCompletion', () => { const textBuffer = useTextBufferForTest(text); const completion = useCommandCompletion( textBuffer, - testDirs, testRootDir, [], mockCommandContext, @@ -517,7 +502,6 @@ describe('useCommandCompletion', () => { const textBuffer = useTextBufferForTest('/mem'); const completion = useCommandCompletion( textBuffer, - testDirs, testRootDir, [], mockCommandContext, @@ -547,7 +531,6 @@ describe('useCommandCompletion', () => { const textBuffer = useTextBufferForTest('@src/fi'); const completion = useCommandCompletion( textBuffer, - testDirs, testRootDir, [], mockCommandContext, @@ -580,7 +563,6 @@ describe('useCommandCompletion', () => { const textBuffer = useTextBufferForTest(text, cursorOffset); const completion = useCommandCompletion( textBuffer, - testDirs, testRootDir, [], mockCommandContext, diff --git a/packages/cli/src/ui/hooks/useCommandCompletion.tsx b/packages/cli/src/ui/hooks/useCommandCompletion.tsx index c78e9e46e..8cb273c98 100644 --- a/packages/cli/src/ui/hooks/useCommandCompletion.tsx +++ b/packages/cli/src/ui/hooks/useCommandCompletion.tsx @@ -39,7 +39,6 @@ export interface UseCommandCompletionReturn { export function useCommandCompletion( buffer: TextBuffer, - dirs: readonly string[], cwd: string, slashCommands: readonly SlashCommand[], commandContext: CommandContext,