better-cmdk 0.0.20 → 0.0.22
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.
- package/README.md +43 -24
- package/dist/index.d.ts +25 -27
- package/dist/index.js +1 -1
- package/dist/nextjs/AGENTS.md +140 -71
- package/dist/remix/AGENTS.md +139 -70
- package/dist/tanstack-start/AGENTS.md +139 -70
- package/dist/vite/AGENTS.md +141 -70
- package/package.json +1 -1
package/dist/nextjs/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Set up better-cmdk
|
|
1
|
+
# Set up better-cmdk action palette (Next.js (App Router))
|
|
2
2
|
|
|
3
|
-
better-cmdk is a command palette with AI chat for React. Your task is to install it, discover
|
|
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
|
|
15
|
-
- No AI —
|
|
16
|
-
- Built-in chat —
|
|
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.
|
|
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
|
-
**
|
|
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
|
|
47
|
+
bun add better-cmdk
|
|
50
48
|
# pnpm
|
|
51
|
-
pnpm add better-cmdk
|
|
49
|
+
pnpm add better-cmdk
|
|
52
50
|
# npm
|
|
53
|
-
npm install better-cmdk
|
|
51
|
+
npm install better-cmdk
|
|
54
52
|
# yarn
|
|
55
|
-
yarn add better-cmdk
|
|
53
|
+
yarn add better-cmdk
|
|
56
54
|
```
|
|
57
55
|
|
|
58
|
-
|
|
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
|
|
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,83 +109,129 @@ 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.
|
|
115
|
+
|
|
116
|
+
### Scope rules (required)
|
|
117
117
|
|
|
118
|
-
|
|
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
|
|
119
126
|
|
|
120
|
-
###
|
|
127
|
+
### Discovery checklist
|
|
121
128
|
|
|
122
|
-
1.
|
|
123
|
-
2.
|
|
124
|
-
3.
|
|
125
|
-
4.
|
|
126
|
-
5.
|
|
127
|
-
6.
|
|
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`)
|
|
128
137
|
|
|
129
|
-
###
|
|
138
|
+
### Canonical single-array rules
|
|
130
139
|
|
|
131
|
-
|
|
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`
|
|
140
|
+
Use **one deduped `actions` array** as the source of truth:
|
|
137
141
|
|
|
138
|
-
|
|
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
|
|
142
|
-
- `group`:
|
|
143
|
-
- `icon`:
|
|
144
|
-
- `shortcut`:
|
|
145
|
-
- `keywords`:
|
|
146
|
-
- `
|
|
147
|
-
- `
|
|
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)
|
|
167
|
+
|
|
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.
|
|
172
|
+
|
|
173
|
+
### Label distinctiveness for mixed arrays
|
|
174
|
+
|
|
175
|
+
When navigation and data actions share the same domain concept, make labels clearly distinct:
|
|
176
|
+
|
|
177
|
+
- Navigation: "Out of Office" (navigates to the page)
|
|
178
|
+
- Data: "Create Out of Office Entry" (creates via API)
|
|
148
179
|
|
|
149
|
-
|
|
180
|
+
Prefix data-action labels with their verb ("Create …", "Update …", "Delete …") to disambiguate from navigation labels.
|
|
150
181
|
|
|
151
182
|
---
|
|
152
183
|
|
|
153
184
|
## Step 5: Create the component
|
|
154
185
|
|
|
155
|
-
|
|
186
|
+
Use one shared `actions` array (from Step 4). If one already exists, extend it. Do not create a second array.
|
|
187
|
+
Replace examples with discovered actions.
|
|
156
188
|
|
|
157
189
|
```tsx
|
|
158
190
|
"use client"
|
|
159
191
|
|
|
160
192
|
import { useState, useEffect } from "react"
|
|
161
193
|
import { useRouter } from "next/navigation"
|
|
162
|
-
import { CommandMenu, type
|
|
194
|
+
import { CommandMenu, type CommandAction } from "better-cmdk"
|
|
163
195
|
import { LayoutDashboardIcon, SettingsIcon, SunMoonIcon } from "lucide-react"
|
|
164
196
|
|
|
165
197
|
export function CommandPalette() {
|
|
166
198
|
const [open, setOpen] = useState(false)
|
|
167
199
|
const router = useRouter()
|
|
168
200
|
|
|
169
|
-
// REPLACE with discovered
|
|
170
|
-
const
|
|
201
|
+
// REPLACE with discovered actions from my codebase
|
|
202
|
+
const actions: CommandAction[] = [
|
|
171
203
|
{
|
|
172
|
-
name: "dashboard",
|
|
204
|
+
name: "go-dashboard",
|
|
173
205
|
label: "Go to Dashboard",
|
|
206
|
+
description: "Navigate to the dashboard page",
|
|
174
207
|
group: "Navigation",
|
|
175
208
|
icon: <LayoutDashboardIcon className="size-4" />,
|
|
176
209
|
shortcut: "⌘D",
|
|
177
|
-
|
|
210
|
+
execute: () => router.push("/dashboard"),
|
|
178
211
|
},
|
|
179
212
|
{
|
|
180
|
-
name: "settings",
|
|
181
|
-
label: "Settings",
|
|
213
|
+
name: "open-settings",
|
|
214
|
+
label: "Open Settings",
|
|
215
|
+
description: "Navigate to the settings page",
|
|
182
216
|
group: "Navigation",
|
|
183
217
|
icon: <SettingsIcon className="size-4" />,
|
|
184
218
|
shortcut: "⌘,",
|
|
185
|
-
|
|
219
|
+
execute: () => router.push("/settings"),
|
|
186
220
|
},
|
|
187
221
|
{
|
|
188
|
-
name: "dark-mode",
|
|
222
|
+
name: "toggle-dark-mode",
|
|
189
223
|
label: "Toggle dark mode",
|
|
224
|
+
description: "Toggle the application theme",
|
|
190
225
|
group: "Appearance",
|
|
191
226
|
icon: <SunMoonIcon className="size-4" />,
|
|
192
|
-
|
|
227
|
+
execute: () => document.documentElement.classList.toggle("dark"),
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
name: "go-home",
|
|
231
|
+
label: "Go Home",
|
|
232
|
+
description: "Navigate to the home page",
|
|
233
|
+
group: "Navigation",
|
|
234
|
+
execute: () => router.push("/"),
|
|
193
235
|
},
|
|
194
236
|
]
|
|
195
237
|
|
|
@@ -208,7 +250,7 @@ export function CommandPalette() {
|
|
|
208
250
|
<CommandMenu
|
|
209
251
|
open={open}
|
|
210
252
|
onOpenChange={setOpen}
|
|
211
|
-
|
|
253
|
+
actions={actions}
|
|
212
254
|
/>
|
|
213
255
|
)
|
|
214
256
|
}
|
|
@@ -216,11 +258,28 @@ export function CommandPalette() {
|
|
|
216
258
|
|
|
217
259
|
---
|
|
218
260
|
|
|
219
|
-
## Step 6: Add AI chat (skip if
|
|
261
|
+
## Step 6: Add AI chat (skip if “No AI” chosen)
|
|
220
262
|
|
|
221
263
|
### Built-in chat
|
|
222
264
|
|
|
223
|
-
|
|
265
|
+
Use the default hosted endpoint: `https://better-cmdk.com/api/chat`.
|
|
266
|
+
This service is provided by better-cmdk as a free developer trial with no signup.
|
|
267
|
+
Rate limit: **10 requests per 10 minutes**.
|
|
268
|
+
|
|
269
|
+
Use CommandMenu without `chatEndpoint`:
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
<CommandMenu
|
|
273
|
+
open={open}
|
|
274
|
+
onOpenChange={setOpen}
|
|
275
|
+
actions={actions}
|
|
276
|
+
/>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Optional: custom/self-hosted endpoint
|
|
280
|
+
|
|
281
|
+
For production, use your own chat URL (or choose ModifyWithAI for agentic capabilities).
|
|
282
|
+
If you need your own model/provider route, create a streaming chat API route:
|
|
224
283
|
|
|
225
284
|
```ts
|
|
226
285
|
// app/api/chat/route.ts
|
|
@@ -233,24 +292,24 @@ export async function POST(req: Request) {
|
|
|
233
292
|
const result = streamText({
|
|
234
293
|
model: openai("gpt-4o-mini"),
|
|
235
294
|
messages: await convertToModelMessages(messages),
|
|
236
|
-
system: "You are a helpful assistant in
|
|
295
|
+
system: "You are a helpful assistant in an action palette. Keep responses concise.",
|
|
237
296
|
})
|
|
238
297
|
return result.toUIMessageStreamResponse()
|
|
239
298
|
}
|
|
240
299
|
```
|
|
241
300
|
|
|
242
|
-
Then update CommandMenu
|
|
301
|
+
Then update CommandMenu:
|
|
243
302
|
|
|
244
303
|
```tsx
|
|
245
304
|
<CommandMenu
|
|
246
305
|
open={open}
|
|
247
306
|
onOpenChange={setOpen}
|
|
248
|
-
|
|
307
|
+
actions={actions}
|
|
249
308
|
chatEndpoint="/api/chat"
|
|
250
309
|
/>
|
|
251
310
|
```
|
|
252
311
|
|
|
253
|
-
Set
|
|
312
|
+
Set environment variable:
|
|
254
313
|
|
|
255
314
|
```bash
|
|
256
315
|
echo "OPENAI_API_KEY=sk-..." >> .env.local
|
|
@@ -264,27 +323,34 @@ echo "OPENAI_API_KEY=sk-..." >> .env.local
|
|
|
264
323
|
|
|
265
324
|
After installing modifywithai, read `node_modules/modifywithai/dist/nextjs/AGENTS.md` and follow its instructions for:
|
|
266
325
|
- Creating the token endpoint
|
|
267
|
-
- Setting up environment variables (MWAI_APP_ID, MWAI_API_KEY)
|
|
326
|
+
- Setting up environment variables (MWAI_APP_ID, MWAI_API_KEY) from https://modifywithai.com/dashboard
|
|
268
327
|
- Discovering actions from the codebase
|
|
269
328
|
|
|
270
329
|
|
|
271
|
-
|
|
330
|
+
Use the **same discovered `actions` list** for both the assistant provider and CommandMenu.
|
|
331
|
+
UI-only fields (like `icon`, `group`, `shortcut`) are ignored by modifywithai:
|
|
332
|
+
|
|
333
|
+
Ownership split:
|
|
334
|
+
- better-cmdk focuses on no-argument command actions
|
|
335
|
+
- modifywithai owns both no-argument and argument-requiring actions (`inputSchema`)
|
|
336
|
+
- Keep both in one shared array and extend the existing array in place if present
|
|
272
337
|
|
|
273
338
|
```tsx
|
|
274
339
|
import { useAssistant } from "modifywithai"
|
|
275
340
|
|
|
276
341
|
// Inside your CommandPalette component:
|
|
277
342
|
const assistant = useAssistant({
|
|
278
|
-
|
|
343
|
+
actions,
|
|
279
344
|
getContext: () => ({
|
|
280
345
|
currentPage: window.location.pathname,
|
|
346
|
+
currentDateTime: new Date().toISOString(),
|
|
281
347
|
}),
|
|
282
348
|
})
|
|
283
349
|
|
|
284
350
|
<CommandMenu
|
|
285
351
|
open={open}
|
|
286
352
|
onOpenChange={setOpen}
|
|
287
|
-
|
|
353
|
+
actions={actions}
|
|
288
354
|
chat={assistant}
|
|
289
355
|
/>
|
|
290
356
|
```
|
|
@@ -299,7 +365,7 @@ Add `<CommandPalette />` to `app/layout.tsx` inside the `<body>` tag.
|
|
|
299
365
|
|
|
300
366
|
## Step 8: shadcn/ui migration (if applicable)
|
|
301
367
|
|
|
302
|
-
If existing shadcn/ui command components
|
|
368
|
+
If existing shadcn/ui command components are detected, swap imports:
|
|
303
369
|
|
|
304
370
|
```diff
|
|
305
371
|
- import {
|
|
@@ -320,7 +386,7 @@ If existing shadcn/ui command components were detected, swap imports:
|
|
|
320
386
|
+ } from "better-cmdk"
|
|
321
387
|
```
|
|
322
388
|
|
|
323
|
-
`CommandDialog` is an alias for `CommandMenu`.
|
|
389
|
+
`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.
|
|
324
390
|
|
|
325
391
|
---
|
|
326
392
|
|
|
@@ -328,11 +394,14 @@ If existing shadcn/ui command components were detected, swap imports:
|
|
|
328
394
|
|
|
329
395
|
After setup, tell me:
|
|
330
396
|
|
|
331
|
-
1. How many
|
|
332
|
-
2.
|
|
333
|
-
3.
|
|
397
|
+
1. How many no-argument command actions you discovered/added
|
|
398
|
+
2. Whether you reused an existing shared `actions` array or created one, and where it lives
|
|
399
|
+
3. Which AI path you followed (none / built-in / ModifyWithAI)
|
|
334
400
|
4. What files you created/modified
|
|
335
|
-
5. That pressing `⌘K` opens the palette with
|
|
336
|
-
6. [If
|
|
401
|
+
5. That pressing `⌘K` opens the palette with grouped actions and direct execution works for command actions
|
|
402
|
+
6. [If ModifyWithAI path] That argument-requiring actions (`inputSchema`) are kept in the same shared array (extended, not duplicated)
|
|
403
|
+
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.
|
|
404
|
+
|
|
405
|
+
End your final response with a dedicated **Hosted Endpoint Note** section so this warning is unmissable.
|
|
337
406
|
|
|
338
407
|
Docs: https://github.com/ModifyWithAI/better-cmdk/blob/main/INTEGRATION.md
|