From 45347b14c1bc0dbe65d1b1e00edc16f957c766b3 Mon Sep 17 00:00:00 2001 From: jms830 Date: Tue, 16 Jun 2026 18:09:42 -0400 Subject: [PATCH] fix(client): raise project-open & directory-suggestion timeouts for large repos openProject 10s->60s and getDirectorySuggestions 10s->30s + debounce the project-picker query 250ms. On large local repos the daemon's path-resolve and home-tree scan take several seconds; firing per-keystroke against a 10s timeout raced the suggestion list to empty (e.g. ~/gi found a hit but ~/gith blanked) and surfaced a spurious 'Timeout waiting for message (10000ms)' on add. --- .../app/src/components/project-picker-modal.tsx | 13 +++++++++++-- packages/client/src/daemon-client.ts | 8 ++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/app/src/components/project-picker-modal.tsx b/packages/app/src/components/project-picker-modal.tsx index 5a5b0616d..606a0e57e 100644 --- a/packages/app/src/components/project-picker-modal.tsx +++ b/packages/app/src/components/project-picker-modal.tsx @@ -103,6 +103,7 @@ export function ProjectPickerModal() { const inputRef = useRef(null); const [query, setQuery] = useState(""); + const [debouncedQuery, setDebouncedQuery] = useState(""); const [activeIndex, setActiveIndex] = useState(0); const openProject = useOpenProject(serverId); @@ -124,11 +125,11 @@ export function ProjectPickerModal() { ); const directorySuggestionsQuery = useQuery({ - queryKey: ["project-picker-directory-suggestions", serverId, query], + queryKey: ["project-picker-directory-suggestions", serverId, debouncedQuery], queryFn: async () => { if (!client) return []; const result = await client.getDirectorySuggestions({ - query, + query: debouncedQuery, includeDirectories: true, includeFiles: false, limit: 30, @@ -186,11 +187,19 @@ export function ProjectPickerModal() { } setQuery(""); + setDebouncedQuery(""); setActiveIndex(0); const id = setTimeout(() => inputRef.current?.focus(), 0); return () => clearTimeout(id); }, [open, resetSubmit]); + // Debounce the query that drives the (potentially multi-second) directory + // suggestions RPC so fast typing doesn't fire a filesystem scan per keystroke. + useEffect(() => { + const id = setTimeout(() => setDebouncedQuery(query), 250); + return () => clearTimeout(id); + }, [query]); + // Clamp active index useEffect(() => { if (!open) return; diff --git a/packages/client/src/daemon-client.ts b/packages/client/src/daemon-client.ts index a1212c3b5..e4231c874 100644 --- a/packages/client/src/daemon-client.ts +++ b/packages/client/src/daemon-client.ts @@ -1877,7 +1877,9 @@ export class DaemonClient { cwd, }, responseType: "open_project_response", - timeout: 10000, + // Large local repos (e.g. a big monorepo/brain checkout) need >10s for the + // daemon to resolve the path, detect git, and materialize the workspace. + timeout: 60000, }); } @@ -3462,7 +3464,9 @@ export class DaemonClient { limit: options.limit, }, responseType: "directory_suggestions_response", - timeout: 10000, + // Home-tree scans on large home dirs can take several seconds; don't cut + // the suggestion request off early (it would surface as an empty list). + timeout: 30000, }); }