improvement(search): redesign Cmd-K palette with curated empty state and drill-down browse#5194
improvement(search): redesign Cmd-K palette with curated empty state and drill-down browse#5194waleedlatif1 wants to merge 1 commit into
Conversation
…and drill-down browse - Stop dumping the full ~1,500-item catalog (blocks, tools, triggers, 1,000+ tool operations, docs) into the palette on open; surface them only once the user types, mirroring the existing integrations group - Add a curated empty state: frecency-ranked Recents (new persisted store) and a Browse section that drills into block/trigger/integration categories - Scope drill-down shown as a removable pill in the search bar; Backspace on empty input or Escape pops the scope - Cap each result group to keep the DOM bounded on broad queries - Derive browse categories from block category + integrationType
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryLow Risk Overview The empty state adds Recent (persisted frecency in Store/types gain Reviewed by Cursor Bugbot for commit 637a046. Configure here. |
Greptile SummaryThis PR redesigns the Cmd-K command palette from a single flat list of ~1,500 unvirtualized catalog entries into a curated empty state with frecency-ranked recents, a browsable drill-down by category, and per-group result caps (50) that keep the DOM bounded during search.
Confidence Score: 4/5Safe to merge with minor fixes; no user data is at risk and all behavioral regressions are ranking-only. The pruning logic in the new recents store sorts by
Important Files Changed
|
| const kept = keys | ||
| .sort((a, b) => entries[b].lastUsedAt - entries[a].lastUsedAt) | ||
| .slice(0, MAX_ENTRIES) | ||
| const pruned: Record<string, RecentEntry> = {} | ||
| for (const k of kept) pruned[k] = entries[k] | ||
| return { entries: pruned } |
There was a problem hiding this comment.
Pruning sorts by recency, not frecency
When the store grows beyond MAX_ENTRIES, entries are pruned by lastUsedAt (most-recent-first), not by frecencyScore. This means a block used 100 times last week can be evicted in favour of a block used once yesterday — the opposite of the frecency guarantee described in the PR and in the jsdoc comment above (frecencyScore). When the user re-opens the palette after the eviction, their high-frequency block simply disappears from Recents.
The sort should use frecencyScore so that eviction decisions match the display ordering.
| return ( | ||
| <Command.Group heading='Recent' className={GROUP_HEADING_CLASSNAME}> |
There was a problem hiding this comment.
productivity maps to the same Blocks icon as the blocks category
Both 'blocks' and 'productivity' resolve to the Blocks icon, so users would see identical icons for two different browse categories. A more fitting choice for productivity might be Briefcase, LayoutDashboard, or CheckSquare from Lucide.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
What changed
category+integrationType. Selecting one scopes the list to just that category. Typing from the root still does a flat global search.Toolbar block picker (separate component) intentionally left as a follow-up to keep this PR focused.
Type of Change
Testing
store.test.tsupdated + new coverage forintegrationTypecapture and category building (5/5 passing)tscclean (0 errors), biome cleanChecklist