vibesuite 1.3.3 → 2.0.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.
Files changed (75) hide show
  1. package/README.md +75 -6
  2. package/assets/.agent/skills/avoid-feature-creep/SKILL.md +307 -0
  3. package/assets/.agent/skills/avoid-feature-creep/agents/openai.yaml +3 -0
  4. package/assets/.agent/skills/avoid-feature-creep/assets/large-logo.png +0 -0
  5. package/assets/.agent/skills/avoid-feature-creep/assets/small-logo.svg +17 -0
  6. package/assets/.agent/skills/convex/SKILL.md +62 -0
  7. package/assets/.agent/skills/convex/agents/openai.yaml +3 -0
  8. package/assets/.agent/skills/convex/assets/large-logo.png +0 -0
  9. package/assets/.agent/skills/convex/assets/small-logo.svg +17 -0
  10. package/assets/.agent/skills/convex-agents/SKILL.md +516 -0
  11. package/assets/.agent/skills/convex-agents/agents/openai.yaml +3 -0
  12. package/assets/.agent/skills/convex-agents/assets/large-logo.png +0 -0
  13. package/assets/.agent/skills/convex-agents/assets/small-logo.svg +17 -0
  14. package/assets/.agent/skills/convex-best-practices/SKILL.md +369 -0
  15. package/assets/.agent/skills/convex-best-practices/agents/openai.yaml +3 -0
  16. package/assets/.agent/skills/convex-best-practices/assets/large-logo.png +0 -0
  17. package/assets/.agent/skills/convex-best-practices/assets/small-logo.svg +17 -0
  18. package/assets/.agent/skills/convex-component-authoring/SKILL.md +457 -0
  19. package/assets/.agent/skills/convex-component-authoring/agents/openai.yaml +3 -0
  20. package/assets/.agent/skills/convex-component-authoring/assets/large-logo.png +0 -0
  21. package/assets/.agent/skills/convex-component-authoring/assets/small-logo.svg +17 -0
  22. package/assets/.agent/skills/convex-cron-jobs/SKILL.md +604 -0
  23. package/assets/.agent/skills/convex-cron-jobs/agents/openai.yaml +3 -0
  24. package/assets/.agent/skills/convex-cron-jobs/assets/large-logo.png +0 -0
  25. package/assets/.agent/skills/convex-cron-jobs/assets/small-logo.svg +17 -0
  26. package/assets/.agent/skills/convex-file-storage/SKILL.md +467 -0
  27. package/assets/.agent/skills/convex-file-storage/agents/openai.yaml +3 -0
  28. package/assets/.agent/skills/convex-file-storage/assets/large-logo.png +0 -0
  29. package/assets/.agent/skills/convex-file-storage/assets/small-logo.svg +17 -0
  30. package/assets/.agent/skills/convex-functions/SKILL.md +458 -0
  31. package/assets/.agent/skills/convex-functions/agents/openai.yaml +3 -0
  32. package/assets/.agent/skills/convex-functions/assets/large-logo.png +0 -0
  33. package/assets/.agent/skills/convex-functions/assets/small-logo.svg +17 -0
  34. package/assets/.agent/skills/convex-http-actions/SKILL.md +733 -0
  35. package/assets/.agent/skills/convex-http-actions/agents/openai.yaml +3 -0
  36. package/assets/.agent/skills/convex-http-actions/assets/large-logo.png +0 -0
  37. package/assets/.agent/skills/convex-http-actions/assets/small-logo.svg +17 -0
  38. package/assets/.agent/skills/convex-migrations/SKILL.md +712 -0
  39. package/assets/.agent/skills/convex-migrations/agents/openai.yaml +3 -0
  40. package/assets/.agent/skills/convex-migrations/assets/large-logo.png +0 -0
  41. package/assets/.agent/skills/convex-migrations/assets/small-logo.svg +17 -0
  42. package/assets/.agent/skills/convex-realtime/SKILL.md +443 -0
  43. package/assets/.agent/skills/convex-realtime/agents/openai.yaml +3 -0
  44. package/assets/.agent/skills/convex-realtime/assets/large-logo.png +0 -0
  45. package/assets/.agent/skills/convex-realtime/assets/small-logo.svg +17 -0
  46. package/assets/.agent/skills/convex-schema-validator/SKILL.md +400 -0
  47. package/assets/.agent/skills/convex-schema-validator/agents/openai.yaml +3 -0
  48. package/assets/.agent/skills/convex-schema-validator/assets/large-logo.png +0 -0
  49. package/assets/.agent/skills/convex-schema-validator/assets/small-logo.svg +17 -0
  50. package/assets/.agent/skills/convex-security-audit/SKILL.md +539 -0
  51. package/assets/.agent/skills/convex-security-audit/agents/openai.yaml +3 -0
  52. package/assets/.agent/skills/convex-security-audit/assets/large-logo.png +0 -0
  53. package/assets/.agent/skills/convex-security-audit/assets/small-logo.svg +17 -0
  54. package/assets/.agent/skills/convex-security-check/SKILL.md +378 -0
  55. package/assets/.agent/skills/convex-security-check/agents/openai.yaml +3 -0
  56. package/assets/.agent/skills/convex-security-check/assets/large-logo.png +0 -0
  57. package/assets/.agent/skills/convex-security-check/assets/small-logo.svg +17 -0
  58. package/assets/.agent/skills/github-ops/SKILL.md +4 -4
  59. package/assets/.agent/skills/google-trends/SKILL.md +7 -7
  60. package/assets/.agent/skills/optimize-agent-context/SKILL.md +97 -0
  61. package/assets/.agent/skills/youtube-pipeline/SKILL.md +10 -10
  62. package/assets/.agent/workflows/LEGACY/init_smart_ops.md +2 -2
  63. package/assets/.agent/workflows/agent_reset.md +4 -6
  64. package/assets/.agent/workflows/mode-orchestrator.md +17 -22
  65. package/assets/.agent/workflows/mode-visionary.md +3 -10
  66. package/assets/.agent/workflows/optimize-agent-context.md +54 -0
  67. package/assets/.agent/workflows/remotion-build.md +17 -17
  68. package/assets/.agent/workflows/stitch.md +4 -4
  69. package/assets/VibeCode-Agents/vibe-orchestrator.yaml +14 -33
  70. package/assets/VibeCode-Agents/vibe-visionary.yaml +3 -13
  71. package/package.json +1 -1
  72. package/src/cli.js +416 -20
  73. package/src/harness.js +281 -0
  74. package/src/store.js +239 -0
  75. package/assets/VibeCode-Agents/custom_modes.yaml +0 -979
