assistant-ui 0.0.120 → 0.0.122
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 +60 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +1 -2
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/cloud.d.ts +25 -0
- package/dist/commands/cloud.d.ts.map +1 -0
- package/dist/commands/cloud.js +194 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +10 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/info.js +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +95 -23
- package/dist/commands/mcp.js.map +1 -1
- package/dist/lib/agent-skill.d.ts +2 -2
- package/dist/lib/agent-skill.d.ts.map +1 -1
- package/dist/lib/agent-skill.js +10 -28
- package/dist/lib/agent-skill.js.map +1 -1
- package/dist/lib/cloud-abort.d.ts +2 -0
- package/dist/lib/cloud-abort.d.ts.map +1 -0
- package/dist/lib/cloud-abort.js +13 -0
- package/dist/lib/cloud-abort.js.map +1 -0
- package/dist/lib/cloud-auth.d.ts +28 -0
- package/dist/lib/cloud-auth.d.ts.map +1 -0
- package/dist/lib/cloud-auth.js +169 -0
- package/dist/lib/cloud-auth.js.map +1 -0
- package/dist/lib/cloud-config.d.ts +21 -0
- package/dist/lib/cloud-config.d.ts.map +1 -0
- package/dist/lib/cloud-config.js +76 -0
- package/dist/lib/cloud-config.js.map +1 -0
- package/dist/lib/cloud-provision.d.ts +20 -0
- package/dist/lib/cloud-provision.d.ts.map +1 -0
- package/dist/lib/cloud-provision.js +55 -0
- package/dist/lib/cloud-provision.js.map +1 -0
- package/dist/lib/cloud-setup-login.d.ts +9 -0
- package/dist/lib/cloud-setup-login.d.ts.map +1 -0
- package/dist/lib/cloud-setup-login.js +137 -0
- package/dist/lib/cloud-setup-login.js.map +1 -0
- package/dist/lib/cloud-url.d.ts +2 -0
- package/dist/lib/cloud-url.d.ts.map +1 -0
- package/dist/lib/cloud-url.js +14 -0
- package/dist/lib/cloud-url.js.map +1 -0
- package/dist/lib/create-project.d.ts +0 -9
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +15 -46
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/transform.d.ts +0 -4
- package/dist/lib/transform.d.ts.map +1 -1
- package/dist/lib/transform.js +8 -17
- package/dist/lib/transform.js.map +1 -1
- package/dist/lib/utils/download.d.ts +5 -0
- package/dist/lib/utils/download.d.ts.map +1 -0
- package/dist/lib/utils/download.js +41 -0
- package/dist/lib/utils/download.js.map +1 -0
- package/dist/lib/utils/file-scanner.d.ts +0 -1
- package/dist/lib/utils/file-scanner.d.ts.map +1 -1
- package/dist/lib/utils/file-scanner.js +1 -16
- package/dist/lib/utils/file-scanner.js.map +1 -1
- package/dist/lib/utils/package-manager.d.ts +7 -0
- package/dist/lib/utils/package-manager.d.ts.map +1 -1
- package/dist/lib/utils/package-manager.js +15 -1
- package/dist/lib/utils/package-manager.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +2 -1
- package/dist/program.js.map +1 -1
- package/package.json +12 -8
- package/src/commands/add.ts +2 -1
- package/src/commands/cloud.test.ts +238 -0
- package/src/commands/cloud.ts +455 -0
- package/src/commands/create.ts +13 -3
- package/src/commands/init.ts +5 -2
- package/src/commands/mcp.ts +223 -56
- package/src/lib/agent-skill.ts +18 -44
- package/src/lib/cloud-abort.ts +12 -0
- package/src/lib/cloud-auth.test.ts +500 -0
- package/src/lib/cloud-auth.ts +273 -0
- package/src/lib/cloud-config.test.ts +82 -0
- package/src/lib/cloud-config.ts +138 -0
- package/src/lib/cloud-provision.test.ts +132 -0
- package/src/lib/cloud-provision.ts +93 -0
- package/src/lib/cloud-setup-login.test.ts +361 -0
- package/src/lib/cloud-setup-login.ts +240 -0
- package/src/lib/cloud-url.ts +19 -0
- package/src/lib/create-project.test.ts +0 -17
- package/src/lib/create-project.ts +33 -98
- package/src/lib/transform-files.test.ts +1 -3
- package/src/lib/transform.ts +6 -20
- package/src/lib/utils/download.ts +57 -0
- package/src/lib/utils/file-scanner.ts +0 -26
- package/src/lib/utils/package-manager.ts +26 -0
- package/src/lib/utils/registry.test.ts +0 -6
- package/src/program.ts +2 -0
- package/templates/cloud-harness/.assistant-ui/template.json +3 -0
- package/templates/cloud-harness/.env.example +1 -0
- package/templates/cloud-harness/.gitignore +42 -0
- package/templates/cloud-harness/README.md +28 -0
- package/templates/cloud-harness/app/api/chat/route.ts +14 -0
- package/templates/cloud-harness/app/api/credential/route.ts +14 -0
- package/templates/cloud-harness/app/assistant.tsx +83 -0
- package/templates/cloud-harness/app/favicon.ico +0 -0
- package/templates/cloud-harness/app/globals.css +139 -0
- package/templates/cloud-harness/app/layout.tsx +37 -0
- package/templates/cloud-harness/app/page.tsx +5 -0
- package/templates/cloud-harness/components/assistant-ui/elements/attachment.aui.tsx +279 -0
- package/templates/cloud-harness/components/assistant-ui/elements/collapsible-root.tsx +19 -0
- package/templates/cloud-harness/components/assistant-ui/elements/markdown-text.tsx +238 -0
- package/templates/cloud-harness/components/assistant-ui/elements/thread.aui.tsx +521 -0
- package/templates/cloud-harness/components/assistant-ui/elements/tool-fallback.aui.tsx +1321 -0
- package/templates/cloud-harness/components/assistant-ui/elements/tooltip-icon-button.tsx +49 -0
- package/templates/cloud-harness/components/ui/avatar.tsx +109 -0
- package/templates/cloud-harness/components/ui/button.tsx +58 -0
- package/templates/cloud-harness/components/ui/collapsible.tsx +21 -0
- package/templates/cloud-harness/components/ui/dialog.tsx +159 -0
- package/templates/cloud-harness/components/ui/textarea.tsx +18 -0
- package/templates/cloud-harness/components/ui/tooltip.tsx +69 -0
- package/templates/cloud-harness/components.json +24 -0
- package/templates/cloud-harness/hooks/use-attachment-src.ts +46 -0
- package/templates/cloud-harness/hooks/use-copy-to-clipboard.ts +54 -0
- package/templates/cloud-harness/lib/utils.ts +1 -0
- package/templates/cloud-harness/next.config.ts +6 -0
- package/templates/cloud-harness/package.json +51 -0
- package/templates/cloud-harness/postcss.config.mjs +5 -0
- package/templates/cloud-harness/tsconfig.json +33 -0
- package/templates/cloud-harness/vendor/README.md +13 -0
- package/templates/cloud-harness/vendor/assistant-ui-react-harness-sdk-0.0.2.tgz +0 -0
- package/templates/cloud-harness/vendor/harness-sdk-0.3.1.tgz +0 -0
- package/templates/cloud-harness/vendor/provenance.json +38 -0
- package/templates/cloud-harness/vendor/statewire-0.19.3.tgz +0 -0
- /package/{LICENSE → templates/cloud-harness/vendor/LICENSE} +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type ComponentPropsWithRef, forwardRef } from "react";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Tooltip,
|
|
7
|
+
TooltipContent,
|
|
8
|
+
TooltipProvider,
|
|
9
|
+
TooltipTrigger,
|
|
10
|
+
} from "@/components/ui/tooltip";
|
|
11
|
+
import { Button } from "@/components/ui/button";
|
|
12
|
+
import { cn } from "@/lib/utils";
|
|
13
|
+
|
|
14
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
15
|
+
tooltip: string;
|
|
16
|
+
side?: "top" | "bottom" | "left" | "right";
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const TooltipIconButton = forwardRef<
|
|
20
|
+
HTMLButtonElement,
|
|
21
|
+
TooltipIconButtonProps
|
|
22
|
+
>(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
|
|
23
|
+
return (
|
|
24
|
+
<TooltipProvider>
|
|
25
|
+
<Tooltip>
|
|
26
|
+
<TooltipTrigger
|
|
27
|
+
render={
|
|
28
|
+
<Button
|
|
29
|
+
variant="ghost"
|
|
30
|
+
size="icon"
|
|
31
|
+
{...rest}
|
|
32
|
+
className={cn(
|
|
33
|
+
"aui-button-icon size-6 p-1 active:scale-90",
|
|
34
|
+
className,
|
|
35
|
+
)}
|
|
36
|
+
ref={ref}
|
|
37
|
+
/>
|
|
38
|
+
}
|
|
39
|
+
>
|
|
40
|
+
{children}
|
|
41
|
+
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
42
|
+
</TooltipTrigger>
|
|
43
|
+
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
44
|
+
</Tooltip>
|
|
45
|
+
</TooltipProvider>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
TooltipIconButton.displayName = "TooltipIconButton";
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
function Avatar({
|
|
9
|
+
className,
|
|
10
|
+
size = "default",
|
|
11
|
+
...props
|
|
12
|
+
}: AvatarPrimitive.Root.Props & {
|
|
13
|
+
size?: "default" | "sm" | "lg";
|
|
14
|
+
}) {
|
|
15
|
+
return (
|
|
16
|
+
<AvatarPrimitive.Root
|
|
17
|
+
data-slot="avatar"
|
|
18
|
+
data-size={size}
|
|
19
|
+
className={cn(
|
|
20
|
+
"group/avatar after:border-border relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {
|
|
29
|
+
return (
|
|
30
|
+
<AvatarPrimitive.Image
|
|
31
|
+
data-slot="avatar-image"
|
|
32
|
+
className={cn(
|
|
33
|
+
"aspect-square size-full rounded-full object-cover",
|
|
34
|
+
className,
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function AvatarFallback({
|
|
42
|
+
className,
|
|
43
|
+
...props
|
|
44
|
+
}: AvatarPrimitive.Fallback.Props) {
|
|
45
|
+
return (
|
|
46
|
+
<AvatarPrimitive.Fallback
|
|
47
|
+
data-slot="avatar-fallback"
|
|
48
|
+
className={cn(
|
|
49
|
+
"bg-muted text-muted-foreground flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs",
|
|
50
|
+
className,
|
|
51
|
+
)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
|
|
58
|
+
return (
|
|
59
|
+
<span
|
|
60
|
+
data-slot="avatar-badge"
|
|
61
|
+
className={cn(
|
|
62
|
+
"bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none",
|
|
63
|
+
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
|
|
64
|
+
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
|
|
65
|
+
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
|
|
66
|
+
className,
|
|
67
|
+
)}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
74
|
+
return (
|
|
75
|
+
<div
|
|
76
|
+
data-slot="avatar-group"
|
|
77
|
+
className={cn(
|
|
78
|
+
"group/avatar-group *:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:ring-2",
|
|
79
|
+
className,
|
|
80
|
+
)}
|
|
81
|
+
{...props}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function AvatarGroupCount({
|
|
87
|
+
className,
|
|
88
|
+
...props
|
|
89
|
+
}: React.ComponentProps<"div">) {
|
|
90
|
+
return (
|
|
91
|
+
<div
|
|
92
|
+
data-slot="avatar-group-count"
|
|
93
|
+
className={cn(
|
|
94
|
+
"bg-muted text-muted-foreground ring-background relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
|
|
95
|
+
className,
|
|
96
|
+
)}
|
|
97
|
+
{...props}
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
Avatar,
|
|
104
|
+
AvatarImage,
|
|
105
|
+
AvatarFallback,
|
|
106
|
+
AvatarGroup,
|
|
107
|
+
AvatarGroupCount,
|
|
108
|
+
AvatarBadge,
|
|
109
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const buttonVariants = cva(
|
|
7
|
+
"group/button focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:ring-1 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:ring-1 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
12
|
+
outline:
|
|
13
|
+
"bg-muted/70 text-foreground hover:bg-muted aria-expanded:bg-muted aria-expanded:text-foreground dark:bg-muted/50 dark:hover:bg-muted border-transparent",
|
|
14
|
+
secondary:
|
|
15
|
+
"bg-secondary text-secondary-foreground aria-expanded:bg-secondary aria-expanded:text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]",
|
|
16
|
+
ghost:
|
|
17
|
+
"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
18
|
+
destructive:
|
|
19
|
+
"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
20
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
default:
|
|
24
|
+
"h-8 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
25
|
+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
26
|
+
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
27
|
+
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
28
|
+
icon: "size-8",
|
|
29
|
+
"icon-xs":
|
|
30
|
+
"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
|
31
|
+
"icon-sm":
|
|
32
|
+
"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
|
33
|
+
"icon-lg": "size-9",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
variant: "default",
|
|
38
|
+
size: "default",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
function Button({
|
|
44
|
+
className,
|
|
45
|
+
variant = "default",
|
|
46
|
+
size = "default",
|
|
47
|
+
...props
|
|
48
|
+
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
|
|
49
|
+
return (
|
|
50
|
+
<ButtonPrimitive
|
|
51
|
+
data-slot="button"
|
|
52
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible";
|
|
4
|
+
|
|
5
|
+
function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {
|
|
6
|
+
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {
|
|
10
|
+
return (
|
|
11
|
+
<CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {
|
|
16
|
+
return (
|
|
17
|
+
<CollapsiblePrimitive.Panel data-slot="collapsible-content" {...props} />
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
|
5
|
+
import { XIcon } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
import { Button } from "@/components/ui/button";
|
|
8
|
+
import { cn } from "@/lib/utils";
|
|
9
|
+
|
|
10
|
+
function Dialog({ ...props }: DialogPrimitive.Root.Props) {
|
|
11
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
|
|
15
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
|
|
19
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
|
|
23
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function DialogOverlay({
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: DialogPrimitive.Backdrop.Props) {
|
|
30
|
+
return (
|
|
31
|
+
<DialogPrimitive.Backdrop
|
|
32
|
+
data-slot="dialog-overlay"
|
|
33
|
+
className={cn(
|
|
34
|
+
"data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function DialogContent({
|
|
43
|
+
className,
|
|
44
|
+
children,
|
|
45
|
+
showCloseButton = true,
|
|
46
|
+
...props
|
|
47
|
+
}: DialogPrimitive.Popup.Props & {
|
|
48
|
+
showCloseButton?: boolean;
|
|
49
|
+
}) {
|
|
50
|
+
return (
|
|
51
|
+
<DialogPortal>
|
|
52
|
+
<DialogOverlay />
|
|
53
|
+
<DialogPrimitive.Popup
|
|
54
|
+
data-slot="dialog-content"
|
|
55
|
+
className={cn(
|
|
56
|
+
"bg-popover text-popover-foreground ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl p-5 text-sm ring-1 duration-100 outline-none sm:max-w-sm",
|
|
57
|
+
className,
|
|
58
|
+
)}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
{showCloseButton && (
|
|
63
|
+
<DialogPrimitive.Close
|
|
64
|
+
data-slot="dialog-close"
|
|
65
|
+
render={
|
|
66
|
+
<Button
|
|
67
|
+
variant="ghost"
|
|
68
|
+
className="absolute top-2 right-2"
|
|
69
|
+
size="icon-sm"
|
|
70
|
+
/>
|
|
71
|
+
}
|
|
72
|
+
>
|
|
73
|
+
<XIcon />
|
|
74
|
+
<span className="sr-only">Close</span>
|
|
75
|
+
</DialogPrimitive.Close>
|
|
76
|
+
)}
|
|
77
|
+
</DialogPrimitive.Popup>
|
|
78
|
+
</DialogPortal>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
83
|
+
return (
|
|
84
|
+
<div
|
|
85
|
+
data-slot="dialog-header"
|
|
86
|
+
className={cn("flex flex-col gap-2", className)}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function DialogFooter({
|
|
93
|
+
className,
|
|
94
|
+
showCloseButton = false,
|
|
95
|
+
children,
|
|
96
|
+
...props
|
|
97
|
+
}: React.ComponentProps<"div"> & {
|
|
98
|
+
showCloseButton?: boolean;
|
|
99
|
+
}) {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
data-slot="dialog-footer"
|
|
103
|
+
className={cn(
|
|
104
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
105
|
+
className,
|
|
106
|
+
)}
|
|
107
|
+
{...props}
|
|
108
|
+
>
|
|
109
|
+
{children}
|
|
110
|
+
{showCloseButton && (
|
|
111
|
+
<DialogPrimitive.Close render={<Button variant="outline" />}>
|
|
112
|
+
Close
|
|
113
|
+
</DialogPrimitive.Close>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
120
|
+
return (
|
|
121
|
+
<DialogPrimitive.Title
|
|
122
|
+
data-slot="dialog-title"
|
|
123
|
+
className={cn(
|
|
124
|
+
"cn-font-heading text-base leading-none font-medium",
|
|
125
|
+
className,
|
|
126
|
+
)}
|
|
127
|
+
{...props}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function DialogDescription({
|
|
133
|
+
className,
|
|
134
|
+
...props
|
|
135
|
+
}: DialogPrimitive.Description.Props) {
|
|
136
|
+
return (
|
|
137
|
+
<DialogPrimitive.Description
|
|
138
|
+
data-slot="dialog-description"
|
|
139
|
+
className={cn(
|
|
140
|
+
"text-muted-foreground *:[a]:hover:text-foreground text-sm *:[a]:underline *:[a]:underline-offset-3",
|
|
141
|
+
className,
|
|
142
|
+
)}
|
|
143
|
+
{...props}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export {
|
|
149
|
+
Dialog,
|
|
150
|
+
DialogClose,
|
|
151
|
+
DialogContent,
|
|
152
|
+
DialogDescription,
|
|
153
|
+
DialogFooter,
|
|
154
|
+
DialogHeader,
|
|
155
|
+
DialogOverlay,
|
|
156
|
+
DialogPortal,
|
|
157
|
+
DialogTitle,
|
|
158
|
+
DialogTrigger,
|
|
159
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
6
|
+
return (
|
|
7
|
+
<textarea
|
|
8
|
+
data-slot="textarea"
|
|
9
|
+
className={cn(
|
|
10
|
+
"placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 disabled:bg-input/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 bg-muted/60 focus-visible:bg-background field-sizing-content min-h-16 w-full min-w-0 rounded-lg border border-transparent px-3 py-2 text-base transition-colors outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-1 md:text-sm",
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { Textarea };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
function TooltipProvider({
|
|
8
|
+
delay = 0,
|
|
9
|
+
...props
|
|
10
|
+
}: TooltipPrimitive.Provider.Props) {
|
|
11
|
+
return (
|
|
12
|
+
<TooltipPrimitive.Provider
|
|
13
|
+
data-slot="tooltip-provider"
|
|
14
|
+
delay={delay}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
|
|
21
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
|
|
25
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function TooltipContent({
|
|
29
|
+
className,
|
|
30
|
+
side = "top",
|
|
31
|
+
sideOffset = 4,
|
|
32
|
+
align = "center",
|
|
33
|
+
alignOffset = 0,
|
|
34
|
+
children,
|
|
35
|
+
...props
|
|
36
|
+
}: TooltipPrimitive.Popup.Props &
|
|
37
|
+
Pick<
|
|
38
|
+
TooltipPrimitive.Positioner.Props,
|
|
39
|
+
"align" | "alignOffset" | "side" | "sideOffset"
|
|
40
|
+
>) {
|
|
41
|
+
return (
|
|
42
|
+
<TooltipPrimitive.Portal>
|
|
43
|
+
<TooltipPrimitive.Positioner
|
|
44
|
+
align={align}
|
|
45
|
+
alignOffset={alignOffset}
|
|
46
|
+
side={side}
|
|
47
|
+
sideOffset={sideOffset}
|
|
48
|
+
className="isolate z-50"
|
|
49
|
+
>
|
|
50
|
+
<TooltipPrimitive.Popup
|
|
51
|
+
data-slot="tooltip-content"
|
|
52
|
+
className={cn(
|
|
53
|
+
"bg-foreground text-background data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-[var(--radius-surface,var(--radius-lg))] px-3 py-1.5 text-xs has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm",
|
|
54
|
+
className,
|
|
55
|
+
)}
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
<TooltipPrimitive.Arrow
|
|
60
|
+
data-slot="tooltip-arrow"
|
|
61
|
+
className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5"
|
|
62
|
+
/>
|
|
63
|
+
</TooltipPrimitive.Popup>
|
|
64
|
+
</TooltipPrimitive.Positioner>
|
|
65
|
+
</TooltipPrimitive.Portal>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "base-nova",
|
|
4
|
+
"registries": {
|
|
5
|
+
"@assistant-ui": "https://r.assistant-ui.com/styles/{style}/{name}.json"
|
|
6
|
+
},
|
|
7
|
+
"rsc": true,
|
|
8
|
+
"tsx": true,
|
|
9
|
+
"tailwind": {
|
|
10
|
+
"config": "",
|
|
11
|
+
"css": "app/globals.css",
|
|
12
|
+
"baseColor": "zinc",
|
|
13
|
+
"cssVariables": true,
|
|
14
|
+
"prefix": ""
|
|
15
|
+
},
|
|
16
|
+
"aliases": {
|
|
17
|
+
"components": "@/components",
|
|
18
|
+
"utils": "@/lib/utils",
|
|
19
|
+
"ui": "@/components/ui",
|
|
20
|
+
"lib": "@/lib",
|
|
21
|
+
"hooks": "@/hooks"
|
|
22
|
+
},
|
|
23
|
+
"iconLibrary": "lucide"
|
|
24
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { useAuiState } from "@assistant-ui/react";
|
|
5
|
+
import { useShallow } from "zustand/react/shallow";
|
|
6
|
+
|
|
7
|
+
const useFileSrc = (file: File | undefined) => {
|
|
8
|
+
const [entry, setEntry] = useState<{ file: File; url: string } | undefined>(
|
|
9
|
+
undefined,
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
// The object URL is a browser resource whose lifetime has to straddle
|
|
14
|
+
// commit, so allocation, revocation, and clearing the entry that names a
|
|
15
|
+
// revoked URL all belong to the effect.
|
|
16
|
+
if (!file) {
|
|
17
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
18
|
+
setEntry(undefined);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const objectUrl = URL.createObjectURL(file);
|
|
23
|
+
setEntry({ file, url: objectUrl });
|
|
24
|
+
|
|
25
|
+
return () => {
|
|
26
|
+
URL.revokeObjectURL(objectUrl);
|
|
27
|
+
};
|
|
28
|
+
}, [file]);
|
|
29
|
+
|
|
30
|
+
return entry !== undefined && entry.file === file ? entry.url : undefined;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const useAttachmentSrc = () => {
|
|
34
|
+
const { file, src } = useAuiState(
|
|
35
|
+
useShallow((s): { file?: File; src?: string } => {
|
|
36
|
+
if (s.attachment.type !== "image") return {};
|
|
37
|
+
if (s.attachment.file) return { file: s.attachment.file };
|
|
38
|
+
const src = s.attachment.content?.filter((c) => c.type === "image")[0]
|
|
39
|
+
?.image;
|
|
40
|
+
if (!src) return {};
|
|
41
|
+
return { src };
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return useFileSrc(file) ?? src;
|
|
46
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export type UseCopyToClipboardOptions = {
|
|
6
|
+
copiedDuration?: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const useCopyToClipboard = ({
|
|
10
|
+
copiedDuration = 3000,
|
|
11
|
+
}: UseCopyToClipboardOptions = {}) => {
|
|
12
|
+
const [isCopied, setIsCopied] = useState<boolean>(false);
|
|
13
|
+
const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(
|
|
14
|
+
undefined,
|
|
15
|
+
);
|
|
16
|
+
const scopeGenerationRef = useRef(0);
|
|
17
|
+
|
|
18
|
+
useEffect(
|
|
19
|
+
() => () => {
|
|
20
|
+
scopeGenerationRef.current += 1;
|
|
21
|
+
if (copiedTimerRef.current === undefined) return;
|
|
22
|
+
|
|
23
|
+
clearTimeout(copiedTimerRef.current);
|
|
24
|
+
copiedTimerRef.current = undefined;
|
|
25
|
+
setIsCopied(false);
|
|
26
|
+
},
|
|
27
|
+
[],
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const copyToClipboard = (value: string) => {
|
|
31
|
+
if (!value || typeof navigator === "undefined" || !navigator.clipboard) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const scopeGeneration = scopeGenerationRef.current;
|
|
36
|
+
navigator.clipboard.writeText(value).then(
|
|
37
|
+
() => {
|
|
38
|
+
if (scopeGeneration !== scopeGenerationRef.current) return;
|
|
39
|
+
|
|
40
|
+
if (copiedTimerRef.current !== undefined) {
|
|
41
|
+
clearTimeout(copiedTimerRef.current);
|
|
42
|
+
}
|
|
43
|
+
setIsCopied(true);
|
|
44
|
+
copiedTimerRef.current = setTimeout(() => {
|
|
45
|
+
copiedTimerRef.current = undefined;
|
|
46
|
+
setIsCopied(false);
|
|
47
|
+
}, copiedDuration);
|
|
48
|
+
},
|
|
49
|
+
() => {},
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return { isCopied, copyToClipboard };
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { cn } from "cn";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "assistant-ui-starter-cloud-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev --turbopack",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start",
|
|
9
|
+
"format": "oxfmt --check",
|
|
10
|
+
"format:fix": "oxfmt",
|
|
11
|
+
"lint": "oxlint && oxfmt --check",
|
|
12
|
+
"lint:fix": "oxlint --fix && oxfmt",
|
|
13
|
+
"typecheck": "tsc --noEmit"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@ai-sdk/openai": "^4.0.86",
|
|
17
|
+
"@assistant-ui/ai-sdk": "workspace:*",
|
|
18
|
+
"@assistant-ui/core": "workspace:*",
|
|
19
|
+
"@assistant-ui/react": "workspace:*",
|
|
20
|
+
"@assistant-ui/react-harness-sdk": "file:vendor/assistant-ui-react-harness-sdk-0.0.2.tgz",
|
|
21
|
+
"@assistant-ui/react-markdown": "workspace:*",
|
|
22
|
+
"@assistant-ui/store": "workspace:*",
|
|
23
|
+
"@assistant-ui/tap": "workspace:*",
|
|
24
|
+
"@base-ui/react": "^1.8.0",
|
|
25
|
+
"ai": "^7.0.130",
|
|
26
|
+
"assistant-cloud": "workspace:*",
|
|
27
|
+
"class-variance-authority": "^0.7.1",
|
|
28
|
+
"cn": "^0.4.0",
|
|
29
|
+
"harness-sdk": "file:vendor/harness-sdk-0.3.1.tgz",
|
|
30
|
+
"lucide-react": "^1.52.0",
|
|
31
|
+
"next": "^16.4.0",
|
|
32
|
+
"react": "^19.3.0",
|
|
33
|
+
"react-dom": "^19.3.0",
|
|
34
|
+
"remark-gfm": "^4.0.1",
|
|
35
|
+
"statewire": "file:vendor/statewire-0.19.3.tgz",
|
|
36
|
+
"tw-animate-css": "^1.4.0",
|
|
37
|
+
"tw-shimmer": "^0.4.13",
|
|
38
|
+
"zustand": "^5.0.15"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@assistant-ui/next": "workspace:*",
|
|
42
|
+
"@tailwindcss/postcss": "^4.3.3",
|
|
43
|
+
"@types/node": "^26.6.4",
|
|
44
|
+
"@types/react": "^19.3.0",
|
|
45
|
+
"@types/react-dom": "^19.3.0",
|
|
46
|
+
"oxfmt": "^0.72.0",
|
|
47
|
+
"oxlint": "^1.87.0",
|
|
48
|
+
"tailwindcss": "^4.3.3",
|
|
49
|
+
"typescript": "^7.0.2"
|
|
50
|
+
}
|
|
51
|
+
}
|