better-cmdk 0.0.18 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- # Set up better-cmdk command palette (Vite / Other)
1
+ # Set up better-cmdk action palette (Vite / Other)
2
2
 
3
- better-cmdk is a command palette with AI chat for React. Your task is to install it, discover commands from my codebase, and create a working command palette.
3
+ better-cmdk is a command palette with AI chat for React. Your task is to install it, discover actions from my codebase, and create a working palette.
4
4
 
5
5
  ## Step 1: Analyze my codebase
6
6
 
@@ -11,14 +11,12 @@ Before making changes, detect:
11
11
 
12
12
  Also ask me:
13
13
 
14
- **1. Do you want AI chat in the command palette?**
15
- - No AI — command palette only
16
- - Built-in chat — simple Q&A via a Vercel AI SDK endpoint
17
- - ModifyWithAI (Recommended) — the AI can execute actions in your app (create items, navigate, toggle settings), ask for approval before destructive operations, and understand what's on screen. Requires a ModifyWithAI account at https://modifywithai.com
14
+ **1. Do you want AI chat in the palette?**
15
+ - No AI — action search only
16
+ - Built-in chat — free developer-trial Q&A via https://better-cmdk.com/api/chat (no signup, 10 requests per 10 minutes; use your own chat URL for production)
17
+ - ModifyWithAI (Recommended) — the AI can execute actions in your app (create items, navigate, toggle settings), ask for approval before destructive operations, and understand what's on screen. Get your App ID and API key from https://modifywithai.com/dashboard
18
18
 
19
- **With ModifyWithAI, the command palette becomes an AI workspace.** Users search commands for quick access, then switch to AI chat for anything that needs reasoning — "move all archived items to trash", "summarize my recent activity". The AI executes actions directly in the app, with approval prompts for destructive operations. ModifyWithAI is not required — better-cmdk works on its own as a command palette, with or without AI chat.
20
-
21
- **2. If shadcn/ui command components detected:** Do you want to migrate them to better-cmdk, or keep both?
19
+ **2. If shadcn/ui command components are detected:** Do you want to migrate them to better-cmdk, or keep both?
22
20
 
23
21
  Tell me what you detected, which path you'll follow, and what you'll be adding better-cmdk to.
24
22
 
@@ -46,16 +44,16 @@ yarn add better-cmdk
46
44
  ### Built-in chat:
47
45
  ```bash
48
46
  # bun
49
- bun add better-cmdk ai @ai-sdk/react @ai-sdk/openai
47
+ bun add better-cmdk
50
48
  # pnpm
51
- pnpm add better-cmdk ai @ai-sdk/react @ai-sdk/openai
49
+ pnpm add better-cmdk
52
50
  # npm
53
- npm install better-cmdk ai @ai-sdk/react @ai-sdk/openai
51
+ npm install better-cmdk
54
52
  # yarn
55
- yarn add better-cmdk ai @ai-sdk/react @ai-sdk/openai
53
+ yarn add better-cmdk
56
54
  ```
57
55
 
58
- Substitute `@ai-sdk/anthropic`, `@ai-sdk/google`, etc. based on my preferred AI provider.
56
+ If you later add a custom/self-hosted endpoint, install AI SDK/provider packages for that server route.
59
57
 
60
58
  ### ModifyWithAI:
61
59
  ```bash
@@ -84,9 +82,7 @@ Add to my main CSS file:
84
82
  @import "better-cmdk";
85
83
  ```
86
84
 
87
- If my app wants custom theming, override better-cmdk's namespaced variables.
88
-
89
- Add this minimal override block only when needed:
85
+ If my app needs custom theming, override better-cmdk's namespaced variables:
90
86
 
