import * as react_jsx_runtime from 'react/jsx-runtime'; import React, { ReactNode } from 'react'; /** A single command item in the palette */ interface CommandItem { /** Unique identifier */ id: string; /** Display label shown in the palette */ label: string; /** Optional description text */ description?: string; /** Icon — string, emoji, or React element (e.g. ``) */ icon?: ReactNode; /** Additional search terms for fuzzy matching */ keywords?: string[]; /** Group this command belongs to */ group?: string; /** Manual ordering weight (higher = appears first) */ priority?: number; /** Navigation target URL/path for route commands */ href?: string; /** Execution callback when command is selected */ action?: (item: CommandItem) => void | Promise; /** Whether this command is disabled */ disabled?: boolean; /** Hidden from results but still searchable */ hidden?: boolean; /** Required permissions to see this command */ permissions?: string[]; /** Keyboard shortcut display (e.g., ["g", "h"]) */ shortcut?: string[]; /** Extensible metadata for consumer use */ meta?: Record; /** Scopes where this command is most relevant (e.g., ['/billing', '/billing/*']) */ scope?: string[]; /** Child commands for nested/hierarchical menus */ children?: CommandItem[]; /** Parent command ID (set automatically when flattening) */ parentId?: string; } /** Command registry — the central store for all commands */ interface CommandRegistry { /** Register a single command. Returns an unregister function. */ register(command: CommandItem): () => void; /** Register multiple commands. Returns an unregister function for all. */ registerMany(commands: CommandItem[]): () => void; /** Update a command by ID with partial fields */ update(id: string, partial: Partial): void; /** Remove a command by ID */ unregister(id: string): void; /** Get all registered commands */ getAll(): CommandItem[]; /** Get a command by ID */ getById(id: string): CommandItem | undefined; /** Get commands in a specific group */ getByGroup(groupId: string): CommandItem[]; /** Subscribe to changes. Returns an unsubscribe function. */ subscribe(listener: () => void): () => void; /** Get a stable snapshot for useSyncExternalStore */ getSnapshot(): CommandItem[]; } /** A search engine implementation */ interface SearchEngine { /** Search items against a query string. Returns scored results. */ search(query: string, items: CommandItem[]): ScoredItem[]; } /** A command item with a relevance score */ interface ScoredItem { /** The matched command item */ item: CommandItem; /** Relevance score from 0 (worst) to 1 (best match) */ score: number; } /** Interface for checking user permissions */ interface AccessControlProvider { /** Check if user has a specific permission */ hasPermission(permission: string): boolean; /** Check if user has ANY of the given permissions */ hasAnyPermission(permissions: string[]): boolean; /** Check if user has ALL of the given permissions */ hasAllPermissions(permissions: string[]): boolean; } /** Access control check mode */ type AccessCheckMode = 'any' | 'all'; /** A single frecency tracking entry */ interface FrecencyEntry { /** Command ID */ id: string; /** Number of times used */ count: number; /** Unix timestamp of last use */ lastUsed: number; /** Decayed score based on frequency + recency */ halfLifeScore: number; } /** Storage backend for frecency data */ interface FrecencyStorage { /** Get entry by key */ get(key: string): FrecencyEntry | null; /** Set entry */ set(key: string, entry: FrecencyEntry): void; /** Get all entries */ getAll(): FrecencyEntry[]; /** Clear all entries */ clear(): void; } /** Frecency engine configuration */ interface FrecencyOptions { /** Storage backend (defaults to localStorage) */ storage?: FrecencyStorage; /** localStorage key prefix (default: 'cmdk-frecency') */ storageKey?: string; /** Max age in days before entries are removed (default: 30) */ maxAge?: number; /** Half-life in days for exponential decay (default: 7) */ halfLife?: number; } /** A command group definition */ interface CommandGroup { /** Unique group identifier */ id: string; /** Display label for the group */ label: string; /** Rendering priority (higher = rendered first) */ priority?: number; /** Optional icon for the group */ icon?: ReactNode; } /** Map of keyword → synonyms */ interface SynonymMap { [keyword: string]: string[]; } /** Current app context for scope-aware command boosting */ interface CommandContext { /** Current path/URL (e.g., '/billing/overview') */ path?: string; /** Current page/section tags for matching */ tags?: string[]; } /** Translation function — maps a key to a localized string */ type TranslationFn = (key: string, params?: Record) => string; /** A recorded search query */ interface SearchHistoryEntry { /** The search query string */ query: string; /** Timestamp when the search was performed */ timestamp: number; /** Number of results returned */ resultCount: number; } /** Configuration for search history tracking */ interface SearchHistoryConfig { /** Enable search history tracking (default: false) */ enabled?: boolean; /** Maximum history entries to keep (default: 20) */ maxEntries?: number; /** localStorage key prefix (default: 'cmdk-search-history') */ storageKey?: string; /** Minimum query length to record (default: 2) */ minQueryLength?: number; } /** Full command palette state */ interface CommandPaletteState { /** Current search query */ search: string; /** Filtered and ranked results */ results: ScoredItem[]; /** Available groups (only groups with visible items) */ groups: CommandGroup[]; /** Whether the palette is open */ isOpen: boolean; /** Whether results are loading (async) */ isLoading: boolean; /** Breadcrumb trail of parent commands (for nested navigation) */ breadcrumbs: CommandItem[]; /** Current nesting depth (0 = root) */ depth: number; } /** Configuration for the CommandEngine React provider */ interface CommandEngineConfig { /** Custom search engine (defaults to built-in fuzzy search) */ searchEngine?: SearchEngine; /** Access control provider for permission filtering */ accessControl?: AccessControlProvider; /** Access check mode: 'any' or 'all' permissions required */ accessCheckMode?: AccessCheckMode; /** Synonym dictionary for keyword expansion */ synonyms?: SynonymMap; /** Frecency configuration */ frecency?: FrecencyOptions & RecentCommandsConfig; /** Group definitions and ordering */ groups?: CommandGroup[]; /** Maximum results to return */ maxResults?: number; /** Centralized handler when a command is selected. Auto-records frecency. */ onSelect?: (item: CommandItem) => void; /** Current context for scope-aware command boosting */ context?: CommandContext; /** Boost weight for in-scope commands (0-1, default: 0.2) */ contextBoostWeight?: number; /** Translation function for UI strings (defaults to English) */ t?: TranslationFn; /** Locale for collation-aware operations (default: 'en') */ locale?: string; /** Search history configuration */ searchHistory?: SearchHistoryConfig; } /** Configuration for the "Recent" commands group */ interface RecentCommandsConfig { /** Show a "Recent" group when search is empty (default: false) */ showRecent?: boolean; /** Number of recent items to show (default: 5) */ recentCount?: number; /** Label for the recent group (default: "Recent") */ recentLabel?: string; } /** * Create a keyword engine for synonym expansion and user alias management. * * The engine enriches command items with additional searchable keywords * based on a synonym dictionary and optional user-defined aliases. */ declare function createKeywordEngine(synonyms?: SynonymMap, userAliases?: Map): { /** * Expand a search query using the synonym dictionary. * Returns the original query plus any synonym matches. * * e.g., query "money" with synonyms { billing: ["money", "payment"] } * returns ["money", "billing"] */ expandQuery(query: string): string[]; /** * Enrich a command item's keywords with synonyms and user aliases. * Returns a new CommandItem with original keywords preserved and * synonym-expanded keywords stored separately in meta._synonymKeywords. * This lets the search engine score original keywords higher. */ enrichItem(item: CommandItem): CommandItem; /** * Enrich all items in a list. */ enrichAll(items: CommandItem[]): CommandItem[]; /** * Add a user alias for a command. */ addAlias(commandId: string, alias: string): void; /** * Remove a user alias for a command. */ removeAlias(commandId: string, alias: string): void; /** * Get all user aliases. */ getAliases(): Map; /** * Set the synonym dictionary. */ setSynonyms(newSynonyms: SynonymMap): void; }; /** * Create a frecency engine that tracks usage patterns and * ranks items by frequency + recency using exponential decay. * * Algorithm: * score = count * 2^(-timeSinceLastUse / halfLife) * * This means: * - An item used 10 times yesterday ranks higher than one used 100 times a month ago * - The half-life (default 7 days) controls how quickly old usage decays */ declare function createFrecencyEngine(options?: FrecencyOptions): { recordUsage: (commandId: string) => void; getScore: (commandId: string) => number; getRecent: (count?: number) => string[]; rank: (items: ScoredItem[], frecencyWeight?: number) => ScoredItem[]; cleanup: () => void; clear: () => void; }; /** * Create a group manager that tracks command groups and their ordering. */ declare function createGroupManager(initialGroups?: CommandGroup[]): { /** Add or update a group definition */ addGroup(group: CommandGroup): void; /** Remove a group */ removeGroup(id: string): void; /** Get a group by ID */ getGroup(id: string): CommandGroup | undefined; /** Get all defined groups sorted by priority (higher first) */ getAllGroups(): CommandGroup[]; /** * Group scored items by their group field. * When query is empty: groups ordered by priority (higher first). * When query is non-empty: groups ordered by best item score (relevance). * Items without a group go into an "Other" bucket at the end. */ groupResults(items: ScoredItem[], query?: string): GroupedResults; /** * Extract unique groups from a list of commands. * Returns only groups that have at least one command. */ extractGroups(commands: CommandItem[]): CommandGroup[]; }; /** A group with its scored items */ interface GroupedResult { group: CommandGroup; items: ScoredItem[]; } /** Array of grouped results */ type GroupedResults = GroupedResult[]; /** * Create a context engine that boosts commands matching the current app context. * * Commands with a `scope` field (e.g., ['/billing', '/billing/*']) get a score * boost when the current context path matches. * * @param boostWeight - How much to boost in-scope commands (0-1, default: 0.2) */ declare function createContextEngine(boostWeight?: number): { /** * Boost scores for items whose scope matches the current context. * Items without a scope are unaffected. */ boost(items: ScoredItem[], context: CommandContext): ScoredItem[]; }; /** * In-memory search history (for testing or SSR). */ declare function createInMemorySearchHistory(config?: SearchHistoryConfig): { record(query: string, resultCount: number): void; getRecent(count?: number): SearchHistoryEntry[]; remove(query: string): void; clear(): void; }; /** Internal engine context shape */ interface EngineContextValue { registry: CommandRegistry; search: SearchEngine; keywords: ReturnType; accessFilter: ((items: CommandItem[]) => CommandItem[]) | null; frecency: ReturnType; groupManager: ReturnType; contextEngine: ReturnType; searchHistory: ReturnType; t: TranslationFn; config: CommandEngineConfig; } interface CommandEngineProviderProps { children: React.ReactNode; config?: CommandEngineConfig; } /** * Provider that initializes the command engine and makes it available * to all child hooks (useCommandPalette, useCommandRegister). */ declare function CommandEngineProvider({ children, config }: CommandEngineProviderProps): react_jsx_runtime.JSX.Element; interface UseCommandPaletteReturn extends CommandPaletteState { /** Set the search query */ setSearch: (query: string) => void; /** Open the palette */ open: () => void; /** Close the palette */ close: () => void; /** Toggle the palette */ toggle: () => void; /** Record that a command was selected (for frecency) */ recordUsage: (commandId: string) => void; /** Select a command — records frecency, runs onSelect/action/href, closes palette */ select: (itemOrId: CommandItem | string) => void; /** Flat list of all result items (ungrouped) */ flatResults: ScoredItem[]; /** Results grouped by group, sorted by group priority (or relevance during search) */ groupedResults: GroupedResult[]; /** Navigate into a command's children (nested commands) */ drillDown: (item: CommandItem) => void; /** Go back one level in nested navigation */ drillUp: () => void; /** Reset to root level */ resetPath: () => void; } /** * Main hook for the command palette. * Returns filtered, ranked, and grouped results based on the current search query. * * Subscribes to the registry via useSyncExternalStore for efficient updates. */ declare function useCommandPalette(): UseCommandPaletteReturn; /** * Register commands from within a component. * Commands are automatically unregistered when the component unmounts. * * @param commands - Commands to register * @param deps - Dependency array (re-registers when deps change) * * @example * ```tsx * function BillingPage() { * useCommandRegister([ * { id: 'buy-credits', label: 'Buy Credits', action: () => openModal() }, * ]) * return
...
* } * ``` */ declare function useCommandRegister(commands: CommandItem[], deps?: unknown[]): void; /** * Hook to interact with the frecency engine directly. * * @returns Object with recordUsage, getScore, and clear functions */ declare function useFrecency(): { recordUsage: (commandId: string) => void; getScore: (commandId: string) => number; getRecent: (count?: number) => string[]; clear: () => void; }; /** * Hook to access context-related engine features. * Returns the current context config and the context engine for custom boosting. * * Note: To update context, pass it via the `config.context` prop on * ``. This hook provides read access. */ declare function useCommandContext(): { context: CommandContext | undefined; boostWeight: number | undefined; }; /** * Hook for direct access to search history. * Use this to build custom "recent searches" UI or manage history. */ declare function useSearchHistory(): { /** Get recent search queries */ getRecent: (count?: number) => SearchHistoryEntry[]; /** Clear all search history */ clear: () => void; /** Remove a specific query from history */ remove: (query: string) => void; }; export { CommandEngineProvider, type CommandEngineProviderProps, type EngineContextValue, type UseCommandPaletteReturn, useCommandContext, useCommandPalette, useCommandRegister, useFrecency, useSearchHistory };