claude-plugin-wordpress-manager 2.3.1 → 2.4.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 (29) hide show
  1. package/.claude-plugin/plugin.json +8 -3
  2. package/CHANGELOG.md +20 -0
  3. package/agents/wp-distribution-manager.md +98 -0
  4. package/docs/plans/2026-03-01-tier3-wcop-design.md +373 -0
  5. package/docs/plans/2026-03-01-tier3-wcop-implementation.md +915 -0
  6. package/hooks/hooks.json +18 -0
  7. package/package.json +9 -3
  8. package/servers/wp-rest-bridge/build/tools/buffer.d.ts +3 -0
  9. package/servers/wp-rest-bridge/build/tools/buffer.js +205 -0
  10. package/servers/wp-rest-bridge/build/tools/index.js +9 -0
  11. package/servers/wp-rest-bridge/build/tools/mailchimp.d.ts +3 -0
  12. package/servers/wp-rest-bridge/build/tools/mailchimp.js +265 -0
  13. package/servers/wp-rest-bridge/build/tools/sendgrid.d.ts +3 -0
  14. package/servers/wp-rest-bridge/build/tools/sendgrid.js +255 -0
  15. package/servers/wp-rest-bridge/build/types.d.ts +122 -0
  16. package/servers/wp-rest-bridge/build/wordpress.d.ts +9 -0
  17. package/servers/wp-rest-bridge/build/wordpress.js +112 -0
  18. package/skills/wordpress-router/references/decision-tree.md +4 -2
  19. package/skills/wp-content/SKILL.md +1 -0
  20. package/skills/wp-content-repurposing/SKILL.md +1 -0
  21. package/skills/wp-social-email/SKILL.md +152 -0
  22. package/skills/wp-social-email/references/audience-segmentation.md +173 -0
  23. package/skills/wp-social-email/references/buffer-social-publishing.md +124 -0
  24. package/skills/wp-social-email/references/content-to-distribution.md +156 -0
  25. package/skills/wp-social-email/references/distribution-analytics.md +208 -0
  26. package/skills/wp-social-email/references/mailchimp-integration.md +145 -0
  27. package/skills/wp-social-email/references/sendgrid-transactional.md +165 -0
  28. package/skills/wp-social-email/scripts/distribution_inspect.mjs +165 -0
  29. package/skills/wp-webhooks/SKILL.md +1 -0
