ima-claude 2.15.0 → 2.16.0

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 (28) hide show
  1. package/README.md +4 -0
  2. package/dist/cli.js +14 -1
  3. package/package.json +1 -1
  4. package/plugins/ima-claude/.claude-plugin/plugin.json +2 -2
  5. package/plugins/ima-claude/skills/ima-copywriting/SKILL.md +232 -0
  6. package/plugins/ima-claude/skills/ima-copywriting/references/format-blog-post.md +51 -0
  7. package/plugins/ima-claude/skills/ima-copywriting/references/format-fundraising-email.md +54 -0
  8. package/plugins/ima-claude/skills/ima-copywriting/references/format-newsletter.md +54 -0
  9. package/plugins/ima-claude/skills/ima-copywriting/references/format-op-ed.md +41 -0
  10. package/plugins/ima-claude/skills/ima-copywriting/references/format-press-release.md +45 -0
  11. package/plugins/ima-claude/skills/ima-copywriting/references/format-social-media.md +141 -0
  12. package/plugins/ima-claude/skills/ima-copywriting/references/format-webinar-email.md +37 -0
  13. package/plugins/ima-claude/skills/ima-copywriting/references/ima-copy-frameworks.md +299 -0
  14. package/plugins/ima-claude/skills/ima-copywriting/references/ima-transitions.md +199 -0
  15. package/plugins/ima-claude/skills/ima-editorial-scorecard/SKILL.md +159 -0
  16. package/plugins/ima-claude/skills/ima-editorial-scorecard/references/format-expectations.md +66 -0
  17. package/plugins/ima-claude/skills/ima-editorial-scorecard/references/scoring-rubrics.md +73 -0
  18. package/plugins/ima-claude/skills/ima-editorial-workflow/SKILL.md +171 -0
  19. package/plugins/ima-claude/skills/ima-email-creator/SKILL.md +104 -0
  20. package/plugins/ima-claude/skills/ima-email-creator/assets/base-template.html +256 -0
  21. package/plugins/ima-claude/skills/ima-email-creator/references/drip-sequence.md +66 -0
  22. package/plugins/ima-claude/skills/ima-email-creator/references/email-css-safe.md +104 -0
  23. package/plugins/ima-claude/skills/ima-email-creator/references/espocrm-compat.md +58 -0
  24. package/plugins/ima-claude/skills/ima-email-creator/references/newsletter-layout.md +127 -0
  25. package/plugins/ima-claude/skills/ima-email-creator/references/wp-transactional.md +77 -0
  26. package/plugins/ima-claude/skills/ima-email-creator/scripts/css-inliner.py +47 -0
  27. package/plugins/ima-claude/skills/ima-email-creator/scripts/espocrm-prep.py +52 -0
  28. package/plugins/ima-claude/skills/ima-email-creator/scripts/requirements.txt +2 -0
