From f85904210664f34562b7af23023938a12ff1ca52 Mon Sep 17 00:00:00 2001 From: 0xPratik Date: Tue, 6 Oct 2026 17:31:28 +0545 Subject: [PATCH 1/3] Prevent duplicate search results across groups --- apps/web/src/command-palette/command-groups.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/web/src/command-palette/command-groups.ts b/apps/web/src/command-palette/command-groups.ts index 111dd10607..f7df658843 100644 --- a/apps/web/src/command-palette/command-groups.ts +++ b/apps/web/src/command-palette/command-groups.ts @@ -67,7 +67,10 @@ export function buildCommandPaletteGroups( } else if (scope !== null && scope.kind !== source.kind) { continue; } - const items = filterItems(source.items, query); + // ponytail: scan the small palette; use a Set if result counts grow. + const items = filterItems(source.items, query).filter( + (item) => !groups.some((group) => group.items.some((existing) => existing.id === item.id)), + ); if (items.length > 0) { groups.push({ id: source.id, heading: source.heading, items }); } From 4010c4440dfa06e0e021210e17eba739d8c4eaf3 Mon Sep 17 00:00:00 2001 From: 0xPratik Date: Tue, 13 Oct 2026 18:47:34 +0545 Subject: [PATCH 2/3] Add tests for command palette deduplication (CL-1108) --- .../command-palette/command-groups.test.ts | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 apps/web/src/command-palette/command-groups.test.ts diff --git a/apps/web/src/command-palette/command-groups.test.ts b/apps/web/src/command-palette/command-groups.test.ts new file mode 100644 index 0000000000..4a661cf6ae --- /dev/null +++ b/apps/web/src/command-palette/command-groups.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, test } from "bun:test"; + +import { buildCommandPaletteGroups, type PaletteSource } from "./command-groups"; + +const workflows = { id: "route:/workflows", title: "Workflows" }; +const settings = { id: "route:/settings", title: "Settings" }; +const pages: PaletteSource = { + id: "pages", + heading: "Pages", + kind: "pages", + items: [workflows, settings], +}; + +describe("buildCommandPaletteGroups", () => { + test("keeps Recent first and omits later duplicates without reordering other results", () => { + const groups = buildCommandPaletteGroups({ + query: "", + recents: [workflows], + sources: [pages, { id: "duplicates", heading: "Duplicates", items: [workflows, settings] }], + }); + + expect(groups).toEqual([ + { id: "recents", heading: "Recent", items: [workflows] }, + { id: "pages", heading: "Pages", items: [settings] }, + ]); + }); + + test("deduplicates scoped results after excluding Recent and out-of-scope sources", () => { + const workbench = { id: "entity:workbenches:one", title: "One" }; + const groups = buildCommandPaletteGroups({ + query: "#", + recents: [workbench], + sources: [ + { id: "unscoped", heading: "Unscoped", items: [workbench] }, + { id: "pages", heading: "Pages", kind: "pages", items: [workbench] }, + { + id: "workbenches", + heading: "Workbenches", + kind: "workbenches", + items: [workbench], + }, + { + id: "duplicates", + heading: "Duplicates", + kind: "workbenches", + items: [workbench], + }, + ], + }); + + expect(groups).toEqual([{ id: "workbenches", heading: "Workbenches", items: [workbench] }]); + }); + + test("keeps the first matching result even when an earlier copy does not match", () => { + const groups = buildCommandPaletteGroups({ + query: "work", + recents: [workflows], + sources: [ + { + id: "nonmatching", + heading: "Nonmatching", + items: [{ id: workflows.id, title: "Other" }], + }, + pages, + { id: "duplicates", heading: "Duplicates", items: [workflows] }, + ], + }); + + expect(groups).toEqual([{ id: "pages", heading: "Pages", items: [workflows] }]); + }); +}); From a05c649ef72fc57b36ca4e97d99462e4ac2e0e5f Mon Sep 17 00:00:00 2001 From: 0xPratik Date: Tue, 13 Oct 2026 18:47:34 +0545 Subject: [PATCH 3/3] Search: clarify deduplication comment (CL-1108) --- apps/web/src/command-palette/command-groups.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/command-palette/command-groups.ts b/apps/web/src/command-palette/command-groups.ts index f7df658843..878be47d72 100644 --- a/apps/web/src/command-palette/command-groups.ts +++ b/apps/web/src/command-palette/command-groups.ts @@ -67,7 +67,7 @@ export function buildCommandPaletteGroups( } else if (scope !== null && scope.kind !== source.kind) { continue; } - // ponytail: scan the small palette; use a Set if result counts grow. + // Scan the small palette; use a Set if result counts grow. const items = filterItems(source.items, query).filter( (item) => !groups.some((group) => group.items.some((existing) => existing.id === item.id)), );