opencode-skills-collection 1.0.185 → 1.0.187

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 (71) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +5 -1
  2. package/bundled-skills/3d-web-experience/SKILL.md +152 -37
  3. package/bundled-skills/agent-evaluation/SKILL.md +1088 -26
  4. package/bundled-skills/agent-memory-systems/SKILL.md +1037 -25
  5. package/bundled-skills/agent-tool-builder/SKILL.md +668 -16
  6. package/bundled-skills/ai-agents-architect/SKILL.md +271 -31
  7. package/bundled-skills/ai-product/SKILL.md +716 -26
  8. package/bundled-skills/ai-wrapper-product/SKILL.md +450 -44
  9. package/bundled-skills/algolia-search/SKILL.md +867 -15
  10. package/bundled-skills/autonomous-agents/SKILL.md +1033 -26
  11. package/bundled-skills/aws-serverless/SKILL.md +1046 -35
  12. package/bundled-skills/azure-functions/SKILL.md +1318 -19
  13. package/bundled-skills/browser-automation/SKILL.md +1065 -28
  14. package/bundled-skills/browser-extension-builder/SKILL.md +159 -32
  15. package/bundled-skills/bullmq-specialist/SKILL.md +347 -16
  16. package/bundled-skills/clerk-auth/SKILL.md +796 -15
  17. package/bundled-skills/computer-use-agents/SKILL.md +1870 -28
  18. package/bundled-skills/context-window-management/SKILL.md +271 -18
  19. package/bundled-skills/conversation-memory/SKILL.md +453 -24
  20. package/bundled-skills/crewai/SKILL.md +252 -46
  21. package/bundled-skills/discord-bot-architect/SKILL.md +1207 -34
  22. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  23. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  24. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  25. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  26. package/bundled-skills/docs/users/bundles.md +1 -1
  27. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  28. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  29. package/bundled-skills/docs/users/getting-started.md +1 -1
  30. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  31. package/bundled-skills/docs/users/usage.md +4 -4
  32. package/bundled-skills/docs/users/visual-guide.md +4 -4
  33. package/bundled-skills/email-systems/SKILL.md +646 -26
  34. package/bundled-skills/faf-expert/SKILL.md +221 -0
  35. package/bundled-skills/faf-wizard/SKILL.md +252 -0
  36. package/bundled-skills/file-uploads/SKILL.md +212 -11
  37. package/bundled-skills/firebase/SKILL.md +646 -16
  38. package/bundled-skills/gcp-cloud-run/SKILL.md +1117 -32
  39. package/bundled-skills/graphql/SKILL.md +1026 -27
  40. package/bundled-skills/hubspot-integration/SKILL.md +804 -19
  41. package/bundled-skills/idea-darwin/SKILL.md +120 -0
  42. package/bundled-skills/inngest/SKILL.md +431 -16
  43. package/bundled-skills/interactive-portfolio/SKILL.md +342 -44
  44. package/bundled-skills/langfuse/SKILL.md +296 -41
  45. package/bundled-skills/langgraph/SKILL.md +259 -50
  46. package/bundled-skills/micro-saas-launcher/SKILL.md +343 -44
  47. package/bundled-skills/neon-postgres/SKILL.md +572 -15
  48. package/bundled-skills/nextjs-supabase-auth/SKILL.md +269 -21
  49. package/bundled-skills/notion-template-business/SKILL.md +371 -44
  50. package/bundled-skills/personal-tool-builder/SKILL.md +537 -44
  51. package/bundled-skills/plaid-fintech/SKILL.md +825 -19
  52. package/bundled-skills/prompt-caching/SKILL.md +438 -25
  53. package/bundled-skills/rag-engineer/SKILL.md +271 -29
  54. package/bundled-skills/salesforce-development/SKILL.md +912 -19
  55. package/bundled-skills/satori/SKILL.md +54 -0
  56. package/bundled-skills/scroll-experience/SKILL.md +381 -44
  57. package/bundled-skills/segment-cdp/SKILL.md +817 -19
  58. package/bundled-skills/shopify-apps/SKILL.md +1475 -19
  59. package/bundled-skills/slack-bot-builder/SKILL.md +1162 -28
  60. package/bundled-skills/telegram-bot-builder/SKILL.md +152 -37
  61. package/bundled-skills/telegram-mini-app/SKILL.md +445 -44
  62. package/bundled-skills/trigger-dev/SKILL.md +916 -27
  63. package/bundled-skills/twilio-communications/SKILL.md +1310 -28
  64. package/bundled-skills/upstash-qstash/SKILL.md +898 -27
  65. package/bundled-skills/vercel-deployment/SKILL.md +637 -39
  66. package/bundled-skills/viral-generator-builder/SKILL.md +132 -37
  67. package/bundled-skills/voice-agents/SKILL.md +937 -27
  68. package/bundled-skills/voice-ai-development/SKILL.md +375 -46
  69. package/bundled-skills/workflow-automation/SKILL.md +982 -29
  70. package/bundled-skills/zapier-make-patterns/SKILL.md +772 -27
  71. package/package.json +1 -1