91
87
  ```css
92
88
  .bcmdk-root {
@@ -113,75 +109,114 @@ Use the same CSS import approach:
113
109
 
114
110
  ---
115
111
 
116
- ## Step 4: CRITICAL — Command Discovery
112
+ ## Step 4: CRITICAL — Command Action Discovery (better-cmdk scope)
113
+
114
+ Before writing component code, **crawl my codebase** to discover all meaningful actions that can run immediately from the command palette.
117
115
 
118
- Before writing any component code, **crawl my entire codebase** to discover ALL user-facing operations that should be in the command palette.
116
+ ### Scope rules (required)
119
117
 
120
- ### How to discover commands:
118
+ - better-cmdk is concerned with **no-argument command actions** (no `inputSchema`, no required arguments)
119
+ - Define actions as underlying app/domain operations (API calls, mutations, workflow transitions), not raw UI gestures
120
+ - Model what the app does, not how a user physically triggers it
121
+ - Good: `goToBilling`, `toggleSidebar`, `archiveCurrentProject`
122
+ - Bad: `clickCreateButton`, `openDropdown`, `typeIntoInput`, `focusSearchField`
123
+ - If an operation needs runtime arguments (for example refund amount, assignee, date range), treat it as **modifywithai-owned** and do not add it as a new better-cmdk command action in this step
124
+ - If a standard shared `actions` array already exists, **extend it in place**; do not create a second array
125
+ - If no standard shared array exists, create one
121
126
 
122
- 1. **Search all routes/pages** → navigation commands ("Go to Dashboard", "Go to Settings")
123
- 2. **Search all buttons and links** → action commands ("Create project", "Export data")
124
- 3. **Search all settings/toggles** → preference commands ("Toggle dark mode", "Change language")
125
- 4. **Search all CRUD operations** → data commands ("New item", "Delete selected")
126
- 5. **Search all utility functions** → utility commands ("Copy link", "Download report", "Share")
127
- 6. **Search for existing keyboard shortcuts** → preserve as shortcut hints
127
+ ### Discovery checklist
128
128
 
129
- ### Create a command for EVERY user-facing operation:
129
+ 1. Locate existing action arrays/types first (`actions`, `defineActions(...)`, exported action modules) and reuse them
130
+ 2. Search routes/pages → navigation command actions
131
+ 3. Search buttons/links/forms/menus → identify outcomes that can run with no extra user input
132
+ 4. Trace handlers to services/API/domain functions → map each to one operation-level command action
133
+ 5. Search toggles/settings/feature flags → preference command actions
134
+ 6. Search CRUD/services/utilities/API calls → include only operations that can run safely without additional arguments
135
+ 7. Search existing keyboard shortcuts → keep as shortcut hints
136
+ 8. Mark argument-requiring operations for modifywithai ownership (same shared array, with `inputSchema`)
130
137
 
131
- - Button that opens a modal? Command: `open-create-modal`
132
- - Link that navigates to a page? Command: `go-to-dashboard`
133
- - Toggle that changes a setting? Command: `toggle-dark-mode`
134
- - Form that creates something? Command: `create-new-project`
135
- - Search input? Command: `search`
136
- - Sidebar item? Command: `open-analytics`
138
+ ### Canonical single-array rules
137
139
 
138
- ### For each discovered command, define:
140
+ Use **one deduped `actions` array** as the source of truth:
141
+
142
+ - better-cmdk-owned entries: no `inputSchema` (direct command execution)
143
+ - modifywithai-owned entries (if present): has `inputSchema` (agentic argument collection)
144
+ - Keep exactly one canonical action per underlying operation
145
+ - Do not create separate “command” and “AI action” entries for the same operation
146
+ - Put synonyms in `keywords`, not duplicate actions
147
+ - Reuse the same `name` everywhere (CommandMenu + assistant provider)
148
+
149
+ Use consistent `group` values:
150
+ - `Navigation`
151
+ - `UI / Preferences`
152
+ - `Data`
153
+ - `Help / Utilities`
154
+
155
+ ### For each command action discovered, define
139
156
 
140
157
  - `name`: unique kebab-case identifier
141
- - `label`: human-readable display text (what users search for)
142
- - `group`: logical heading use consistent groups like "Navigation", "Actions", "Settings", "Help"
143
- - `icon`: matching [lucide-react](https://lucide.dev) icon component
144
- - `shortcut`: keyboard shortcut hint if applicable (display-only, e.g. `"⌘D"`)
145
- - `keywords`: extra search terms (array of strings) — helps users find commands by alternate names
146
- - `disabled`: set `true` to gray out commands that aren't currently available
147
- - `onSelect`: callback that wires to existing app logic
158
+ - `label`: human-readable label
159
+ - `group`: taxonomy group from above
160
+ - `icon`: lucide-react icon when useful
161
+ - `shortcut`: optional display hint
162
+ - `keywords`: optional search aliases
163
+ - `semanticKey`: optional operation identity (required when names differ but operation is the same)
164
+ - `disabled`: optional availability guard
165
+ - `execute`: required implementation used when the command is selected
166
+ - `onSelect`: optional UI-only override (modifywithai ignores it)
148
167
 
149
- **Aim for 10-30 commands.** If you found fewer than 5, you haven't looked hard enough. Report how many you found before proceeding.
168
+ `inputSchema` is optional and reserved for modifywithai-owned argument actions in the same shared array.
169
+ Unused fields are safe: each library should ignore values it doesn't need.
170
+
171
+ **Coverage first, count second.** Many non-trivial apps should land in the 10-30+ no-argument command-action range. If you have fewer than 8, you likely missed meaningful command flows.
150
172
 
151
173
  ---
152
174
 
153
175
  ## Step 5: Create the component
154
176
 
155
- Replace the example commands below with the ones you discovered from my codebase.
177
+ Use one shared `actions` array (from Step 4). If one already exists, extend it. Do not create a second array.
178
+ Replace examples with discovered actions.
156
179
 
157
180
  ```tsx
