create-next-imagicma 0.1.13 → 0.1.15
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/package.json +1 -1
- package/template-hono/.env.example +16 -3
- package/template-hono/AGENTS.md +91 -16
- package/template-hono/README.md +89 -3
- package/template-hono/client/src/components/HelloClient.tsx +1 -1
- package/template-hono/client/src/globals.css +1 -417
- package/template-hono/client/src/lib/ai-ui-stream.ts +64 -0
- package/template-hono/client/src/providers.tsx +1 -1
- package/template-hono/client/src/theme/default-theme.css +482 -0
- package/template-hono/drizzle.config.ts +3 -36
- package/template-hono/package.json +5 -1
- package/template-hono/pnpm-lock.yaml +186 -54
- package/template-hono/server/app.ts +2 -0
- package/template-hono/server/controllers/ai-chat-controller.ts +49 -0
- package/template-hono/server/controllers/greeting-controller.ts +25 -0
- package/template-hono/server/db/client.ts +25 -0
- package/template-hono/server/env.ts +89 -0
- package/template-hono/server/index.ts +1 -1
- package/template-hono/server/lib/ai-provider.ts +74 -0
- package/template-hono/server/lib/ai.ts +205 -0
- package/template-hono/server/middlewares/auth.ts +69 -0
- package/template-hono/server/middlewares/index.ts +12 -0
- package/template-hono/server/repositories/message-repository.ts +13 -0
- package/template-hono/server/routes/ai-chat.ts +9 -0
- package/template-hono/server/routes/greeting.ts +2 -18
- package/template-hono/shared/routes.ts +55 -0
- package/template-hono/shared/schema/greeting.ts +17 -0
- package/template-hono/shared/schema.ts +8 -16
- package/template-hono/tailwind.config.mjs +111 -62
- package/template-hono/vite.config.ts +1 -1
- package/template-hono/server/database-path.ts +0 -35
- package/template-hono/server/db.ts +0 -20
- package/template-hono/server/storage.ts +0 -30
|
@@ -1,427 +1,11 @@
|
|
|
1
|
-
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800&display=swap");
|
|
2
1
|
@import "tailwindcss";
|
|
2
|
+
@import "./theme/default-theme.css";
|
|
3
3
|
@config "../../tailwind.config.mjs";
|
|
4
4
|
|
|
5
5
|
.backdrop {
|
|
6
6
|
display: none;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
:root {
|
|
10
|
-
/* Fonts */
|
|
11
|
-
--font-sans: "Poppins", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
|
12
|
-
"Noto Sans SC", "Helvetica Neue", sans-serif;
|
|
13
|
-
--font-display: "Poppins", "PingFang SC", "Hiragino Sans GB",
|
|
14
|
-
"Microsoft YaHei", sans-serif;
|
|
15
|
-
--font-serif: "Poppins", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
|
16
|
-
"Noto Sans SC", "Helvetica Neue", sans-serif;
|
|
17
|
-
--font-mono: Menlo, ui-monospace, SFMono-Regular, Monaco, Consolas,
|
|
18
|
-
"Liberation Mono", "Courier New", monospace;
|
|
19
|
-
|
|
20
|
-
/* Core theme tokens (HSL triples) */
|
|
21
|
-
--background: 0 0% 100%;
|
|
22
|
-
--foreground: 240 10% 3.9%;
|
|
23
|
-
|
|
24
|
-
--card: 0 0% 100%;
|
|
25
|
-
--card-foreground: 240 10% 3.9%;
|
|
26
|
-
|
|
27
|
-
--popover: 0 0% 100%;
|
|
28
|
-
--popover-foreground: 240 10% 3.9%;
|
|
29
|
-
|
|
30
|
-
--primary: 240 5.9% 10%;
|
|
31
|
-
--primary-foreground: 0 0% 98%;
|
|
32
|
-
|
|
33
|
-
--secondary: 240 4.8% 95.9%;
|
|
34
|
-
--secondary-foreground: 240 5.9% 10%;
|
|
35
|
-
|
|
36
|
-
--muted: 240 4.8% 95.9%;
|
|
37
|
-
--muted-foreground: 240 3.8% 46.1%;
|
|
38
|
-
|
|
39
|
-
--accent: 240 4.8% 95.9%;
|
|
40
|
-
--accent-foreground: 240 5.9% 10%;
|
|
41
|
-
|
|
42
|
-
--destructive: 0 84.2% 60.2%;
|
|
43
|
-
--destructive-foreground: 0 0% 98%;
|
|
44
|
-
|
|
45
|
-
--border: 240 5.9% 90%;
|
|
46
|
-
--input: 240 5.9% 90%;
|
|
47
|
-
--ring: 240 5.9% 10%;
|
|
48
|
-
|
|
49
|
-
--radius: 0.8rem;
|
|
50
|
-
|
|
51
|
-
/* Visual system tokens for showcase pages */
|
|
52
|
-
--surface-1: 224 40% 98%;
|
|
53
|
-
--surface-2: 220 35% 95%;
|
|
54
|
-
--brand-accent: 201 92% 56%;
|
|
55
|
-
--brand-success: 156 72% 40%;
|
|
56
|
-
--elevation-soft: 0 14px 34px rgba(15, 23, 42, 0.12);
|
|
57
|
-
--elevation-strong: 0 22px 56px rgba(15, 23, 42, 0.18);
|
|
58
|
-
--space-xs: 0.625rem;
|
|
59
|
-
--space-sm: 0.875rem;
|
|
60
|
-
--space-md: 1.125rem;
|
|
61
|
-
--space-lg: 1.625rem;
|
|
62
|
-
|
|
63
|
-
/* Extra tokens used by the migrated shadcn components */
|
|
64
|
-
--card-border: var(--border);
|
|
65
|
-
--popover-border: var(--border);
|
|
66
|
-
--sidebar: var(--background);
|
|
67
|
-
--sidebar-foreground: var(--foreground);
|
|
68
|
-
--sidebar-border: var(--border);
|
|
69
|
-
--sidebar-ring: var(--ring);
|
|
70
|
-
|
|
71
|
-
--chart-1: 220 70% 50%;
|
|
72
|
-
--chart-2: 160 60% 45%;
|
|
73
|
-
--chart-3: 30 80% 55%;
|
|
74
|
-
--chart-4: 280 65% 60%;
|
|
75
|
-
--chart-5: 340 75% 55%;
|
|
76
|
-
|
|
77
|
-
/* Border colors expected by template classnames */
|
|
78
|
-
--primary-border: hsl(var(--primary) / 0.18);
|
|
79
|
-
--secondary-border: hsl(var(--border));
|
|
80
|
-
--muted-border: hsl(var(--border));
|
|
81
|
-
--accent-border: hsl(var(--border));
|
|
82
|
-
--destructive-border: hsl(var(--destructive) / 0.25);
|
|
83
|
-
|
|
84
|
-
--button-outline: hsl(var(--border));
|
|
85
|
-
--badge-outline: hsl(var(--border));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.dark {
|
|
89
|
-
--background: 240 10% 3.9%;
|
|
90
|
-
--foreground: 0 0% 98%;
|
|
91
|
-
|
|
92
|
-
--card: 240 10% 3.9%;
|
|
93
|
-
--card-foreground: 0 0% 98%;
|
|
94
|
-
|
|
95
|
-
--popover: 240 10% 3.9%;
|
|
96
|
-
--popover-foreground: 0 0% 98%;
|
|
97
|
-
|
|
98
|
-
--primary: 0 0% 98%;
|
|
99
|
-
--primary-foreground: 240 5.9% 10%;
|
|
100
|
-
|
|
101
|
-
--secondary: 240 3.7% 15.9%;
|
|
102
|
-
--secondary-foreground: 0 0% 98%;
|
|
103
|
-
|
|
104
|
-
--muted: 240 3.7% 15.9%;
|
|
105
|
-
--muted-foreground: 240 5% 64.9%;
|
|
106
|
-
|
|
107
|
-
--accent: 240 3.7% 15.9%;
|
|
108
|
-
--accent-foreground: 0 0% 98%;
|
|
109
|
-
|
|
110
|
-
--destructive: 0 62.8% 30.6%;
|
|
111
|
-
--destructive-foreground: 0 0% 98%;
|
|
112
|
-
|
|
113
|
-
--border: 240 3.7% 15.9%;
|
|
114
|
-
--input: 240 3.7% 15.9%;
|
|
115
|
-
--ring: 240 4.9% 83.9%;
|
|
116
|
-
|
|
117
|
-
--card-border: var(--border);
|
|
118
|
-
--popover-border: var(--border);
|
|
119
|
-
--sidebar: var(--background);
|
|
120
|
-
--sidebar-foreground: var(--foreground);
|
|
121
|
-
--sidebar-border: var(--border);
|
|
122
|
-
--sidebar-ring: var(--ring);
|
|
123
|
-
|
|
124
|
-
--primary-border: hsl(var(--primary) / 0.15);
|
|
125
|
-
--secondary-border: hsl(var(--border));
|
|
126
|
-
--muted-border: hsl(var(--border));
|
|
127
|
-
--accent-border: hsl(var(--border));
|
|
128
|
-
--destructive-border: hsl(var(--destructive) / 0.35);
|
|
129
|
-
|
|
130
|
-
--button-outline: hsl(var(--border));
|
|
131
|
-
--badge-outline: hsl(var(--border));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* Theme style presets (used by html[data-theme-style="<preset>"]) */
|
|
135
|
-
:root[data-theme-style="quadratic"] {
|
|
136
|
-
--background: 246 33% 96%;
|
|
137
|
-
--foreground: 233 24% 17%;
|
|
138
|
-
|
|
139
|
-
--card: 0 0% 100%;
|
|
140
|
-
--card-foreground: 233 24% 17%;
|
|
141
|
-
--popover: 0 0% 100%;
|
|
142
|
-
--popover-foreground: 233 24% 17%;
|
|
143
|
-
|
|
144
|
-
--primary: 258 84% 63%;
|
|
145
|
-
--primary-foreground: 0 0% 100%;
|
|
146
|
-
--secondary: 250 44% 92%;
|
|
147
|
-
--secondary-foreground: 233 24% 20%;
|
|
148
|
-
--muted: 246 36% 93%;
|
|
149
|
-
--muted-foreground: 230 12% 42%;
|
|
150
|
-
--accent: 257 62% 88%;
|
|
151
|
-
--accent-foreground: 234 24% 24%;
|
|
152
|
-
|
|
153
|
-
--border: 246 24% 86%;
|
|
154
|
-
--input: 246 24% 84%;
|
|
155
|
-
--ring: 258 84% 63%;
|
|
156
|
-
|
|
157
|
-
--chart-1: 258 78% 56%;
|
|
158
|
-
--chart-2: 201 84% 56%;
|
|
159
|
-
--chart-3: 172 65% 45%;
|
|
160
|
-
--chart-4: 338 74% 58%;
|
|
161
|
-
--chart-5: 39 84% 58%;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.dark[data-theme-style="quadratic"] {
|
|
165
|
-
--background: 233 22% 11%;
|
|
166
|
-
--foreground: 246 33% 96%;
|
|
167
|
-
|
|
168
|
-
--card: 232 20% 14%;
|
|
169
|
-
--card-foreground: 246 33% 96%;
|
|
170
|
-
--popover: 232 20% 14%;
|
|
171
|
-
--popover-foreground: 246 33% 96%;
|
|
172
|
-
|
|
173
|
-
--primary: 258 90% 70%;
|
|
174
|
-
--primary-foreground: 233 22% 11%;
|
|
175
|
-
--secondary: 235 16% 20%;
|
|
176
|
-
--secondary-foreground: 246 30% 94%;
|
|
177
|
-
--muted: 234 14% 18%;
|
|
178
|
-
--muted-foreground: 240 15% 76%;
|
|
179
|
-
--accent: 235 16% 20%;
|
|
180
|
-
--accent-foreground: 246 30% 94%;
|
|
181
|
-
|
|
182
|
-
--border: 234 14% 26%;
|
|
183
|
-
--input: 234 14% 26%;
|
|
184
|
-
--ring: 258 90% 70%;
|
|
185
|
-
|
|
186
|
-
--chart-1: 258 90% 70%;
|
|
187
|
-
--chart-2: 201 78% 68%;
|
|
188
|
-
--chart-3: 172 58% 62%;
|
|
189
|
-
--chart-4: 338 76% 72%;
|
|
190
|
-
--chart-5: 39 78% 70%;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
:root[data-theme-style="nomad"] {
|
|
194
|
-
--background: 0 0% 94.1%;
|
|
195
|
-
--foreground: 0 0% 10.2%;
|
|
196
|
-
|
|
197
|
-
--card: 0 0% 98.8%;
|
|
198
|
-
--card-foreground: 0 0% 0%;
|
|
199
|
-
--popover: 45 25% 96.9%;
|
|
200
|
-
--popover-foreground: 0 0% 10.2%;
|
|
201
|
-
|
|
202
|
-
--primary: 341.9 85.1% 52.5%;
|
|
203
|
-
--primary-foreground: 0 0% 100%;
|
|
204
|
-
--secondary: 0 0% 76.9%;
|
|
205
|
-
--secondary-foreground: 0 0% 10.2%;
|
|
206
|
-
--muted: 0 0% 89%;
|
|
207
|
-
--muted-foreground: 0 0% 12.9%;
|
|
208
|
-
--accent: 0 0% 100%;
|
|
209
|
-
--accent-foreground: 0 0% 10.2%;
|
|
210
|
-
|
|
211
|
-
--border: 0 0% 91%;
|
|
212
|
-
--input: 0 0% 71%;
|
|
213
|
-
--ring: 0 0% 42%;
|
|
214
|
-
|
|
215
|
-
--chart-1: 203.9 88.3% 53.1%;
|
|
216
|
-
--chart-2: 159.8 100% 36.1%;
|
|
217
|
-
--chart-3: 42 92.8% 56.3%;
|
|
218
|
-
--chart-4: 147.1 78.5% 42%;
|
|
219
|
-
--chart-5: 341.5 75.2% 51%;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.dark[data-theme-style="nomad"] {
|
|
223
|
-
--background: 0 0% 10%;
|
|
224
|
-
--foreground: 0 0% 96%;
|
|
225
|
-
|
|
226
|
-
--card: 0 0% 13%;
|
|
227
|
-
--card-foreground: 0 0% 98%;
|
|
228
|
-
--popover: 0 0% 8%;
|
|
229
|
-
--popover-foreground: 0 0% 96%;
|
|
230
|
-
|
|
231
|
-
--primary: 341.9 85.1% 60%;
|
|
232
|
-
--primary-foreground: 0 0% 100%;
|
|
233
|
-
--secondary: 0 0% 26%;
|
|
234
|
-
--secondary-foreground: 0 0% 96%;
|
|
235
|
-
--muted: 0 0% 18%;
|
|
236
|
-
--muted-foreground: 0 0% 72%;
|
|
237
|
-
--accent: 0 0% 22%;
|
|
238
|
-
--accent-foreground: 0 0% 96%;
|
|
239
|
-
|
|
240
|
-
--border: 0 0% 24%;
|
|
241
|
-
--input: 0 0% 34%;
|
|
242
|
-
--ring: 0 0% 62%;
|
|
243
|
-
|
|
244
|
-
--chart-1: 203.9 88.3% 62%;
|
|
245
|
-
--chart-2: 159.8 100% 44%;
|
|
246
|
-
--chart-3: 42 92.8% 64%;
|
|
247
|
-
--chart-4: 147.1 78.5% 50%;
|
|
248
|
-
--chart-5: 341.5 75.2% 59%;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
:root[data-theme-style="honey"] {
|
|
252
|
-
--background: 49 38.1% 91.8%;
|
|
253
|
-
--foreground: 40 52.9% 27.5%;
|
|
254
|
-
|
|
255
|
-
--card: 49 42% 95%;
|
|
256
|
-
--card-foreground: 40 52.9% 27.5%;
|
|
257
|
-
--popover: 49 42% 95%;
|
|
258
|
-
--popover-foreground: 40 52.9% 27.5%;
|
|
259
|
-
|
|
260
|
-
--primary: 40 72.8% 68.2%;
|
|
261
|
-
--primary-foreground: 40 52.9% 18%;
|
|
262
|
-
--secondary: 63 20.8% 79.2%;
|
|
263
|
-
--secondary-foreground: 40 52.9% 27.5%;
|
|
264
|
-
--muted: 49 30% 88%;
|
|
265
|
-
--muted-foreground: 40 24% 38%;
|
|
266
|
-
--accent: 63 20.8% 79.2%;
|
|
267
|
-
--accent-foreground: 40 52.9% 27.5%;
|
|
268
|
-
|
|
269
|
-
--border: 52 22% 74%;
|
|
270
|
-
--input: 52 22% 74%;
|
|
271
|
-
--ring: 40 72.8% 68.2%;
|
|
272
|
-
|
|
273
|
-
--chart-1: 40 72.8% 55%;
|
|
274
|
-
--chart-2: 63 30% 45%;
|
|
275
|
-
--chart-3: 173 25% 42%;
|
|
276
|
-
--chart-4: 18 56% 50%;
|
|
277
|
-
--chart-5: 240 16% 52%;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
.dark[data-theme-style="honey"] {
|
|
281
|
-
--background: 36 38% 10%;
|
|
282
|
-
--foreground: 49 30% 88%;
|
|
283
|
-
|
|
284
|
-
--card: 34 30% 14%;
|
|
285
|
-
--card-foreground: 49 30% 88%;
|
|
286
|
-
--popover: 34 30% 14%;
|
|
287
|
-
--popover-foreground: 49 30% 88%;
|
|
288
|
-
|
|
289
|
-
--primary: 40 72.8% 68.2%;
|
|
290
|
-
--primary-foreground: 36 38% 10%;
|
|
291
|
-
--secondary: 38 20% 20%;
|
|
292
|
-
--secondary-foreground: 49 30% 88%;
|
|
293
|
-
--muted: 38 18% 18%;
|
|
294
|
-
--muted-foreground: 49 18% 70%;
|
|
295
|
-
--accent: 38 18% 18%;
|
|
296
|
-
--accent-foreground: 49 30% 88%;
|
|
297
|
-
|
|
298
|
-
--border: 38 18% 26%;
|
|
299
|
-
--input: 38 18% 26%;
|
|
300
|
-
--ring: 40 72.8% 68.2%;
|
|
301
|
-
|
|
302
|
-
--chart-1: 40 72.8% 68.2%;
|
|
303
|
-
--chart-2: 63 35% 58%;
|
|
304
|
-
--chart-3: 173 30% 56%;
|
|
305
|
-
--chart-4: 20 56% 64%;
|
|
306
|
-
--chart-5: 240 22% 70%;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
:root[data-theme-style="zen-garden"] {
|
|
310
|
-
--background: 84 9.8% 90%;
|
|
311
|
-
--foreground: 225 18.2% 8.6%;
|
|
312
|
-
|
|
313
|
-
--card: 84 12% 94%;
|
|
314
|
-
--card-foreground: 225 18.2% 8.6%;
|
|
315
|
-
--popover: 84 12% 94%;
|
|
316
|
-
--popover-foreground: 225 18.2% 8.6%;
|
|
317
|
-
|
|
318
|
-
--primary: 173 24.7% 62%;
|
|
319
|
-
--primary-foreground: 225 18.2% 8.6%;
|
|
320
|
-
--secondary: 289 32.9% 72%;
|
|
321
|
-
--secondary-foreground: 225 18.2% 8.6%;
|
|
322
|
-
--muted: 84 10% 86%;
|
|
323
|
-
--muted-foreground: 225 10% 36%;
|
|
324
|
-
--accent: 289 32.9% 72%;
|
|
325
|
-
--accent-foreground: 225 18.2% 8.6%;
|
|
326
|
-
|
|
327
|
-
--border: 84 8% 78%;
|
|
328
|
-
--input: 84 8% 78%;
|
|
329
|
-
--ring: 173 24.7% 62%;
|
|
330
|
-
|
|
331
|
-
--chart-1: 173 24.7% 48%;
|
|
332
|
-
--chart-2: 289 32.9% 58%;
|
|
333
|
-
--chart-3: 40 68% 56%;
|
|
334
|
-
--chart-4: 220 26% 50%;
|
|
335
|
-
--chart-5: 0 55% 58%;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
.dark[data-theme-style="zen-garden"] {
|
|
339
|
-
--background: 225 18.2% 8.6%;
|
|
340
|
-
--foreground: 84 9.8% 90%;
|
|
341
|
-
|
|
342
|
-
--card: 225 16% 12%;
|
|
343
|
-
--card-foreground: 84 9.8% 90%;
|
|
344
|
-
--popover: 225 16% 12%;
|
|
345
|
-
--popover-foreground: 84 9.8% 90%;
|
|
346
|
-
|
|
347
|
-
--primary: 173 30% 66%;
|
|
348
|
-
--primary-foreground: 225 18.2% 8.6%;
|
|
349
|
-
--secondary: 225 12% 18%;
|
|
350
|
-
--secondary-foreground: 84 9.8% 90%;
|
|
351
|
-
--muted: 225 10% 15%;
|
|
352
|
-
--muted-foreground: 84 8% 72%;
|
|
353
|
-
--accent: 225 10% 15%;
|
|
354
|
-
--accent-foreground: 84 9.8% 90%;
|
|
355
|
-
|
|
356
|
-
--border: 225 10% 24%;
|
|
357
|
-
--input: 225 10% 24%;
|
|
358
|
-
--ring: 173 30% 66%;
|
|
359
|
-
|
|
360
|
-
--chart-1: 173 30% 66%;
|
|
361
|
-
--chart-2: 289 36% 70%;
|
|
362
|
-
--chart-3: 40 68% 64%;
|
|
363
|
-
--chart-4: 220 30% 70%;
|
|
364
|
-
--chart-5: 355 65% 68%;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
:root[data-theme-style="highlighter"] {
|
|
368
|
-
--background: 228 23.8% 95.9%;
|
|
369
|
-
--foreground: 223 18.9% 7.3%;
|
|
370
|
-
|
|
371
|
-
--card: 228 24% 98%;
|
|
372
|
-
--card-foreground: 223 18.9% 7.3%;
|
|
373
|
-
--popover: 228 24% 98%;
|
|
374
|
-
--popover-foreground: 223 18.9% 7.3%;
|
|
375
|
-
|
|
376
|
-
--primary: 97 70.5% 64.1%;
|
|
377
|
-
--primary-foreground: 223 18.9% 7.3%;
|
|
378
|
-
--secondary: 249 35.6% 88.4%;
|
|
379
|
-
--secondary-foreground: 223 18.9% 7.3%;
|
|
380
|
-
--muted: 228 20% 92%;
|
|
381
|
-
--muted-foreground: 223 10% 35%;
|
|
382
|
-
--accent: 249 35.6% 88.4%;
|
|
383
|
-
--accent-foreground: 223 18.9% 7.3%;
|
|
384
|
-
|
|
385
|
-
--border: 238 20% 84%;
|
|
386
|
-
--input: 238 20% 84%;
|
|
387
|
-
--ring: 97 70.5% 64.1%;
|
|
388
|
-
|
|
389
|
-
--chart-1: 97 70.5% 48%;
|
|
390
|
-
--chart-2: 249 45% 56%;
|
|
391
|
-
--chart-3: 202 72% 54%;
|
|
392
|
-
--chart-4: 339 78% 58%;
|
|
393
|
-
--chart-5: 40 78% 58%;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
.dark[data-theme-style="highlighter"] {
|
|
397
|
-
--background: 223 18.9% 7.3%;
|
|
398
|
-
--foreground: 228 23.8% 95.9%;
|
|
399
|
-
|
|
400
|
-
--card: 223 16% 11%;
|
|
401
|
-
--card-foreground: 228 23.8% 95.9%;
|
|
402
|
-
--popover: 223 16% 11%;
|
|
403
|
-
--popover-foreground: 228 23.8% 95.9%;
|
|
404
|
-
|
|
405
|
-
--primary: 97 74% 66%;
|
|
406
|
-
--primary-foreground: 223 18.9% 7.3%;
|
|
407
|
-
--secondary: 223 12% 18%;
|
|
408
|
-
--secondary-foreground: 228 23.8% 95.9%;
|
|
409
|
-
--muted: 223 10% 15%;
|
|
410
|
-
--muted-foreground: 228 14% 72%;
|
|
411
|
-
--accent: 223 10% 15%;
|
|
412
|
-
--accent-foreground: 228 23.8% 95.9%;
|
|
413
|
-
|
|
414
|
-
--border: 223 10% 24%;
|
|
415
|
-
--input: 223 10% 24%;
|
|
416
|
-
--ring: 97 74% 66%;
|
|
417
|
-
|
|
418
|
-
--chart-1: 97 74% 66%;
|
|
419
|
-
--chart-2: 249 50% 72%;
|
|
420
|
-
--chart-3: 202 78% 70%;
|
|
421
|
-
--chart-4: 339 80% 70%;
|
|
422
|
-
--chart-5: 40 78% 68%;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
9
|
@layer base {
|
|
426
10
|
* {
|
|
427
11
|
border-color: hsl(var(--border));
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type AiUiStreamPart =
|
|
2
|
+
| { type: "start" | "start-step" | "finish-step" | "finish"; [key: string]: unknown }
|
|
3
|
+
| { type: "text-start"; id?: string; [key: string]: unknown }
|
|
4
|
+
| { type: "text-delta"; id?: string; delta: string; [key: string]: unknown }
|
|
5
|
+
| { type: "text-end"; id?: string; [key: string]: unknown }
|
|
6
|
+
| { type: "error"; errorText?: string; [key: string]: unknown };
|
|
7
|
+
|
|
8
|
+
export async function readAiUiMessageStream(
|
|
9
|
+
stream: ReadableStream<Uint8Array>,
|
|
10
|
+
options?: {
|
|
11
|
+
onPart?: (part: AiUiStreamPart) => void;
|
|
12
|
+
onTextDelta?: (delta: string, fullText: string) => void;
|
|
13
|
+
},
|
|
14
|
+
) {
|
|
15
|
+
const reader = stream.getReader();
|
|
16
|
+
const decoder = new TextDecoder();
|
|
17
|
+
let buffer = "";
|
|
18
|
+
let text = "";
|
|
19
|
+
|
|
20
|
+
const consumeEvent = (eventText: string) => {
|
|
21
|
+
const dataLines = eventText
|
|
22
|
+
.split("\n")
|
|
23
|
+
.map((line) => line.trim())
|
|
24
|
+
.filter((line) => line.startsWith("data:"))
|
|
25
|
+
.map((line) => line.slice(5).trim());
|
|
26
|
+
|
|
27
|
+
if (dataLines.length === 0) return;
|
|
28
|
+
|
|
29
|
+
const payload = dataLines.join("\n");
|
|
30
|
+
if (!payload || payload === "[DONE]") return;
|
|
31
|
+
|
|
32
|
+
const part = JSON.parse(payload) as AiUiStreamPart;
|
|
33
|
+
options?.onPart?.(part);
|
|
34
|
+
|
|
35
|
+
if (part.type === "error") {
|
|
36
|
+
throw new Error(part.errorText || "AI stream failed");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (part.type === "text-delta") {
|
|
40
|
+
text += part.delta;
|
|
41
|
+
options?.onTextDelta?.(part.delta, text);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
while (true) {
|
|
46
|
+
const { value, done } = await reader.read();
|
|
47
|
+
if (value) {
|
|
48
|
+
buffer += decoder.decode(value, { stream: true });
|
|
49
|
+
const events = buffer.split("\n\n");
|
|
50
|
+
buffer = events.pop() ?? "";
|
|
51
|
+
for (const eventText of events) {
|
|
52
|
+
consumeEvent(eventText);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (done) break;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (buffer.trim()) {
|
|
60
|
+
consumeEvent(buffer);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return text;
|
|
64
|
+
}
|
|
@@ -9,7 +9,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
9
9
|
const [queryClient] = React.useState(() => makeQueryClient());
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
|
-
<ThemeProvider attribute="class" defaultTheme="
|
|
12
|
+
<ThemeProvider attribute="class" defaultTheme="light">
|
|
13
13
|
<QueryClientProvider client={queryClient}>
|
|
14
14
|
<TooltipProvider>
|
|
15
15
|
<Toaster />
|