@@ -1,18 +1,36 @@
1
1
  ---
2
2
  name: email-systems
3
- description: "You are an email systems engineer who has maintained 99.9% deliverability across millions of emails. You've debugged SPF/DKIM/DMARC, dealt with blacklists, and optimized for inbox placement. You know that email is the highest ROI channel when done right, and a spam folder nightmare when done wrong."
3
+ description: Email has the highest ROI of any marketing channel. $36 for every
4
+ $1 spent. Yet most startups treat it as an afterthought - bulk blasts, no
5
+ personalization, landing in spam folders.
4
6
  risk: none
5
7
  source: vibeship-spawner-skills (Apache 2.0)
6
- date_added: '2026-02-27'
8
+ date_added: 2026-02-27
7
9
  ---
8
10
 
9
11
  # Email Systems
10
12
 
11
- You are an email systems engineer who has maintained 99.9% deliverability
12
- across millions of emails. You've debugged SPF/DKIM/DMARC, dealt with
13
- blacklists, and optimized for inbox placement. You know that email is the
14
- highest ROI channel when done right, and a spam folder nightmare when done
15
- wrong. You treat deliverability as infrastructure, not an afterthought.
13
+ Email has the highest ROI of any marketing channel. $36 for every $1 spent.
14
+ Yet most startups treat it as an afterthought - bulk blasts, no personalization,
15
+ landing in spam folders.
16
+
17
+ This skill covers transactional email that works, marketing automation that
18
+ converts, deliverability that reaches inboxes, and the infrastructure decisions
19
+ that scale.
20
+
21
+ ## Principles
22
+
23
+ - Transactional vs Marketing separation | Description: Transactional emails (password reset, receipts) need 100% delivery.
24
+ Marketing emails (newsletters, promos) have lower priority. Use separate
25
+ IP addresses and providers to protect transactional deliverability. | Examples: Good: Password resets via Postmark, marketing via ConvertKit | Bad: All emails through one SendGrid account
26
+ - Permission is everything | Description: Only email people who asked to hear from you. Double opt-in for marketing.
27
+ Easy unsubscribe. Clean your list ruthlessly. Bad lists destroy deliverability. | Examples: Good: Confirmed subscription + one-click unsubscribe | Bad: Scraped email list, hidden unsubscribe, bought contacts
28
+ - Deliverability is infrastructure | Description: SPF, DKIM, DMARC are not optional. Warm up new IPs. Monitor bounce rates.
29
+ Deliverability is earned through technical setup and good behavior. | Examples: Good: All DNS records configured, dedicated IP warmed for 4 weeks | Bad: Using free tier shared IP, no authentication records
30
+ - One email, one goal | Description: Each email should have exactly one purpose and one CTA. Multiple asks
31
+ means nothing gets clicked. Clear single action. | Examples: Good: "Click here to verify your email" (one button) | Bad: "Verify email, check out our blog, follow us on Twitter, refer a friend..."
32
+ - Timing and frequency matter | Description: Wrong time = low open rates. Too frequent = unsubscribes. Let users
33
+ set preferences. Test send times. Respect inbox fatigue. | Examples: Good: Weekly digest on Tuesday 10am user's timezone, preference center | Bad: Daily emails at random times, no way to reduce frequency
16
34
 
