From 7be7d43cc7c762d96c2c80aed566f7333beeced3 Mon Sep 17 00:00:00 2001 From: David Hu Date: Thu, 27 Aug 2026 10:48:48 -0700 Subject: [PATCH 1/2] fix(web): support fuzzy project search --- apps/web/src/components/CommandPalette.logic.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/web/src/components/CommandPalette.logic.ts b/apps/web/src/components/CommandPalette.logic.ts index 688a8a8ea791..ef72cf825b22 100644 --- a/apps/web/src/components/CommandPalette.logic.ts +++ b/apps/web/src/components/CommandPalette.logic.ts @@ -5,6 +5,7 @@ import { } from "@t3tools/contracts"; import { filterFilesystemBrowseEntries } from "@t3tools/client-runtime/state/filesystem"; import type { SidebarThreadSortOrder } from "@t3tools/contracts/settings"; +import { scoreSubsequenceMatch } from "@t3tools/shared/searchRanking"; import * as Arr from "effect/Array"; import * as Result from "effect/Result"; import { type ReactNode } from "react"; @@ -257,7 +258,10 @@ export function buildThreadActionItems { const items = Arr.filterMap(group.items, (item, index) => { - const haystack = normalizeSearchText(item.searchTerms.join(" ")); - if (!haystack.includes(normalizedQuery)) { + const rank = rankCommandPaletteItemMatch(item, normalizedQuery); + if (rank === 0) { return Result.failVoid; } return Result.succeed({ item, index, - rank: rankCommandPaletteItemMatch(item, normalizedQuery), + rank, }); }) .toSorted((left, right) => right.rank - left.rank || left.index - right.index) From d2660542fe856b536b8d3c33fa03046824b1c77a Mon Sep 17 00:00:00 2001 From: David Hu Date: Thu, 27 Aug 2026 11:24:47 -0700 Subject: [PATCH 2/2] fix(web): preserve cross-field palette search --- apps/web/src/components/CommandPalette.logic.test.ts | 4 ++-- apps/web/src/components/CommandPalette.logic.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/CommandPalette.logic.test.ts b/apps/web/src/components/CommandPalette.logic.test.ts index d521c119303d..f22689ff56c1 100644 --- a/apps/web/src/components/CommandPalette.logic.test.ts +++ b/apps/web/src/components/CommandPalette.logic.test.ts @@ -243,7 +243,7 @@ describe("buildThreadActionItems", () => { ]); }); - it("preserves thread project-name matches when there is no stronger title match", () => { + it("preserves queries spanning thread and project search terms", () => { const group: CommandPaletteGroup = { value: "threads-search", label: "Threads", @@ -262,7 +262,7 @@ describe("buildThreadActionItems", () => { const groups = filterCommandPaletteGroups({ activeGroups: [group], - query: "project", + query: "spacing project", isInSubmenu: false, projectSearchItems: [], threadSearchItems: [], diff --git a/apps/web/src/components/CommandPalette.logic.ts b/apps/web/src/components/CommandPalette.logic.ts index ef72cf825b22..87c337efb148 100644 --- a/apps/web/src/components/CommandPalette.logic.ts +++ b/apps/web/src/components/CommandPalette.logic.ts @@ -338,7 +338,8 @@ export function filterCommandPaletteGroups(input: { return searchableGroups.flatMap((group) => { const items = Arr.filterMap(group.items, (item, index) => { const rank = rankCommandPaletteItemMatch(item, normalizedQuery); - if (rank === 0) { + const haystack = normalizeSearchText(item.searchTerms.join(" ")); + if (rank === 0 && !haystack.includes(normalizedQuery)) { return Result.failVoid; }