@@ -0,0 +1,17 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_3_23)">
3
+ <g clip-path="url(#clip1_3_23)">
4
+ <path d="M10.0643 12.5735C12.3769 12.3166 14.5572 11.0843 15.7577 9.02756C15.1892 14.1148 9.62646 17.3302 5.08583 15.356C4.66743 15.1746 4.30728 14.8728 4.06013 14.4848C3.03973 12.8825 2.7043 10.8437 3.18626 8.99344C4.56327 11.37 7.3632 12.8267 10.0643 12.5735Z" fill="#F3B01C"/>
5
+ <path d="M3.1018 7.50072C2.16436 9.66714 2.12376 12.2034 3.27303 14.2907C-0.771507 11.2479 -0.72737 4.7362 3.2236 1.72378C3.58904 1.44535 4.02333 1.2801 4.47881 1.25494C6.3519 1.15614 8.25501 1.88006 9.58963 3.22909C6.87799 3.25604 4.23695 4.99308 3.1018 7.50072Z" fill="#8D2676"/>
6
+ <path d="M10.8974 3.89562C9.52924 1.98794 7.38779 0.68921 5.04156 0.649695C9.57686 -1.40888 15.1555 1.92867 15.7629 6.86314C15.8194 7.32119 15.7452 7.78824 15.5421 8.20138C14.6948 9.92223 13.1236 11.2569 11.2876 11.7508C12.6328 9.25579 12.4668 6.20748 10.8974 3.89562Z" fill="#EE342F"/>
7
+ </g>
8
+ </g>
9
+ <defs>
10
+ <clipPath id="clip0_3_23">
11
+ <rect width="16" height="16" fill="white"/>
12
+ </clipPath>
13
+ <clipPath id="clip1_3_23">
14
+ <rect width="16" height="16" fill="white"/>
15
+ </clipPath>
16
+ </defs>
17
+ </svg>
@@ -0,0 +1,443 @@
1
+ ---
2
+ name: convex-realtime
3
+ displayName: Convex Realtime
4
+ description: Patterns for building reactive apps including subscription management, optimistic updates, cache behavior, and paginated queries with cursor-based loading
5
+ version: 1.0.0
6
+ author: Convex
7
+ tags: [convex, realtime, subscriptions, optimistic-updates, pagination]
8
+ ---
9
+
10
+ # Convex Realtime
11
+
12
+ Build reactive applications with Convex's real-time subscriptions, optimistic updates, intelligent caching, and cursor-based pagination.
13
+
14
+ ## Documentation Sources
15
+
16
+ Before implementing, do not assume; fetch the latest documentation:
17
+
18
+ - Primary: https://docs.convex.dev/client/react
19
+ - Optimistic Updates: https://docs.convex.dev/client/react/optimistic-updates
20
+ - Pagination: https://docs.convex.dev/database/pagination
21
+ - For broader context: https://docs.convex.dev/llms.txt
22
+
23
+ ## Instructions
24
+
25
+ ### How Convex Realtime Works
26
+
27
+ 1. **Automatic Subscriptions** - useQuery creates a subscription that updates automatically
28
+ 2. **Smart Caching** - Query results are cached and shared across components
29
+ 3. **Consistency** - All subscriptions see a consistent view of the database
30
+ 4. **Efficient Updates** - Only re-renders when relevant data changes
31
+
32
+ ### Basic Subscriptions
33
+
34
+ ```typescript
35
+ // React component with real-time data
36
+ import { useQuery } from "convex/react";
37
+ import { api } from "../convex/_generated/api";
38
+
39
+ function TaskList({ userId }: { userId: Id<"users"> }) {
40
+ // Automatically subscribes and updates in real-time
41
+ const tasks = useQuery(api.tasks.list, { userId });
42
+
43
+ if (tasks === undefined) {
44
+ return <div>Loading...</div>;
45
+ }
46
+
47
+ return (
48
+ <ul>
49
+ {tasks.map((task) => (
50
+ <li key={task._id}>{task.title}</li>
51
+ ))}
52
+ </ul>
53
+ );
54
+ }
55
+ ```
56
+
57
+ ### Conditional Queries
58
+
59
+ ```typescript
60
+ import { useQuery } from "convex/react";
61
+ import { api } from "../convex/_generated/api";
62
+
63
+ function UserProfile({ userId }: { userId: Id<"users"> | null }) {
64
+ // Skip query when userId is null
65
+ const user = useQuery(
66
+ api.users.get,
67
+ userId ? { userId } : "skip"
68
+ );
69
+
70
+ if (userId === null) {
71
+ return <div>Select a user</div>;
72
+ }
73
+
74
+ if (user === undefined) {
75
+ return <div>Loading...</div>;
76
+ }
77
+
78
+ return <div>{user.name}</div>;
79
+ }
80
+ ```
81
+
82
+ ### Mutations with Real-time Updates
83
+
84
+ ```typescript
85
+ import { useMutation, useQuery } from "convex/react";
86
+ import { api } from "../convex/_generated/api";
87
+
88
+ function TaskManager({ userId }: { userId: Id<"users"> }) {
89
+ const tasks = useQuery(api.tasks.list, { userId });
90
+ const createTask = useMutation(api.tasks.create);
91
+ const toggleTask = useMutation(api.tasks.toggle);
92
+
93
+ const handleCreate = async (title: string) => {
94
+ // Mutation triggers automatic re-render when data changes
95
+ await createTask({ title, userId });
96
+ };
97
+
98
+ const handleToggle = async (taskId: Id<"tasks">) => {
99
+ await toggleTask({ taskId });
100
+ };
101
+
102
+ return (
103
+ <div>
104
+ <button onClick={() => handleCreate("New Task")}>Add Task</button>
105
+ <ul>
106
+ {tasks?.map((task) => (
107
+ <li key={task._id} onClick={() => handleToggle(task._id)}>
108
+ {task.completed ? "✓" : "○"} {task.title}
109
+ </li>
110
+ ))}
111
+ </ul>
112
+ </div>
113
+ );
114
+ }
115
+ ```
116
+
117
+ ### Optimistic Updates
118
+
119
+ Show changes immediately before server confirmation:
120
+
121
+ ```typescript
122
+ import { useMutation, useQuery } from "convex/react";
123
+ import { api } from "../convex/_generated/api";
124
+ import { Id } from "../convex/_generated/dataModel";
125
+
126
+ function TaskItem({ task }: { task: Task }) {
127
+ const toggleTask = useMutation(api.tasks.toggle).withOptimisticUpdate(
128
+ (localStore, args) => {
129
+ const { taskId } = args;
130
+ const currentValue = localStore.getQuery(api.tasks.get, { taskId });
131
+
132
+ if (currentValue !== undefined) {
133
+ localStore.setQuery(api.tasks.get, { taskId }, {
134
+ ...currentValue,
135
+ completed: !currentValue.completed,
136
+ });
137
+ }
138
+ }
139
+ );
140
+
141
+ return (
142
+ <div onClick={() => toggleTask({ taskId: task._id })}>
143
+ {task.completed ? "✓" : "○"} {task.title}
144
+ </div>
145
+ );
146
+ }
147
+ ```
148
+
149
+ ### Optimistic Updates for Lists
150
+
151
+ ```typescript
152
+ import { useMutation } from "convex/react";
153
+ import { api } from "../convex/_generated/api";
154
+
155
+ function useCreateTask(userId: Id<"users">) {
156
+ return useMutation(api.tasks.create).withOptimisticUpdate(
157
+ (localStore, args) => {
158
+ const { title, userId } = args;
159
+ const currentTasks = localStore.getQuery(api.tasks.list, { userId });
160
+
161
+ if (currentTasks !== undefined) {
162
+ // Add optimistic task to the list
163
+ const optimisticTask = {
164
+ _id: crypto.randomUUID() as Id<"tasks">,
165
+ _creationTime: Date.now(),
166
+ title,
167
+ userId,
168
+ completed: false,
169
+ };
170
+
171
+ localStore.setQuery(api.tasks.list, { userId }, [
172
+ optimisticTask,
173
+ ...currentTasks,
174
+ ]);
175
+ }
176
+ }
177
+ );
178
+ }
179
+ ```
180
+
181
+ ### Cursor-Based Pagination
182
+
183
+ ```typescript
184
+ // convex/messages.ts
185
+ import { query } from "./_generated/server";
186
+ import { v } from "convex/values";
187
+ import { paginationOptsValidator } from "convex/server";
188
+
189
+ export const listPaginated = query({
190
+ args: {
191
+ channelId: v.id("channels"),
192
+ paginationOpts: paginationOptsValidator,
193
+ },
194
+ handler: async (ctx, args) => {
195
+ return await ctx.db
196
+ .query("messages")
197
+ .withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
198
+ .order("desc")
199
+ .paginate(args.paginationOpts);
200
+ },
201
+ });
202
+ ```
203
+
204
+ ```typescript
205
+ // React component with pagination
206
+ import { usePaginatedQuery } from "convex/react";
207
+ import { api } from "../convex/_generated/api";
208
+
209
+ function MessageList({ channelId }: { channelId: Id<"channels"> }) {
210
+ const { results, status, loadMore } = usePaginatedQuery(
211
+ api.messages.listPaginated,
212
+ { channelId },
213
+ { initialNumItems: 20 }
214
+ );
215
+
216
+ return (
217
+ <div>
218
+ {results.map((message) => (
219
+ <div key={message._id}>{message.content}</div>
220
+ ))}
221
+
222
+ {status === "CanLoadMore" && (
223
+ <button onClick={() => loadMore(20)}>Load More</button>
224
+ )}
225
+
226
+ {status === "LoadingMore" && <div>Loading...</div>}
227
+
228
+ {status === "Exhausted" && <div>No more messages</div>}
229
+ </div>
230
+ );
231
+ }
232
+ ```
233
+
234
+ ### Infinite Scroll Pattern
235
+
236
+ ```typescript
237
+ import { usePaginatedQuery } from "convex/react";
238
+ import { useEffect, useRef } from "react";
239
+ import { api } from "../convex/_generated/api";
240
+
241
+ function InfiniteMessageList({ channelId }: { channelId: Id<"channels"> }) {
242
+ const { results, status, loadMore } = usePaginatedQuery(
243
+ api.messages.listPaginated,
244
+ { channelId },
245
+ { initialNumItems: 20 }
246
+ );
247
+
248
+ const observerRef = useRef<IntersectionObserver>();
249
+ const loadMoreRef = useRef<HTMLDivElement>(null);
250
+
251
+ useEffect(() => {
252
+ if (observerRef.current) {
253
+ observerRef.current.disconnect();
254
+ }
255
+
256
+ observerRef.current = new IntersectionObserver((entries) => {
257
+ if (entries[0].isIntersecting && status === "CanLoadMore") {
258
+ loadMore(20);
259
+ }
260
+ });
261
+
262
+ if (loadMoreRef.current) {
263
+ observerRef.current.observe(loadMoreRef.current);
264
+ }
265
+
266
+ return () => observerRef.current?.disconnect();
267
+ }, [status, loadMore]);
268
+
269
+ return (
270
+ <div>
271
+ {results.map((message) => (
272
+ <div key={message._id}>{message.content}</div>
273
+ ))}
274
+ <div ref={loadMoreRef} style={{ height: 1 }} />
275
+ {status === "LoadingMore" && <div>Loading...</div>}
276
+ </div>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ### Multiple Subscriptions
282
+
283
+ ```typescript
284
+ import { useQuery } from "convex/react";
285
+ import { api } from "../convex/_generated/api";
286
+
287
+ function Dashboard({ userId }: { userId: Id<"users"> }) {
288
+ // Multiple subscriptions update independently
289
+ const user = useQuery(api.users.get, { userId });
290
+ const tasks = useQuery(api.tasks.list, { userId });
291
+ const notifications = useQuery(api.notifications.unread, { userId });
292
+
293
+ const isLoading = user === undefined ||
294
+ tasks === undefined ||
295
+ notifications === undefined;
296
+
297
+ if (isLoading) {
298
+ return <div>Loading...</div>;
299
+ }
300
+
301
+ return (
302
+ <div>
303
+ <h1>Welcome, {user.name}</h1>
304
+ <p>You have {tasks.length} tasks</p>
305
+ <p>{notifications.length} unread notifications</p>
306
+ </div>
307
+ );
308
+ }
309
+ ```
310
+
311
+ ## Examples
312
+
313
+ ### Real-time Chat Application
314
+
315
+ ```typescript
316
+ // convex/messages.ts
317
+ import { query, mutation } from "./_generated/server";
318
+ import { v } from "convex/values";
319
+
320
+ export const list = query({
321
+ args: { channelId: v.id("channels") },
322
+ returns: v.array(v.object({
323
+ _id: v.id("messages"),
324
+ _creationTime: v.number(),
325
+ content: v.string(),
326
+ authorId: v.id("users"),
327
+ authorName: v.string(),
328
+ })),
329
+ handler: async (ctx, args) => {
330
+ const messages = await ctx.db
331
+ .query("messages")
332
+ .withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
333
+ .order("desc")
334
+ .take(100);
335
+
336
+ // Enrich with author names
337
+ return Promise.all(
338
+ messages.map(async (msg) => {
339
+ const author = await ctx.db.get(msg.authorId);
340
+ return {
341
+ ...msg,
342
+ authorName: author?.name ?? "Unknown",
343
+ };
344
+ })
345
+ );
346
+ },
347
+ });
348
+
349
+ export const send = mutation({
350
+ args: {
351
+ channelId: v.id("channels"),
352
+ authorId: v.id("users"),
353
+ content: v.string(),
354
+ },
355
+ returns: v.id("messages"),
356
+ handler: async (ctx, args) => {
357
+ return await ctx.db.insert("messages", {
358
+ channelId: args.channelId,
359
+ authorId: args.authorId,
360
+ content: args.content,
361
+ });
362
+ },
363
+ });
364
+ ```
365
+
366
+ ```typescript
367
+ // ChatRoom.tsx
368
+ import { useQuery, useMutation } from "convex/react";
369
+ import { api } from "../convex/_generated/api";
370
+ import { useState, useRef, useEffect } from "react";
371
+
372
+ function ChatRoom({ channelId, userId }: Props) {
373
+ const messages = useQuery(api.messages.list, { channelId });
374
+ const sendMessage = useMutation(api.messages.send);
375
+ const [input, setInput] = useState("");
376
+ const messagesEndRef = useRef<HTMLDivElement>(null);
377
+
378
+ // Auto-scroll to bottom on new messages
379
+ useEffect(() => {
380
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
381
+ }, [messages]);
382
+
383
+ const handleSend = async (e: React.FormEvent) => {
384
+ e.preventDefault();
385
+ if (!input.trim()) return;
386
+
387
+ await sendMessage({
388
+ channelId,
389
+ authorId: userId,
390
+ content: input.trim(),
391
+ });
392
+ setInput("");
393
+ };
394
+
395
+ return (
396
+ <div className="chat-room">
397
+ <div className="messages">
398
+ {messages?.map((msg) => (
399
+ <div key={msg._id} className="message">
400
+ <strong>{msg.authorName}:</strong> {msg.content}
401
+ </div>
402
+ ))}
403
+ <div ref={messagesEndRef} />
404
+ </div>
405
+
406
+ <form onSubmit={handleSend}>
407
+ <input
408
+ value={input}
409
+ onChange={(e) => setInput(e.target.value)}
410
+ placeholder="Type a message..."
411
+ />
412
+ <button type="submit">Send</button>
413
+ </form>
414
+ </div>
415
+ );
416
+ }
417
+ ```
418
+
419
+ ## Best Practices
420
+
421
+ - Never run `npx convex deploy` unless explicitly instructed
422
+ - Never run any git commands unless explicitly instructed
423
+ - Use "skip" for conditional queries instead of conditionally calling hooks
424
+ - Implement optimistic updates for better perceived performance
425
+ - Use usePaginatedQuery for large datasets
426
+ - Handle undefined state (loading) explicitly
427
+ - Avoid unnecessary re-renders by memoizing derived data
428
+
429
+ ## Common Pitfalls
430
+
431
+ 1. **Conditional hook calls** - Use "skip" instead of if statements
432
+ 2. **Not handling loading state** - Always check for undefined
433
+ 3. **Missing optimistic update rollback** - Optimistic updates auto-rollback on error
434
+ 4. **Over-fetching with pagination** - Use appropriate page sizes
435
+ 5. **Ignoring subscription cleanup** - React handles this automatically
436
+
437
+ ## References
438
+
439
+ - Convex Documentation: https://docs.convex.dev/
440
+ - Convex LLMs.txt: https://docs.convex.dev/llms.txt
441
+ - React Client: https://docs.convex.dev/client/react
442
+ - Optimistic Updates: https://docs.convex.dev/client/react/optimistic-updates
443
+ - Pagination: https://docs.convex.dev/database/pagination
@@ -0,0 +1,3 @@
1
+ interface:
2
+ icon_small: "./assets/small-logo.svg"
3
+ icon_large: "./assets/large-logo.png"
@@ -0,0 +1,17 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_3_23)">
3
+ <g clip-path="url(#clip1_3_23)">
4
+ <path d="M10.0643 12.5735C12.3769 12.3166 14.5572 11.0843 15.7577 9.02756C15.1892 14.1148 9.62646 17.3302 5.08583 15.356C4.66743 15.1746 4.30728 14.8728 4.06013 14.4848C3.03973 12.8825 2.7043 10.8437 3.18626 8.99344C4.56327 11.37 7.3632 12.8267 10.0643 12.5735Z" fill="#F3B01C"/>
5
+ <path d="M3.1018 7.50072C2.16436 9.66714 2.12376 12.2034 3.27303 14.2907C-0.771507 11.2479 -0.72737 4.7362 3.2236 1.72378C3.58904 1.44535 4.02333 1.2801 4.47881 1.25494C6.3519 1.15614 8.25501 1.88006 9.58963 3.22909C6.87799 3.25604 4.23695 4.99308 3.1018 7.50072Z" fill="#8D2676"/>
6
+ <path d="M10.8974 3.89562C9.52924 1.98794 7.38779 0.68921 5.04156 0.649695C9.57686 -1.40888 15.1555 1.92867 15.7629 6.86314C15.8194 7.32119 15.7452 7.78824 15.5421 8.20138C14.6948 9.92223 13.1236 11.2569 11.2876 11.7508C12.6328 9.25579 12.4668 6.20748 10.8974 3.89562Z" fill="#EE342F"/>
7
+ </g>
8
+ </g>
9
+ <defs>
10
+ <clipPath id="clip0_3_23">
11
+ <rect width="16" height="16" fill="white"/>
12
+ </clipPath>
13
+ <clipPath id="clip1_3_23">
14
+ <rect width="16" height="16" fill="white"/>
15
+ </clipPath>
16
+ </defs>
17
+ </svg>