17
35
  ## Patterns
18
36
 
@@ -20,40 +38,642 @@ wrong. You treat deliverability as infrastructure, not an afterthought.
20
38
 
21
39
  Queue all transactional emails with retry logic and monitoring
22
40
 
41
+ **When to use**: Sending any critical email (password reset, receipts, confirmations)
42
+
43
+ // Don't block request on email send
44
+ await queue.add('email', {
45
+ template: 'password-reset',
46
+ to: user.email,
47
+ data: { resetToken, expiresAt }
48
+ }, {
49
+ attempts: 3,
50
+ backoff: { type: 'exponential', delay: 2000 }
51
+ });
52
+
23
53
  ### Email Event Tracking
24
54
 
25
55
  Track delivery, opens, clicks, bounces, and complaints
26
56
 
57
+ **When to use**: Any email campaign or transactional flow
58
+
59
+ # Track lifecycle:
60
+ - Queued: Email entered system
61
+ - Sent: Handed to provider
62
+ - Delivered: Reached inbox
63
+ - Opened: Recipient viewed
64
+ - Clicked: Recipient engaged
65
+ - Bounced: Permanent failure
66
+ - Complained: Marked as spam
67
+
27
68
  ### Template Versioning
28
69
 
29
70
  Version email templates for rollback and A/B testing
30
71
 
