vibesuite 1.3.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/assets/.agent/skills/avoid-feature-creep/SKILL.md +307 -0
- package/assets/.agent/skills/avoid-feature-creep/agents/openai.yaml +3 -0
- package/assets/.agent/skills/avoid-feature-creep/assets/large-logo.png +0 -0
- package/assets/.agent/skills/avoid-feature-creep/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex/SKILL.md +62 -0
- package/assets/.agent/skills/convex/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-agents/SKILL.md +516 -0
- package/assets/.agent/skills/convex-agents/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-agents/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-agents/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-best-practices/SKILL.md +369 -0
- package/assets/.agent/skills/convex-best-practices/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-best-practices/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-best-practices/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-component-authoring/SKILL.md +457 -0
- package/assets/.agent/skills/convex-component-authoring/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-component-authoring/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-component-authoring/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-cron-jobs/SKILL.md +604 -0
- package/assets/.agent/skills/convex-cron-jobs/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-cron-jobs/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-cron-jobs/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-file-storage/SKILL.md +467 -0
- package/assets/.agent/skills/convex-file-storage/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-file-storage/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-file-storage/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-functions/SKILL.md +458 -0
- package/assets/.agent/skills/convex-functions/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-functions/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-functions/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-http-actions/SKILL.md +733 -0
- package/assets/.agent/skills/convex-http-actions/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-http-actions/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-http-actions/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-migrations/SKILL.md +712 -0
- package/assets/.agent/skills/convex-migrations/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-migrations/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-migrations/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-realtime/SKILL.md +443 -0
- package/assets/.agent/skills/convex-realtime/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-realtime/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-realtime/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-schema-validator/SKILL.md +400 -0
- package/assets/.agent/skills/convex-schema-validator/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-schema-validator/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-schema-validator/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-security-audit/SKILL.md +539 -0
- package/assets/.agent/skills/convex-security-audit/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-security-audit/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-security-audit/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/convex-security-check/SKILL.md +378 -0
- package/assets/.agent/skills/convex-security-check/agents/openai.yaml +3 -0
- package/assets/.agent/skills/convex-security-check/assets/large-logo.png +0 -0
- package/assets/.agent/skills/convex-security-check/assets/small-logo.svg +17 -0
- package/assets/.agent/skills/github-ops/SKILL.md +4 -4
- package/assets/.agent/skills/google-trends/SKILL.md +7 -7
- package/assets/.agent/skills/optimize-agent-context/SKILL.md +97 -0
- package/assets/.agent/skills/youtube-pipeline/SKILL.md +10 -10
- package/assets/.agent/workflows/LEGACY/init_smart_ops.md +2 -2
- package/assets/.agent/workflows/agent_reset.md +2 -2
- package/assets/.agent/workflows/mode-orchestrator.md +114 -640
- package/assets/.agent/workflows/mode-visionary.md +192 -0
- package/assets/.agent/workflows/optimize-agent-context.md +54 -0
- package/assets/.agent/workflows/remotion-build.md +17 -17
- package/assets/.agent/workflows/stitch.md +4 -4
- package/assets/VibeCode-Agents/custom_modes.yaml +1257 -0
- package/assets/VibeCode-Agents/vibe-orchestrator.yaml +427 -145
- package/assets/VibeCode-Agents/vibe-visionary.yaml +617 -0
- package/package.json +2 -2
- package/src/cli.js +416 -20
- package/src/harness.js +281 -0
- package/src/store.js +239 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: convex-schema-validator
|
|
3
|
+
displayName: Convex Schema Validator
|
|
4
|
+
description: Defining and validating database schemas with proper typing, index configuration, optional fields, unions, and migration strategies for schema changes
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
author: Convex
|
|
7
|
+
tags: [convex, schema, validation, typescript, indexes, migrations]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Convex Schema Validator
|
|
11
|
+
|
|
12
|
+
Define and validate database schemas in Convex with proper typing, index configuration, optional fields, unions, and strategies for schema migrations.
|
|
13
|
+
|
|
14
|
+
## Documentation Sources
|
|
15
|
+
|
|
16
|
+
Before implementing, do not assume; fetch the latest documentation:
|
|
17
|
+
|
|
18
|
+
- Primary: https://docs.convex.dev/database/schemas
|
|
19
|
+
- Indexes: https://docs.convex.dev/database/indexes
|
|
20
|
+
- Data Types: https://docs.convex.dev/database/types
|
|
21
|
+
- For broader context: https://docs.convex.dev/llms.txt
|
|
22
|
+
|
|
23
|
+
## Instructions
|
|
24
|
+
|
|
25
|
+
### Basic Schema Definition
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// convex/schema.ts
|
|
29
|
+
import { defineSchema, defineTable } from "convex/server";
|
|
30
|
+
import { v } from "convex/values";
|
|
31
|
+
|
|
32
|
+
export default defineSchema({
|
|
33
|
+
users: defineTable({
|
|
34
|
+
name: v.string(),
|
|
35
|
+
email: v.string(),
|
|
36
|
+
avatarUrl: v.optional(v.string()),
|
|
37
|
+
createdAt: v.number(),
|
|
38
|
+
}),
|
|
39
|
+
|
|
40
|
+
tasks: defineTable({
|
|
41
|
+
title: v.string(),
|
|
42
|
+
description: v.optional(v.string()),
|
|
43
|
+
completed: v.boolean(),
|
|
44
|
+
userId: v.id("users"),
|
|
45
|
+
priority: v.union(
|
|
46
|
+
v.literal("low"),
|
|
47
|
+
v.literal("medium"),
|
|
48
|
+
v.literal("high")
|
|
49
|
+
),
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Validator Types
|
|
55
|
+
|
|
56
|
+
| Validator | TypeScript Type | Example |
|
|
57
|
+
|-----------|----------------|---------|
|
|
58
|
+
| `v.string()` | `string` | `"hello"` |
|
|
59
|
+
| `v.number()` | `number` | `42`, `3.14` |
|
|
60
|
+
| `v.boolean()` | `boolean` | `true`, `false` |
|
|
61
|
+
| `v.null()` | `null` | `null` |
|
|
62
|
+
| `v.int64()` | `bigint` | `9007199254740993n` |
|
|
63
|
+
| `v.bytes()` | `ArrayBuffer` | Binary data |
|
|
64
|
+
| `v.id("table")` | `Id<"table">` | Document reference |
|
|
65
|
+
| `v.array(v)` | `T[]` | `[1, 2, 3]` |
|
|
66
|
+
| `v.object({})` | `{ ... }` | `{ name: "..." }` |
|
|
67
|
+
| `v.optional(v)` | `T \| undefined` | Optional field |
|
|
68
|
+
| `v.union(...)` | `T1 \| T2` | Multiple types |
|
|
69
|
+
| `v.literal(x)` | `"x"` | Exact value |
|
|
70
|
+
| `v.any()` | `any` | Any value |
|
|
71
|
+
| `v.record(k, v)` | `Record<K, V>` | Dynamic keys |
|
|
72
|
+
|
|
73
|
+
### Index Configuration
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
export default defineSchema({
|
|
77
|
+
messages: defineTable({
|
|
78
|
+
channelId: v.id("channels"),
|
|
79
|
+
authorId: v.id("users"),
|
|
80
|
+
content: v.string(),
|
|
81
|
+
sentAt: v.number(),
|
|
82
|
+
})
|
|
83
|
+
// Single field index
|
|
84
|
+
.index("by_channel", ["channelId"])
|
|
85
|
+
// Compound index
|
|
86
|
+
.index("by_channel_and_author", ["channelId", "authorId"])
|
|
87
|
+
// Index for sorting
|
|
88
|
+
.index("by_channel_and_time", ["channelId", "sentAt"]),
|
|
89
|
+
|
|
90
|
+
// Full-text search index
|
|
91
|
+
articles: defineTable({
|
|
92
|
+
title: v.string(),
|
|
93
|
+
body: v.string(),
|
|
94
|
+
category: v.string(),
|
|
95
|
+
})
|
|
96
|
+
.searchIndex("search_content", {
|
|
97
|
+
searchField: "body",
|
|
98
|
+
filterFields: ["category"],
|
|
99
|
+
}),
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Complex Types
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
export default defineSchema({
|
|
107
|
+
// Nested objects
|
|
108
|
+
profiles: defineTable({
|
|
109
|
+
userId: v.id("users"),
|
|
110
|
+
settings: v.object({
|
|
111
|
+
theme: v.union(v.literal("light"), v.literal("dark")),
|
|
112
|
+
notifications: v.object({
|
|
113
|
+
email: v.boolean(),
|
|
114
|
+
push: v.boolean(),
|
|
115
|
+
}),
|
|
116
|
+
}),
|
|
117
|
+
}),
|
|
118
|
+
|
|
119
|
+
// Arrays of objects
|
|
120
|
+
orders: defineTable({
|
|
121
|
+
customerId: v.id("users"),
|
|
122
|
+
items: v.array(v.object({
|
|
123
|
+
productId: v.id("products"),
|
|
124
|
+
quantity: v.number(),
|
|
125
|
+
price: v.number(),
|
|
126
|
+
})),
|
|
127
|
+
status: v.union(
|
|
128
|
+
v.literal("pending"),
|
|
129
|
+
v.literal("processing"),
|
|
130
|
+
v.literal("shipped"),
|
|
131
|
+
v.literal("delivered")
|
|
132
|
+
),
|
|
133
|
+
}),
|
|
134
|
+
|
|
135
|
+
// Record type for dynamic keys
|
|
136
|
+
analytics: defineTable({
|
|
137
|
+
date: v.string(),
|
|
138
|
+
metrics: v.record(v.string(), v.number()),
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Discriminated Unions
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
export default defineSchema({
|
|
147
|
+
events: defineTable(
|
|
148
|
+
v.union(
|
|
149
|
+
v.object({
|
|
150
|
+
type: v.literal("user_signup"),
|
|
151
|
+
userId: v.id("users"),
|
|
152
|
+
email: v.string(),
|
|
153
|
+
}),
|
|
154
|
+
v.object({
|
|
155
|
+
type: v.literal("purchase"),
|
|
156
|
+
userId: v.id("users"),
|
|
157
|
+
orderId: v.id("orders"),
|
|
158
|
+
amount: v.number(),
|
|
159
|
+
}),
|
|
160
|
+
v.object({
|
|
161
|
+
type: v.literal("page_view"),
|
|
162
|
+
sessionId: v.string(),
|
|
163
|
+
path: v.string(),
|
|
164
|
+
})
|
|
165
|
+
)
|
|
166
|
+
).index("by_type", ["type"]),
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Optional vs Nullable Fields
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
export default defineSchema({
|
|
174
|
+
items: defineTable({
|
|
175
|
+
// Optional: field may not exist
|
|
176
|
+
description: v.optional(v.string()),
|
|
177
|
+
|
|
178
|
+
// Nullable: field exists but can be null
|
|
179
|
+
deletedAt: v.union(v.number(), v.null()),
|
|
180
|
+
|
|
181
|
+
// Optional and nullable
|
|
182
|
+
notes: v.optional(v.union(v.string(), v.null())),
|
|
183
|
+
}),
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Index Naming Convention
|
|
188
|
+
|
|
189
|
+
Always include all indexed fields in the index name:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
export default defineSchema({
|
|
193
|
+
posts: defineTable({
|
|
194
|
+
authorId: v.id("users"),
|
|
195
|
+
categoryId: v.id("categories"),
|
|
196
|
+
publishedAt: v.number(),
|
|
197
|
+
status: v.string(),
|
|
198
|
+
})
|
|
199
|
+
// Good: descriptive names
|
|
200
|
+
.index("by_author", ["authorId"])
|
|
201
|
+
.index("by_author_and_category", ["authorId", "categoryId"])
|
|
202
|
+
.index("by_category_and_status", ["categoryId", "status"])
|
|
203
|
+
.index("by_status_and_published", ["status", "publishedAt"]),
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Schema Migration Strategies
|
|
208
|
+
|
|
209
|
+
#### Adding New Fields
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
// Before
|
|
213
|
+
users: defineTable({
|
|
214
|
+
name: v.string(),
|
|
215
|
+
email: v.string(),
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// After - add as optional first
|
|
219
|
+
users: defineTable({
|
|
220
|
+
name: v.string(),
|
|
221
|
+
email: v.string(),
|
|
222
|
+
avatarUrl: v.optional(v.string()), // New optional field
|
|
223
|
+
})
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Backfilling Data
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// convex/migrations.ts
|
|
230
|
+
import { internalMutation } from "./_generated/server";
|
|
231
|
+
import { v } from "convex/values";
|
|
232
|
+
|
|
233
|
+
export const backfillAvatars = internalMutation({
|
|
234
|
+
args: {},
|
|
235
|
+
returns: v.number(),
|
|
236
|
+
handler: async (ctx) => {
|
|
237
|
+
const users = await ctx.db
|
|
238
|
+
.query("users")
|
|
239
|
+
.filter((q) => q.eq(q.field("avatarUrl"), undefined))
|
|
240
|
+
.take(100);
|
|
241
|
+
|
|
242
|
+
for (const user of users) {
|
|
243
|
+
await ctx.db.patch(user._id, {
|
|
244
|
+
avatarUrl: `https://api.dicebear.com/7.x/initials/svg?seed=${user.name}`,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return users.length;
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### Making Optional Fields Required
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// Step 1: Backfill all null values
|
|
257
|
+
// Step 2: Update schema to required
|
|
258
|
+
users: defineTable({
|
|
259
|
+
name: v.string(),
|
|
260
|
+
email: v.string(),
|
|
261
|
+
avatarUrl: v.string(), // Now required after backfill
|
|
262
|
+
})
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Examples
|
|
266
|
+
|
|
267
|
+
### Complete E-commerce Schema
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// convex/schema.ts
|
|
271
|
+
import { defineSchema, defineTable } from "convex/server";
|
|
272
|
+
import { v } from "convex/values";
|
|
273
|
+
|
|
274
|
+
export default defineSchema({
|
|
275
|
+
users: defineTable({
|
|
276
|
+
email: v.string(),
|
|
277
|
+
name: v.string(),
|
|
278
|
+
role: v.union(v.literal("customer"), v.literal("admin")),
|
|
279
|
+
createdAt: v.number(),
|
|
280
|
+
})
|
|
281
|
+
.index("by_email", ["email"])
|
|
282
|
+
.index("by_role", ["role"]),
|
|
283
|
+
|
|
284
|
+
products: defineTable({
|
|
285
|
+
name: v.string(),
|
|
286
|
+
description: v.string(),
|
|
287
|
+
price: v.number(),
|
|
288
|
+
category: v.string(),
|
|
289
|
+
inventory: v.number(),
|
|
290
|
+
isActive: v.boolean(),
|
|
291
|
+
})
|
|
292
|
+
.index("by_category", ["category"])
|
|
293
|
+
.index("by_active_and_category", ["isActive", "category"])
|
|
294
|
+
.searchIndex("search_products", {
|
|
295
|
+
searchField: "name",
|
|
296
|
+
filterFields: ["category", "isActive"],
|
|
297
|
+
}),
|
|
298
|
+
|
|
299
|
+
orders: defineTable({
|
|
300
|
+
userId: v.id("users"),
|
|
301
|
+
items: v.array(v.object({
|
|
302
|
+
productId: v.id("products"),
|
|
303
|
+
quantity: v.number(),
|
|
304
|
+
priceAtPurchase: v.number(),
|
|
305
|
+
})),
|
|
306
|
+
total: v.number(),
|
|
307
|
+
status: v.union(
|
|
308
|
+
v.literal("pending"),
|
|
309
|
+
v.literal("paid"),
|
|
310
|
+
v.literal("shipped"),
|
|
311
|
+
v.literal("delivered"),
|
|
312
|
+
v.literal("cancelled")
|
|
313
|
+
),
|
|
314
|
+
shippingAddress: v.object({
|
|
315
|
+
street: v.string(),
|
|
316
|
+
city: v.string(),
|
|
317
|
+
state: v.string(),
|
|
318
|
+
zip: v.string(),
|
|
319
|
+
country: v.string(),
|
|
320
|
+
}),
|
|
321
|
+
createdAt: v.number(),
|
|
322
|
+
updatedAt: v.number(),
|
|
323
|
+
})
|
|
324
|
+
.index("by_user", ["userId"])
|
|
325
|
+
.index("by_user_and_status", ["userId", "status"])
|
|
326
|
+
.index("by_status", ["status"]),
|
|
327
|
+
|
|
328
|
+
reviews: defineTable({
|
|
329
|
+
productId: v.id("products"),
|
|
330
|
+
userId: v.id("users"),
|
|
331
|
+
rating: v.number(),
|
|
332
|
+
comment: v.optional(v.string()),
|
|
333
|
+
createdAt: v.number(),
|
|
334
|
+
})
|
|
335
|
+
.index("by_product", ["productId"])
|
|
336
|
+
.index("by_user", ["userId"]),
|
|
337
|
+
});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Using Schema Types in Functions
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
// convex/products.ts
|
|
344
|
+
import { query, mutation } from "./_generated/server";
|
|
345
|
+
import { v } from "convex/values";
|
|
346
|
+
import { Doc, Id } from "./_generated/dataModel";
|
|
347
|
+
|
|
348
|
+
// Use Doc type for full documents
|
|
349
|
+
type Product = Doc<"products">;
|
|
350
|
+
|
|
351
|
+
// Use Id type for references
|
|
352
|
+
type ProductId = Id<"products">;
|
|
353
|
+
|
|
354
|
+
export const get = query({
|
|
355
|
+
args: { productId: v.id("products") },
|
|
356
|
+
returns: v.union(
|
|
357
|
+
v.object({
|
|
358
|
+
_id: v.id("products"),
|
|
359
|
+
_creationTime: v.number(),
|
|
360
|
+
name: v.string(),
|
|
361
|
+
description: v.string(),
|
|
362
|
+
price: v.number(),
|
|
363
|
+
category: v.string(),
|
|
364
|
+
inventory: v.number(),
|
|
365
|
+
isActive: v.boolean(),
|
|
366
|
+
}),
|
|
367
|
+
v.null()
|
|
368
|
+
),
|
|
369
|
+
handler: async (ctx, args): Promise<Product | null> => {
|
|
370
|
+
return await ctx.db.get(args.productId);
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Best Practices
|
|
376
|
+
|
|
377
|
+
- Never run `npx convex deploy` unless explicitly instructed
|
|
378
|
+
- Never run any git commands unless explicitly instructed
|
|
379
|
+
- Always define explicit schemas rather than relying on inference
|
|
380
|
+
- Use descriptive index names that include all indexed fields
|
|
381
|
+
- Start with optional fields when adding new columns
|
|
382
|
+
- Use discriminated unions for polymorphic data
|
|
383
|
+
- Validate data at the schema level, not just in functions
|
|
384
|
+
- Plan index strategy based on query patterns
|
|
385
|
+
|
|
386
|
+
## Common Pitfalls
|
|
387
|
+
|
|
388
|
+
1. **Missing indexes for queries** - Every withIndex needs a corresponding schema index
|
|
389
|
+
2. **Wrong index field order** - Fields must be queried in order defined
|
|
390
|
+
3. **Using v.any() excessively** - Lose type safety benefits
|
|
391
|
+
4. **Not making new fields optional** - Breaks existing data
|
|
392
|
+
5. **Forgetting system fields** - _id and _creationTime are automatic
|
|
393
|
+
|
|
394
|
+
## References
|
|
395
|
+
|
|
396
|
+
- Convex Documentation: https://docs.convex.dev/
|
|
397
|
+
- Convex LLMs.txt: https://docs.convex.dev/llms.txt
|
|
398
|
+
- Schemas: https://docs.convex.dev/database/schemas
|
|
399
|
+
- Indexes: https://docs.convex.dev/database/indexes
|
|
400
|
+
- Data Types: https://docs.convex.dev/database/types
|
|
@@ -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>
|