create-agents24-app 0.1.0 → 0.1.2
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 +40 -2
- package/dist/{chunk-OCIF3LSI.js → chunk-PXJTBSPX.js} +99 -23
- package/dist/chunk-PXJTBSPX.js.map +1 -0
- package/dist/cli.js +39 -61
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -7
- package/dist/index.js +9 -1
- package/dist/scaffold/components.json +25 -0
- package/dist/scaffold/manifest.json +28 -0
- package/dist/scaffold/src/app.tsx +71 -0
- package/dist/scaffold/src/chat.css +54 -0
- package/dist/scaffold/src/components/chat/chat-composer.tsx +237 -0
- package/dist/scaffold/src/components/chat/chat-message.tsx +76 -0
- package/dist/scaffold/src/components/chat/chat-shell.tsx +257 -0
- package/dist/scaffold/src/components/chat/collapsible-user-message.tsx +37 -0
- package/dist/scaffold/src/components/chat/external-link-dialog.tsx +48 -0
- package/dist/scaffold/src/components/chat/identity-control.tsx +69 -0
- package/dist/scaffold/src/components/chat/message-parts.tsx +83 -0
- package/dist/scaffold/src/components/chat/theme-menu.tsx +79 -0
- package/dist/scaffold/src/components/chat/thread-sidebar.tsx +114 -0
- package/dist/scaffold/src/components/chat/timeline-loading.ts +17 -0
- package/dist/scaffold/src/components/chat/turn-outline.tsx +73 -0
- package/dist/scaffold/src/components/theme-provider.tsx +91 -0
- package/dist/scaffold/src/components/ui/attachment.tsx +204 -0
- package/dist/scaffold/src/components/ui/bubble.tsx +125 -0
- package/dist/scaffold/src/components/ui/button-group.tsx +83 -0
- package/dist/scaffold/src/components/ui/button.tsx +65 -0
- package/dist/scaffold/src/components/ui/dialog.tsx +171 -0
- package/dist/scaffold/src/components/ui/dropdown-menu.tsx +271 -0
- package/dist/scaffold/src/components/ui/input.tsx +19 -0
- package/dist/scaffold/src/components/ui/marker.tsx +69 -0
- package/dist/scaffold/src/components/ui/message-scroller.tsx +129 -0
- package/dist/scaffold/src/components/ui/message.tsx +92 -0
- package/dist/scaffold/src/components/ui/popover.tsx +40 -0
- package/dist/scaffold/src/components/ui/select.tsx +92 -0
- package/dist/scaffold/src/components/ui/separator.tsx +28 -0
- package/dist/scaffold/src/components/ui/sheet.tsx +150 -0
- package/dist/scaffold/src/components/ui/sidebar.tsx +677 -0
- package/dist/scaffold/src/components/ui/skeleton.tsx +13 -0
- package/dist/scaffold/src/components/ui/textarea.tsx +18 -0
- package/dist/scaffold/src/components/ui/tooltip.tsx +56 -0
- package/dist/scaffold/src/hooks/use-mobile.ts +24 -0
- package/dist/scaffold/src/identity.ts +17 -0
- package/dist/scaffold/src/index.css +221 -0
- package/dist/scaffold/src/index.tsx +39 -0
- package/dist/scaffold/src/lib/utils.ts +6 -0
- package/dist/scaffold/styles.css +3 -0
- package/dist/scaffold-manifest.json +66 -0
- package/package.json +7 -3
- package/templates/common/README.md +16 -3
- package/templates/common/index.html +3 -3
- package/templates/common/scripts/apply-preset.mjs +17 -0
- package/templates/common/scripts/scope-preset-theme.mjs +38 -0
- package/templates/common/src/styles.css +10 -6
- package/templates/common/src/use-thread-query-navigation.ts +41 -0
- package/templates/common/tsconfig.json +2 -1
- package/templates/integrations/bff/server/env.ts +3 -3
- package/templates/integrations/bff/server/index.ts +1 -2
- package/templates/integrations/bff/server/principal.ts +3 -3
- package/templates/integrations/bff/src/host-identity.ts +6 -0
- package/templates/integrations/bff/src/main.tsx +21 -16
- package/templates/integrations/bff/tsconfig.json +2 -1
- package/templates/integrations/bff/vite.config.ts +5 -1
- package/templates/integrations/client-deployment/src/main.tsx +26 -18
- package/templates/integrations/client-deployment/vite.config.ts +37 -4
- package/templates/starters/rag/agents24/agents/assistant.md +11 -0
- package/templates/starters/rag/agents24/agents24.yaml +19 -0
- package/templates/starters/rag/agents24/rag/knowledge.yaml +32 -0
- package/templates/starters/rag/agents24/stores/knowledge.yaml +10 -0
- package/templates/starters/rag/agents24/workflows/main.yaml +16 -0
- package/versions.json +4 -4
- package/dist/chunk-OCIF3LSI.js.map +0 -1
- package/templates/themes/essential/src/theme.css +0 -2
- package/templates/themes/flow/src/theme.css +0 -60
- package/templates/themes/workbench/src/theme.css +0 -51
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Slot } from "radix-ui"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils"
|
|
5
|
+
|
|
6
|
+
function TooltipProvider({ children }: { children: React.ReactNode }) {
|
|
7
|
+
return children
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function Tooltip({ className, ...props }: React.ComponentProps<"span">) {
|
|
11
|
+
return (
|
|
12
|
+
<span
|
|
13
|
+
data-slot="tooltip"
|
|
14
|
+
className={cn("group/tooltip relative inline-flex", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function TooltipTrigger({
|
|
21
|
+
asChild: _asChild,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof Slot.Root> & { asChild?: boolean }) {
|
|
24
|
+
return <Slot.Root data-slot="tooltip-trigger" {...props} />
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function TooltipContent({
|
|
28
|
+
className,
|
|
29
|
+
align: _align,
|
|
30
|
+
side = "top",
|
|
31
|
+
sideOffset: _sideOffset,
|
|
32
|
+
...props
|
|
33
|
+
}: React.ComponentProps<"span"> & {
|
|
34
|
+
side?: "top" | "right" | "bottom" | "left"
|
|
35
|
+
sideOffset?: number
|
|
36
|
+
align?: "start" | "center" | "end"
|
|
37
|
+
}) {
|
|
38
|
+
return (
|
|
39
|
+
<span
|
|
40
|
+
role="tooltip"
|
|
41
|
+
data-side={side}
|
|
42
|
+
data-slot="tooltip-content"
|
|
43
|
+
className={cn(
|
|
44
|
+
"pointer-events-none absolute z-50 hidden w-max max-w-xs items-center gap-1.5 rounded-xl bg-foreground px-3 py-1.5 text-xs text-background group-hover/tooltip:inline-flex group-focus-within/tooltip:inline-flex",
|
|
45
|
+
"data-[side=top]:bottom-full data-[side=top]:left-1/2 data-[side=top]:mb-2 data-[side=top]:-translate-x-1/2",
|
|
46
|
+
"data-[side=bottom]:top-full data-[side=bottom]:left-1/2 data-[side=bottom]:mt-2 data-[side=bottom]:-translate-x-1/2",
|
|
47
|
+
"data-[side=left]:end-full data-[side=left]:top-1/2 data-[side=left]:me-2 data-[side=left]:-translate-y-1/2",
|
|
48
|
+
"data-[side=right]:start-full data-[side=right]:top-1/2 data-[side=right]:ms-2 data-[side=right]:-translate-y-1/2",
|
|
49
|
+
className
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
const MOBILE_BREAKPOINT = 768
|
|
4
|
+
|
|
5
|
+
export function useIsMobile() {
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
|
7
|
+
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
const onChange = () => {
|
|
10
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
11
|
+
}
|
|
12
|
+
if (typeof window.matchMedia !== "function") {
|
|
13
|
+
onChange()
|
|
14
|
+
window.addEventListener("resize", onChange)
|
|
15
|
+
return () => window.removeEventListener("resize", onChange)
|
|
16
|
+
}
|
|
17
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
|
18
|
+
mql.addEventListener("change", onChange)
|
|
19
|
+
onChange()
|
|
20
|
+
return () => mql.removeEventListener("change", onChange)
|
|
21
|
+
}, [])
|
|
22
|
+
|
|
23
|
+
return !!isMobile
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type Agents24ChatIdentityState =
|
|
2
|
+
| "loading"
|
|
3
|
+
| "guest"
|
|
4
|
+
| "authenticated"
|
|
5
|
+
| "signed_out"
|
|
6
|
+
| "error"
|
|
7
|
+
|
|
8
|
+
export type Agents24ChatIdentity = {
|
|
9
|
+
state: Agents24ChatIdentityState
|
|
10
|
+
displayName?: string
|
|
11
|
+
secondaryText?: string
|
|
12
|
+
avatarUrl?: string
|
|
13
|
+
onSignIn?: () => void | Promise<void>
|
|
14
|
+
onSignOut?: () => void | Promise<void>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const GUEST_CHAT_IDENTITY: Agents24ChatIdentity = { state: "guest" }
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
3
|
+
@import "@fontsource-variable/jetbrains-mono";
|
|
4
|
+
@import "@fontsource-variable/merriweather";
|
|
5
|
+
@import "@fontsource-variable/inter";
|
|
6
|
+
|
|
7
|
+
@source "./**/*.{ts,tsx}";
|
|
8
|
+
|
|
9
|
+
@custom-variant dark (&:is(.dark *));
|
|
10
|
+
|
|
11
|
+
@theme inline {
|
|
12
|
+
--font-heading: var(--a24-font-heading);
|
|
13
|
+
--font-sans: var(--a24-font-sans);
|
|
14
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
15
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
16
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
17
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
18
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
19
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
20
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
21
|
+
--color-sidebar: var(--sidebar);
|
|
22
|
+
--color-ring: var(--ring);
|
|
23
|
+
--color-input: var(--input);
|
|
24
|
+
--color-border: var(--border);
|
|
25
|
+
--color-destructive: var(--destructive);
|
|
26
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
27
|
+
--color-accent: var(--accent);
|
|
28
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
29
|
+
--color-muted: var(--muted);
|
|
30
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
31
|
+
--color-secondary: var(--secondary);
|
|
32
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
33
|
+
--color-primary: var(--primary);
|
|
34
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
35
|
+
--color-popover: var(--popover);
|
|
36
|
+
--color-card-foreground: var(--card-foreground);
|
|
37
|
+
--color-card: var(--card);
|
|
38
|
+
--color-foreground: var(--foreground);
|
|
39
|
+
--color-background: var(--background);
|
|
40
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
41
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
42
|
+
--radius-lg: var(--radius);
|
|
43
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
44
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
45
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
46
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
47
|
+
--a24-composer-single-row-radius: 9999px;
|
|
48
|
+
--color-chart-5: var(--chart-5);
|
|
49
|
+
--color-chart-4: var(--chart-4);
|
|
50
|
+
--color-chart-3: var(--chart-3);
|
|
51
|
+
--color-chart-2: var(--chart-2);
|
|
52
|
+
--color-chart-1: var(--chart-1);
|
|
53
|
+
--font-serif: var(--a24-font-heading);
|
|
54
|
+
--font-mono: var(--a24-font-mono);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
[data-agents24-theme-root] {
|
|
58
|
+
color-scheme: light;
|
|
59
|
+
--a24-font-heading: 'Inter Variable', sans-serif;
|
|
60
|
+
--a24-font-sans: 'Inter Variable', sans-serif;
|
|
61
|
+
--a24-font-mono: 'JetBrains Mono Variable', monospace;
|
|
62
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
63
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
64
|
+
--radius-lg: var(--radius);
|
|
65
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
66
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
67
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
68
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
69
|
+
--background: oklch(1 0 0);
|
|
70
|
+
--foreground: oklch(0.147 0.004 49.25);
|
|
71
|
+
--card: oklch(1 0 0);
|
|
72
|
+
--card-foreground: oklch(0.147 0.004 49.25);
|
|
73
|
+
--popover: oklch(1 0 0);
|
|
74
|
+
--popover-foreground: oklch(0.147 0.004 49.25);
|
|
75
|
+
--primary: oklch(0.52 0.105 223.128);
|
|
76
|
+
--primary-foreground: oklch(0.984 0.019 200.873);
|
|
77
|
+
--secondary: oklch(0.967 0.001 286.375);
|
|
78
|
+
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
79
|
+
--muted: oklch(0.97 0.001 106.424);
|
|
80
|
+
--muted-foreground: oklch(0.553 0.013 58.071);
|
|
81
|
+
--accent: oklch(0.97 0.001 106.424);
|
|
82
|
+
--accent-foreground: oklch(0.216 0.006 56.043);
|
|
83
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
84
|
+
--border: oklch(0.923 0.003 48.717);
|
|
85
|
+
--input: oklch(0.923 0.003 48.717);
|
|
86
|
+
--ring: oklch(0.709 0.01 56.259);
|
|
87
|
+
--radius: 0.875rem;
|
|
88
|
+
--sidebar: oklch(0.985 0.001 106.423);
|
|
89
|
+
--sidebar-foreground: oklch(0.147 0.004 49.25);
|
|
90
|
+
--sidebar-primary: oklch(0.609 0.126 221.723);
|
|
91
|
+
--sidebar-primary-foreground: oklch(0.984 0.019 200.873);
|
|
92
|
+
--sidebar-accent: oklch(0.97 0.001 106.424);
|
|
93
|
+
--sidebar-accent-foreground: oklch(0.216 0.006 56.043);
|
|
94
|
+
--sidebar-border: oklch(0.923 0.003 48.717);
|
|
95
|
+
--sidebar-ring: oklch(0.709 0.01 56.259);
|
|
96
|
+
--chart-1: oklch(0.845 0.143 164.978);
|
|
97
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
98
|
+
--chart-3: oklch(0.596 0.145 163.225);
|
|
99
|
+
--chart-4: oklch(0.508 0.118 165.612);
|
|
100
|
+
--chart-5: oklch(0.432 0.095 166.913);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
[data-agents24-theme-root].dark {
|
|
104
|
+
color-scheme: dark;
|
|
105
|
+
--background: oklch(0.147 0.004 49.25);
|
|
106
|
+
--foreground: oklch(0.985 0.001 106.423);
|
|
107
|
+
--card: oklch(0.216 0.006 56.043);
|
|
108
|
+
--card-foreground: oklch(0.985 0.001 106.423);
|
|
109
|
+
--popover: oklch(0.216 0.006 56.043);
|
|
110
|
+
--popover-foreground: oklch(0.985 0.001 106.423);
|
|
111
|
+
--primary: oklch(0.45 0.085 224.283);
|
|
112
|
+
--primary-foreground: oklch(0.984 0.019 200.873);
|
|
113
|
+
--secondary: oklch(0.274 0.006 286.033);
|
|
114
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
115
|
+
--muted: oklch(0.268 0.007 34.298);
|
|
116
|
+
--muted-foreground: oklch(0.709 0.01 56.259);
|
|
117
|
+
--accent: oklch(0.268 0.007 34.298);
|
|
118
|
+
--accent-foreground: oklch(0.985 0.001 106.423);
|
|
119
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
120
|
+
--border: oklch(1 0 0 / 10%);
|
|
121
|
+
--input: oklch(1 0 0 / 15%);
|
|
122
|
+
--ring: oklch(0.553 0.013 58.071);
|
|
123
|
+
--sidebar: oklch(0.216 0.006 56.043);
|
|
124
|
+
--sidebar-foreground: oklch(0.985 0.001 106.423);
|
|
125
|
+
--sidebar-primary: oklch(0.715 0.143 215.221);
|
|
126
|
+
--sidebar-primary-foreground: oklch(0.302 0.056 229.695);
|
|
127
|
+
--sidebar-accent: oklch(0.268 0.007 34.298);
|
|
128
|
+
--sidebar-accent-foreground: oklch(0.985 0.001 106.423);
|
|
129
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
130
|
+
--sidebar-ring: oklch(0.553 0.013 58.071);
|
|
131
|
+
--chart-1: oklch(0.845 0.143 164.978);
|
|
132
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
133
|
+
--chart-3: oklch(0.596 0.145 163.225);
|
|
134
|
+
--chart-4: oklch(0.508 0.118 165.612);
|
|
135
|
+
--chart-5: oklch(0.432 0.095 166.913);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
[data-agents24-theme-root][data-agents24-theme="sharp"] {
|
|
139
|
+
--a24-composer-single-row-radius: 0;
|
|
140
|
+
--a24-font-heading: 'Merriweather Variable', serif;
|
|
141
|
+
--a24-font-sans: 'JetBrains Mono Variable', monospace;
|
|
142
|
+
--a24-font-mono: 'JetBrains Mono Variable', monospace;
|
|
143
|
+
--background: oklch(1 0 0);
|
|
144
|
+
--foreground: oklch(0.141 0.005 285.823);
|
|
145
|
+
--card: oklch(1 0 0);
|
|
146
|
+
--card-foreground: oklch(0.141 0.005 285.823);
|
|
147
|
+
--popover: oklch(1 0 0);
|
|
148
|
+
--popover-foreground: oklch(0.141 0.005 285.823);
|
|
149
|
+
--primary: oklch(0.21 0.006 285.885);
|
|
150
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
151
|
+
--secondary: oklch(0.967 0.001 286.375);
|
|
152
|
+
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
153
|
+
--muted: oklch(0.967 0.001 286.375);
|
|
154
|
+
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
155
|
+
--accent: oklch(0.967 0.001 286.375);
|
|
156
|
+
--accent-foreground: oklch(0.21 0.006 285.885);
|
|
157
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
158
|
+
--border: oklch(0.92 0.004 286.32);
|
|
159
|
+
--input: oklch(0.92 0.004 286.32);
|
|
160
|
+
--ring: oklch(0.705 0.015 286.067);
|
|
161
|
+
--radius: 0;
|
|
162
|
+
--sidebar: oklch(0.985 0 0);
|
|
163
|
+
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
|
164
|
+
--sidebar-primary: oklch(0.21 0.006 285.885);
|
|
165
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
166
|
+
--sidebar-accent: oklch(0.967 0.001 286.375);
|
|
167
|
+
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
|
168
|
+
--sidebar-border: oklch(0.92 0.004 286.32);
|
|
169
|
+
--sidebar-ring: oklch(0.705 0.015 286.067);
|
|
170
|
+
--chart-1: oklch(0.865 0.127 207.078);
|
|
171
|
+
--chart-2: oklch(0.715 0.143 215.221);
|
|
172
|
+
--chart-3: oklch(0.609 0.126 221.723);
|
|
173
|
+
--chart-4: oklch(0.52 0.105 223.128);
|
|
174
|
+
--chart-5: oklch(0.45 0.085 224.283);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
[data-agents24-theme-root][data-agents24-theme="sharp"].dark {
|
|
178
|
+
--background: oklch(0.141 0.005 285.823);
|
|
179
|
+
--foreground: oklch(0.985 0 0);
|
|
180
|
+
--card: oklch(0.21 0.006 285.885);
|
|
181
|
+
--card-foreground: oklch(0.985 0 0);
|
|
182
|
+
--popover: oklch(0.21 0.006 285.885);
|
|
183
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
184
|
+
--primary: oklch(0.92 0.004 286.32);
|
|
185
|
+
--primary-foreground: oklch(0.21 0.006 285.885);
|
|
186
|
+
--secondary: oklch(0.274 0.006 286.033);
|
|
187
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
188
|
+
--muted: oklch(0.274 0.006 286.033);
|
|
189
|
+
--muted-foreground: oklch(0.705 0.015 286.067);
|
|
190
|
+
--accent: oklch(0.274 0.006 286.033);
|
|
191
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
192
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
193
|
+
--border: oklch(1 0 0 / 10%);
|
|
194
|
+
--input: oklch(1 0 0 / 15%);
|
|
195
|
+
--ring: oklch(0.552 0.016 285.938);
|
|
196
|
+
--sidebar: oklch(0.21 0.006 285.885);
|
|
197
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
198
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
199
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
200
|
+
--sidebar-accent: oklch(0.274 0.006 286.033);
|
|
201
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
202
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
203
|
+
--sidebar-ring: oklch(0.552 0.016 285.938);
|
|
204
|
+
--chart-1: oklch(0.865 0.127 207.078);
|
|
205
|
+
--chart-2: oklch(0.715 0.143 215.221);
|
|
206
|
+
--chart-3: oklch(0.609 0.126 221.723);
|
|
207
|
+
--chart-4: oklch(0.52 0.105 223.128);
|
|
208
|
+
--chart-5: oklch(0.45 0.085 224.283);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@layer base {
|
|
212
|
+
[data-agents24-theme-root], [data-agents24-theme-root] * {
|
|
213
|
+
@apply border-border outline-ring/50;
|
|
214
|
+
box-sizing: border-box;
|
|
215
|
+
}
|
|
216
|
+
[data-agents24-theme-root] {
|
|
217
|
+
@apply size-full overflow-hidden bg-background font-sans text-foreground antialiased;
|
|
218
|
+
}
|
|
219
|
+
[data-agents24-theme-root] button,
|
|
220
|
+
[data-agents24-theme-root] textarea { font: inherit; }
|
|
221
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import { App, type Agents24ChatAppProps } from "./app"
|
|
4
|
+
import {
|
|
5
|
+
ThemeProvider,
|
|
6
|
+
type Agents24ChatAppearanceController,
|
|
7
|
+
type Agents24ChatTheme,
|
|
8
|
+
} from "./components/theme-provider"
|
|
9
|
+
import { TooltipProvider } from "./components/ui/tooltip"
|
|
10
|
+
|
|
11
|
+
export type Agents24ChatScaffoldProps = Agents24ChatAppProps & {
|
|
12
|
+
appearanceController?: Agents24ChatAppearanceController
|
|
13
|
+
theme?: Agents24ChatTheme
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function Agents24ChatScaffold({ appearanceController, theme, ...props }: Agents24ChatScaffoldProps) {
|
|
17
|
+
return (
|
|
18
|
+
<ThemeProvider controller={appearanceController} theme={theme}>
|
|
19
|
+
<TooltipProvider>
|
|
20
|
+
<App {...props} />
|
|
21
|
+
</TooltipProvider>
|
|
22
|
+
</ThemeProvider>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { App as Agents24ChatScaffoldApp }
|
|
27
|
+
export { ThemeProvider as Agents24ChatThemeProvider }
|
|
28
|
+
export type {
|
|
29
|
+
Agents24ChatAppearance,
|
|
30
|
+
Agents24ChatAppearanceController,
|
|
31
|
+
Agents24ChatTheme,
|
|
32
|
+
} from "./components/theme-provider"
|
|
33
|
+
export type { Agents24ChatIdentity, Agents24ChatIdentityState } from "./identity"
|
|
34
|
+
export type {
|
|
35
|
+
ChatHitlResponse,
|
|
36
|
+
Agents24ChatScaffoldComponents,
|
|
37
|
+
Agents24ChatTimelineSlotProps,
|
|
38
|
+
} from "./app"
|
|
39
|
+
export { TooltipProvider as Agents24ChatTooltipProvider }
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "agents24.chat-scaffold-build.v1",
|
|
3
|
+
"default_preset": "b2D1FHzlY",
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"@fontsource-variable/inter": "^5.3.0",
|
|
6
|
+
"@fontsource-variable/jetbrains-mono": "^5.3.0",
|
|
7
|
+
"@fontsource-variable/merriweather": "^5.3.0",
|
|
8
|
+
"@shadcn/react": "^0.2.1",
|
|
9
|
+
"class-variance-authority": "^0.7.1",
|
|
10
|
+
"clsx": "^2.1.1",
|
|
11
|
+
"lucide-react": "0.542.0",
|
|
12
|
+
"radix-ui": "1.4.3",
|
|
13
|
+
"streamdown": "^2.5.0",
|
|
14
|
+
"tailwind-merge": "^3.6.0",
|
|
15
|
+
"tw-animate-css": "^1.4.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@tailwindcss/vite": "^4.1.16",
|
|
19
|
+
"shadcn": "4.13.1",
|
|
20
|
+
"tailwindcss": "^4.1.16"
|
|
21
|
+
},
|
|
22
|
+
"source": "packages/agents24-chat-react/scaffold",
|
|
23
|
+
"sha256": "c0cd4f7235384fb8297a0f5d364dbf75898e1a12e2b8c88128ee78f4ac0044c0",
|
|
24
|
+
"files": [
|
|
25
|
+
"components.json",
|
|
26
|
+
"manifest.json",
|
|
27
|
+
"src/app.tsx",
|
|
28
|
+
"src/chat.css",
|
|
29
|
+
"src/components/chat/chat-composer.tsx",
|
|
30
|
+
"src/components/chat/chat-message.tsx",
|
|
31
|
+
"src/components/chat/chat-shell.tsx",
|
|
32
|
+
"src/components/chat/collapsible-user-message.tsx",
|
|
33
|
+
"src/components/chat/external-link-dialog.tsx",
|
|
34
|
+
"src/components/chat/identity-control.tsx",
|
|
35
|
+
"src/components/chat/message-parts.tsx",
|
|
36
|
+
"src/components/chat/theme-menu.tsx",
|
|
37
|
+
"src/components/chat/thread-sidebar.tsx",
|
|
38
|
+
"src/components/chat/timeline-loading.ts",
|
|
39
|
+
"src/components/chat/turn-outline.tsx",
|
|
40
|
+
"src/components/theme-provider.tsx",
|
|
41
|
+
"src/components/ui/attachment.tsx",
|
|
42
|
+
"src/components/ui/bubble.tsx",
|
|
43
|
+
"src/components/ui/button-group.tsx",
|
|
44
|
+
"src/components/ui/button.tsx",
|
|
45
|
+
"src/components/ui/dialog.tsx",
|
|
46
|
+
"src/components/ui/dropdown-menu.tsx",
|
|
47
|
+
"src/components/ui/input.tsx",
|
|
48
|
+
"src/components/ui/marker.tsx",
|
|
49
|
+
"src/components/ui/message-scroller.tsx",
|
|
50
|
+
"src/components/ui/message.tsx",
|
|
51
|
+
"src/components/ui/popover.tsx",
|
|
52
|
+
"src/components/ui/select.tsx",
|
|
53
|
+
"src/components/ui/separator.tsx",
|
|
54
|
+
"src/components/ui/sheet.tsx",
|
|
55
|
+
"src/components/ui/sidebar.tsx",
|
|
56
|
+
"src/components/ui/skeleton.tsx",
|
|
57
|
+
"src/components/ui/textarea.tsx",
|
|
58
|
+
"src/components/ui/tooltip.tsx",
|
|
59
|
+
"src/hooks/use-mobile.ts",
|
|
60
|
+
"src/identity.ts",
|
|
61
|
+
"src/index.css",
|
|
62
|
+
"src/index.tsx",
|
|
63
|
+
"src/lib/utils.ts",
|
|
64
|
+
"styles.css"
|
|
65
|
+
]
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-agents24-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Create a production-ready Agents24 React application.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"provenance": false
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@clack/prompts": "1.7.0"
|
|
36
|
+
"@clack/prompts": "1.7.0",
|
|
37
|
+
"shadcn": "4.13.1"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@types/node": "^24.7.2",
|
|
@@ -41,7 +42,10 @@
|
|
|
41
42
|
"typescript": "^5.9.3"
|
|
42
43
|
},
|
|
43
44
|
"scripts": {
|
|
44
|
-
"
|
|
45
|
+
"sync:scaffold": "node scripts/sync-chat-scaffold.mjs",
|
|
46
|
+
"check:scaffold": "node scripts/sync-chat-scaffold.mjs --check",
|
|
47
|
+
"build": "tsup && pnpm run sync:scaffold && tsc --noEmit",
|
|
48
|
+
"materialize:fixture": "pnpm run build && node scripts/materialize-dev-fixture.mjs",
|
|
45
49
|
"test": "pnpm run build && node --test tests/*.test.mjs",
|
|
46
50
|
"prepack": "pnpm run build && pnpm run test"
|
|
47
51
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# __APP_NAME__
|
|
2
2
|
|
|
3
|
-
Last Updated: 2026-07-
|
|
3
|
+
Last Updated: 2026-07-29
|
|
4
4
|
|
|
5
|
-
This app was generated by `create-agents24-app` with the `__INTEGRATION__` integration and
|
|
5
|
+
This app was generated by `create-agents24-app` with the `__INTEGRATION__` integration and Shadcn preset `__PRESET__`.
|
|
6
6
|
|
|
7
7
|
The app includes a strict document CSP. If you deploy the static client-deployment build without the generated BFF, configure your host to send `Content-Security-Policy: frame-ancestors 'none'`; browsers do not honor that directive in an HTML meta tag.
|
|
8
8
|
|
|
@@ -14,6 +14,8 @@ __PM_DEV__
|
|
|
14
14
|
|
|
15
15
|
Configuration lives in `.env.local`. Commit `.env.example`, never `.env.local`.
|
|
16
16
|
|
|
17
|
+
__STARTER_SETUP__
|
|
18
|
+
|
|
17
19
|
## Production
|
|
18
20
|
|
|
19
21
|
```bash
|
|
@@ -21,4 +23,15 @@ __PM_BUILD__
|
|
|
21
23
|
__PM_PRODUCTION__
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
The
|
|
26
|
+
The application owns its Shadcn component source under `src/components`. Agents24 packages own the runtime, state, hardened streaming markdown, and MCP security helpers.
|
|
27
|
+
|
|
28
|
+
## Timeline customization
|
|
29
|
+
|
|
30
|
+
The generated scaffold renders canonical ordered `message.parts` with the
|
|
31
|
+
default `AgentResponseTimeline`. Pass `components={{ Timeline }}` to
|
|
32
|
+
`Agents24ChatScaffold` to use the default, pass a copied/reordered `parts`
|
|
33
|
+
array to `AgentResponseTimeline`, or render a fully custom timeline with
|
|
34
|
+
`AgentChatPart` and the supplied HITL callbacks. Never mutate `message.parts`;
|
|
35
|
+
the replacement owns its accessibility and pending-HITL visibility.
|
|
36
|
+
|
|
37
|
+
To try another Shadcn preset later, run `__PM_PRESET__ <preset-code> --yes`. Commit first: Shadcn intentionally updates component source and theme variables.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="en"
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
|
6
|
-
<meta content="default-src 'self'; base-uri 'none'; object-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data: blob:; connect-src 'self'
|
|
5
|
+
<meta content="width=device-width, initial-scale=1.0, viewport-fit=cover" name="viewport" />
|
|
6
|
+
<meta content="default-src 'self'; base-uri 'none'; object-src 'none'; script-src 'self'; style-src 'self'; font-src 'self' data:; img-src 'self' data: blob:; connect-src 'self'__CONNECT_SOURCE__; form-action 'self'" http-equiv="Content-Security-Policy" />
|
|
7
7
|
<link href="/src/styles.css" rel="stylesheet" />
|
|
8
8
|
<title>__APP_NAME__</title>
|
|
9
9
|
</head>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process"
|
|
2
|
+
import { resolve } from "node:path"
|
|
3
|
+
import { fileURLToPath } from "node:url"
|
|
4
|
+
|
|
5
|
+
import { scopePresetTheme } from "./scope-preset-theme.mjs"
|
|
6
|
+
|
|
7
|
+
const preset = String(process.argv[2] || "").trim()
|
|
8
|
+
if (!preset) throw new Error("Pass a shadcn preset code, for example: pnpm preset -- b2D1FHzlY")
|
|
9
|
+
|
|
10
|
+
const shadcn = fileURLToPath(import.meta.resolve("shadcn"))
|
|
11
|
+
const result = spawnSync(process.execPath, [shadcn, "apply", preset, "--yes", "--cwd", resolve(".")], {
|
|
12
|
+
stdio: "inherit",
|
|
13
|
+
})
|
|
14
|
+
if (result.error) throw result.error
|
|
15
|
+
if (result.status !== 0) process.exit(result.status || 1)
|
|
16
|
+
|
|
17
|
+
scopePresetTheme()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readFileSync, realpathSync, writeFileSync } from "node:fs"
|
|
2
|
+
import { resolve } from "node:path"
|
|
3
|
+
import { fileURLToPath } from "node:url"
|
|
4
|
+
|
|
5
|
+
const startMarker = "/* agents24-preset-theme:start */"
|
|
6
|
+
const endMarker = "/* agents24-preset-theme:end */"
|
|
7
|
+
|
|
8
|
+
function lastTopLevelBlock(css, selector) {
|
|
9
|
+
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
10
|
+
const matches = [...css.matchAll(new RegExp(`^${escaped}\\s*\\{([\\s\\S]*?)^\\}`, "gm"))]
|
|
11
|
+
return matches.at(-1)?.[1]?.trim() || null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function scopePresetTheme(cssPath = resolve("src/index.css")) {
|
|
15
|
+
let css = readFileSync(cssPath, "utf8")
|
|
16
|
+
css = css.replace(new RegExp(`\\n?${startMarker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${endMarker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\n?`, "g"), "\n")
|
|
17
|
+
|
|
18
|
+
const light = lastTopLevelBlock(css, ":root")
|
|
19
|
+
const dark = lastTopLevelBlock(css, ".dark")
|
|
20
|
+
if (!light || !dark) throw new Error("The applied shadcn preset did not provide :root and .dark theme tokens.")
|
|
21
|
+
|
|
22
|
+
// Generated apps are standalone, but the chat root remains scoped so dialogs and
|
|
23
|
+
// overlays inherit one consistent theme. Remove the canonical default token blocks
|
|
24
|
+
// before adding the selected preset at the same scope.
|
|
25
|
+
css = css
|
|
26
|
+
.replace(/^\[data-agents24-theme-root\]\s*\{[\s\S]*?^\}\n?/m, "")
|
|
27
|
+
.replace(/^\[data-agents24-theme-root\]\.dark\s*\{[\s\S]*?^\}\n?/m, "")
|
|
28
|
+
.replace(/^\[data-agents24-theme-root\]\[data-agents24-theme="sharp"\]\s*\{[\s\S]*?^\}\n?/m, "")
|
|
29
|
+
.replace(/^\[data-agents24-theme-root\]\[data-agents24-theme="sharp"\]\.dark\s*\{[\s\S]*?^\}\n?/m, "")
|
|
30
|
+
.trimEnd()
|
|
31
|
+
|
|
32
|
+
css += `\n\n${startMarker}\n[data-agents24-theme-root] {\n color-scheme: light;\n${light}\n}\n\n[data-agents24-theme-root].dark {\n color-scheme: dark;\n${dark}\n}\n${endMarker}\n`
|
|
33
|
+
writeFileSync(cssPath, css)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (process.argv[1] && realpathSync(resolve(process.argv[1])) === realpathSync(fileURLToPath(import.meta.url))) {
|
|
37
|
+
scopePresetTheme(process.argv[2] ? resolve(process.argv[2]) : undefined)
|
|
38
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
@import "
|
|
2
|
-
@
|
|
1
|
+
@import "../styles.css";
|
|
2
|
+
@source "../node_modules/streamdown/dist/*.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
html,
|
|
5
|
+
body,
|
|
6
|
+
#root {
|
|
7
|
+
height: 100%;
|
|
8
|
+
margin: 0;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
width: 100%;
|
|
11
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AgentChatActiveThreadChange } from "@agents24/chat-react/runtime"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
|
|
4
|
+
const THREAD_ID_PARAM = "threadId"
|
|
5
|
+
|
|
6
|
+
function readThreadId(): string | null {
|
|
7
|
+
const value = new URL(window.location.href).searchParams.get(THREAD_ID_PARAM)
|
|
8
|
+
return value?.trim() || null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function writeThreadId(threadId: string | null, mode: "push" | "replace") {
|
|
12
|
+
const url = new URL(window.location.href)
|
|
13
|
+
if (threadId) url.searchParams.set(THREAD_ID_PARAM, threadId)
|
|
14
|
+
else url.searchParams.delete(THREAD_ID_PARAM)
|
|
15
|
+
window.history[mode === "push" ? "pushState" : "replaceState"](
|
|
16
|
+
{ ...window.history.state, agents24ThreadId: threadId },
|
|
17
|
+
"",
|
|
18
|
+
url,
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function useThreadQueryNavigation() {
|
|
23
|
+
const [activeThreadId, setActiveThreadId] = React.useState<string | null>(readThreadId)
|
|
24
|
+
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
const onPopState = () => setActiveThreadId(readThreadId())
|
|
27
|
+
window.addEventListener("popstate", onPopState)
|
|
28
|
+
return () => window.removeEventListener("popstate", onPopState)
|
|
29
|
+
}, [])
|
|
30
|
+
|
|
31
|
+
const onActiveThreadIdChange = React.useCallback((change: AgentChatActiveThreadChange) => {
|
|
32
|
+
setActiveThreadId((current) => {
|
|
33
|
+
if (current === change.threadId) return current
|
|
34
|
+
const mode = change.reason === "created" || change.reason === "deleted" ? "replace" : "push"
|
|
35
|
+
writeThreadId(change.threadId, mode)
|
|
36
|
+
return change.threadId
|
|
37
|
+
})
|
|
38
|
+
}, [])
|
|
39
|
+
|
|
40
|
+
return { activeThreadId, onActiveThreadIdChange }
|
|
41
|
+
}
|