31
- ## Anti-Patterns
72
+ **When to use**: Changing production email templates
73
+
74
+ templates/
75
+ password-reset/
76
+ v1.tsx (current)
77
+ v2.tsx (testing 10%)
78
+ v1-deprecated.tsx (archived)
79
+
80
+ # Deploy new version gradually
81
+ # Monitor metrics before full rollout
82
+
83
+ ### Bounce Handling State Machine
84
+
85
+ Automatically handle bounces to protect sender reputation
86
+
87
+ **When to use**: Processing bounce and complaint webhooks
88
+
89
+ switch (bounceType) {
90
+ case 'hard':
91
+ await markEmailInvalid(email);
92
+ break;
93
+ case 'soft':
94
+ await incrementBounceCount(email);
95
+ if (count >= 3) await markEmailInvalid(email);
96
+ break;
97
+ case 'complaint':
98
+ await unsubscribeImmediately(email);
99
+ break;
100
+ }
101
+
102
+ ### React Email Components
103
+
104
+ Build emails with reusable React components
105
+
106
+ **When to use**: Creating email templates
107
+
108
+ import { Button, Html } from '@react-email/components';
109
+
110
+ export default function WelcomeEmail({ userName }) {
111
+ return (
112
+ <Html>
113
+ <h1>Welcome {userName}!</h1>
114
+ <Button href="https://app.com/start">
115
+ Get Started
116
+ </Button>
117
+ </Html>
118
+ );
119
+ }
120
+
121
+ ### Preference Center
122
+
123
+ Let users control email frequency and topics
124
+
125
+ **When to use**: Building marketing or notification systems
126
+
127
+ Preferences:
128
+ ☑ Product updates (weekly)
129
+ ☑ New features (monthly)
130
+ ☐ Marketing promotions
131
+ ☑ Account notifications (always)
132
+
133
+ # Respect preferences in all sends
134
+ # Required for GDPR compliance
135
+
136
+ ## Sharp Edges
137
+
138
+ ### Missing SPF, DKIM, or DMARC records
139
+
140
+ Severity: CRITICAL
141
+
142
+ Situation: Sending emails without authentication. Emails going to spam folder.
143
+ Low open rates. No idea why. Turns out DNS records were never set up.
144
+
145
+ Symptoms:
146
+ - Emails going to spam
147
+ - Low deliverability rates
148
+ - mail-tester.com score below 8
149
+ - No DMARC reports received
150
+
151
+ Why this breaks:
152
+ Email authentication (SPF, DKIM, DMARC) tells receiving servers you're
153
+ legit. Without them, you look like a spammer. Modern email providers
154
+ increasingly require all three.
155
+
156
+ Recommended fix:
157
+
158
+ # Required DNS records:
159
+
160
+ ## SPF (Sender Policy Framework)
161
+ TXT record: v=spf1 include:_spf.google.com include:sendgrid.net ~all
162
+
163
+ ## DKIM (DomainKeys Identified Mail)
164
+ TXT record provided by your email provider
165
+ Adds cryptographic signature to emails
166
+
167
+ ## DMARC (Domain-based Message Authentication)
168
+ TXT record: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com
169
+
170
+ # Verify setup:
171
+ - Send test email to mail-tester.com
172
+ - Check MXToolbox for record validation
173
+ - Monitor DMARC reports
174
+
175
+ ### Using shared IP for transactional email
176
+
177
+ Severity: HIGH
178
+
179
+ Situation: Password resets going to spam. Using free tier of email provider.
180
+ Some other customer on your shared IP got flagged for spam.
181
+ Your reputation is ruined by association.
182
+
183
+ Symptoms:
184
+ - Transactional emails in spam
185
+ - Inconsistent delivery
186
+ - Using same provider for marketing and transactional
187
+
188
+ Why this breaks:
189
+ Shared IPs share reputation. One bad actor affects everyone. For
190
+ critical transactional email, you need your own IP or a provider
191
+ with strict shared IP policies.
192
+
193
+ Recommended fix:
194
+
195
+ # Transactional email strategy:
196
+
197
+ ## Option 1: Dedicated IP (high volume)
198
+ - Get dedicated IP from your provider
199
+ - Warm it up slowly (start with 100/day)
200
+ - Maintain consistent volume
201
+
202
+ ## Option 2: Transactional-only provider
203
+ - Postmark (very strict, great reputation)
204
+ - Includes shared pool with high standards
205
+
206
+ ## Separate concerns:
207
+ - Transactional: Postmark or Resend
208
+ - Marketing: ConvertKit or Customer.io
209
+ - Never mix marketing and transactional
210
+
211
+ ### Not processing bounce notifications
212
+
213
+ Severity: HIGH
214
+
215
+ Situation: Emailing same dead addresses over and over. Bounce rate climbing.
216
+ Email provider threatening to suspend account. List is 40% dead.
217
+
218
+ Symptoms:
219
+ - Bounce rate above 2%
220
+ - No webhook handlers for bounces
221
+ - Same emails failing repeatedly
222
+
223
+ Why this breaks:
224
+ Bounces damage sender reputation. Email providers track bounce rates.
225
+ Above 2% and you start looking like a spammer. Dead addresses must
226
+ be removed immediately.
227
+
228
+ Recommended fix:
229
+
230
+ # Bounce handling requirements:
231
+
232
+ ## Hard bounces:
233
+ Remove immediately on first occurrence
234
+ Invalid address, domain doesn't exist
235
+
236
+ ## Soft bounces:
237
+ Retry 3 times over 72 hours
238
+ After 3 failures, treat as hard bounce
239
+
240
+ ## Implementation:
241
+ ```typescript
242
+ // Webhook handler for bounces
243
+ app.post('/webhooks/email', (req, res) => {
244
+ const event = req.body;
245
+ if (event.type === 'bounce') {
246
+ await markEmailInvalid(event.email);
247
+ await removeFromAllLists(event.email);
248
+ }
249
+ });
250
+ ```
251
+
252
+ ## Monitor:
253
+ Track bounce rate by campaign
254
+ Alert if bounce rate exceeds 1%
255
+
256
+ ### Missing or hidden unsubscribe link
257
+
258
+ Severity: CRITICAL
259
+
260
+ Situation: Users marking as spam because they cannot unsubscribe. Spam complaints
261
+ rising. CAN-SPAM violation. Email provider suspends account.
262
+
263
+ Symptoms:
264
+ - Hidden unsubscribe links
265
+ - Multi-step unsubscribe process
266
+ - No List-Unsubscribe header
267
+ - High spam complaint rate
268
+
269
+ Why this breaks:
270
+ Users who cannot unsubscribe will mark as spam. Spam complaints hurt
271
+ reputation more than unsubscribes. Also it is literally illegal.
272
+ CAN-SPAM, GDPR all require clear unsubscribe.
273
+
274
+ Recommended fix:
275
+
276
+ # Unsubscribe requirements:
277
+
278
+ ## Visible:
279
+ - Above the fold in email footer
280
+ - Clear text, not hidden
281
+ - Not styled to be invisible
282
+
283
+ ## One-click:
284
+ - Link directly unsubscribes
285
+ - No login required
286
+ - No "are you sure" hoops
287
+
288
+ ## List-Unsubscribe header:
289
+ ```
290
+ List-Unsubscribe: <mailto:unsubscribe@example.com>,
291
+ <https://example.com/unsubscribe?token=xxx>
292
+ List-Unsubscribe-Post: List-Unsubscribe=One-Click
293
+ ```
294
+
295
+ ## Preference center:
296
+ Option to reduce frequency instead of full unsubscribe
297
+
298
+ ### Sending HTML without plain text alternative
299
+
300
+ Severity: MEDIUM
301
+
302
+ Situation: Some users see blank emails. Spam filters flagging emails. Accessibility
303
+ issues for screen readers. Email clients that strip HTML show nothing.
304
+
305
+ Symptoms:
306
+ - No text/plain part in emails
307
+ - Blank emails for some users
308
+ - Lower engagement in some segments
309
+
310
+ Why this breaks:
311
+ Not everyone can render HTML. Screen readers work better with plain text.
312
+ Spam filters are suspicious of HTML-only. Multipart is the standard.
313
+
314
+ Recommended fix:
315
+
316
+ # Always send multipart:
317
+ ```typescript
318
+ await resend.emails.send({
319
+ from: 'you@example.com',
320
+ to: 'user@example.com',
321
+ subject: 'Welcome!',
322
+ html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
323
+ text: 'Welcome!\n\nThanks for signing up.',
324
+ });
325
+ ```
326
+
327
+ # Auto-generate text from HTML:
328
+ Use html-to-text library as fallback
329
+ But hand-crafted plain text is better
330
+
331
+ # Plain text should be readable:
332
+ Not just HTML stripped of tags
333
+ Actual formatted text content
334
+
335
+ ### Sending high volume from new IP immediately
336
+
337
+ Severity: HIGH
338
+
339
+ Situation: Just switched providers. Started sending 50,000 emails/day immediately.
340
+ Massive deliverability issues. New IP has no reputation. Looks like spam.
341
+
342
+ Symptoms:
343
+ - New IP/provider
344
+ - Sending high volume immediately
345
+ - Sudden deliverability drop
346
+
347
+ Why this breaks:
348
+ New IPs have no reputation. Sending high volume immediately looks
349
+ like a spammer who just spun up. You need to gradually build trust.
350
+
351
+ Recommended fix:
352
+
353
+ # IP warm-up schedule:
354
+
355
+ Week 1: 50-100 emails/day
356
+ Week 2: 200-500 emails/day
357
+ Week 3: 500-1000 emails/day
358
+ Week 4: 1000-5000 emails/day
359
+ Continue doubling until at volume
360
+
361
+ # Best practices:
362
+ - Start with most engaged users
363
+ - Send to Gmail/Microsoft first (they set reputation)
364
+ - Maintain consistent volume
365
+ - Don't spike and drop
366
+
367
+ # During warm-up:
368
+ - Monitor deliverability closely
369
+ - Check feedback loops
370
+ - Adjust pace if issues arise
371
+
372
+ ### Emailing people who did not opt in
32
373
 