@@ -0,0 +1,77 @@
1
+ # PHP Email Template Patterns for WordPress
2
+
3
+ ## Architecture: Pure Function + WordPress Wrapper
4
+
5
+ The IMA codebase separates email generation from sending:
6
+ - **Pure functions** generate HTML/text with zero WordPress dependencies (testable)
7
+ - **WordPress wrappers** handle side effects (wp_mail, user lookups, logging)
8
+
9
+ ## Brand Alignment Note
10
+
11
+ WordPress transactional emails use the **ima-brand plugin colors**: `#00066F` Indigo headers, `#00B8B8` Aquatic Pulse CTAs, `#494949` Gravel text — applied via `ima_brand_email_wrapper()`.
12
+
13
+ Marketing emails (BeeFree/EspoCRM drip and campaign) are now aligned to the same brand book colors: `#00B8B8` Aquatic Pulse CTAs, `#494949` Gravel text — replacing the old `#0296a1`/`#374751` palette. The only distinction is that transactional emails also use `#00066F` Indigo for headers (via `ima_brand_email_wrapper()`), which marketing email templates handle in their own header blocks.
14
+
15
+ ## The Brand Wrapper
16
+
17
+ `ima_brand_email_wrapper()` from `ima-brand` plugin provides:
18
+ - Consistent outer HTML structure (header with logo, footer)
19
+ - Brand colors and typography
20
+ - Location: `wp-content/plugins/ima-brand/includes/email-template.php`
21
+
22
+ ```php
23
+ $html = ima_brand_email_wrapper($inner_html, $subject);
24
+ ```
25
+
26
+ ## Pure Template Pattern
27
+
28
+ ```php
29
+ // inc/pure/email-templates.php
30
+ declare(strict_types=1);
31
+
32
+ function ima_build_invitation_email(array $data): string {
33
+ // Pure function — no WordPress calls, no side effects
34
+ $name = htmlspecialchars($data['name'], ENT_QUOTES, 'UTF-8');
35
+ // ... build HTML with inline styles ...
36
+ return $html;
37
+ }
38
+ ```
39
+
40
+ ## WordPress Wrapper Pattern
41
+
42
+ ```php
43
+ // inc/invitation-emails.php
44
+ function ima_send_invitation_email(int $user_id, string $code): bool {
45
+ $user = get_userdata($user_id);
46
+ $html = ima_build_invitation_email([
47
+ 'name' => $user->display_name,
48
+ 'code' => $code,
49
+ ]);
50
+ $wrapped = ima_brand_email_wrapper($html, 'Your Invitation');
51
+ return wp_mail($user->user_email, 'Your Invitation', $wrapped, [
52
+ 'Content-Type: text/html; charset=UTF-8',
53
+ ]);
54
+ }
55
+ ```
56
+
57
+ ## Existing Email Modules
58
+
59
+ | Module | Location | Purpose |
60
+ |--------|----------|---------|
61
+ | Invitations | child theme `inc/pure/email-templates.php` | Invitation, activation, application emails |
62
+ | Payments | `ima-payments` plugin | Receipt emails with PDF attachments |
63
+ | Memberships | `ima-memberships` plugin | Retention and welcome emails |
64
+ | Registration | `ima-registration` plugin | Email verification codes |
65
+ | Contact forms | `ima-forms` plugin | Form submission notifications |
66
+
67
+ ## Key Rules
68
+
69
+ - Always escape: `htmlspecialchars($value, ENT_QUOTES, 'UTF-8')`
70
+ - Set content type header: `Content-Type: text/html; charset=UTF-8`
71
+ - Use `do_action('ima_log_info', 'Email sent to: ' . $email)` for logging
72
+ - Plain text fallback via `wp_mail` multipart (optional but good practice)
73
+
74
+ ## When to Use This vs. Newsletter/Campaign
75
+
76
+ - **This pattern**: System-triggered emails (verification, receipts, notifications) — lives in PHP, runs in WordPress
77
+ - **Newsletter/Campaign**: Marketing emails created in Claude, pasted into EspoCRM — platform-agnostic HTML
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Inline <style> blocks into element style attributes.
4
+
5
+ Uses premailer to handle CSS specificity correctly. Designed for emails
6
+ built with style blocks (e.g. BeeFree exports) that need inlining for
7
+ Gmail compatibility.
8
+
9
+ Usage:
10
+ python3 css-inliner.py input.html
11
+ python3 css-inliner.py input.html --out output.html
12
+ """
13
+
14
+ import argparse
15
+ import sys
16
+ import premailer
17
+
18
+
19
+ def inline_css(html: str) -> str:
20
+ return premailer.transform(
21
+ html,
22
+ remove_classes=False,
23
+ strip_important=True,
24
+ keep_style_tags=False,
25
+ )
26
+
27
+
28
+ def main():
29
+ parser = argparse.ArgumentParser(description="Inline CSS for email compatibility")
30
+ parser.add_argument("input", help="Input HTML file")
31
+ parser.add_argument("--out", help="Output file (default: stdout)")
32
+ args = parser.parse_args()
33
+
34
+ with open(args.input, "r", encoding="utf-8") as f:
35
+ html = f.read()
36
+
37
+ result = inline_css(html)
38
+
39
+ if args.out:
40
+ with open(args.out, "w", encoding="utf-8") as f:
41
+ f.write(result)
42
+ else:
43
+ sys.stdout.write(result)
44
+
45
+
46
+ if __name__ == "__main__":
47
+ main()
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Extract body content from any HTML email and wrap it in a styled div.
4
+
5
+ Strips document-level tags (<html>, <head>, <body>) and migrates body styles
6
+ to a wrapping div. Works on BeeFree exports, IMA emails, or any HTML.
7
+
8
+ Usage:
9
+ python3 espocrm-prep.py input.html
10
+ python3 espocrm-prep.py input.html --out output.html
11
+ """
12
+
13
+ import argparse
14
+ import sys
15
+ from bs4 import BeautifulSoup
16
+
17
+
18
+ def extract_body_content(html: str) -> str:
19
+ soup = BeautifulSoup(html, "html.parser")
20
+ body = soup.find("body")
21
+
22
+ if body is None:
23
+ return html
24
+
25
+ style = body.get("style", "")
26
+ inner_html = body.decode_contents()
27
+
28
+ if style:
29
+ return f'<div style="{style}">{inner_html}</div>'
30
+ return inner_html
31
+
32
+
33
+ def main():
34
+ parser = argparse.ArgumentParser(description="Prepare HTML email for EspoCRM")
35
+ parser.add_argument("input", help="Input HTML file")
36
+ parser.add_argument("--out", help="Output file (default: stdout)")
37
+ args = parser.parse_args()
38
+
39
+ with open(args.input, "r", encoding="utf-8") as f:
40
+ html = f.read()
41
+
42
+ result = extract_body_content(html)
43
+
44
+ if args.out:
45
+ with open(args.out, "w", encoding="utf-8") as f:
46
+ f.write(result)
47
+ else:
48
+ sys.stdout.write(result)
49
+
50
+
51
+ if __name__ == "__main__":
52
+ main()
@@ -0,0 +1,2 @@
1
+ beautifulsoup4>=4.12
2
+ premailer>=3.10