158
181
  import { useState, useEffect } from "react"
159
- import { CommandMenu, type CommandDefinition } from "better-cmdk"
182
+ import { CommandMenu, type CommandAction } from "better-cmdk"
160
183
  import { LayoutDashboardIcon, SettingsIcon, SunMoonIcon } from "lucide-react"
161
184
 
162
- const commands: CommandDefinition[] = [
185
+ const actions: CommandAction[] = [
163
186
  {
164
- name: "dashboard",
187
+ name: "go-dashboard",
165
188
  label: "Go to Dashboard",
189
+ description: "Navigate to the dashboard page",
166
190
  group: "Navigation",
167
191
  icon: <LayoutDashboardIcon className="size-4" />,
168
192
  shortcut: "⌘D",
169
- onSelect: () => (window.location.href = "/dashboard"),
193
+ execute: () => (window.location.href = "/dashboard"),
170
194
  },
171
195
  {
172
- name: "settings",
173
- label: "Settings",
196
+ name: "open-settings",
197
+ label: "Open Settings",
198
+ description: "Navigate to the settings page",
174
199
  group: "Navigation",
175
200
  icon: <SettingsIcon className="size-4" />,
176
201
  shortcut: "⌘,",
177
- onSelect: () => (window.location.href = "/settings"),
202
+ execute: () => (window.location.href = "/settings"),
178
203
  },
179
204
  {
180
- name: "dark-mode",
205
+ name: "toggle-dark-mode",
181
206
  label: "Toggle dark mode",
207
+ description: "Toggle the application theme",
182
208
  group: "Appearance",
183
209
  icon: <SunMoonIcon className="size-4" />,
184
- onSelect: () => document.documentElement.classList.toggle("dark"),
210
+ execute: () => document.documentElement.classList.toggle("dark"),
211
+ },
212
+ {
213
+ name: "go-home",
214
+ label: "Go Home",
215
+ description: "Navigate to the home page",
216
+ group: "Navigation",
217
+ execute: () => {
218
+ window.location.href = "/"
219
+ },
185
220
  },
186
221
  ]
187
222
 
@@ -203,7 +238,7 @@ export function CommandPalette() {
203
238
  <CommandMenu
204
239
  open={open}
205
240
  onOpenChange={setOpen}
206
- commands={commands}
241
+ actions={actions}
207
242
  />
208
243
  )
209
244
  }