33
- ### ❌ HTML email soup
374
+ Severity: CRITICAL
34
375
 
35
- **Why bad**: Email clients render differently. Outlook breaks everything.
376
+ Situation: Bought an email list. Scraped emails from LinkedIn. Added conference
377
+ contacts. Spam complaints through the roof. Provider suspends account.
378
+ Maybe a lawsuit.
36
379
 
37
- ### ❌ No plain text fallback
380
+ Symptoms:
381
+ - Purchased email lists
382
+ - Scraped contacts
383
+ - High unsubscribe rate on first send
384
+ - Spam complaints above 0.1%
38
385
 
39
- **Why bad**: Some clients strip HTML. Accessibility issues. Spam signal.
386
+ Why this breaks:
387
+ Permission-based email is not optional. It is the law (CAN-SPAM, GDPR).
388
+ It is also effective - unwilling recipients hurt your metrics and
389
+ reputation more than they help.
40
390
 
41
- ### ❌ Huge image emails
391
+ Recommended fix:
42
392
 
43
- **Why bad**: Images blocked by default. Spam trigger. Slow loading.
393
+ # Permission requirements:
44
394
 
45
- ## ⚠️ Sharp Edges
395
+ ## Explicit opt-in:
396
+ - User actively chooses to receive email
397
+ - Not pre-checked boxes
398
+ - Clear what they are signing up for
46
399
 
