better-cmdk 0.0.1
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 +232 -0
- package/dist/index.d.ts +514 -0
- package/dist/index.js +1 -0
- package/dist/lib/utils.d.ts +6 -0
- package/dist/lib/utils.js +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# better-cmdk
|
|
2
|
+
|
|
3
|
+
A beautiful command palette component for React, built on [cmdk](https://github.com/dip/cmdk) and [Radix UI](https://www.radix-ui.com/). Styled with Tailwind CSS v4 using the shadcn/ui design system.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install better-cmdk
|
|
9
|
+
# or
|
|
10
|
+
pnpm add better-cmdk
|
|
11
|
+
# or
|
|
12
|
+
bun add better-cmdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Peer Dependencies
|
|
16
|
+
|
|
17
|
+
This library requires React 18+ and Tailwind CSS v4:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install react react-dom tailwindcss
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
### 1. Configure Tailwind to scan the package
|
|
26
|
+
|
|
27
|
+
Add the package to your Tailwind CSS sources in your main CSS file:
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
@import "tailwindcss";
|
|
31
|
+
@source "node_modules/better-cmdk";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Add CSS variables
|
|
35
|
+
|
|
36
|
+
Add the required CSS variables to your global styles:
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
:root {
|
|
40
|
+
--background: 0 0% 100%;
|
|
41
|
+
--foreground: 240 10% 3.9%;
|
|
42
|
+
--popover: 0 0% 100%;
|
|
43
|
+
--popover-foreground: 240 10% 3.9%;
|
|
44
|
+
--primary: 240 5.9% 10%;
|
|
45
|
+
--primary-foreground: 0 0% 98%;
|
|
46
|
+
--muted: 240 4.8% 95.9%;
|
|
47
|
+
--muted-foreground: 240 3.8% 46.1%;
|
|
48
|
+
--accent: 240 4.8% 95.9%;
|
|
49
|
+
--accent-foreground: 240 5.9% 10%;
|
|
50
|
+
--border: 240 5.9% 90%;
|
|
51
|
+
--input: 240 5.9% 90%;
|
|
52
|
+
--ring: 240 5.9% 10%;
|
|
53
|
+
--radius: 0.5rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@theme inline {
|
|
57
|
+
--color-background: hsl(var(--background));
|
|
58
|
+
--color-foreground: hsl(var(--foreground));
|
|
59
|
+
--color-popover: hsl(var(--popover));
|
|
60
|
+
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
61
|
+
--color-primary: hsl(var(--primary));
|
|
62
|
+
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
63
|
+
--color-muted: hsl(var(--muted));
|
|
64
|
+
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
65
|
+
--color-accent: hsl(var(--accent));
|
|
66
|
+
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
67
|
+
--color-border: hsl(var(--border));
|
|
68
|
+
--color-input: hsl(var(--input));
|
|
69
|
+
--color-ring: hsl(var(--ring));
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
"use client";
|
|
77
|
+
|
|
78
|
+
import { useState, useEffect } from "react";
|
|
79
|
+
import {
|
|
80
|
+
CommandDialog,
|
|
81
|
+
CommandEmpty,
|
|
82
|
+
CommandGroup,
|
|
83
|
+
CommandInput,
|
|
84
|
+
CommandItem,
|
|
85
|
+
CommandList,
|
|
86
|
+
CommandSeparator,
|
|
87
|
+
CommandShortcut,
|
|
88
|
+
} from "better-cmdk";
|
|
89
|
+
|
|
90
|
+
export function CommandPalette() {
|
|
91
|
+
const [open, setOpen] = useState(false);
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const down = (e: KeyboardEvent) => {
|
|
95
|
+
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
|
96
|
+
e.preventDefault();
|
|
97
|
+
setOpen((open) => !open);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
document.addEventListener("keydown", down);
|
|
102
|
+
return () => document.removeEventListener("keydown", down);
|
|
103
|
+
}, []);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<CommandDialog open={open} onOpenChange={setOpen}>
|
|
107
|
+
<CommandInput placeholder="Type a command or search..." />
|
|
108
|
+
<CommandList>
|
|
109
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
110
|
+
<CommandGroup heading="Suggestions">
|
|
111
|
+
<CommandItem>
|
|
112
|
+
<span>Calendar</span>
|
|
113
|
+
</CommandItem>
|
|
114
|
+
<CommandItem>
|
|
115
|
+
<span>Search</span>
|
|
116
|
+
</CommandItem>
|
|
117
|
+
</CommandGroup>
|
|
118
|
+
<CommandSeparator />
|
|
119
|
+
<CommandGroup heading="Settings">
|
|
120
|
+
<CommandItem>
|
|
121
|
+
<span>Profile</span>
|
|
122
|
+
<CommandShortcut>⌘P</CommandShortcut>
|
|
123
|
+
</CommandItem>
|
|
124
|
+
<CommandItem>
|
|
125
|
+
<span>Settings</span>
|
|
126
|
+
<CommandShortcut>⌘S</CommandShortcut>
|
|
127
|
+
</CommandItem>
|
|
128
|
+
</CommandGroup>
|
|
129
|
+
</CommandList>
|
|
130
|
+
</CommandDialog>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Components
|
|
136
|
+
|
|
137
|
+
### CommandDialog
|
|
138
|
+
|
|
139
|
+
The main dialog wrapper. Opens as a modal command palette.
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
<CommandDialog
|
|
143
|
+
open={open}
|
|
144
|
+
onOpenChange={setOpen}
|
|
145
|
+
title="Command Palette" // optional, for accessibility
|
|
146
|
+
description="Search commands" // optional, for accessibility
|
|
147
|
+
>
|
|
148
|
+
{children}
|
|
149
|
+
</CommandDialog>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### CommandInput
|
|
153
|
+
|
|
154
|
+
Search input with built-in search icon.
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<CommandInput placeholder="Search..." />
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### CommandList
|
|
161
|
+
|
|
162
|
+
Scrollable container for command items.
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<CommandList>{children}</CommandList>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### CommandGroup
|
|
169
|
+
|
|
170
|
+
Groups related commands with an optional heading.
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
<CommandGroup heading="Actions">{children}</CommandGroup>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### CommandItem
|
|
177
|
+
|
|
178
|
+
Individual selectable command item.
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
<CommandItem onSelect={() => console.log("Selected!")}>
|
|
182
|
+
<Icon className="mr-2 h-4 w-4" />
|
|
183
|
+
<span>Label</span>
|
|
184
|
+
</CommandItem>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### CommandShortcut
|
|
188
|
+
|
|
189
|
+
Displays keyboard shortcut hints.
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
<CommandShortcut>⌘K</CommandShortcut>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### CommandSeparator
|
|
196
|
+
|
|
197
|
+
Visual separator between groups.
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
<CommandSeparator />
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### CommandEmpty
|
|
204
|
+
|
|
205
|
+
Shown when no results match the search.
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Subpath Exports
|
|
212
|
+
|
|
213
|
+
Import specific components directly:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { Command, CommandDialog } from "better-cmdk/command";
|
|
217
|
+
import { Dialog, DialogContent } from "better-cmdk/dialog";
|
|
218
|
+
import { Button } from "better-cmdk/button";
|
|
219
|
+
import { cn } from "better-cmdk/utils";
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Styling
|
|
223
|
+
|
|
224
|
+
The component uses Tailwind CSS with the shadcn/ui design tokens. Customize by:
|
|
225
|
+
|
|
226
|
+
1. Overriding CSS variables
|
|
227
|
+
2. Passing `className` props to components
|
|
228
|
+
3. Using the `cn()` utility for conditional classes
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
import { cn } from "./lib/utils.js";
|
|
2
|
+
import { ComponentRegistry } from "@json-render/react";
|
|
3
|
+
import * as React$2 from "react";
|
|
4
|
+
import React$1, { CSSProperties, ComponentProps, HTMLAttributes, ReactNode } from "react";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
7
|
+
import { Streamdown } from "streamdown";
|
|
8
|
+
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
9
|
+
import { VariantProps } from "class-variance-authority";
|
|
10
|
+
import { Dialog as Dialog$1 } from "radix-ui";
|
|
11
|
+
import { Command as Command$1 } from "cmdk";
|
|
12
|
+
import { ToolUIPart, UIMessage } from "ai";
|
|
13
|
+
import * as class_variance_authority_types0 from "class-variance-authority/types";
|
|
14
|
+
import { UITree } from "@json-render/core";
|
|
15
|
+
|
|
16
|
+
//#region components/ui/assistant-messages.d.ts
|
|
17
|
+
declare const ToolActionSchema: z.ZodObject<{
|
|
18
|
+
name: z.ZodString;
|
|
19
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
name: string;
|
|
22
|
+
options?: Record<string, unknown> | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
name: string;
|
|
25
|
+
options?: Record<string, unknown> | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
type ToolAction = z.infer<typeof ToolActionSchema>;
|
|
28
|
+
interface AssistantMessagesProps {
|
|
29
|
+
messages: UIMessage[];
|
|
30
|
+
sendMessage: (message: {
|
|
31
|
+
text: string;
|
|
32
|
+
}) => void;
|
|
33
|
+
addToolApprovalResponse: (response: {
|
|
34
|
+
id: string;
|
|
35
|
+
approved: boolean;
|
|
36
|
+
}) => void;
|
|
37
|
+
getActionDescription?: (action: ToolAction) => string;
|
|
38
|
+
}
|
|
39
|
+
declare function AssistantMessages({
|
|
40
|
+
messages,
|
|
41
|
+
sendMessage,
|
|
42
|
+
addToolApprovalResponse,
|
|
43
|
+
getActionDescription
|
|
44
|
+
}: AssistantMessagesProps): react_jsx_runtime0.JSX.Element;
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region components/ui/button.d.ts
|
|
47
|
+
declare const buttonVariants: (props?: ({
|
|
48
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
|
|
49
|
+
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
50
|
+
} & class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
51
|
+
declare function Button({
|
|
52
|
+
className,
|
|
53
|
+
variant,
|
|
54
|
+
size,
|
|
55
|
+
asChild,
|
|
56
|
+
...props
|
|
57
|
+
}: React$2.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
58
|
+
asChild?: boolean;
|
|
59
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region components/ui/chat.d.ts
|
|
62
|
+
interface ChatMessageListProps extends React$2.ComponentProps<"div"> {
|
|
63
|
+
children: React$2.ReactNode;
|
|
64
|
+
}
|
|
65
|
+
declare function ChatMessageList({
|
|
66
|
+
children,
|
|
67
|
+
className,
|
|
68
|
+
...props
|
|
69
|
+
}: ChatMessageListProps): react_jsx_runtime0.JSX.Element;
|
|
70
|
+
interface ChatLoadingProps extends React$2.ComponentProps<"div"> {
|
|
71
|
+
text?: string;
|
|
72
|
+
}
|
|
73
|
+
declare function ChatLoading({
|
|
74
|
+
text,
|
|
75
|
+
className,
|
|
76
|
+
...props
|
|
77
|
+
}: ChatLoadingProps): react_jsx_runtime0.JSX.Element;
|
|
78
|
+
interface ChatEmptyProps extends React$2.ComponentProps<"div"> {
|
|
79
|
+
title?: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
}
|
|
82
|
+
declare function ChatEmpty({
|
|
83
|
+
title,
|
|
84
|
+
description,
|
|
85
|
+
className,
|
|
86
|
+
...props
|
|
87
|
+
}: ChatEmptyProps): react_jsx_runtime0.JSX.Element;
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region components/ui/collapsible.d.ts
|
|
90
|
+
declare function Collapsible({
|
|
91
|
+
...props
|
|
92
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>): react_jsx_runtime0.JSX.Element;
|
|
93
|
+
declare function CollapsibleTrigger({
|
|
94
|
+
...props
|
|
95
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>): react_jsx_runtime0.JSX.Element;
|
|
96
|
+
declare function CollapsibleContent({
|
|
97
|
+
...props
|
|
98
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): react_jsx_runtime0.JSX.Element;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region components/ui/dialog.d.ts
|
|
101
|
+
declare function Dialog({
|
|
102
|
+
...props
|
|
103
|
+
}: React$2.ComponentProps<typeof Dialog$1.Root>): react_jsx_runtime0.JSX.Element;
|
|
104
|
+
declare function DialogTrigger({
|
|
105
|
+
...props
|
|
106
|
+
}: React$2.ComponentProps<typeof Dialog$1.Trigger>): react_jsx_runtime0.JSX.Element;
|
|
107
|
+
declare function DialogPortal({
|
|
108
|
+
...props
|
|
109
|
+
}: React$2.ComponentProps<typeof Dialog$1.Portal>): react_jsx_runtime0.JSX.Element;
|
|
110
|
+
declare function DialogClose({
|
|
111
|
+
...props
|
|
112
|
+
}: React$2.ComponentProps<typeof Dialog$1.Close>): react_jsx_runtime0.JSX.Element;
|
|
113
|
+
declare function DialogOverlay({
|
|
114
|
+
className,
|
|
115
|
+
...props
|
|
116
|
+
}: React$2.ComponentProps<typeof Dialog$1.Overlay>): react_jsx_runtime0.JSX.Element;
|
|
117
|
+
declare function DialogContent({
|
|
118
|
+
className,
|
|
119
|
+
children,
|
|
120
|
+
showCloseButton,
|
|
121
|
+
...props
|
|
122
|
+
}: React$2.ComponentProps<typeof Dialog$1.Content> & {
|
|
123
|
+
showCloseButton?: boolean;
|
|
124
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
125
|
+
declare function DialogHeader({
|
|
126
|
+
className,
|
|
127
|
+
...props
|
|
128
|
+
}: React$2.ComponentProps<"div">): react_jsx_runtime0.JSX.Element;
|
|
129
|
+
declare function DialogFooter({
|
|
130
|
+
className,
|
|
131
|
+
showCloseButton,
|
|
132
|
+
children,
|
|
133
|
+
...props
|
|
134
|
+
}: React$2.ComponentProps<"div"> & {
|
|
135
|
+
showCloseButton?: boolean;
|
|
136
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
137
|
+
declare function DialogTitle({
|
|
138
|
+
className,
|
|
139
|
+
...props
|
|
140
|
+
}: React$2.ComponentProps<typeof Dialog$1.Title>): react_jsx_runtime0.JSX.Element;
|
|
141
|
+
declare function DialogDescription({
|
|
142
|
+
className,
|
|
143
|
+
...props
|
|
144
|
+
}: React$2.ComponentProps<typeof Dialog$1.Description>): react_jsx_runtime0.JSX.Element;
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region components/ui/command.d.ts
|
|
147
|
+
declare function Command({
|
|
148
|
+
className,
|
|
149
|
+
...props
|
|
150
|
+
}: React$2.ComponentProps<typeof Command$1>): react_jsx_runtime0.JSX.Element;
|
|
151
|
+
declare function CommandDialogContent({
|
|
152
|
+
className,
|
|
153
|
+
children,
|
|
154
|
+
...props
|
|
155
|
+
}: React$2.ComponentProps<typeof Dialog$1.Content>): react_jsx_runtime0.JSX.Element;
|
|
156
|
+
declare function CommandGroup({
|
|
157
|
+
className,
|
|
158
|
+
...props
|
|
159
|
+
}: React$2.ComponentProps<typeof Command$1.Group>): react_jsx_runtime0.JSX.Element;
|
|
160
|
+
declare function CommandSeparator({
|
|
161
|
+
className,
|
|
162
|
+
...props
|
|
163
|
+
}: React$2.ComponentProps<typeof Command$1.Separator>): react_jsx_runtime0.JSX.Element;
|
|
164
|
+
declare function CommandItem({
|
|
165
|
+
className,
|
|
166
|
+
style,
|
|
167
|
+
...props
|
|
168
|
+
}: React$2.ComponentProps<typeof Command$1.Item>): react_jsx_runtime0.JSX.Element;
|
|
169
|
+
declare function CommandShortcut({
|
|
170
|
+
className,
|
|
171
|
+
...props
|
|
172
|
+
}: React$2.ComponentProps<"span">): react_jsx_runtime0.JSX.Element;
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region hooks/use-chat-history.d.ts
|
|
175
|
+
interface ChatConversation {
|
|
176
|
+
id: string;
|
|
177
|
+
title: string;
|
|
178
|
+
messages: UIMessage[];
|
|
179
|
+
createdAt: number;
|
|
180
|
+
updatedAt: number;
|
|
181
|
+
}
|
|
182
|
+
interface UseChatHistoryOptions {
|
|
183
|
+
storageKey?: string;
|
|
184
|
+
maxConversations?: number;
|
|
185
|
+
messages: UIMessage[];
|
|
186
|
+
setMessages?: (messages: UIMessage[] | ((msgs: UIMessage[]) => UIMessage[])) => void;
|
|
187
|
+
}
|
|
188
|
+
interface UseChatHistoryReturn {
|
|
189
|
+
conversations: ChatConversation[];
|
|
190
|
+
currentConversationId: string | null;
|
|
191
|
+
startNewChat: () => void;
|
|
192
|
+
loadConversation: (id: string) => void;
|
|
193
|
+
saveCurrentConversation: () => void;
|
|
194
|
+
}
|
|
195
|
+
declare function useChatHistory({
|
|
196
|
+
storageKey,
|
|
197
|
+
maxConversations,
|
|
198
|
+
messages,
|
|
199
|
+
setMessages
|
|
200
|
+
}: UseChatHistoryOptions): UseChatHistoryReturn;
|
|
201
|
+
//#endregion
|
|
202
|
+
//#region context/command-menu-context.d.ts
|
|
203
|
+
type CommandMenuMode = "command" | "chat";
|
|
204
|
+
type CommandMenuStatus = "idle" | "submitted" | "streaming" | "error";
|
|
205
|
+
interface ExternalChat {
|
|
206
|
+
messages: UIMessage[];
|
|
207
|
+
setMessages?: (messages: UIMessage[] | ((msgs: UIMessage[]) => UIMessage[])) => void;
|
|
208
|
+
sendMessage: (message: {
|
|
209
|
+
text: string;
|
|
210
|
+
}) => void;
|
|
211
|
+
status: "ready" | "submitted" | "streaming" | "error";
|
|
212
|
+
error: Error | null;
|
|
213
|
+
addToolApprovalResponse?: (response: {
|
|
214
|
+
id: string;
|
|
215
|
+
approved: boolean;
|
|
216
|
+
}) => void;
|
|
217
|
+
agenticActions?: CommandAction[];
|
|
218
|
+
}
|
|
219
|
+
interface CommandMenuContextValue {
|
|
220
|
+
mode: CommandMenuMode;
|
|
221
|
+
setMode: (mode: CommandMenuMode) => void;
|
|
222
|
+
inputValue: string;
|
|
223
|
+
setInputValue: (value: string) => void;
|
|
224
|
+
chatEndpoint: string | null;
|
|
225
|
+
status: CommandMenuStatus;
|
|
226
|
+
error: Error | null;
|
|
227
|
+
switchToChat: (initialQuery?: string) => void;
|
|
228
|
+
switchToCommand: () => void;
|
|
229
|
+
messages: UIMessage[];
|
|
230
|
+
sendMessage: (content: string) => Promise<void>;
|
|
231
|
+
isLoading: boolean;
|
|
232
|
+
isEnabled: boolean;
|
|
233
|
+
addToolApprovalResponse?: (response: {
|
|
234
|
+
id: string;
|
|
235
|
+
approved: boolean;
|
|
236
|
+
}) => void;
|
|
237
|
+
agenticActions?: CommandAction[];
|
|
238
|
+
requestClose?: () => void;
|
|
239
|
+
conversations: ChatConversation[];
|
|
240
|
+
currentConversationId: string | null;
|
|
241
|
+
startNewChat: () => void;
|
|
242
|
+
loadConversation: (id: string) => void;
|
|
243
|
+
}
|
|
244
|
+
declare const CommandMenuContext: React$2.Context<CommandMenuContextValue | null>;
|
|
245
|
+
interface CommandMenuProviderProps {
|
|
246
|
+
children: React$2.ReactNode;
|
|
247
|
+
chatEndpoint?: string | null;
|
|
248
|
+
chat?: ExternalChat;
|
|
249
|
+
onModeChange?: (mode: CommandMenuMode) => void;
|
|
250
|
+
onOpenChange?: (open: boolean) => void;
|
|
251
|
+
historyStorageKey?: string;
|
|
252
|
+
maxConversations?: number;
|
|
253
|
+
}
|
|
254
|
+
declare function CommandMenuProvider({
|
|
255
|
+
children,
|
|
256
|
+
chatEndpoint,
|
|
257
|
+
chat: externalChat,
|
|
258
|
+
onModeChange,
|
|
259
|
+
onOpenChange,
|
|
260
|
+
historyStorageKey,
|
|
261
|
+
maxConversations
|
|
262
|
+
}: CommandMenuProviderProps): react_jsx_runtime0.JSX.Element;
|
|
263
|
+
declare function useCommandMenuContext(): CommandMenuContextValue;
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region components/ui/command-menu.d.ts
|
|
266
|
+
type CommandMenuCorners = "none" | "sm" | "md" | "lg" | "xl";
|
|
267
|
+
interface CommandMenuProps extends Omit<React$2.ComponentProps<typeof Dialog>, "children"> {
|
|
268
|
+
title?: string;
|
|
269
|
+
description?: string;
|
|
270
|
+
className?: string;
|
|
271
|
+
corners?: CommandMenuCorners;
|
|
272
|
+
borderColor?: string;
|
|
273
|
+
chatEndpoint?: string | null;
|
|
274
|
+
chat?: ExternalChat;
|
|
275
|
+
askAILabel?: string;
|
|
276
|
+
onModeChange?: (mode: CommandMenuMode) => void;
|
|
277
|
+
historyStorageKey?: string;
|
|
278
|
+
maxConversations?: number;
|
|
279
|
+
/** Declarative command definitions. Mutually exclusive with children. */
|
|
280
|
+
commands?: CommandDefinition[];
|
|
281
|
+
/** Placeholder for the command input when using `commands` prop. */
|
|
282
|
+
commandsPlaceholder?: string;
|
|
283
|
+
/** Label for the "Ask AI" trigger when using `commands` prop. */
|
|
284
|
+
commandsAskAILabel?: string;
|
|
285
|
+
children?: React$2.ReactNode | ((context: {
|
|
286
|
+
mode: CommandMenuMode;
|
|
287
|
+
messages: UIMessage[];
|
|
288
|
+
status: "idle" | "submitted" | "streaming" | "error";
|
|
289
|
+
isEnabled: boolean;
|
|
290
|
+
}) => React$2.ReactNode);
|
|
291
|
+
}
|
|
292
|
+
declare function CommandContent({
|
|
293
|
+
className,
|
|
294
|
+
children,
|
|
295
|
+
corners,
|
|
296
|
+
borderColor,
|
|
297
|
+
...props
|
|
298
|
+
}: React$2.ComponentProps<typeof Dialog$1.Content> & {
|
|
299
|
+
corners?: CommandMenuCorners;
|
|
300
|
+
borderColor?: string;
|
|
301
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
302
|
+
declare function CommandMenu({
|
|
303
|
+
chatEndpoint,
|
|
304
|
+
chat,
|
|
305
|
+
onModeChange,
|
|
306
|
+
onOpenChange,
|
|
307
|
+
historyStorageKey,
|
|
308
|
+
maxConversations,
|
|
309
|
+
commands,
|
|
310
|
+
commandsPlaceholder,
|
|
311
|
+
commandsAskAILabel,
|
|
312
|
+
...props
|
|
313
|
+
}: CommandMenuProps): react_jsx_runtime0.JSX.Element;
|
|
314
|
+
interface CommandInputProps extends Omit<React$2.ComponentProps<typeof Command$1.Input>, "value" | "onValueChange"> {
|
|
315
|
+
showSendButton?: boolean;
|
|
316
|
+
}
|
|
317
|
+
declare function CommandInput({
|
|
318
|
+
className,
|
|
319
|
+
showSendButton,
|
|
320
|
+
...props
|
|
321
|
+
}: CommandInputProps): react_jsx_runtime0.JSX.Element;
|
|
322
|
+
interface CommandEmptyProps extends React$2.ComponentProps<typeof Command$1.Item> {
|
|
323
|
+
label?: string;
|
|
324
|
+
description?: string;
|
|
325
|
+
}
|
|
326
|
+
declare function CommandEmpty({
|
|
327
|
+
label,
|
|
328
|
+
className,
|
|
329
|
+
...props
|
|
330
|
+
}: CommandEmptyProps): react_jsx_runtime0.JSX.Element;
|
|
331
|
+
declare namespace CommandEmpty {
|
|
332
|
+
var displayName: string;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Describes a single option/parameter for an action.
|
|
336
|
+
* Compatible with ActionOption from modifywithai.
|
|
337
|
+
*/
|
|
338
|
+
interface CommandActionOption {
|
|
339
|
+
type: string;
|
|
340
|
+
description?: string;
|
|
341
|
+
required?: boolean;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Minimal action interface compatible with ActionDefinition from modifywithai.
|
|
345
|
+
* Only `name` and `execute` are needed — all other ActionDefinition fields are ignored.
|
|
346
|
+
*/
|
|
347
|
+
interface CommandAction {
|
|
348
|
+
name: string;
|
|
349
|
+
label?: string;
|
|
350
|
+
options?: Record<string, CommandActionOption>;
|
|
351
|
+
execute?: (options: Record<string, unknown>) => void;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Declarative command definition for the `commands` prop.
|
|
355
|
+
* Named CommandDefinition to avoid collision with cmdk's Command component.
|
|
356
|
+
*/
|
|
357
|
+
interface CommandDefinition {
|
|
358
|
+
/** Unique key used as cmdk value */
|
|
359
|
+
name: string;
|
|
360
|
+
/** Display text (falls back to name) */
|
|
361
|
+
label?: string;
|
|
362
|
+
/** Group heading — commands with the same string appear in the same group */
|
|
363
|
+
group?: string;
|
|
364
|
+
/** Icon rendered before the label */
|
|
365
|
+
icon?: React$2.ReactNode;
|
|
366
|
+
/** Display-only shortcut hint (right-aligned) */
|
|
367
|
+
shortcut?: string;
|
|
368
|
+
/** Extra cmdk search terms */
|
|
369
|
+
keywords?: string[];
|
|
370
|
+
/** Grayed out, not selectable */
|
|
371
|
+
disabled?: boolean;
|
|
372
|
+
/** Called when the command is selected */
|
|
373
|
+
onSelect?: () => void;
|
|
374
|
+
}
|
|
375
|
+
interface CommandListProps extends React$2.ComponentProps<typeof Command$1.List> {
|
|
376
|
+
/** Actions to render as CommandItems. Compatible with ActionDefinition[]. */
|
|
377
|
+
actions?: CommandAction[];
|
|
378
|
+
/** Heading for the auto-rendered actions group */
|
|
379
|
+
actionsHeading?: string;
|
|
380
|
+
}
|
|
381
|
+
declare function CommandList({
|
|
382
|
+
className,
|
|
383
|
+
children,
|
|
384
|
+
actions,
|
|
385
|
+
actionsHeading,
|
|
386
|
+
...props
|
|
387
|
+
}: CommandListProps): react_jsx_runtime0.JSX.Element;
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region components/ui/confirmation.d.ts
|
|
390
|
+
type ToolUIPartApproval = {
|
|
391
|
+
id: string;
|
|
392
|
+
approved?: never;
|
|
393
|
+
reason?: never;
|
|
394
|
+
} | {
|
|
395
|
+
id: string;
|
|
396
|
+
approved: boolean;
|
|
397
|
+
reason?: string;
|
|
398
|
+
} | undefined;
|
|
399
|
+
type ConfirmationProps = Omit<ComponentProps<"div">, "className"> & {
|
|
400
|
+
approval?: ToolUIPartApproval;
|
|
401
|
+
state: ToolUIPart["state"];
|
|
402
|
+
};
|
|
403
|
+
declare function Confirmation({
|
|
404
|
+
approval,
|
|
405
|
+
state,
|
|
406
|
+
style,
|
|
407
|
+
...props
|
|
408
|
+
}: ConfirmationProps & {
|
|
409
|
+
style?: CSSProperties;
|
|
410
|
+
}): react_jsx_runtime0.JSX.Element | null;
|
|
411
|
+
type ConfirmationTitleProps = Omit<ComponentProps<"p">, "className">;
|
|
412
|
+
declare function ConfirmationTitle(props: ConfirmationTitleProps): react_jsx_runtime0.JSX.Element;
|
|
413
|
+
type ConfirmationRequestProps = {
|
|
414
|
+
children?: ReactNode;
|
|
415
|
+
};
|
|
416
|
+
declare function ConfirmationRequest({
|
|
417
|
+
children
|
|
418
|
+
}: ConfirmationRequestProps): react_jsx_runtime0.JSX.Element | null;
|
|
419
|
+
type ConfirmationAcceptedProps = {
|
|
420
|
+
children?: ReactNode;
|
|
421
|
+
};
|
|
422
|
+
declare function ConfirmationAccepted({
|
|
423
|
+
children
|
|
424
|
+
}: ConfirmationAcceptedProps): react_jsx_runtime0.JSX.Element | null;
|
|
425
|
+
type ConfirmationRejectedProps = {
|
|
426
|
+
children?: ReactNode;
|
|
427
|
+
};
|
|
428
|
+
declare function ConfirmationRejected({
|
|
429
|
+
children
|
|
430
|
+
}: ConfirmationRejectedProps): react_jsx_runtime0.JSX.Element | null;
|
|
431
|
+
type ConfirmationActionsProps = Omit<ComponentProps<"div">, "className">;
|
|
432
|
+
declare function ConfirmationActions(props: ConfirmationActionsProps): react_jsx_runtime0.JSX.Element | null;
|
|
433
|
+
type ConfirmationActionProps = Omit<ComponentProps<"button">, "className"> & {
|
|
434
|
+
variant?: "default" | "outline" | "destructive";
|
|
435
|
+
};
|
|
436
|
+
declare function ConfirmationAction({
|
|
437
|
+
variant,
|
|
438
|
+
style,
|
|
439
|
+
...props
|
|
440
|
+
}: ConfirmationActionProps & {
|
|
441
|
+
style?: CSSProperties;
|
|
442
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region components/ui/form-components.d.ts
|
|
445
|
+
declare const defaultFormRegistry: ComponentRegistry;
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region components/ui/form-renderer.d.ts
|
|
448
|
+
interface AssistantFormRendererProps {
|
|
449
|
+
ui: UITree;
|
|
450
|
+
context?: Record<string, unknown>;
|
|
451
|
+
onSubmit: (formId: string, data: Record<string, string>) => void;
|
|
452
|
+
onCancel?: (formId: string) => void;
|
|
453
|
+
registry?: ComponentRegistry;
|
|
454
|
+
}
|
|
455
|
+
declare function AssistantFormRenderer({
|
|
456
|
+
ui,
|
|
457
|
+
context,
|
|
458
|
+
onSubmit,
|
|
459
|
+
onCancel,
|
|
460
|
+
registry
|
|
461
|
+
}: AssistantFormRendererProps): react_jsx_runtime0.JSX.Element;
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region components/ui/message.d.ts
|
|
464
|
+
type MessageProps = Omit<HTMLAttributes<HTMLDivElement>, "className"> & {
|
|
465
|
+
from: UIMessage["role"];
|
|
466
|
+
};
|
|
467
|
+
declare function Message({
|
|
468
|
+
from,
|
|
469
|
+
...props
|
|
470
|
+
}: MessageProps): react_jsx_runtime0.JSX.Element;
|
|
471
|
+
type MessageContentProps = Omit<HTMLAttributes<HTMLDivElement>, "className">;
|
|
472
|
+
declare function MessageContent({
|
|
473
|
+
children,
|
|
474
|
+
style,
|
|
475
|
+
...props
|
|
476
|
+
}: MessageContentProps & {
|
|
477
|
+
style?: CSSProperties;
|
|
478
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
479
|
+
type MessageResponseProps = Omit<ComponentProps<typeof Streamdown>, "className">;
|
|
480
|
+
declare const MessageResponse: React$1.MemoExoticComponent<(props: MessageResponseProps) => React$1.JSX.Element>;
|
|
481
|
+
//#endregion
|
|
482
|
+
//#region components/ui/task.d.ts
|
|
483
|
+
type TaskItemFileProps = Omit<ComponentProps<"div">, "className">;
|
|
484
|
+
declare function TaskItemFile({
|
|
485
|
+
children,
|
|
486
|
+
...props
|
|
487
|
+
}: TaskItemFileProps): react_jsx_runtime0.JSX.Element;
|
|
488
|
+
type TaskItemProps = Omit<ComponentProps<"div">, "className">;
|
|
489
|
+
declare function TaskItem({
|
|
490
|
+
children,
|
|
491
|
+
...props
|
|
492
|
+
}: TaskItemProps): react_jsx_runtime0.JSX.Element;
|
|
493
|
+
type TaskProps = Omit<ComponentProps<typeof Collapsible>, "className">;
|
|
494
|
+
declare function Task({
|
|
495
|
+
defaultOpen,
|
|
496
|
+
...props
|
|
497
|
+
}: TaskProps): react_jsx_runtime0.JSX.Element;
|
|
498
|
+
type TaskTriggerProps = Omit<ComponentProps<typeof CollapsibleTrigger>, "className"> & {
|
|
499
|
+
title: string;
|
|
500
|
+
icon?: ReactNode;
|
|
501
|
+
};
|
|
502
|
+
declare function TaskTrigger({
|
|
503
|
+
children,
|
|
504
|
+
title,
|
|
505
|
+
icon,
|
|
506
|
+
...props
|
|
507
|
+
}: TaskTriggerProps): react_jsx_runtime0.JSX.Element;
|
|
508
|
+
type TaskContentProps = Omit<ComponentProps<typeof CollapsibleContent>, "className">;
|
|
509
|
+
declare function TaskContent({
|
|
510
|
+
children,
|
|
511
|
+
...props
|
|
512
|
+
}: TaskContentProps): react_jsx_runtime0.JSX.Element;
|
|
513
|
+
//#endregion
|
|
514
|
+
export { AssistantFormRenderer, type AssistantFormRendererProps, AssistantMessages, type AssistantMessagesProps, Button, type ChatConversation, ChatEmpty, type ChatEmptyProps, ChatLoading, type ChatLoadingProps, ChatMessageList, type ChatMessageListProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, type CommandAction, type CommandActionOption, CommandContent, type CommandDefinition, CommandMenu as CommandDialog, CommandMenu, CommandDialogContent, CommandEmpty, type CommandEmptyProps, CommandGroup, CommandInput, type CommandInputProps, CommandItem, CommandList, type CommandListProps, CommandMenuContext, type CommandMenuContextValue, type CommandMenuCorners, type CommandMenuMode, type CommandMenuProps, CommandMenuProvider, type CommandMenuProviderProps, type CommandMenuStatus, CommandSeparator, CommandShortcut, Confirmation, ConfirmationAccepted, type ConfirmationAcceptedProps, ConfirmationAction, type ConfirmationActionProps, ConfirmationActions, type ConfirmationActionsProps, type ConfirmationProps, ConfirmationRejected, type ConfirmationRejectedProps, ConfirmationRequest, type ConfirmationRequestProps, ConfirmationTitle, type ConfirmationTitleProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type ExternalChat, Message, MessageContent, type MessageContentProps, type MessageProps, MessageResponse, type MessageResponseProps, Task, TaskContent, type TaskContentProps, TaskItem, TaskItemFile, type TaskItemFileProps, type TaskItemProps, type TaskProps, TaskTrigger, type TaskTriggerProps, type ToolUIPartApproval, type UseChatHistoryOptions, type UseChatHistoryReturn, buttonVariants, cn, defaultFormRegistry, useChatHistory, useCommandMenuContext };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cn as e}from"./lib/utils.js";import{JSONUIProvider as t,Renderer as n,flatToTree as r}from"@json-render/react";import*as i from"react";import{createContext as a,memo as o,useCallback as s,useContext as c,useEffect as l,useMemo as u,useRef as d,useState as f}from"react";import{z as p}from"zod";import{Fragment as m,jsx as h,jsxs as g}from"react/jsx-runtime";import{Streamdown as _}from"streamdown";import{ChevronDownIcon as v,CornerDownLeftIcon as y,LoaderIcon as b,MessageCircleIcon as x,SearchIcon as S,SparklesIcon as C,XIcon as w}from"lucide-react";import*as T from"@radix-ui/react-collapsible";import{cva as E}from"class-variance-authority";import{Dialog as D,Slot as O}from"radix-ui";import{Command as k,defaultFilter as ee,useCommandState as A}from"cmdk";import{useChat as te}from"@ai-sdk/react";import{DefaultChatTransport as ne}from"ai";import{BrowserClient as j,Scope as M,dedupeIntegration as N,defaultStackParser as P,linkedErrorsIntegration as F,makeFetchTransport as I}from"@sentry/browser";const re=a(null);function L(){let e=c(re);if(!e)throw Error(`Confirmation components must be used within Confirmation`);return e}function ie({approval:t,state:n,style:r,...i}){return!t||n===`input-streaming`||n===`input-available`?null:h(re.Provider,{value:{approval:t,state:n},children:h(`div`,{"data-slot":`confirmation`,"data-state":n,"data-approved":t?.approved,role:`alertdialog`,"aria-labelledby":`confirmation-title`,style:{borderRadius:`var(--cmdk-radius, 0.5rem)`,...r},className:e(`flex flex-col gap-2 border p-4`,`data-[state=approval-requested]:border-amber-500/50 data-[state=approval-requested]:bg-amber-50/50 dark:data-[state=approval-requested]:bg-amber-950/20`,`data-[approved=true]:border-green-500/50 data-[approved=true]:bg-green-50/50 dark:data-[approved=true]:bg-green-950/20`,`data-[approved=false]:border-red-500/50 data-[approved=false]:bg-red-50/50 dark:data-[approved=false]:bg-red-950/20`),...i})})}function ae(e){return h(`p`,{id:`confirmation-title`,"data-slot":`confirmation-title`,className:`text-sm font-medium`,...e})}function R({children:e}){let{state:t}=L();return t===`approval-requested`?h(`div`,{"data-slot":`confirmation-request`,children:e}):null}function oe({children:e}){let{approval:t,state:n}=L();return!t?.approved||n!==`approval-responded`&&n!==`output-denied`&&n!==`output-available`?null:h(`div`,{"data-slot":`confirmation-accepted`,children:e})}function se({children:e}){let{approval:t,state:n}=L();return t?.approved!==!1||n!==`approval-responded`&&n!==`output-denied`&&n!==`output-available`?null:h(`div`,{"data-slot":`confirmation-rejected`,children:e})}function ce(e){let{state:t}=L();return t===`approval-requested`?h(`div`,{"data-slot":`confirmation-actions`,className:`flex items-center justify-end gap-2 self-end`,...e}):null}function z({variant:t=`default`,style:n,...r}){return h(`button`,{"data-slot":`confirmation-action`,"data-variant":t,type:`button`,className:e(`inline-flex h-8 items-center justify-center gap-2 whitespace-nowrap px-3 text-sm font-medium transition-colors`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`,`disabled:pointer-events-none disabled:opacity-50`,t===`default`&&`bg-primary text-primary-foreground shadow hover:bg-primary/90`,t===`outline`&&`border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground`,t===`destructive`&&`bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90`),style:{borderRadius:`var(--cmdk-radius, 0.375rem)`,...n},...r})}function B(e){e.stopPropagation()}function le({element:t,children:n,onAction:r}){let{id:i=`form`,title:a,submitLabel:o=`Submit`}=t.props??{},s=e=>{e.preventDefault();let t=new FormData(e.currentTarget),n={};t.forEach((e,t)=>{typeof e==`string`&&(n[t]=e)}),r?.({name:`submit`,params:{formId:i,data:n}})};return g(`div`,{"data-slot":`form-card`,className:e(`w-full rounded-lg border bg-card text-card-foreground shadow-sm`),children:[a&&h(`div`,{className:`flex flex-col space-y-1.5 p-4 pb-3`,children:h(`h3`,{className:`text-base font-semibold leading-none tracking-tight`,children:a})}),h(`div`,{className:e(`p-4`,a?``:`pt-4`),children:g(`form`,{onSubmit:s,className:`space-y-4`,children:[n,g(`div`,{className:`flex justify-end gap-2 pt-2`,children:[h(`button`,{type:`button`,className:e(`inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium shadow-sm transition-colors`,`hover:bg-accent hover:text-accent-foreground`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`,`disabled:pointer-events-none disabled:opacity-50`),onClick:()=>r?.({name:`cancel`,params:{formId:i}}),children:`Cancel`}),h(`button`,{type:`submit`,className:e(`inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow transition-colors`,`hover:bg-primary/90`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`,`disabled:pointer-events-none disabled:opacity-50`),children:o})]})]})})]})}function ue({element:t}){let{name:n=`field`,label:r=`Field`,placeholder:i,required:a,defaultValue:o}=t.props??{};return g(`div`,{className:`space-y-1.5`,children:[g(`label`,{htmlFor:n,className:`text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70`,children:[r,a&&h(`span`,{className:`ml-1 text-destructive`,children:`*`})]}),h(`input`,{id:n,name:n,type:`text`,placeholder:i,required:a,defaultValue:o,autoComplete:`off`,onKeyDown:B,onKeyUp:B,className:e(`flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors`,`placeholder:text-muted-foreground`,`focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`,`disabled:cursor-not-allowed disabled:opacity-50`)})]})}function de({element:t}){let{name:n=`field`,label:r=`Field`,placeholder:i,required:a,defaultValue:o,rows:s=3}=t.props??{};return g(`div`,{className:`space-y-1.5`,children:[g(`label`,{htmlFor:n,className:`text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70`,children:[r,a&&h(`span`,{className:`ml-1 text-destructive`,children:`*`})]}),h(`textarea`,{id:n,name:n,placeholder:i,required:a,defaultValue:o,rows:s,onKeyDown:B,onKeyUp:B,className:e(`flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors`,`placeholder:text-muted-foreground`,`focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`,`disabled:cursor-not-allowed disabled:opacity-50`)})]})}function fe({element:t}){let{name:n=`date`,label:r=`Date`,required:i,defaultValue:a,min:o,max:s}=t.props??{};return g(`div`,{className:`space-y-1.5`,children:[g(`label`,{htmlFor:n,className:`text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70`,children:[r,i&&h(`span`,{className:`ml-1 text-destructive`,children:`*`})]}),h(`input`,{type:`date`,id:n,name:n,required:i,defaultValue:a,min:o,max:s,onKeyDown:B,onKeyUp:B,className:e(`flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors`,`focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`,`disabled:cursor-not-allowed disabled:opacity-50`)})]})}const V={Form:le,TextField:ue,TextArea:de,DateField:fe},pe=p.object({formId:p.string(),data:p.record(p.string(),p.string())}),me=p.object({formId:p.string()});function H({ui:e,context:r,onSubmit:i,onCancel:a,registry:o=V}){let c=s(e=>{let t=pe.safeParse(e);t.success?i(t.data.formId,t.data.data):console.warn(`Form submit: Invalid params`,t.error.flatten())},[i]),l=s(e=>{let t=me.safeParse(e);t.success?a?.(t.data.formId):console.warn(`Form cancel: Invalid params`,t.error.flatten())},[a]);return h(t,{registry:o,initialData:r,actionHandlers:u(()=>({submit:c,cancel:l}),[c,l]),children:h(n,{tree:e,registry:o})})}function he({from:t,...n}){return h(`div`,{"data-slot":`message`,"data-from":t,className:e(`group flex w-full max-w-[95%] flex-col gap-2`,t===`user`?`is-user ml-auto justify-end`:`is-assistant`),...n})}function ge({children:t,style:n,...r}){return h(`div`,{"data-slot":`message-content`,className:e(`flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm`,`group-[.is-user]:ml-auto group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground`,`group-[.is-assistant]:text-foreground`),style:{borderRadius:`var(--cmdk-radius, 0.5rem)`,...n},...r,children:t})}const _e=o(function(e){return h(_,{"data-slot":`message-response`,className:`size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0`,...e})},(e,t)=>e.children===t.children);function ve({...e}){return h(T.Root,{"data-slot":`collapsible`,...e})}function ye({...e}){return h(T.CollapsibleTrigger,{"data-slot":`collapsible-trigger`,...e})}function be({...e}){return h(T.CollapsibleContent,{"data-slot":`collapsible-content`,...e})}function xe({children:e,...t}){return h(`div`,{"data-slot":`task-item-file`,className:`inline-flex items-center gap-1 rounded-md border bg-secondary px-1.5 py-0.5 text-xs text-foreground`,...t,children:e})}function Se({children:e,...t}){return h(`div`,{"data-slot":`task-item`,className:`text-sm text-muted-foreground`,...t,children:e})}function Ce({defaultOpen:e=!0,...t}){return h(ve,{"data-slot":`task`,defaultOpen:e,...t})}function we({children:e,title:t,icon:n,...r}){return h(ye,{asChild:!0,className:`group`,...r,children:e??g(`div`,{className:`flex w-full cursor-pointer items-center gap-2 text-sm text-muted-foreground transition-colors hover:text-foreground`,children:[n??h(S,{className:`size-4`}),h(`p`,{className:`text-sm`,children:t}),h(v,{className:`size-4 transition-transform group-data-[state=open]:rotate-180`})]})})}function Te({children:t,...n}){return h(be,{"data-slot":`task-content`,className:e(`text-popover-foreground outline-none`,`data-[state=closed]:animate-out data-[state=open]:animate-in`,`data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,`data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2`),...n,children:h(`div`,{className:`mt-4 space-y-2 border-l-2 border-muted pl-4`,children:t})})}const Ee=p.object({name:p.string(),options:p.record(p.string(),p.unknown()).optional()}),De=p.object({actions:p.array(Ee).optional()}),Oe=p.object({id:p.string(),approved:p.boolean().optional()}),ke=p.object({type:p.string(),props:p.record(p.string(),p.unknown()).default({}),children:p.array(p.string()).optional(),parentKey:p.string().nullable().optional()}),Ae=p.object({ui:p.object({elements:p.record(p.string(),ke)}),context:p.record(p.string(),p.unknown()).optional()});function je(e){return e.name}function Me({messages:e,sendMessage:t,addToolApprovalResponse:n,getActionDescription:r=je}){let i=e.filter(e=>e.role===`user`||e.role===`assistant`);return h(m,{children:i.map((e,a)=>{let o=a===i.length-1;return h(he,{from:e.role,children:h(ge,{children:e.parts.map((i,a)=>h(Ne,{part:i,messageId:e.id,partIndex:a,isLastMessage:o,sendMessage:t,addToolApprovalResponse:n,getActionDescription:r},`${e.id}-${a}`))})},e.id)})})}function Ne({part:e,messageId:t,partIndex:n,isLastMessage:r,sendMessage:i,addToolApprovalResponse:a,getActionDescription:o}){if(e.type===`text`)return h(_e,{children:e.text});if(e.type===`tool-performActions`){let r=`input`in e?e.input:void 0,i=De.safeParse(r),s=i.success?i.data.actions??[]:[];if(s.length===0)return null;let c=s.length,l=`state`in e?e.state:void 0,u=`approval`in e?e.approval:void 0,d=Oe.safeParse(u),f=d.success?d.data:void 0;return f&&l?g(ie,{state:l,approval:f,children:[h(ae,{children:c===1?`Confirm action`:`Confirm ${c} actions`}),h(R,{children:h(`ul`,{className:`list-disc list-inside text-sm text-muted-foreground mt-2`,children:s.map((e,r)=>h(`li`,{children:o(e)},`${t}-${n}-${r}`))})}),h(oe,{children:h(`span`,{className:`text-sm text-muted-foreground`,children:c===1?`Action approved`:`${c} actions approved`})}),h(se,{children:h(`span`,{className:`text-sm text-muted-foreground`,children:c===1?`Action cancelled`:`${c} actions cancelled`})}),g(ce,{children:[h(z,{variant:`outline`,onClick:()=>a({id:f.id,approved:!1}),children:`Deny`}),h(z,{onClick:()=>a({id:f.id,approved:!0}),children:`Approve`})]})]}):g(Ce,{defaultOpen:!1,children:[h(we,{title:c===1?`Performing 1 action`:`Performing ${c} actions`}),h(Te,{children:s.map((e,r)=>h(Se,{children:o(e)},`${t}-${n}-${r}`))})]})}return e.type===`tool-renderUI`&&r&&(`state`in e?e.state:void 0)===`output-available`&&`output`in e?h(Pe,{output:e.output,sendMessage:i}):null}function Pe({output:e,sendMessage:t}){let n=i.useMemo(()=>{let t=Ae.safeParse(e);return t.success?{ui:r(Object.entries(t.data.ui.elements).map(([e,t])=>({...t,key:e}))),context:t.data.context}:null},[e]),a=i.useCallback((e,n)=>{t({text:`[Form:${e}] ${JSON.stringify(n)}`})},[t]),o=i.useCallback(e=>{t({text:`[Form:${e}] cancelled`})},[t]);return n?h(H,{ui:n.ui,context:n.context,onSubmit:a,onCancel:o}):null}const Fe=E(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90`,destructive:`bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60`,outline:`border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2 has-[>svg]:px-3`,xs:`h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3`,sm:`h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5`,lg:`h-10 rounded-md px-6 has-[>svg]:px-4`,icon:`size-9`,"icon-xs":`size-6 rounded-md [&_svg:not([class*='size-'])]:size-3`,"icon-sm":`size-8`,"icon-lg":`size-10`}},defaultVariants:{variant:`default`,size:`default`}});function Ie({className:t,variant:n=`default`,size:r=`default`,asChild:i=!1,...a}){return h(i?O.Root:`button`,{"data-slot":`button`,"data-variant":n,"data-size":r,className:e(Fe({variant:n,size:r,className:t})),...a})}function Le({children:t,className:n,...r}){let a=i.useRef(null);return i.useEffect(()=>{a.current&&(a.current.scrollTop=a.current.scrollHeight)},[t]),h(`div`,{ref:a,"data-slot":`chat-message-list`,className:e(`flex flex-col overflow-y-auto scroll-smooth`,n),...r,children:t})}function Re({text:t=`AI is thinking...`,className:n,...r}){return g(`div`,{"data-slot":`chat-loading`,className:e(`flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground`,n),...r,children:[h(b,{className:`size-4 animate-spin`}),h(`span`,{children:t})]})}function ze({title:t=`Start a conversation`,description:n=`Ask a question or describe what you need help with.`,className:r,...i}){return h(`div`,{"data-slot":`chat-empty`,className:e(`flex flex-col items-center justify-center gap-2 py-8 text-center`,r),...i,children:g(`div`,{className:`space-y-1`,children:[h(`h3`,{className:`text-sm font-medium`,children:t}),h(`p`,{className:`text-xs text-muted-foreground`,children:n})]})})}function Be({...e}){return h(D.Root,{"data-slot":`dialog`,...e})}function Ve({...e}){return h(D.Trigger,{"data-slot":`dialog-trigger`,...e})}function U({...e}){return h(D.Portal,{"data-slot":`dialog-portal`,...e})}function He({...e}){return h(D.Close,{"data-slot":`dialog-close`,...e})}function Ue({className:t,...n}){return h(D.Overlay,{"data-slot":`dialog-overlay`,className:e(`data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50`,t),...n})}function We({className:t,children:n,showCloseButton:r=!0,...i}){return g(U,{"data-slot":`dialog-portal`,children:[h(Ue,{}),g(D.Content,{"data-slot":`dialog-content`,className:e(`bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg`,t),...i,children:[n,r&&g(D.Close,{"data-slot":`dialog-close`,className:`ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,children:[h(w,{}),h(`span`,{className:`sr-only`,children:`Close`})]})]})]})}function Ge({className:t,...n}){return h(`div`,{"data-slot":`dialog-header`,className:e(`flex flex-col gap-2 text-center sm:text-left`,t),...n})}function Ke({className:t,showCloseButton:n=!1,children:r,...i}){return g(`div`,{"data-slot":`dialog-footer`,className:e(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,t),...i,children:[r,n&&h(D.Close,{asChild:!0,children:h(Ie,{variant:`outline`,children:`Close`})})]})}function qe({className:t,...n}){return h(D.Title,{"data-slot":`dialog-title`,className:e(`text-lg leading-none font-semibold`,t),...n})}function Je({className:t,...n}){return h(D.Description,{"data-slot":`dialog-description`,className:e(`text-muted-foreground text-sm`,t),...n})}function Ye({className:t,...n}){return h(k,{"data-slot":`command`,className:e(`bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md`,t),...n})}function Xe({className:t,children:n,...r}){return h(U,{"data-slot":`dialog-portal`,children:h(D.Content,{"data-slot":`dialog-content`,className:e(`bg-background fixed top-1/3 left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] overflow-hidden rounded-xl border-none p-2 shadow-2xl ring-4 ring-neutral-200/80 duration-200 outline-none sm:max-w-lg dark:bg-neutral-900 dark:ring-neutral-800`,t),...r,children:n})})}function Ze({className:t,...n}){return h(k.Empty,{"data-slot":`command-empty`,className:e(`text-muted-foreground py-6 text-center text-sm`,t),...n})}function W({className:t,...n}){return h(k.Group,{"data-slot":`command-group`,className:e(`text-foreground !p-0 [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden [&_[cmdk-group-heading]]:scroll-mt-16 [&_[cmdk-group-heading]]:pt-0! [&_[cmdk-group-heading]]:!p-3 [&_[cmdk-group-heading]]:!pb-1 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium`,t),...n})}function Qe({className:t,...n}){return h(k.Separator,{"data-slot":`command-separator`,className:e(`bg-border -mx-1 h-px`,t),...n})}function G({className:t,style:n,...r}){return h(k.Item,{"data-slot":`command-item`,className:e(`data-[selected=true]:border-input data-[selected=true]:bg-input/50 [&_svg:not([class*='text-'])]:text-muted-foreground relative flex h-9 cursor-default items-center gap-2 border border-transparent px-3 text-sm font-medium outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,t),style:{borderRadius:`var(--cmdk-radius, 0.375rem)`,...n},...r})}function $e({className:t,...n}){return h(`span`,{"data-slot":`command-shortcut`,className:e(`text-muted-foreground ml-auto text-xs tracking-widest`,t),...n})}function et(){return crypto.randomUUID()}function tt(e){let t=e.find(e=>e.role===`user`);if(!t)return`New conversation`;let n=t.parts?.filter(e=>e.type===`text`).map(e=>e.text).join(` `)||`New conversation`;return n.length>50?n.slice(0,50)+`...`:n}function nt(e){return typeof e!=`object`||!e||!(`version`in e)||e.version!==1||!(`conversations`in e)||!Array.isArray(e.conversations)?null:e}function rt({storageKey:e=`cmdk-chat-history`,maxConversations:t=50,messages:n,setMessages:r}){let[i,a]=f([]),[o,c]=f(null),[p,m]=f(!1),h=d(n);h.current=n;let g=d(r);g.current=r;let _=d(i);_.current=i;let v=d(o);v.current=o,l(()=>{try{let t=localStorage.getItem(e);if(t){let n=nt(JSON.parse(t));n?a(n.conversations):(console.warn(`Chat history: stored data failed validation. Discarding.`),localStorage.removeItem(e))}}catch(e){console.error(`Failed to load chat history:`,e)}finally{m(!0)}},[e]),l(()=>{if(p)try{let t={version:1,conversations:i};localStorage.setItem(e,JSON.stringify(t))}catch(e){console.error(`Failed to save chat history:`,e)}},[i,e,p]);let y=s(()=>{let e=h.current,n=v.current;!n||e.length===0||a(r=>{let i=Date.now();return r.find(e=>e.id===n)?r.map(t=>t.id===n?{...t,messages:e,title:tt(e),updatedAt:i}:t):[{id:n,title:tt(e),messages:e,createdAt:i,updatedAt:i},...r].slice(0,t)})},[t]),b=s(()=>{v.current&&h.current.length>0&&y(),g.current?.([]),c(et())},[y]),x=s(e=>{v.current&&h.current.length>0&&y();let t=_.current.find(t=>t.id===e);t&&(g.current?.(t.messages),c(e))},[y]);return u(()=>({conversations:i,currentConversationId:o,startNewChat:b,loadConversation:x,saveCurrentConversation:y}),[i,o,b,x,y])}let K=null,q=null;function it(){try{return typeof process<`u`&&process.env?.BETTER_CMDK_TELEMETRY_DISABLED===`1`}catch{return!1}}function at(e,t){return delete e.user,delete e.server_name,e.request&&(delete e.request.cookies,delete e.request.headers,delete e.request.env,delete e.request.data),e.breadcrumbs=[],e}function ot(){typeof window>`u`||K===null&&(it()||(K=new j({dsn:`https://7d9fc7e14e8769805297d46569e33c05@o4510706172755968.ingest.us.sentry.io/4510846832017408`,transport:I,stackParser:P,integrations:[N(),F()],beforeSend:at,sendDefaultPii:!1,tracesSampleRate:1}),q=new M,q.setClient(K),K.init()))}function J(e,t){!q||!K||(t?q.captureException(e,{captureContext:e=>(e.setExtras(t),e)}):q.captureException(e))}function st(e){try{let t=new Uint8Array(e/2);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,`0`)).join(``)}catch{let t=``;for(let n=0;n<e;n++)t+=Math.floor(Math.random()*16).toString(16);return t}}function ct(e,t,n){if(!q||!K)return n();let r=Date.now()/1e3,i=st(32),a=st(16),o=`ok`,s=()=>{let n=Date.now()/1e3;q.captureEvent({type:`transaction`,transaction:e,start_timestamp:r,timestamp:n,contexts:{trace:{trace_id:i,span_id:a,op:t,status:o}}})};try{let e=n();return e instanceof Promise?e.then(e=>(s(),e),e=>{throw o=`internal_error`,s(),e}):(s(),e)}catch(e){throw o=`internal_error`,s(),e}}const Y=i.createContext(null),lt=[];function ut({children:e,chatEndpoint:t=null,chat:n,onModeChange:r,onOpenChange:a,historyStorageKey:o,maxConversations:s}){let[c,l]=i.useState(`command`),[u,d]=i.useState(``),[f,p]=i.useState(`idle`),[m,g]=i.useState(null),_=i.useRef(n);_.current=n;let v=!!n;i.useEffect(()=>{ot()},[]);let y=i.useMemo(()=>{if(!(v||!t))return new ne({api:t})},[t,v]),b=te(i.useMemo(()=>y?{transport:y,onError:e=>{J(e,{source:`internalChat.onError`}),p(`error`),g(e)}}:{},[y])),x=n?.status,S=n?.error??null;i.useEffect(()=>{if(v)x===`ready`?p(`idle`):x===`streaming`?p(`streaming`):x===`submitted`?p(`submitted`):x===`error`&&p(`error`),g(S);else{let e=b.status;e===`streaming`?p(`streaming`):e===`submitted`?p(`submitted`):e===`error`?p(`error`):e===`ready`&&p(`idle`)}},[x,S,b.status,v]);let C=i.useCallback(e=>{l(e),r?.(e)},[r]),w=!!(n||t),T=i.useCallback(e=>{w&&ct(`switchToChat`,`ui.action`,()=>{C(`chat`),e&&d(e)})},[w,C]),E=i.useCallback(()=>{C(`command`),d(``),p(`idle`),g(null)},[C]),D=i.useCallback(async e=>{e.trim()&&await ct(`sendMessage`,`function`,async()=>{try{let t=_.current;if(t){d(``),t.sendMessage({text:e.trim()});return}if(!y)return;p(`submitted`),d(``),await b.sendMessage({text:e.trim()})}catch(e){throw J(e,{source:`sendMessage`}),e}})},[b,y]),O=f===`submitted`||f===`streaming`,k=n?n.messages:b.messages??lt,ee=n?.setMessages??b.setMessages,A=n?.addToolApprovalResponse,j=n?.agenticActions,M=rt({storageKey:o,maxConversations:s,messages:k,setMessages:ee}),N=i.useCallback(e=>{M.loadConversation(e),C(`chat`)},[M.loadConversation,C]),P=i.useRef(f);i.useEffect(()=>{let e=P.current;P.current=f,(e===`streaming`||e===`submitted`)&&f===`idle`&&k.length>0&&M.saveCurrentConversation()},[f,k.length,M.saveCurrentConversation]);let F=i.useCallback(()=>{a?.(!1)},[a]),I=i.useMemo(()=>({mode:c,setMode:C,inputValue:u,setInputValue:d,chatEndpoint:t,status:f,error:m,switchToChat:T,switchToCommand:E,messages:k,sendMessage:D,isLoading:O,isEnabled:w,addToolApprovalResponse:A,agenticActions:j,requestClose:F,conversations:M.conversations,currentConversationId:M.currentConversationId,startNewChat:M.startNewChat,loadConversation:N}),[c,C,u,t,f,m,T,E,k,D,O,w,A,j,F,M.conversations,M.currentConversationId,M.startNewChat,N]);return h(Y.Provider,{value:I,children:e})}function X(){let e=i.useContext(Y);if(!e)throw Error(`useCommandMenuContext must be used within a CommandMenuProvider`);return e}var dt=class extends i.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,t){J(e,{componentStack:t.componentStack??void 0})}render(){return this.state.hasError?null:this.props.children}};const ft=e=>{},pt={none:`rounded-none`,sm:`rounded-sm`,md:`rounded-md`,lg:`rounded-lg`,xl:`rounded-xl`},mt={none:`0px`,sm:`0.125rem`,md:`0.375rem`,lg:`0.5rem`,xl:`0.75rem`};function ht(e){let t=Date.now()-e,n=Math.floor(t/6e4);if(n<1)return`just now`;if(n<60)return`${n}m ago`;let r=Math.floor(n/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}function gt({className:t,children:n,corners:r=`xl`,borderColor:i,...a}){return h(U,{"data-slot":`dialog-portal`,children:h(D.Content,{"data-slot":`dialog-content`,className:e(`bg-background fixed top-1/3 left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] overflow-hidden border-none p-2 shadow-2xl ring-4 ring-neutral-200/80 duration-200 outline-none sm:max-w-lg dark:bg-neutral-900 dark:ring-neutral-800`,pt[r],t),style:{"--cmdk-radius":mt[r],...i?{"--tw-ring-color":i}:{}},...a,children:n})})}const _t=g(m,{children:[h(Z,{placeholder:`Search or ask AI...`,showSendButton:!0}),h($,{children:h(Q,{})})]});function vt({title:t=`Command Palette`,description:n=`Search for a command to run...`,children:r,className:i,corners:a=`xl`,borderColor:o,commands:s,commandsPlaceholder:c=`Search or ask AI...`,commandsAskAILabel:l=`Ask AI`,...u}){let{mode:d,status:f,switchToCommand:p,messages:m,isEnabled:_,sendMessage:v,addToolApprovalResponse:y}=X(),b=()=>s&&s.length>0?h(xt,{commands:s,placeholder:c,askAILabel:l}):typeof r==`function`?r({mode:d,messages:m,status:f,isEnabled:_}):r??_t,x=e=>{d===`chat`&&(e.preventDefault(),p())};return h(Be,{...u,children:g(gt,{className:i,corners:a,borderColor:o,onEscapeKeyDown:x,children:[g(Ge,{className:`sr-only`,children:[h(qe,{children:t}),h(Je,{children:n})]}),h(k,{"data-slot":`command`,className:e(`**:data-[slot=command-input-wrapper]:bg-input/50 **:data-[slot=command-input-wrapper]:border-input rounded-none bg-transparent **:data-[slot=command-input]:!h-9 **:data-[slot=command-input]:py-0 **:data-[slot=command-input-wrapper]:mb-0 **:data-[slot=command-input-wrapper]:!h-9 **:data-[slot=command-input-wrapper]:border`,`bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden`),style:{borderRadius:`var(--cmdk-radius, 0.75rem)`},children:b()})]})})}function yt({chatEndpoint:e=null,chat:t,onModeChange:n,onOpenChange:r,historyStorageKey:i,maxConversations:a,commands:o,commandsPlaceholder:s,commandsAskAILabel:c,...l}){return h(ut,{chatEndpoint:e,chat:t,onModeChange:n,onOpenChange:r,historyStorageKey:i,maxConversations:a,children:h(dt,{children:h(vt,{onOpenChange:r,commands:o,commandsPlaceholder:s,commandsAskAILabel:c,...l})})})}function Z({className:t,showSendButton:n=!1,...r}){let{mode:i,inputValue:a,setInputValue:o,sendMessage:s,isLoading:c,switchToChat:l,startNewChat:u}=X(),d=()=>{a.trim()&&i===`chat`&&s(a)},f=e=>{if((e.metaKey||e.ctrlKey)&&e.key===`Enter`){e.preventDefault(),i===`command`&&a.trim()?(u(),l(),s(a)):i===`chat`&&a.trim()&&s(a);return}if(i===`chat`&&e.key===`Enter`&&!e.shiftKey){e.preventDefault(),a.trim()&&s(a);return}};return g(`div`,{"data-slot":`command-input-wrapper`,className:`order-2 flex h-9 items-center gap-2 border-t px-3 mt-2`,style:{borderRadius:`var(--cmdk-radius, 0.75rem)`},children:[i===`command`?h(S,{className:`size-4 shrink-0 opacity-50`}):h(C,{className:`size-4 shrink-0 text-primary`}),h(k.Input,{"data-slot":`command-input`,value:a,onValueChange:o,onKeyDown:f,className:e(`placeholder:text-muted-foreground flex h-10 w-full bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50`,t),...r,placeholder:i===`chat`?`Ask AI...`:r.placeholder}),n&&i===`chat`&&h(`button`,{type:`button`,onClick:d,disabled:!a.trim()||c,className:`flex items-center justify-center size-6 bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,style:{borderRadius:`var(--cmdk-radius, 0.75rem)`},children:h(y,{className:`size-3`})})]})}function Q({label:t=`Ask AI`,className:n,...r}){let{inputValue:i,setInputValue:a,switchToChat:o,sendMessage:s,isEnabled:c,startNewChat:l}=X(),u=A(e=>e.filtered.count),d=()=>{if(c)if(i.trim()){let e=ee(`ask-ai`,i.trim())>0;u===0&&!e?(l(),o(),s(i)):(o(),a(``))}else o()};return c?h(k.Group,{forceMount:!0,children:g(k.Item,{"data-slot":`command-item`,value:`ask-ai`,onSelect:d,className:e(`data-[selected=true]:border-input data-[selected=true]:bg-input/50 relative flex cursor-default items-center gap-3 border border-transparent px-3 py-2 text-sm outline-hidden select-none`,n),style:{borderRadius:`var(--cmdk-radius, 0.75rem)`},...r,children:[h(C,{className:`size-4 shrink-0 text-primary`}),h(`div`,{className:`flex flex-col items-start gap-0.5`,children:h(`span`,{className:`font-medium`,children:t})})]})}):h(k.Empty,{"data-slot":`command-empty`,className:e(`text-muted-foreground py-6 text-center text-sm`,n),children:`No results found.`})}function bt(e){let t=[],n=new Map;for(let r of e){let e=r.group,i=n.get(e);i===void 0?(n.set(e,t.length),t.push({heading:e,items:[r]})):t[i].items.push(r)}let r=t.findIndex(e=>e.heading===void 0);if(r>0){let e=t.splice(r,1)[0];t.unshift(e)}return t}function xt({commands:e,placeholder:t,askAILabel:n}){let r=bt(e);return g(m,{children:[h(Z,{placeholder:t,showSendButton:!0}),g($,{children:[r.map((e,t)=>{let n=e.items.map(e=>{let t=e.label??e.name,n=[...e.keywords??[]];return e.label&&e.label!==e.name&&n.push(e.label),g(G,{value:e.name,keywords:n.length>0?n:void 0,disabled:e.disabled,onSelect:()=>e.onSelect?.(),children:[e.icon,t,e.shortcut&&h($e,{children:e.shortcut})]},e.name)});return e.heading?h(W,{heading:e.heading,children:n},e.heading):h(i.Fragment,{children:n},`__ungrouped_${t}`)}),h(Q,{label:n})]})]})}function $({className:t,children:n,actions:r,actionsHeading:a=`Actions`,...o}){let{mode:s,status:c,messages:l,sendMessage:u,addToolApprovalResponse:d,agenticActions:f,requestClose:p,switchToChat:m,startNewChat:_,conversations:v,loadConversation:y}=X(),b=i.useCallback(e=>u(e.text),[u]),S=d??ft;if(s===`chat`)return h(`div`,{"data-slot":`command-list`,className:e(`order-1 max-h-[300px] min-h-0 flex-1 overflow-hidden`,t),children:l.length===0?h(ze,{}):g(Le,{className:`max-h-[300px]`,children:[h(`div`,{className:`px-3 py-2 space-y-4`,children:h(Me,{messages:l,sendMessage:b,addToolApprovalResponse:S})}),c===`streaming`&&h(Re,{})]})});let C=i.Children.toArray(n),w=[],T=[];C.forEach(e=>{i.isValidElement(e)&&(e.type===Q||e.type.displayName===`CommandEmpty`)?w.push(e):i.isValidElement(e)&&e.type===Ze||T.push(e)});let E=(r??f)?.filter(e=>e.execute),D=e=>{let t=e.label??e.name;_(),m(),u(t)};return g(k.List,{"data-slot":`command-list`,className:e(`order-1 max-h-[300px] min-h-0 flex-1 overflow-x-hidden overflow-y-auto`,t),...o,children:[T,v.length>0&&h(W,{heading:`Recent Chats`,children:v.slice(0,5).map(e=>g(G,{value:`chat-history-${e.title}`,onSelect:()=>y(e.id),children:[h(x,{className:`size-4`}),h(`span`,{className:`truncate`,children:e.title}),h(`span`,{className:`ml-auto text-xs text-muted-foreground`,children:ht(e.updatedAt)})]},e.id))}),E&&E.length>0&&h(W,{heading:a,children:E.map(e=>h(G,{value:e.label??e.name,onSelect:()=>D(e),children:e.label??e.name},e.name))}),w]})}Q.displayName=`CommandEmpty`;export{H as AssistantFormRenderer,Me as AssistantMessages,Ie as Button,ze as ChatEmpty,Re as ChatLoading,Le as ChatMessageList,ve as Collapsible,be as CollapsibleContent,ye as CollapsibleTrigger,Ye as Command,gt as CommandContent,yt as CommandDialog,yt as CommandMenu,Xe as CommandDialogContent,Q as CommandEmpty,W as CommandGroup,Z as CommandInput,G as CommandItem,$ as CommandList,Y as CommandMenuContext,ut as CommandMenuProvider,Qe as CommandSeparator,$e as CommandShortcut,ie as Confirmation,oe as ConfirmationAccepted,z as ConfirmationAction,ce as ConfirmationActions,se as ConfirmationRejected,R as ConfirmationRequest,ae as ConfirmationTitle,Be as Dialog,He as DialogClose,We as DialogContent,Je as DialogDescription,Ke as DialogFooter,Ge as DialogHeader,Ue as DialogOverlay,U as DialogPortal,qe as DialogTitle,Ve as DialogTrigger,he as Message,ge as MessageContent,_e as MessageResponse,Ce as Task,Te as TaskContent,Se as TaskItem,xe as TaskItemFile,we as TaskTrigger,Fe as buttonVariants,e as cn,V as defaultFormRegistry,rt as useChatHistory,X as useCommandMenuContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{clsx as e}from"clsx";import{twMerge as t}from"tailwind-merge";function n(...n){return t(e(n))}export{n as cn};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "better-cmdk",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"types": "./index.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/index.js",
|
|
8
|
+
"./lib/utils": "./dist/lib/utils.js",
|
|
9
|
+
"./package.json": "./package.json"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "bun run --bun tsdown"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@biomejs/biome": "^2.3.14",
|
|
19
|
+
"@types/bun": "latest",
|
|
20
|
+
"tsdown": "^0.20.3"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": "^18 || ^19",
|
|
24
|
+
"react-dom": "^18 || ^19",
|
|
25
|
+
"typescript": "^5"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@ai-sdk/react": "^3.0.0",
|
|
29
|
+
"@json-render/core": "^0.2.0",
|
|
30
|
+
"@json-render/react": "^0.2.0",
|
|
31
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
32
|
+
"ai": "^6.0.0",
|
|
33
|
+
"class-variance-authority": "^0.7.1",
|
|
34
|
+
"clsx": "^2.1.1",
|
|
35
|
+
"cmdk": "^1.1.1",
|
|
36
|
+
"lucide-react": "^0.563.0",
|
|
37
|
+
"radix-ui": "^1.4.3",
|
|
38
|
+
"streamdown": "^2.1.0",
|
|
39
|
+
"tailwind-merge": "^3.4.0",
|
|
40
|
+
"zod": "^3.24.0",
|
|
41
|
+
"@sentry/browser": "^9.0.0"
|
|
42
|
+
}
|
|
43
|
+
}
|