From 930660074d557301fcd6239597785ad2e9f0bd77 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sun, 29 Mar 2026 23:10:15 +0700 Subject: [PATCH] fix(server): treat bare slash queries as search terms in project picker Queries like "faro/main" were treated as literal paths relative to ~, so the picker tried to list ~/faro/ (which doesn't exist) instead of searching the home tree for paths containing "faro/main". Only treat queries as paths when explicitly rooted with ~, ~/, ./, or /. --- .../server/src/utils/directory-suggestions.ts | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/server/src/utils/directory-suggestions.ts b/packages/server/src/utils/directory-suggestions.ts index 27dacfb4b..aa6225716 100644 --- a/packages/server/src/utils/directory-suggestions.ts +++ b/packages/server/src/utils/directory-suggestions.ts @@ -604,7 +604,13 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null return null; } + // Only treat the query as a literal path when the user explicitly roots it + // with ~, ~/, ./, or an absolute path. Bare queries like "faro/main" are + // search terms, not paths. + let isRooted = false; + if (normalized.startsWith("~")) { + isRooted = true; normalized = normalized.slice(1); if (normalized.startsWith("/")) { normalized = normalized.slice(1); @@ -612,6 +618,7 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null } if (path.isAbsolute(normalized)) { + isRooted = true; const absolute = path.resolve(normalized); if (!isPathInsideRoot(homeRoot, absolute)) { return null; @@ -619,6 +626,9 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null normalized = normalizeRelativePath(homeRoot, absolute); } + if (normalized.startsWith("./")) { + isRooted = true; + } normalized = normalized.replace(/^\.\/+/, "").replace(/\/{2,}/g, "/"); if (!normalized) { // Treat "~" and "~/" as a request to browse the home root. @@ -632,13 +642,21 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null return null; } - const isPathQuery = normalized.includes("/"); + const isPathQuery = isRooted && normalized.includes("/"); + if (!isPathQuery) { + return { + isPathQuery: false, + parentPart: "", + searchTerm: normalized, + }; + } + const slashIndex = normalized.lastIndexOf("/"); - const parentPart = slashIndex >= 0 ? normalized.slice(0, slashIndex) : ""; - const searchTerm = slashIndex >= 0 ? normalized.slice(slashIndex + 1) : normalized; + const parentPart = normalized.slice(0, slashIndex); + const searchTerm = normalized.slice(slashIndex + 1); return { - isPathQuery, + isPathQuery: true, parentPart, searchTerm, };