47
- | Issue | Severity | Solution |
48
- |-------|----------|----------|
49
- | Missing SPF, DKIM, or DMARC records | critical | # Required DNS records: |
50
- | Using shared IP for transactional email | high | # Transactional email strategy: |
51
- | Not processing bounce notifications | high | # Bounce handling requirements: |
52
- | Missing or hidden unsubscribe link | critical | # Unsubscribe requirements: |
53
- | Sending HTML without plain text alternative | medium | # Always send multipart: |
54
- | Sending high volume from new IP immediately | high | # IP warm-up schedule: |
55
- | Emailing people who did not opt in | critical | # Permission requirements: |
56
- | Emails that are mostly or entirely images | medium | # Balance images and text: |
400
+ ## Double opt-in:
401
+ - Confirmation email with link
402
+ - Only add to list after confirmation
403
+ - Best practice for marketing lists
404
+
405
+ ## What you cannot do:
406
+ - Buy email lists
407
+ - Scrape emails from websites
408
+ - Add conference contacts without consent
409
+ - Use partner/customer lists without consent
410
+
411
+ ## Transactional exception:
412
+ Password resets, receipts, account alerts
413
+ do not need marketing opt-in
414
+
415
+ ### Emails that are mostly or entirely images
416
+
417
+ Severity: MEDIUM
418
+
419
+ Situation: Beautiful designed email that is one big image. Users with images
420
+ blocked see nothing. Spam filters flag it. Mobile loading is slow.
421
+ No one can copy text.
422
+
423
+ Symptoms:
424
+ - Single image emails
425
+ - No text content visible
426
+ - Missing or generic alt text
427
+ - Low engagement when images blocked
428
+
429
+ Why this breaks:
430
+ Images are blocked by default in many clients. Spam filters are
431
+ suspicious of image-only emails. Accessibility suffers. Load times
432
+ increase.
433
+
434
+ Recommended fix:
435
+
436
+ # Balance images and text:
437
+
438
+ ## 60/40 rule:
439
+ - At least 60% text content
440
+ - Images for enhancement, not content
441
+
442
+ ## Always include:
443
+ - Alt text on every image
444
+ - Key message in text, not just image
445
+ - Fallback for images-off view
446
+
447
+ ## Test:
448
+ - Preview with images disabled
449
+ - Should still be usable
450
+
451
+ # Example:
452
+ ```html
453
+ <img
454
+ src="hero.jpg"
455
+ alt="Save 50% this week - use code SAVE50"
456
+ style="max-width: 100%"
457
+ />
458
+ <p>Use code <strong>SAVE50</strong> to save 50% this week.</p>
459
+ ```
460
+
461
+ ### Missing or default preview text
462
+
463
+ Severity: MEDIUM
464
+
465
+ Situation: Inbox shows "View this email in browser" or random HTML as preview.
466
+ Lower open rates. First impression wasted on boilerplate.
467
+
468
+ Symptoms:
469
+ - View in browser as preview
470
+ - HTML code visible in preview
471
+ - No preview component in template
472
+
473
+ Why this breaks:
474
+ Preview text is prime real estate - appears right after subject line.
475
+ Default or missing preview text wastes this space. Good preview text
476
+ increases open rates 10-30%.
477
+
478
+ Recommended fix:
479
+
480
+ # Add explicit preview text:
481
+
482
+ ## In HTML:
483
+ ```html
484
+ <div style="display:none;max-height:0;overflow:hidden;">
485
+ Your preview text here. This appears in inbox preview.
486
+ <!-- Add whitespace to push footer text out -->
487
+ &nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;
488
+ </div>
489
+ ```
490
+
491
+ ## With React Email:
492
+ ```tsx
493
+ <Preview>
494
+ Your preview text here. This appears in inbox preview.
495
+ </Preview>
496
+ ```
497
+
498
+ ## Best practices:
499
+ - Complement the subject line
500
+ - 40-100 characters optimal
501
+ - Create curiosity or value
502
+ - Different from first line of email
503
+
504
+ ### Not handling partial send failures
505
+
506
+ Severity: HIGH
507
+
508
+ Situation: Sending to 10,000 users. API fails at 3,000. No tracking of what sent.
509
+ Either double-send or lose 7,000. No way to know who got the email.
510
+
511
+ Symptoms:
512
+ - No per-recipient send logging
513
+ - Cannot tell who received email
514
+ - Double-sending issues
515
+ - No retry mechanism
516
+
517
+ Why this breaks:
518
+ Bulk sends fail partially. APIs timeout. Rate limits hit. Without
519
+ tracking individual send status, you cannot recover gracefully.
520
+
521
+ Recommended fix:
522
+
523
+ # Track each send individually:
524
+
525
+ ```typescript
526
+ async function sendCampaign(emails: string[]) {
527
+ const results = await Promise.allSettled(
528
+ emails.map(async (email) => {
529
+ try {
530
+ const result = await resend.emails.send({ to: email, ... });
531
+ await db.emailLog.create({
532
+ email,
533
+ status: 'sent',
534
+ messageId: result.id,
535
+ });
536
+ return result;
537
+ } catch (error) {
538
+ await db.emailLog.create({
539
+ email,
540
+ status: 'failed',
541
+ error: error.message,
542
+ });
543
+ throw error;
544
+ }
545
+ })
546
+ );
547
+
548
+ const failed = results.filter(r => r.status === 'rejected');
549
+ // Retry failed sends or alert
550
+ }
551
+ ```
552
+
553
+ # Best practices:
554
+ - Log every send attempt
555
+ - Include message ID for tracking
556
+ - Build retry queue for failures
557
+ - Monitor success rate per campaign
558
+
559
+ ## Validation Checks
560
+
561
+ ### Missing plain text email part
562
+
563
+ Severity: WARNING
564
+
565
+ Emails should always include a plain text alternative
566
+
567
+ Message: Email being sent with HTML but no plain text part. Add 'text:' property for accessibility and deliverability.
568
+
569
+ ### Hardcoded from email address
570
+
571
+ Severity: WARNING
572
+
573
+ From addresses should come from environment variables
574
+
575
+ Message: From email appears hardcoded. Use environment variable for flexibility.
576
+
577
+ ### Missing bounce webhook handler
578
+
579
+ Severity: WARNING
580
+
581
+ Email bounces should be handled to maintain list hygiene
582
+
583
+ Message: Email provider used but no bounce handling detected. Implement webhook handler for bounces.
584
+
585
+ ### Missing List-Unsubscribe header
586
+
587
+ Severity: INFO
588
+
589
+ Marketing emails should include List-Unsubscribe header
590
+
591
+ Message: Marketing email detected without List-Unsubscribe header. Add header for better deliverability.
592
+
593
+ ### Synchronous email send in request handler
594
+
595
+ Severity: WARNING
596
+
597
+ Email sends should be queued, not blocking
598
+
599
+ Message: Email sent synchronously in request handler. Consider queuing for better reliability.
600
+
601
+ ### Email send without retry logic
602
+
603
+ Severity: INFO
604
+
605
+ Email sends should have retry mechanism for failures
606
+
607
+ Message: Email send without apparent retry logic. Add retry for transient failures.
608
+
609
+ ### Email API key in code
610
+
611
+ Severity: ERROR
612
+
613
+ API keys should come from environment variables
614
+
615
+ Message: Email API key appears hardcoded in source code. Use environment variable.
616
+
617
+ ### Bulk email without rate limiting
618
+
619
+ Severity: WARNING
620
+
621
+ Bulk sends should respect provider rate limits
622
+
623
+ Message: Bulk email sending without apparent rate limiting. Add throttling to avoid hitting limits.
624
+
625
+ ### Email without preview text
626
+
627
+ Severity: INFO
628
+
629
+ Emails should include preview/preheader text
630
+
631
+ Message: Email template without preview text. Add hidden preheader for inbox preview.
632
+
633
+ ### Email send without logging
634
+
635
+ Severity: WARNING
636
+
637
+ Email sends should be logged for debugging and auditing
638
+
639
+ Message: Email being sent without apparent logging. Log sends for debugging and compliance.
640
+
641
+ ## Collaboration
642
+
643
+ ### Delegation Triggers
644
+
645
+ - copy|subject|messaging|content -> copywriting (Email needs copy)
646
+ - design|template|visual|layout -> ui-design (Email needs design)
647
+ - track|analytics|measure|metrics -> analytics-architecture (Email needs tracking)
648
+ - infrastructure|deploy|server|queue -> devops (Email needs infrastructure)
649
+
650
+ ### Email Marketing Stack
651
+
652
+ Skills: email-systems, copywriting, marketing, analytics-architecture
653
+
654
+ Workflow:
655
+
656
+ ```
657
+ 1. Infrastructure setup (email-systems)
658
+ 2. Template creation (email-systems)
659
+ 3. Copy writing (copywriting)
660
+ 4. Campaign launch (marketing)
661
+ 5. Performance tracking (analytics-architecture)
662
+ ```
663
+
664
+ ### Transactional Email
665
+
666
+ Skills: email-systems, backend, devops
667
+
668
+ Workflow:
669
+
670
+ ```
671
+ 1. Provider setup (email-systems)
672
+ 2. Template coding (email-systems)
673
+ 3. Queue integration (backend)
674
+ 4. Monitoring (devops)
675
+ ```
57
676
 
58
677
  ## When to Use
59
- This skill is applicable to execute the workflow or actions described in the overview.
678
+
679
+ Use this skill when the request clearly matches the capabilities and patterns described above.