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 };