@@ -0,0 +1,208 @@
1
+ # Distribution Analytics
2
+
3
+ ## Overview
4
+
5
+ Distribution analytics measure the effectiveness of content distributed across email (Mailchimp, SendGrid) and social (Buffer) channels. Tracking performance per channel enables data-driven decisions on content strategy, send timing, and audience targeting.
6
+
7
+ ## Mailchimp Campaign Reports
8
+
9
+ ### Get campaign performance
10
+
11
+ ```
12
+ Tool: mc_get_campaign_report
13
+ Params:
14
+ campaign_id: "campaign_xyz"
15
+ Returns:
16
+ emails_sent: 1250
17
+ opens:
18
+ total: 487
19
+ unique: 412
20
+ rate: 0.33
21
+ clicks:
22
+ total: 98
23
+ unique: 76
24
+ rate: 0.061
25
+ bounces:
26
+ hard: 3
27
+ soft: 12
28
+ unsubscribes: 2
29
+ forwards: 5
30
+ abuse_reports: 0
31
+ ```
32
+
33
+ ### Key Mailchimp metrics
34
+
35
+ | Metric | Calculation | Benchmark |
36
+ |--------|-------------|-----------|
37
+ | Open rate | Unique opens / Delivered | 20-25% |
38
+ | Click rate | Unique clicks / Delivered | 2.5-5% |
39
+ | Click-to-open rate | Unique clicks / Unique opens | 10-15% |
40
+ | Bounce rate | (Hard + Soft bounces) / Sent | < 2% |
41
+ | Unsubscribe rate | Unsubscribes / Delivered | < 0.5% |
42
+ | List growth rate | (New - Unsubscribes) / Total | > 2% monthly |
43
+
44
+ ### Analyzing campaign trends
45
+
46
+ Compare multiple campaigns to identify patterns:
47
+
48
+ ```
49
+ # Fetch reports for recent campaigns
50
+ mc_get_campaign_report campaign_id="campaign_1" → { open_rate: 0.28, click_rate: 0.04 }
51
+ mc_get_campaign_report campaign_id="campaign_2" → { open_rate: 0.35, click_rate: 0.07 }
52
+ mc_get_campaign_report campaign_id="campaign_3" → { open_rate: 0.22, click_rate: 0.03 }
53
+
54
+ # Campaign 2 outperformed — analyze: subject line? send time? content type?
55
+ ```
56
+
57
+ ## Buffer Analytics
58
+
59
+ ### Get social profile analytics
60
+
61
+ ```
62
+ Tool: buf_get_analytics
63
+ Params:
64
+ profile_id: "profile_abc123"
65
+ Returns:
66
+ posts_count: 45
67
+ total_reach: 12500
68
+ total_engagement: 890
69
+ total_clicks: 234
70
+ per_post_average:
71
+ reach: 278
72
+ engagement: 19.8
73
+ clicks: 5.2
74
+ ```
75
+
76
+ ### Key Buffer metrics
77
+
78
+ | Metric | Description | Benchmark |
79
+ |--------|-------------|-----------|
80
+ | Reach | Number of unique users who saw the post | Varies by platform |
81
+ | Engagement | Likes + comments + shares + retweets | 1-3% of reach |
82
+ | Engagement rate | Engagement / Reach | 1-5% (varies by platform) |
83
+ | Clicks | Link clicks from post | 0.5-2% of reach |
84
+ | Click-through rate | Clicks / Reach | 1-3% |
85
+ | Best time to post | Time slot with highest engagement | Platform-specific |
86
+
87
+ ### Identifying top-performing content
88
+
89
+ ```
90
+ Tool: buf_list_sent
91
+ Params:
92
+ profile_id: "profile_abc123"
93
+ count: 50
94
+
95
+ # Sort results by engagement metrics to find top performers
96
+ # Re-share top content using buf_create_update with updated text
97
+ ```
98
+
99
+ ## SendGrid Statistics
100
+
101
+ ### Get email delivery stats
102
+
103
+ ```
104
+ Tool: sg_get_stats
105
+ Params:
106
+ start_date: "2026-03-01"
107
+ end_date: "2026-03-15"
108
+ Returns:
109
+ - date: "2026-03-01"
110
+ metrics:
111
+ requests: 150
112
+ delivered: 148
113
+ opens: 52
114
+ unique_opens: 45
115
+ clicks: 12
116
+ unique_clicks: 10
117
+ bounces: 2
118
+ spam_reports: 0
119
+ blocks: 0
120
+ ```
121
+
122
+ ### Key SendGrid metrics
123
+
124
+ | Metric | Calculation | Benchmark |
125
+ |--------|-------------|-----------|
126
+ | Delivery rate | Delivered / Requests | > 95% |
127
+ | Open rate | Unique opens / Delivered | 15-25% (transactional: 40-60%) |
128
+ | Click rate | Unique clicks / Delivered | 2-5% |
129
+ | Bounce rate | Bounces / Requests | < 3% |
130
+ | Spam complaint rate | Spam reports / Delivered | < 0.1% |
131
+ | Block rate | Blocks / Requests | < 1% |
132
+
133
+ ### Transactional vs marketing benchmarks
134
+
135
+ Transactional emails (welcome, order confirmation) consistently outperform marketing emails:
136
+
137
+ | Type | Open Rate | Click Rate |
138
+ |------|-----------|------------|
139
+ | Transactional | 40-60% | 10-20% |
140
+ | Marketing | 15-25% | 2-5% |
141
+
142
+ ## Cross-Channel Performance Comparison
143
+
144
+ ### Unified metrics dashboard
145
+
146
+ Build a cross-channel view by combining data from all three services:
147
+
148
+ ```
149
+ # Email (Mailchimp campaigns)
150
+ mc_get_campaign_report → opens, clicks, unsubscribes
151
+
152
+ # Social (Buffer)
153
+ buf_get_analytics → reach, engagement, clicks
154
+
155
+ # Transactional (SendGrid)
156
+ sg_get_stats → deliveries, opens, clicks
157
+ ```
158
+
159
+ ### Channel comparison table
160
+
161
+ | Channel | Reach | Engagement Rate | Click Rate | Cost per Click |
162
+ |---------|-------|-----------------|------------|----------------|
163
+ | Email (Mailchimp) | Audience size | Open rate 20-25% | 2.5-5% | Low |
164
+ | Social (Buffer) | Follower count + viral | 1-5% | 0.5-2% | Free (organic) |
165
+ | Transactional (SendGrid) | Per-event | 40-60% open | 10-20% | Per email |
166
+
167
+ ### Attribution tracking
168
+
169
+ Use UTM parameters to track which channel drives conversions in WordPress/WooCommerce:
170
+
171
+ | Channel | UTM Source | UTM Medium | UTM Campaign |
172
+ |---------|-----------|------------|--------------|
173
+ | Mailchimp | `mailchimp` | `email` | `{campaign_name}` |
174
+ | Buffer | `buffer` | `social` | `{post_slug}` |
175
+ | SendGrid | `sendgrid` | `email` | `{template_name}` |
176
+
177
+ ## KPIs and Benchmarks
178
+
179
+ ### Weekly KPIs to track
180
+
181
+ | KPI | Target | Tool |
182
+ |-----|--------|------|
183
+ | Email open rate | > 22% | `mc_get_campaign_report` |
184
+ | Email click rate | > 3% | `mc_get_campaign_report` |
185
+ | Social engagement rate | > 2% | `buf_get_analytics` |
186
+ | Email delivery rate | > 95% | `sg_get_stats` |
187
+ | List growth (net) | > 50/week | `mc_get_audience_members` count delta |
188
+ | Content distributed | 3+ posts/week | Track distribution events |
189
+
190
+ ### Red flags requiring action
191
+
192
+ | Signal | Threshold | Action |
193
+ |--------|-----------|--------|
194
+ | Open rate drop | < 15% | Review subject lines, check deliverability |
195
+ | High unsubscribe rate | > 0.5% | Reduce frequency, improve segmentation |
196
+ | Bounce rate spike | > 5% | Clean list, verify new signups |
197
+ | Spam complaints | > 0.1% | Review content, check opt-in process |
198
+ | Social engagement decline | < 0.5% | Refresh content format, test new posting times |
199
+ | Delivery blocks | > 1% | Check domain reputation, review SPF/DKIM |
200
+
201
+ ## Best Practices
202
+
203
+ - **Weekly review cadence**: Pull analytics every Monday; compare to previous week and 4-week average
204
+ - **A/B test systematically**: Test one variable at a time (subject line, send time, content format) and track results in `mc_get_campaign_report`
205
+ - **Channel-specific goals**: Email optimizes for clicks; social optimizes for engagement; transactional optimizes for delivery
206
+ - **Sunset inactive contacts**: After 90 days of no opens, move contacts to a re-engagement segment or suppress
207
+ - **Document learnings**: Record what subject lines, content types, and send times produce the best results
208
+ - **Automate reporting**: Build a weekly script that calls `mc_get_campaign_report`, `buf_get_analytics`, and `sg_get_stats` to generate a unified report
@@ -0,0 +1,145 @@
1
+ # Mailchimp Integration
2
+
3
+ ## Overview
4
+
5
+ Mailchimp is the email marketing platform for audience management and campaign delivery. The WP REST Bridge provides 7 MCP tools (`mc_*`) that cover the full campaign lifecycle: audience management, campaign creation, content setting, sending, and reporting.
6
+
7
+ ## Setup
8
+
9
+ ### API Key Configuration
10
+
11
+ Add Mailchimp credentials to `WP_SITES_CONFIG`:
12
+
13
+ ```json
14
+ {
15
+ "sites": [{
16
+ "name": "my-site",
17
+ "url": "https://example.com",
18
+ "distribution": {
19
+ "mailchimp": {
20
+ "api_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us14",
21
+ "server_prefix": "us14"
22
+ }
23
+ }
24
+ }]
25
+ }
26
+ ```
27
+
28
+ The server prefix is the suffix of your API key (e.g., `us14`). All Mailchimp API requests route through `https://{server_prefix}.api.mailchimp.com/3.0/`.
29
+
30
+ ## Audience Management
31
+
32
+ ### List all audiences
33
+
34
+ ```
35
+ Tool: mc_list_audiences
36
+ Returns: Array of audiences with id, name, member count, stats
37
+ ```
38
+
39
+ ### Get audience members
40
+
41
+ ```
42
+ Tool: mc_get_audience_members
43
+ Params:
44
+ audience_id: "abc123def4"
45
+ count: 50
46
+ offset: 0
47
+ status: "subscribed" # subscribed | unsubscribed | cleaned | pending
48
+ ```
49
+
50
+ ### Add a subscriber
51
+
52
+ ```
53
+ Tool: mc_add_subscriber
54
+ Params:
55
+ audience_id: "abc123def4"
56
+ email: "user@example.com"
57
+ status: "subscribed"
58
+ merge_fields:
59
+ FNAME: "Jane"
60
+ LNAME: "Doe"
61
+ tags: ["wordpress-user", "blog-subscriber"]
62
+ ```
63
+
64
+ If the email already exists, the subscriber record is updated (upsert behavior).
65
+
66
+ ## Campaign Workflow
67
+
68
+ The campaign lifecycle follows four steps: create → set content → send → report.
69
+
70
+ ### Step 1: Create campaign
71
+
72
+ ```
73
+ Tool: mc_create_campaign
74
+ Params:
75
+ type: "regular" # regular | plaintext | absplit
76
+ audience_id: "abc123def4"
77
+ subject: "March Newsletter: New Blog Posts"
78
+ from_name: "My Site"
79
+ reply_to: "newsletter@example.com"
80
+ Returns: campaign_id
81
+ ```
82
+
83
+ ### Step 2: Set campaign content
84
+
85
+ ```
86
+ Tool: mc_set_campaign_content
87
+ Params:
88
+ campaign_id: "campaign_xyz"
89
+ html: "<html><body><h1>Newsletter</h1>...</body></html>"
90
+ ```
91
+
92
+ For WordPress content, fetch the post with `wp_get_post` and format the content as HTML for the campaign body.
93
+
94
+ ### Step 3: Send campaign
95
+
96
+ ```
97
+ Tool: mc_send_campaign
98
+ Params:
99
+ campaign_id: "campaign_xyz"
100
+ # Or schedule for later:
101
+ # schedule_time: "2026-03-15T10:00:00Z"
102
+ ```
103
+
104
+ ### Step 4: Get report
105
+
106
+ ```
107
+ Tool: mc_get_campaign_report
108
+ Params:
109
+ campaign_id: "campaign_xyz"
110
+ Returns:
111
+ emails_sent: 1250
112
+ opens: { total: 487, unique: 412, rate: 0.33 }
113
+ clicks: { total: 98, unique: 76, rate: 0.061 }
114
+ bounces: { hard: 3, soft: 12 }
115
+ unsubscribes: 2
116
+ ```
117
+
118
+ ## A/B Testing
119
+
120
+ Create an A/B split campaign to test subject lines, content, or send times:
121
+
122
+ ```
123
+ Tool: mc_create_campaign
124
+ Params:
125
+ type: "absplit"
126
+ audience_id: "abc123def4"
127
+ subject: "Version A Subject"
128
+ variate_settings:
129
+ test_size: 30 # 30% of audience gets test
130
+ wait_time: 4 # hours before picking winner
131
+ winner_criteria: "opens"
132
+ subject_lines:
133
+ - "Version A Subject"
134
+ - "Version B Subject"
135
+ ```
136
+
137
+ ## Best Practices
138
+
139
+ - **Send time optimization**: Analyze `mc_get_campaign_report` data to identify peak open hours; schedule campaigns accordingly
140
+ - **List hygiene**: Regularly check for `cleaned` status members; high bounce rates damage sender reputation
141
+ - **Merge fields**: Use `FNAME` personalization in subject lines — personalized subjects see 20-30% higher open rates
142
+ - **Tags over groups**: Use tags for flexible segmentation; they are easier to manage via API than interest groups
143
+ - **Double opt-in**: Enable for GDPR compliance; set subscriber status to `pending` and let Mailchimp handle the confirmation email
144
+ - **Unsubscribe handling**: Never re-add unsubscribed users; check status before calling `mc_add_subscriber`
145
+ - **Frequency**: Monitor unsubscribe rate per campaign; rates above 0.5% indicate over-sending
@@ -0,0 +1,165 @@
1
+ # SendGrid Transactional Email
2
+
3
+ ## Overview
4
+
5
+ SendGrid handles transactional email delivery — messages triggered by user actions such as account creation, password resets, order confirmations, and notifications. The WP REST Bridge provides 6 MCP tools (`sg_*`) for sending email, managing templates, and tracking contacts.
6
+
7
+ ## Setup
8
+
9
+ ### API Key Configuration
10
+
11
+ Add SendGrid credentials to `WP_SITES_CONFIG`:
12
+
13
+ ```json
14
+ {
15
+ "sites": [{
16
+ "name": "my-site",
17
+ "url": "https://example.com",
18
+ "distribution": {
19
+ "sendgrid": {
20
+ "api_key": "SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
21
+ "from_email": "noreply@example.com",
22
+ "from_name": "My Site"
23
+ }
24
+ }
25
+ }]
26
+ }
27
+ ```
28
+
29
+ Use a Restricted Access API key with only the permissions needed (Mail Send, Template Engine, Marketing Contacts).
30
+
31
+ ## Transactional Email
32
+
33
+ ### Send a plain email
34
+
35
+ ```
36
+ Tool: sg_send_email
37
+ Params:
38
+ to: "user@example.com"
39
+ subject: "Welcome to My Site"
40
+ html: "<h1>Welcome!</h1><p>Thanks for creating your account.</p>"
41
+ ```
42
+
43
+ ### Send with a dynamic template
44
+
45
+ ```
46
+ Tool: sg_send_email
47
+ Params:
48
+ to: "user@example.com"
49
+ template_id: "d-abc123def456"
50
+ dynamic_template_data:
51
+ first_name: "Jane"
52
+ order_number: "WC-1042"
53
+ order_total: "$49.99"
54
+ order_url: "https://example.com/my-account/orders/1042"
55
+ ```
56
+
57
+ ### Common transactional email types
58
+
59
+ | Type | Trigger | Template Variables |
60
+ |------|---------|-------------------|
61
+ | Welcome email | User registration | `first_name`, `login_url` |
62
+ | Password reset | Password reset request | `reset_link`, `expiry_time` |
63
+ | Order confirmation | WooCommerce order placed | `order_number`, `items`, `total` |
64
+ | Shipping notification | Order status → shipped | `tracking_number`, `carrier`, `eta` |
65
+ | Review request | 7 days after delivery | `product_name`, `review_url` |
66
+
67
+ ## Template Management
68
+
69
+ ### List templates
70
+
71
+ ```
72
+ Tool: sg_list_templates
73
+ Params:
74
+ generations: "dynamic" # legacy | dynamic
75
+ Returns: Array of templates with id, name, generation, versions
76
+ ```
77
+
78
+ ### Get template details
79
+
80
+ ```
81
+ Tool: sg_get_template
82
+ Params:
83
+ template_id: "d-abc123def456"
84
+ Returns:
85
+ id, name, generation
86
+ versions: [{ id, name, subject, html_content, active }]
87
+ ```
88
+
89
+ Dynamic templates use Handlebars syntax for variable substitution:
90
+
91
+ ```html
92
+ <h1>Hi {{first_name}},</h1>
93
+ <p>Your order #{{order_number}} has been confirmed.</p>
94
+ {{#if tracking_number}}
95
+ <p>Tracking: {{tracking_number}}</p>
96
+ {{/if}}
97
+ ```
98
+
99
+ ## Contact Management
100
+
101
+ ### List contacts
102
+
103
+ ```
104
+ Tool: sg_list_contacts
105
+ Params:
106
+ # Optional search query using SGQL
107
+ query: "email LIKE '%@example.com'"
108
+ Returns: Array of contacts with id, email, first_name, last_name, custom_fields
109
+ ```
110
+
111
+ ### Add or update contacts
112
+
113
+ ```
114
+ Tool: sg_add_contacts
115
+ Params:
116
+ list_ids: ["list_abc123"]
117
+ contacts:
118
+ - email: "user@example.com"
119
+ first_name: "Jane"
120
+ last_name: "Doe"
121
+ custom_fields:
122
+ wp_user_id: "42"
123
+ signup_source: "blog"
124
+ ```
125
+
126
+ Contacts are upserted by email address. If the email already exists, fields are merged.
127
+
128
+ ## WordPress Integration Patterns
129
+
130
+ ### New user → Welcome email
131
+
132
+ ```
133
+ 1. WordPress user_register event triggers webhook
134
+ 2. Webhook handler calls sg_send_email with welcome template
135
+ 3. sg_add_contacts adds user to "New Users" contact list
136
+ ```
137
+
138
+ ### WooCommerce order → Confirmation email
139
+
140
+ ```
141
+ 1. order.created webhook fires
142
+ 2. Extract order details (number, items, total)
143
+ 3. sg_send_email with order confirmation template + dynamic data
144
+ ```
145
+
146
+ ### Blog subscriber → Drip sequence
147
+
148
+ ```
149
+ 1. Newsletter form submission adds subscriber via mc_add_subscriber
150
+ 2. sg_send_email sends immediate welcome/confirmation
151
+ 3. Scheduled follow-ups via campaign automation
152
+ ```
153
+
154
+ ## Best Practices
155
+
156
+ - **SPF/DKIM/DMARC**: Configure DNS records for your sending domain; without these, emails land in spam
157
+ - SPF: Add SendGrid's include to your TXT record
158
+ - DKIM: Create CNAME records provided by SendGrid domain authentication
159
+ - DMARC: Start with `p=none` policy, move to `p=quarantine` after monitoring
160
+ - **Dedicated IP**: For volumes above 50k emails/month, use a dedicated IP and warm it gradually (start with 100/day, increase over 4 weeks)
161
+ - **Bounce handling**: Monitor `sg_get_stats` for bounce rates; rates above 5% trigger SendGrid compliance review
162
+ - **Unsubscribe**: Include an unsubscribe link in every email (required by CAN-SPAM); use SendGrid's built-in unsubscribe groups
163
+ - **Template versioning**: Keep templates in version control; use SendGrid's active version feature to deploy changes safely
164
+ - **Rate limiting**: SendGrid enforces rate limits per API key; batch contact additions in groups of 1000
165
+ - **From address consistency**: Use the same `from_email` across all transactional messages to build domain reputation
@@ -0,0 +1,165 @@
1
+ /**
2
+ * distribution_inspect.mjs — Detect social/email distribution configuration.
3
+ *
4
+ * Checks WP_SITES_CONFIG for connector API keys, WordPress plugins,
5
+ * and content readiness for distribution.
6
+ *
7
+ * Usage:
8
+ * node distribution_inspect.mjs [--cwd=/path/to/project]
9
+ *
10
+ * Exit codes:
11
+ * 0 — distribution configuration found
12
+ * 1 — no distribution configuration found
13
+ */
14
+
15
+ import { readFileSync, existsSync, readdirSync } from 'node:fs';
16
+ import { join, resolve } from 'node:path';
17
+ import { argv, stdout, exit } from 'node:process';
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // Helpers
21
+ // ---------------------------------------------------------------------------
22
+
23
+ function readFileSafe(filePath) {
24
+ try { return readFileSync(filePath, 'utf-8'); } catch { return null; }
25
+ }
26
+
27
+ function existsSafe(filePath) {
28
+ try { return existsSync(filePath); } catch { return false; }
29
+ }
30
+
31
+ function globDir(dirPath) {
32
+ try { return readdirSync(dirPath); } catch { return []; }
33
+ }
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // Detectors
37
+ // ---------------------------------------------------------------------------
38
+
39
+ function detectServices() {
40
+ const services = {
41
+ mailchimp: { configured: false, indicators: [] },
42
+ buffer: { configured: false, indicators: [] },
43
+ sendgrid: { configured: false, indicators: [] },
44
+ };
45
+
46
+ const raw = process.env.WP_SITES_CONFIG;
47
+ if (!raw) return services;
48
+
49
+ let sites;
50
+ try { sites = JSON.parse(raw); } catch { return services; }
51
+ if (!Array.isArray(sites)) return services;
52
+
53
+ for (const site of sites) {
54
+ const label = site.name || site.url || 'unknown';
55
+
56
+ if (site.mailchimp_api_key) {
57
+ services.mailchimp.configured = true;
58
+ services.mailchimp.indicators.push(`mailchimp_api_key configured for ${label}`);
59
+ }
60
+ if (site.buffer_access_token) {
61
+ services.buffer.configured = true;
62
+ services.buffer.indicators.push(`buffer_access_token configured for ${label}`);
63
+ }
64
+ if (site.sendgrid_api_key) {
65
+ services.sendgrid.configured = true;
66
+ services.sendgrid.indicators.push(`sendgrid_api_key configured for ${label}`);
67
+ }
68
+ }
69
+
70
+ return services;
71
+ }
72
+
73
+ function detectDistributionPlugins(cwd) {
74
+ const indicators = [];
75
+ const plugins = globDir(join(cwd, 'wp-content', 'plugins'));
76
+
77
+ const distributionPlugins = [
78
+ 'mailchimp-for-wp', 'mc4wp',
79
+ 'jetpack',
80
+ 'social-warfare', 'monarch', 'shared-counts',
81
+ 'newsletter', 'email-subscribers',
82
+ ];
83
+
84
+ for (const plugin of plugins) {
85
+ if (distributionPlugins.some(dp => plugin.toLowerCase().includes(dp))) {
86
+ indicators.push(`distribution_plugin: ${plugin}`);
87
+ }
88
+ }
89
+
90
+ return { found: indicators.length > 0, indicators };
91
+ }
92
+
93
+ function detectContentReadiness(cwd) {
94
+ // Check wp-content directory exists
95
+ if (!existsSafe(join(cwd, 'wp-content'))) return false;
96
+
97
+ // Check for posts/content indicators
98
+ const uploads = globDir(join(cwd, 'wp-content', 'uploads'));
99
+ if (uploads.length > 0) return true;
100
+
101
+ // Check for themes (site is set up)
102
+ const themes = globDir(join(cwd, 'wp-content', 'themes'));
103
+ if (themes.length > 0) return true;
104
+
105
+ return false;
106
+ }
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // Main
110
+ // ---------------------------------------------------------------------------
111
+
112
+ function main() {
113
+ const cwdArg = argv.find(a => a.startsWith('--cwd='));
114
+ const cwd = cwdArg ? resolve(cwdArg.split('=')[1]) : process.cwd();
115
+
116
+ const services = detectServices();
117
+ const plugins = detectDistributionPlugins(cwd);
118
+ const contentReady = detectContentReadiness(cwd);
119
+
120
+ const hasServices = services.mailchimp.configured ||
121
+ services.buffer.configured ||
122
+ services.sendgrid.configured;
123
+ const found = hasServices || plugins.found;
124
+
125
+ const recommendations = [];
126
+
127
+ if (services.mailchimp.configured) {
128
+ recommendations.push('Mailchimp configured — use distribution_send skill to create and send email campaigns');
129
+ }
130
+ if (services.buffer.configured) {
131
+ recommendations.push('Buffer configured — use distribution_send skill to schedule social media posts');
132
+ }
133
+ if (services.sendgrid.configured) {
134
+ recommendations.push('SendGrid configured — use distribution_send skill for transactional and marketing emails');
135
+ }
136
+ if (plugins.found) {
137
+ recommendations.push('Distribution plugins detected — check plugin settings for additional integration opportunities');
138
+ }
139
+ if (!found) {
140
+ recommendations.push('No distribution configuration detected — use wp-social-email skill to set up Mailchimp, Buffer, or SendGrid');
141
+ }
142
+ if (!contentReady) {
143
+ recommendations.push('No content detected — create posts before setting up distribution workflows');
144
+ }
145
+ if (found && contentReady) {
146
+ recommendations.push('Distribution services and content are ready — consider scheduling an automated campaign');
147
+ }
148
+
149
+ const report = {
150
+ tool: 'distribution_inspect',
151
+ version: '1.0.0',
152
+ timestamp: new Date().toISOString(),
153
+ cwd,
154
+ found,
155
+ services,
156
+ plugins,
157
+ content_ready: contentReady,
158
+ recommendations,
159
+ };
160
+
161
+ stdout.write(JSON.stringify(report, null, 2) + '\n');
162
+ exit(found ? 0 : 1);
163
+ }
164
+
165
+ main();
@@ -105,3 +105,4 @@ See `references/payload-formats.md`
105
105
  - **`wp-headless`** — headless revalidation webhooks and ISR triggers
106
106
  - **`wp-woocommerce`** — WooCommerce store operations (webhook source events)
107
107
  - **`wp-cicd`** — CI/CD webhooks for deployment triggers
108
+ - **wp-social-email** — direct publishing to social/email (alternative to webhook-based distribution)