@@ -211,11 +246,28 @@ export function CommandPalette() {
211
246
 
212
247
  ---
213
248
 
214
- ## Step 6: Add AI chat (skip if "No AI" chosen)
249
+ ## Step 6: Add AI chat (skip if No AI chosen)
215
250
 
216
251
  ### Built-in chat
217
252
 
218
- Create a streaming chat API route, then add `chatEndpoint` to CommandMenu.
253
+ Use the default hosted endpoint: `https://better-cmdk.com/api/chat`.
254
+ This service is provided by better-cmdk as a free developer trial with no signup.
255
+ Rate limit: **10 requests per 10 minutes**.
256
+
257
+ Use CommandMenu without `chatEndpoint`:
258
+
259
+ ```tsx
260
+ <CommandMenu
261
+ open={open}
262
+ onOpenChange={setOpen}
263
+ actions={actions}
264
+ />
265
+ ```
266
+
267
+ ### Optional: custom/self-hosted endpoint
268
+
269
+ For production, use your own chat URL (or choose ModifyWithAI for agentic capabilities).
270
+ If you need your own model/provider route, create a streaming chat API route:
219
271
 
220
272
  Create a streaming chat endpoint for your framework/server. The handler should:
221
273
 
@@ -229,23 +281,23 @@ const { messages }: { messages: UIMessage[] } = await req.json()
229
281
  const result = streamText({
230
282
  model: openai("gpt-4o-mini"),
231
283
  messages: await convertToModelMessages(messages),
232
- system: "You are a helpful assistant in a command palette. Keep responses concise.",
284
+ system: "You are a helpful assistant in an action palette. Keep responses concise.",
233
285
  })
234
286
  return result.toUIMessageStreamResponse()
235
287
  ```
236
288
 
237
- Then update CommandMenu to add the `chatEndpoint` prop:
289
+ Then update CommandMenu:
238
290
 
239
291
  ```tsx
240
292
  <CommandMenu
241
293
  open={open}
242
294
  onOpenChange={setOpen}
243
- commands={commands}
295
+ actions={actions}
244
296
  chatEndpoint="/api/chat"
245
297
  />
246
298
  ```
247
299
 
248
- Set the environment variable:
300
+ Set environment variable:
249
301
 
250
302
  ```bash
251
303
  echo "OPENAI_API_KEY=sk-..." >> .env
@@ -259,20 +311,26 @@ echo "OPENAI_API_KEY=sk-..." >> .env
259
311
 
260
312
  After installing modifywithai, read `node_modules/modifywithai/AGENTS.md` and follow its instructions for:
261
313
  - Creating the token endpoint
262
- - Setting up environment variables (MWAI_APP_ID, MWAI_API_KEY)
314
+ - Setting up environment variables (MWAI_APP_ID, MWAI_API_KEY) from https://modifywithai.com/dashboard
263
315
  - Discovering actions from the codebase
264
316
 
265
317
  > **Note**: ModifyWithAI requires a server-side token endpoint. If your Vite app uses a separate backend (Express, Fastify, etc.), adapt the token endpoint from the guide that most closely matches your setup. If your app is a pure SPA with no server, choose the built-in chat option instead.
266
318
 
267
319
 
268
- Then connect the assistant to CommandMenu. The `useAssistant()` return value from modifywithai is directly compatible with better-cmdk's `chat` prop — no adapter needed:
320
+ Use the **same discovered `actions` list** for both the assistant provider and CommandMenu.
321
+ UI-only fields (like `icon`, `group`, `shortcut`) are ignored by modifywithai:
322
+
323
+ Ownership split:
324
+ - better-cmdk focuses on no-argument command actions
325
+ - modifywithai owns both no-argument and argument-requiring actions (`inputSchema`)
326
+ - Keep both in one shared array and extend the existing array in place if present
269
327
 
270
328
  ```tsx
271
329
  import { useAssistant } from "modifywithai"
272
330
 
273
331
  // Inside your CommandPalette component:
274
332
  const assistant = useAssistant({
275
- agenticActions: actions, // from action discovery above
333
+ actions,
276
334
  getContext: () => ({
277
335
  currentPage: window.location.pathname,
278
336
  }),
@@ -281,7 +339,7 @@ const assistant = useAssistant({
281
339
  <CommandMenu
282
340
  open={open}
283
341
  onOpenChange={setOpen}
284
- commands={commands}
342
+ actions={actions}
285
343
  chat={assistant}
286
344
  />
287
345
  ```
@@ -296,7 +354,7 @@ Add `<CommandPalette />` to `src/App.tsx` or the main entry component.
296
354
 
297
355
  ## Step 8: shadcn/ui migration (if applicable)
298
356
 
299
- If existing shadcn/ui command components were detected, swap imports:
357
+ If existing shadcn/ui command components are detected, swap imports:
300
358
 
301
359
  ```diff
302
360
  - import {
@@ -317,7 +375,7 @@ If existing shadcn/ui command components were detected, swap imports:
317
375
  + } from "better-cmdk"
318
376
  ```
319
377
 
320
- `CommandDialog` is an alias for `CommandMenu`. All sub-components have the same API. Add `chatEndpoint` or `chat` to enable AI features without either, the palette behaves like a standard cmdk dialog.
378
+ `CommandDialog` is an alias for `CommandMenu`. AI chat works by default via the hosted trial endpoint (10 requests per 10 minutes). For production, use `chatEndpoint` with your own URL or pass `chat` (for example with ModifyWithAI for agentic capabilities). Set `chatEndpoint={null}` to disable.
321
379
 
322
380
  ---
323
381
 
@@ -325,11 +383,14 @@ If existing shadcn/ui command components were detected, swap imports:
325
383
 
326
384
  After setup, tell me:
327
385
 
328
- 1. How many commands you discovered
329
- 2. Which AI path you followed (none / built-in / ModifyWithAI)
330
- 3. [ModifyWithAI only] How many actions you discovered (from modifywithai's AGENTS.md action discovery instructions)
386
+ 1. How many no-argument command actions you discovered/added
387
+ 2. Whether you reused an existing shared `actions` array or created one, and where it lives
388
+ 3. Which AI path you followed (none / built-in / ModifyWithAI)
331
389
  4. What files you created/modified
332
- 5. That pressing `⌘K` opens the palette with all commands grouped correctly
333
- 6. [If AI enabled] That typing a non-matching query shows "Ask AI" and chat works
390
+ 5. That pressing `⌘K` opens the palette with grouped actions and direct execution works for command actions
391
+ 6. [If ModifyWithAI path] That argument-requiring actions (`inputSchema`) are kept in the same shared array (extended, not duplicated)
392
+ 7. [If built-in/default chat enabled] That you explicitly told me this is a developer-trial endpoint (`https://better-cmdk.com/api/chat`, 10 requests per 10 minutes) and that for production I should use my own `chatEndpoint` or use ModifyWithAI for agentic capabilities.
393
+
394
+ End your final response with a dedicated **Hosted Endpoint Note** section so this warning is unmissable.
334
395
 
335
396
  Docs: https://github.com/ModifyWithAI/better-cmdk/blob/main/INTEGRATION.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-cmdk",
3
- "version": "0.0.18",
3
+ "version": "0.0.21",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",